[PATCH v6 15/18] fpga: region: move device tree support to of-fpga-region.c

2017-11-15 Thread Alan Tull
Create of-fpga-region.c and move the following functions without
modification from fpga-region.c.

* of_fpga_region_find
* of_fpga_region_get_mgr
* of_fpga_region_get_bridges
* child_regions_with_firmware
* of_fpga_region_parse_ov
* of_fpga_region_notify_pre_apply
* of_fpga_region_notify_post_remove
* of_fpga_region_notify
* of_fpga_region_probe
* of_fpga_region_remove

Create two new functions with some code from fpga_region_init/exit.

* of_fpga_region_init
* of_fpga_region_exit

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: split out code changes into other patches, only move code here
v3: updated to move changed code to of-fpga-region.c
v4: rebase on current for-next
remove fpga-bridge dependency on CONFIG_OF
v5: fix some nits in the header
reword Kconfig description of OF_FPGA_REGION
v6: Add Moritz' ack
---
 drivers/fpga/Kconfig  |  15 +-
 drivers/fpga/Makefile |   1 +
 drivers/fpga/fpga-region.c| 452 +-
 drivers/fpga/of-fpga-region.c | 496 ++
 4 files changed, 509 insertions(+), 455 deletions(-)
 create mode 100644 drivers/fpga/of-fpga-region.c

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index ad5448f..12bd1c7 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -13,10 +13,18 @@ if FPGA
 
 config FPGA_REGION
tristate "FPGA Region"
-   depends on OF && FPGA_BRIDGE
+   depends on FPGA_BRIDGE
+   help
+ FPGA Region common code.  A FPGA Region controls a FPGA Manager
+ and the FPGA Bridges associated with either a reconfigurable
+ region of an FPGA or a whole FPGA.
+
+config OF_FPGA_REGION
+   tristate "FPGA Region Device Tree Overlay Support"
+   depends on OF && FPGA_REGION
help
- FPGA Regions allow loading FPGA images under control of
- the Device Tree.
+ Support for loading FPGA images by applying a Device Tree
+ overlay.
 
 config FPGA_MGR_ICE40_SPI
tristate "Lattice iCE40 SPI"
@@ -74,7 +82,6 @@ config FPGA_MGR_ZYNQ_FPGA
 
 config FPGA_BRIDGE
tristate "FPGA Bridge Framework"
-   depends on OF
help
  Say Y here if you want to support bridges connected between host
  processors and FPGAs or between FPGAs.
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index f98dcf1..3cb276a 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_XILINX_PR_DECOUPLER) += xilinx-pr-decoupler.o
 
 # High Level Interfaces
 obj-$(CONFIG_FPGA_REGION)  += fpga-region.o
+obj-$(CONFIG_OF_FPGA_REGION)   += of-fpga-region.o
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 5c086957..afc6188 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -2,6 +2,7 @@
  * FPGA Region - Device Tree support for FPGA programming under Linux
  *
  *  Copyright (C) 2013-2016 Altera Corporation
+ *  Copyright (C) 2017 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -23,7 +24,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 
@@ -44,30 +44,6 @@ struct fpga_region *fpga_region_class_find(
 }
 EXPORT_SYMBOL_GPL(fpga_region_class_find);
 
-static const struct of_device_id fpga_region_of_match[] = {
-   { .compatible = "fpga-region", },
-   {},
-};
-MODULE_DEVICE_TABLE(of, fpga_region_of_match);
-
-static int fpga_region_of_node_match(struct device *dev, const void *data)
-{
-   return dev->of_node == data;
-}
-
-/**
- * of_fpga_region_find - find FPGA region
- * @np: device node of FPGA Region
- *
- * Caller will need to put_device(>dev) when done.
- *
- * Returns FPGA Region struct or NULL
- */
-static struct fpga_region *of_fpga_region_find(struct device_node *np)
-{
-   return fpga_region_class_find(NULL, np, fpga_region_of_node_match);
-}
-
 /**
  * fpga_region_get - get an exclusive reference to a fpga region
  * @region: FPGA Region struct
@@ -116,102 +92,6 @@ static void fpga_region_put(struct fpga_region *region)
 }
 
 /**
- * of_fpga_region_get_mgr - get reference for FPGA manager
- * @np: device node of FPGA region
- *
- * Get FPGA Manager from "fpga-mgr" property or from ancestor region.
- *
- * Caller should call fpga_mgr_put() when done with manager.
- *
- * Return: fpga manager struct or IS_ERR() condition containing error code.
- */
-static struct fpga_manager *of_fpga_region_get_mgr(struct device_node *np)
-{
-   struct device_node  *mgr_node;
-   struct fpga_manager *mgr;
-
-   of_node_get(np);
-   while (np) {
-   if (of_device_is_compatible(np, "fpga-region")) {
-   mgr_node = of_parse

[PATCH v6 16/18] fpga: of-fpga-region: accept overlays that don't program FPGA

2017-11-15 Thread Alan Tull
The FPGA may already have a static image programmed when
Linux boots.  In that case a DT overlay may be used to add
the devices that already exist.  This commit allows that
by shuffling the order of some checks.

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v4: Patch added to patchset in v4
v5: no change to this patch in this version of patchset
v6: Add Moritz' ack
---
 drivers/fpga/of-fpga-region.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index 1533506..c6b2119 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -298,18 +298,19 @@ static int of_fpga_region_notify_pre_apply(struct 
fpga_region *region,
struct fpga_image_info *info;
int ret;
 
-   if (region->info) {
-   dev_err(dev, "Region already has overlay applied.\n");
-   return -EINVAL;
-   }
-
info = of_fpga_region_parse_ov(region, nd->overlay);
if (IS_ERR(info))
return PTR_ERR(info);
 
+   /* If overlay doesn't program the FPGA, accept it anyway. */
if (!info)
return 0;
 
+   if (region->info) {
+   dev_err(dev, "Region already has overlay applied.\n");
+   return -EINVAL;
+   }
+
region->info = info;
ret = fpga_region_program_fpga(region);
if (ret) {
-- 
2.7.4



[PATCH v6 18/18] fpga: add attribute groups

2017-11-15 Thread Alan Tull
Make it easy to add attributes to low level FPGA drivers the right
way.  Add attribute groups pointers to structures that are used when
registering a manager, bridge, or group.  When the low level driver
registers, set the device attribute group.  The attributes are
created in device_add.

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v4: Patch added to patchset in v4
v5: no change to this patch in this version of patchset
v6: Add Moritz' ack
---
 drivers/fpga/fpga-bridge.c   | 1 +
 drivers/fpga/fpga-mgr.c  | 1 +
 drivers/fpga/fpga-region.c   | 1 +
 include/linux/fpga/fpga-bridge.h | 2 ++
 include/linux/fpga/fpga-mgr.h| 2 ++
 include/linux/fpga/fpga-region.h | 2 ++
 6 files changed, 9 insertions(+)

diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
index 0dfe9d7..e693c36 100644
--- a/drivers/fpga/fpga-bridge.c
+++ b/drivers/fpga/fpga-bridge.c
@@ -367,6 +367,7 @@ int fpga_bridge_register(struct device *dev, const char 
*name,
bridge->priv = priv;
 
device_initialize(>dev);
+   bridge->dev.groups = br_ops->groups;
bridge->dev.class = fpga_bridge_class;
bridge->dev.parent = dev;
bridge->dev.of_node = dev->of_node;
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index d27e8d2..223f240 100644
--- a/drivers/fpga/fpga-mgr.c
+++ b/drivers/fpga/fpga-mgr.c
@@ -569,6 +569,7 @@ int fpga_mgr_register(struct device *dev, const char *name,
 
device_initialize(>dev);
mgr->dev.class = fpga_mgr_class;
+   mgr->dev.groups = mops->groups;
mgr->dev.parent = dev;
mgr->dev.of_node = dev->of_node;
mgr->dev.id = id;
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index afc6188..edab2a2 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -173,6 +173,7 @@ int fpga_region_register(struct device *dev, struct 
fpga_region *region)
mutex_init(>mutex);
INIT_LIST_HEAD(>bridge_list);
device_initialize(>dev);
+   region->dev.groups = region->groups;
region->dev.class = fpga_region_class;
region->dev.parent = dev;
region->dev.of_node = dev->of_node;
diff --git a/include/linux/fpga/fpga-bridge.h b/include/linux/fpga/fpga-bridge.h
index 6ca41f8..3694821 100644
--- a/include/linux/fpga/fpga-bridge.h
+++ b/include/linux/fpga/fpga-bridge.h
@@ -13,11 +13,13 @@ struct fpga_bridge;
  * @enable_show: returns the FPGA bridge's status
  * @enable_set: set a FPGA bridge as enabled or disabled
  * @fpga_bridge_remove: set FPGA into a specific state during driver remove
+ * @groups: optional attribute groups.
  */
 struct fpga_bridge_ops {
int (*enable_show)(struct fpga_bridge *bridge);
int (*enable_set)(struct fpga_bridge *bridge, bool enable);
void (*fpga_bridge_remove)(struct fpga_bridge *bridge);
+   const struct attribute_group **groups;
 };
 
 /**
diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
index 4fb706b..3c6de23 100644
--- a/include/linux/fpga/fpga-mgr.h
+++ b/include/linux/fpga/fpga-mgr.h
@@ -115,6 +115,7 @@ struct fpga_image_info {
  * @write_sg: write the scatter list of configuration data to the FPGA
  * @write_complete: set FPGA to operating state after writing is done
  * @fpga_remove: optional: Set FPGA into a specific state during driver remove
+ * @groups: optional attribute groups.
  *
  * fpga_manager_ops are the low level functions implemented by a specific
  * fpga manager driver.  The optional ones are tested for NULL before being
@@ -131,6 +132,7 @@ struct fpga_manager_ops {
int (*write_complete)(struct fpga_manager *mgr,
  struct fpga_image_info *info);
void (*fpga_remove)(struct fpga_manager *mgr);
+   const struct attribute_group **groups;
 };
 
 /**
diff --git a/include/linux/fpga/fpga-region.h b/include/linux/fpga/fpga-region.h
index 7048449..b652031 100644
--- a/include/linux/fpga/fpga-region.h
+++ b/include/linux/fpga/fpga-region.h
@@ -14,6 +14,7 @@
  * @info: FPGA image info
  * @priv: private data
  * @get_bridges: optional function to get bridges to a list
+ * @groups: optional attribute groups.
  */
 struct fpga_region {
struct device dev;
@@ -23,6 +24,7 @@ struct fpga_region {
struct fpga_image_info *info;
void *priv;
int (*get_bridges)(struct fpga_region *region);
+   const struct attribute_group **groups;
 };
 
 #define to_fpga_region(d) container_of(d, struct fpga_region, dev)
-- 
2.7.4



[PATCH v6 13/18] fpga: region: add register/unregister functions

2017-11-15 Thread Alan Tull
Another step in separating common code from device tree specific
code for FPGA regions.

* add FPGA region register/unregister functions.
* add the register/unregister functions to the header
* use devm_kzalloc to alloc the region.
* add a method for getting bridges to the region struct
* add priv to the region struct
* use region->info in of_fpga_region_get_bridges

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: split out from another patch
v3: use region->info, remove info param where applicable
v4: no change to this patch in this version of patchset
v5: add back in fpga_mgr_put in of_fpga_region_remove
v6: Add Moritz' ack
---
 drivers/fpga/fpga-region.c   | 105 ---
 include/linux/fpga/fpga-region.h |   7 +++
 2 files changed, 72 insertions(+), 40 deletions(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 92ab216..76db81d 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -143,7 +143,6 @@ static struct fpga_manager *of_fpga_region_get_mgr(struct 
device_node *np)
 /**
  * of_fpga_region_get_bridges - create a list of bridges
  * @region: FPGA region
- * @info: FPGA image info
  *
  * Create a list of bridges including the parent bridge and the bridges
  * specified by "fpga-bridges" property.  Note that the
@@ -156,11 +155,11 @@ static struct fpga_manager *of_fpga_region_get_mgr(struct 
device_node *np)
  * Return 0 for success (even if there are no bridges specified)
  * or -EBUSY if any of the bridges are in use.
  */
-static int of_fpga_region_get_bridges(struct fpga_region *region,
- struct fpga_image_info *info)
+static int of_fpga_region_get_bridges(struct fpga_region *region)
 {
struct device *dev = >dev;
struct device_node *region_np = dev->of_node;
+   struct fpga_image_info *info = region->info;
struct device_node *br, *np, *parent_br = NULL;
int i, ret;
 
@@ -192,7 +191,7 @@ static int of_fpga_region_get_bridges(struct fpga_region 
*region,
continue;
 
/* If node is a bridge, get it and add to list */
-   ret = of_fpga_bridge_get_to_list(br, region->info,
+   ret = of_fpga_bridge_get_to_list(br, info,
 >bridge_list);
 
/* If any of the bridges are in use, give up */
@@ -229,10 +228,16 @@ int fpga_region_program_fpga(struct fpga_region *region)
goto err_put_region;
}
 
-   ret = of_fpga_region_get_bridges(region, info);
-   if (ret) {
-   dev_err(dev, "failed to get FPGA bridges\n");
-   goto err_unlock_mgr;
+   /*
+* In some cases, we already have a list of bridges in the
+* fpga region struct.  Or we don't have any bridges.
+*/
+   if (region->get_bridges) {
+   ret = region->get_bridges(region);
+   if (ret) {
+   dev_err(dev, "failed to get fpga region bridges\n");
+   goto err_unlock_mgr;
+   }
}
 
ret = fpga_bridges_disable(>bridge_list);
@@ -259,7 +264,8 @@ int fpga_region_program_fpga(struct fpga_region *region)
return 0;
 
 err_put_br:
-   fpga_bridges_put(>bridge_list);
+   if (region->get_bridges)
+   fpga_bridges_put(>bridge_list);
 err_unlock_mgr:
fpga_mgr_unlock(region->mgr);
 err_put_region:
@@ -522,39 +528,20 @@ static struct notifier_block fpga_region_of_nb = {
.notifier_call = of_fpga_region_notify,
 };
 
-static int of_fpga_region_probe(struct platform_device *pdev)
+int fpga_region_register(struct device *dev, struct fpga_region *region)
 {
-   struct device *dev = >dev;
-   struct device_node *np = dev->of_node;
-   struct fpga_region *region;
-   struct fpga_manager *mgr;
int id, ret = 0;
 
-   mgr = of_fpga_region_get_mgr(np);
-   if (IS_ERR(mgr))
-   return -EPROBE_DEFER;
-
-   region = kzalloc(sizeof(*region), GFP_KERNEL);
-   if (!region) {
-   ret = -ENOMEM;
-   goto err_put_mgr;
-   }
-
-   region->mgr = mgr;
-
id = ida_simple_get(_region_ida, 0, 0, GFP_KERNEL);
-   if (id < 0) {
-   ret = id;
-   goto err_kfree;
-   }
+   if (id < 0)
+   return id;
 
mutex_init(>mutex);
INIT_LIST_HEAD(>bridge_list);
-
device_initialize(>dev);
region->dev.class = fpga_region_class;
region->dev.parent = dev;
-   region->dev.of_node = np;
+   region->dev.of_node = dev->of_node;
region->dev.id = id;
dev_set_drvdata(dev, region);
 
@@ -566,19 +553,58 @@ static int of_fpga_region_probe(struct platform

[PATCH v6 17/18] fpga: clean up fpga Kconfig

2017-11-15 Thread Alan Tull
The fpga menuconfig has gotten messy.  The bridges and managers are
mixed together.

* Separate the bridges and things dependent on CONFIG_FPGA_BRIDGE
  from the managers.
* Group the managers by vendor in order that they were added
  to the kernel.

The following is what the menuconfig ends up looking like more or less
(platform dependencies are hiding some of these on any given
platform).

--- FPGA Configuration Framework
<*>   Altera SOCFPGA FPGA Manager
<*>   Altera SoCFPGA Arria10
<*>   Altera Partial Reconfiguration IP Core
<*> Platform support of Altera Partial Reconfiguration IP Core
<*>   Altera FPGA Passive Serial over SPI
<*>   Altera Arria-V/Cyclone-V/Stratix-V CvP FPGA Manager
<*>   Xilinx Zynq FPGA
<*>   Xilinx Configuration over Slave Serial (SPI)
<*>   Lattice iCE40 SPI
<*>   Technologic Systems TS-73xx SBC FPGA Manager
<*>   FPGA Bridge Framework
<*> Altera SoCFPGA FPGA Bridges
<*> Altera FPGA Freeze Bridge
<*> Xilinx LogiCORE PR Decoupler
<*>     FPGA Region
<*>   FPGA Region Device Tree Overlay Support

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v4: Patch added to patchset in v4
v5: s/mixxed/mixed/
v6: Add Moritz' ack
---
 drivers/fpga/Kconfig | 108 +--
 1 file changed, 54 insertions(+), 54 deletions(-)

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index 12bd1c7..f47ef84 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -11,33 +11,30 @@ menuconfig FPGA
 
 if FPGA
 
-config FPGA_REGION
-   tristate "FPGA Region"
-   depends on FPGA_BRIDGE
+config FPGA_MGR_SOCFPGA
+   tristate "Altera SOCFPGA FPGA Manager"
+   depends on ARCH_SOCFPGA || COMPILE_TEST
help
- FPGA Region common code.  A FPGA Region controls a FPGA Manager
- and the FPGA Bridges associated with either a reconfigurable
- region of an FPGA or a whole FPGA.
+ FPGA manager driver support for Altera SOCFPGA.
 
-config OF_FPGA_REGION
-   tristate "FPGA Region Device Tree Overlay Support"
-   depends on OF && FPGA_REGION
+config FPGA_MGR_SOCFPGA_A10
+   tristate "Altera SoCFPGA Arria10"
+   depends on ARCH_SOCFPGA || COMPILE_TEST
+   select REGMAP_MMIO
help
- Support for loading FPGA images by applying a Device Tree
- overlay.
+ FPGA manager driver support for Altera Arria10 SoCFPGA.
 
-config FPGA_MGR_ICE40_SPI
-   tristate "Lattice iCE40 SPI"
-   depends on OF && SPI
-   help
- FPGA manager driver support for Lattice iCE40 FPGAs over SPI.
+config ALTERA_PR_IP_CORE
+tristate "Altera Partial Reconfiguration IP Core"
+help
+  Core driver support for Altera Partial Reconfiguration IP component
 
-config FPGA_MGR_ALTERA_CVP
-   tristate "Altera Arria-V/Cyclone-V/Stratix-V CvP FPGA Manager"
-   depends on PCI
+config ALTERA_PR_IP_CORE_PLAT
+   tristate "Platform support of Altera Partial Reconfiguration IP Core"
+   depends on ALTERA_PR_IP_CORE && OF && HAS_IOMEM
help
- FPGA manager driver support for Arria-V, Cyclone-V, Stratix-V
- and Arria 10 Altera FPGAs using the CvP interface over PCIe.
+ Platform driver support for Altera Partial Reconfiguration IP
+ component
 
 config FPGA_MGR_ALTERA_PS_SPI
tristate "Altera FPGA Passive Serial over SPI"
@@ -46,25 +43,19 @@ config FPGA_MGR_ALTERA_PS_SPI
  FPGA manager driver support for Altera Arria/Cyclone/Stratix
  using the passive serial interface over SPI.
 
-config FPGA_MGR_SOCFPGA
-   tristate "Altera SOCFPGA FPGA Manager"
-   depends on ARCH_SOCFPGA || COMPILE_TEST
-   help
- FPGA manager driver support for Altera SOCFPGA.
-
-config FPGA_MGR_SOCFPGA_A10
-   tristate "Altera SoCFPGA Arria10"
-   depends on ARCH_SOCFPGA || COMPILE_TEST
-   select REGMAP_MMIO
+config FPGA_MGR_ALTERA_CVP
+   tristate "Altera Arria-V/Cyclone-V/Stratix-V CvP FPGA Manager"
+   depends on PCI
help
- FPGA manager driver support for Altera Arria10 SoCFPGA.
+ FPGA manager driver support for Arria-V, Cyclone-V, Stratix-V
+ and Arria 10 Altera FPGAs using the CvP interface over PCIe.
 
-config FPGA_MGR_TS73XX
-   tristate "Technologic Systems TS-73xx SBC FPGA Manager"
-   depends on ARCH_EP93XX && MACH_TS72XX
+config FPGA_MGR_ZYNQ_FPGA
+   tristate "Xilinx Zynq FPGA"
+   depends on ARCH_ZYNQ || COMPILE_TEST
+   depends on HAS_DMA
help
- FPGA manager driver support for the Altera Cyclone II F

[PATCH v6 11/18] fpga: region: add fpga-region.h header

2017-11-15 Thread Alan Tull
* Create fpga-region.h.
* Export fpga_region_program_fpga.
* Move struct fpga_region and other things to the header.

This is a step in separating FPGA region common code
from Device Tree support.

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: split out from another patch
update author email
v3: changes due to fpga_region_program_fpga() removed info param
v4: no change to this patch in this version of patchset
v5: fpga-region.h - move #ifndef before #includes
v6: Add Moritz' ack
---
 drivers/fpga/fpga-region.c   | 24 
 include/linux/fpga/fpga-region.h | 28 
 2 files changed, 32 insertions(+), 20 deletions(-)
 create mode 100644 include/linux/fpga/fpga-region.h

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 2a8621d..402d0b6 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -18,6 +18,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -26,24 +27,6 @@
 #include 
 #include 
 
-/**
- * struct fpga_region - FPGA Region structure
- * @dev: FPGA Region device
- * @mutex: enforces exclusive reference to region
- * @bridge_list: list of FPGA bridges specified in region
- * @mgr: FPGA manager
- * @info: fpga image specific information
- */
-struct fpga_region {
-   struct device dev;
-   struct mutex mutex; /* for exclusive reference to region */
-   struct list_head bridge_list;
-   struct fpga_manager *mgr;
-   struct fpga_image_info *info;
-};
-
-#define to_fpga_region(d) container_of(d, struct fpga_region, dev)
-
 static DEFINE_IDA(fpga_region_ida);
 static struct class *fpga_region_class;
 
@@ -226,7 +209,7 @@ static int fpga_region_get_bridges(struct fpga_region 
*region,
  * Program an FPGA using fpga image info (region->info).
  * Return 0 for success or negative error code.
  */
-static int fpga_region_program_fpga(struct fpga_region *region)
+int fpga_region_program_fpga(struct fpga_region *region)
 {
struct device *dev = >dev;
struct fpga_image_info *info = region->info;
@@ -282,6 +265,7 @@ static int fpga_region_program_fpga(struct fpga_region 
*region)
 
return ret;
 }
+EXPORT_SYMBOL_GPL(fpga_region_program_fpga);
 
 /**
  * child_regions_with_firmware
@@ -667,5 +651,5 @@ subsys_initcall(fpga_region_init);
 module_exit(fpga_region_exit);
 
 MODULE_DESCRIPTION("FPGA Region");
-MODULE_AUTHOR("Alan Tull <at...@opensource.altera.com>");
+MODULE_AUTHOR("Alan Tull <at...@kernel.org>");
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/fpga/fpga-region.h b/include/linux/fpga/fpga-region.h
new file mode 100644
index 000..8a35517
--- /dev/null
+++ b/include/linux/fpga/fpga-region.h
@@ -0,0 +1,28 @@
+#ifndef _FPGA_REGION_H
+#define _FPGA_REGION_H
+
+#include 
+#include 
+#include 
+
+/**
+ * struct fpga_region - FPGA Region structure
+ * @dev: FPGA Region device
+ * @mutex: enforces exclusive reference to region
+ * @bridge_list: list of FPGA bridges specified in region
+ * @mgr: FPGA manager
+ * @info: FPGA image info
+ */
+struct fpga_region {
+   struct device dev;
+   struct mutex mutex; /* for exclusive reference to region */
+   struct list_head bridge_list;
+   struct fpga_manager *mgr;
+   struct fpga_image_info *info;
+};
+
+#define to_fpga_region(d) container_of(d, struct fpga_region, dev)
+
+int fpga_region_program_fpga(struct fpga_region *region);
+
+#endif /* _FPGA_REGION_H */
-- 
2.7.4



[PATCH v6 09/18] fpga: region: use image info as parameter for programming region

2017-11-15 Thread Alan Tull
Use FPGA image info (region->info) when region code is
programming the FPGA to pass in multiple parameters.

This is a baby step in refactoring the FPGA region code to
separate out common FPGA region code from FPGA region
Device Tree overlay support.

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: split out from another patch
v3: change API to use the region->info, remove info param
remove check for region->info, not needed
v4: no change to this patch in this version of patchset
v5: no change to this patch in this version of patchset
v6: Add Moritz' ack
---
 drivers/fpga/fpga-region.c| 16 +---
 include/linux/fpga/fpga-mgr.h |  4 
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 35af952..eaacf50 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -223,14 +223,13 @@ static int fpga_region_get_bridges(struct fpga_region 
*region,
 /**
  * fpga_region_program_fpga - program FPGA
  * @region: FPGA region
- * @overlay: device node of the overlay
- * Program an FPGA using information in the region's fpga image info.
+ * Program an FPGA using fpga image info (region->info).
  * Return 0 for success or negative error code.
  */
-static int fpga_region_program_fpga(struct fpga_region *region,
-   struct device_node *overlay)
+static int fpga_region_program_fpga(struct fpga_region *region)
 {
struct device *dev = >dev;
+   struct fpga_image_info *info = region->info;
int ret;
 
region = fpga_region_get(region);
@@ -245,7 +244,7 @@ static int fpga_region_program_fpga(struct fpga_region 
*region,
goto err_put_region;
}
 
-   ret = fpga_region_get_bridges(region, overlay);
+   ret = fpga_region_get_bridges(region, info->overlay);
if (ret) {
dev_err(dev, "failed to get FPGA bridges\n");
goto err_unlock_mgr;
@@ -257,7 +256,7 @@ static int fpga_region_program_fpga(struct fpga_region 
*region,
goto err_put_br;
}
 
-   ret = fpga_mgr_load(region->mgr, region->info);
+   ret = fpga_mgr_load(region->mgr, info);
if (ret) {
dev_err(dev, "failed to load FPGA image\n");
goto err_put_br;
@@ -373,6 +372,8 @@ static int fpga_region_notify_pre_apply(struct fpga_region 
*region,
if (!info)
return -ENOMEM;
 
+   info->overlay = nd->overlay;
+
/* Read FPGA region properties from the overlay */
if (of_property_read_bool(nd->overlay, "partial-fpga-config"))
info->flags |= FPGA_MGR_PARTIAL_RECONFIG;
@@ -421,7 +422,8 @@ static int fpga_region_notify_pre_apply(struct fpga_region 
*region,
}
 
region->info = info;
-   ret = fpga_region_program_fpga(region, nd->overlay);
+
+   ret = fpga_region_program_fpga(region);
if (ret) {
fpga_image_info_free(info);
region->info = NULL;
diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
index cb5615c..4fb706b 100644
--- a/include/linux/fpga/fpga-mgr.h
+++ b/include/linux/fpga/fpga-mgr.h
@@ -89,6 +89,7 @@ enum fpga_mgr_states {
  * @buf: contiguous buffer containing FPGA image
  * @count: size of buf
  * @dev: device that owns this
+ * @overlay: Device Tree overlay
  */
 struct fpga_image_info {
u32 flags;
@@ -100,6 +101,9 @@ struct fpga_image_info {
const char *buf;
size_t count;
struct device *dev;
+#ifdef CONFIG_OF
+   struct device_node *overlay;
+#endif
 };
 
 /**
-- 
2.7.4



[PATCH v6 06/18] fpga: region: get mgr early on

2017-11-15 Thread Alan Tull
Get the FPGA manager during region creation.

This is a baby step in refactoring the FPGA region code to
separate out common FPGA region code from FPGA region
Device Tree overlay support.

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: split out from another patch
v3: no change to this patch in this version of patchset
v4: no change to this patch in this version of patchset
v5: no change to this patch in this version of patchset
v6: Add Moritz' ack
---
 drivers/fpga/fpga-region.c | 45 +++--
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 352661f..d78f444 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -31,12 +31,14 @@
  * @dev: FPGA Region device
  * @mutex: enforces exclusive reference to region
  * @bridge_list: list of FPGA bridges specified in region
+ * @mgr: FPGA manager
  * @info: fpga image specific information
  */
 struct fpga_region {
struct device dev;
struct mutex mutex; /* for exclusive reference to region */
struct list_head bridge_list;
+   struct fpga_manager *mgr;
struct fpga_image_info *info;
 };
 
@@ -123,7 +125,7 @@ static void fpga_region_put(struct fpga_region *region)
 
 /**
  * fpga_region_get_manager - get reference for FPGA manager
- * @region: FPGA region
+ * @np: device node of FPGA region
  *
  * Get FPGA Manager from "fpga-mgr" property or from ancestor region.
  *
@@ -131,10 +133,8 @@ static void fpga_region_put(struct fpga_region *region)
  *
  * Return: fpga manager struct or IS_ERR() condition containing error code.
  */
-static struct fpga_manager *fpga_region_get_manager(struct fpga_region *region)
+static struct fpga_manager *fpga_region_get_manager(struct device_node *np)
 {
-   struct device *dev = >dev;
-   struct device_node *np = dev->of_node;
struct device_node  *mgr_node;
struct fpga_manager *mgr;
 
@@ -231,7 +231,6 @@ static int fpga_region_program_fpga(struct fpga_region 
*region,
struct device_node *overlay)
 {
struct device *dev = >dev;
-   struct fpga_manager *mgr;
int ret;
 
region = fpga_region_get(region);
@@ -240,17 +239,10 @@ static int fpga_region_program_fpga(struct fpga_region 
*region,
return PTR_ERR(region);
}
 
-   mgr = fpga_region_get_manager(region);
-   if (IS_ERR(mgr)) {
-   dev_err(dev, "failed to get FPGA manager\n");
-   ret = PTR_ERR(mgr);
-   goto err_put_region;
-   }
-
-   ret = fpga_mgr_lock(mgr);
+   ret = fpga_mgr_lock(region->mgr);
if (ret) {
dev_err(dev, "FPGA manager is busy\n");
-   goto err_put_mgr;
+   goto err_put_region;
}
 
ret = fpga_region_get_bridges(region, overlay);
@@ -265,7 +257,7 @@ static int fpga_region_program_fpga(struct fpga_region 
*region,
goto err_put_br;
}
 
-   ret = fpga_mgr_load(mgr, region->info);
+   ret = fpga_mgr_load(region->mgr, region->info);
if (ret) {
dev_err(dev, "failed to load FPGA image\n");
goto err_put_br;
@@ -277,8 +269,7 @@ static int fpga_region_program_fpga(struct fpga_region 
*region,
goto err_put_br;
}
 
-   fpga_mgr_unlock(mgr);
-   fpga_mgr_put(mgr);
+   fpga_mgr_unlock(region->mgr);
fpga_region_put(region);
 
return 0;
@@ -286,9 +277,7 @@ static int fpga_region_program_fpga(struct fpga_region 
*region,
 err_put_br:
fpga_bridges_put(>bridge_list);
 err_unlock_mgr:
-   fpga_mgr_unlock(mgr);
-err_put_mgr:
-   fpga_mgr_put(mgr);
+   fpga_mgr_unlock(region->mgr);
 err_put_region:
fpga_region_put(region);
 
@@ -517,11 +506,20 @@ static int fpga_region_probe(struct platform_device *pdev)
struct device *dev = >dev;
struct device_node *np = dev->of_node;
struct fpga_region *region;
+   struct fpga_manager *mgr;
int id, ret = 0;
 
+   mgr = fpga_region_get_manager(np);
+   if (IS_ERR(mgr))
+   return -EPROBE_DEFER;
+
region = kzalloc(sizeof(*region), GFP_KERNEL);
-   if (!region)
-   return -ENOMEM;
+   if (!region) {
+   ret = -ENOMEM;
+   goto err_put_mgr;
+   }
+
+   region->mgr = mgr;
 
id = ida_simple_get(_region_ida, 0, 0, GFP_KERNEL);
if (id < 0) {
@@ -557,6 +555,8 @@ static int fpga_region_probe(struct platform_device *pdev)
ida_simple_remove(_region_ida, id);
 err_kfree:
kfree(region);
+err_put_mgr:
+   fpga_mgr_put(mgr);
 
return ret;
 }
@@ -566,6 +566,7 @@ static int fpga_region_remove(struct platform_device *pdev)
   

[PATCH v6 07/18] fpga: region: check for child regions before allocing image info

2017-11-15 Thread Alan Tull
During a device tree overlay pre-apply notification, the check
for child FPGA regions can happen slightly earlier.  This saves
us from allocating the FPGA image info that just gets thrown
away.

This is a baby step in refactoring the FPGA region code to
separate out common FPGA region code from FPGA region
Device Tree overlay support.

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: split out from another patch
v3: s/dev/>dev/ in one place
add Moritz' ack
v4: no change to this patch in this version of patchset
v5: no change to this patch in this version of patchset
v6: no change to this patch in this version of patchset
---
 drivers/fpga/fpga-region.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index d78f444..afac543 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -355,15 +355,19 @@ static int fpga_region_notify_pre_apply(struct 
fpga_region *region,
const char *firmware_name;
int ret;
 
-   info = fpga_image_info_alloc(dev);
-   if (!info)
-   return -ENOMEM;
-
-   /* Reject overlay if child FPGA Regions have firmware-name property */
+   /*
+* Reject overlay if child FPGA Regions added in the overlay have
+* firmware-name property (would mean that an FPGA region that has
+* not been added to the live tree yet is doing FPGA programming).
+*/
ret = child_regions_with_firmware(nd->overlay);
if (ret)
return ret;
 
+   info = fpga_image_info_alloc(dev);
+   if (!info)
+   return -ENOMEM;
+
/* Read FPGA region properties from the overlay */
if (of_property_read_bool(nd->overlay, "partial-fpga-config"))
info->flags |= FPGA_MGR_PARTIAL_RECONFIG;
-- 
2.7.4



[PATCH v6 05/18] fpga: region: remove unneeded of_node_get and put

2017-11-15 Thread Alan Tull
Remove of_node_get/put in fpga_region_get/put.  Not
needed and will get in the way when I separate out
the common FPGA region code from Device Tree support
code.

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: split out from another patch
v3: Add Moritz' ack
v4: no change to this patch in this version of patchset
v5: no change to this patch in this version of patchset
v6: no change to this patch in this version of patchset
---
 drivers/fpga/fpga-region.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 6b4f9ab..352661f 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -94,9 +94,7 @@ static struct fpga_region *fpga_region_get(struct fpga_region 
*region)
}
 
get_device(dev);
-   of_node_get(dev->of_node);
if (!try_module_get(dev->parent->driver->owner)) {
-   of_node_put(dev->of_node);
put_device(dev);
mutex_unlock(>mutex);
return ERR_PTR(-ENODEV);
@@ -119,7 +117,6 @@ static void fpga_region_put(struct fpga_region *region)
dev_dbg(dev, "put\n");
 
module_put(dev->parent->driver->owner);
-   of_node_put(dev->of_node);
put_device(dev);
mutex_unlock(>mutex);
 }
-- 
2.7.4



[PATCH v6 10/18] fpga: region: separate out code that parses the overlay

2017-11-15 Thread Alan Tull
New function of_fpga_region_parse_ov added, moving code
from fpga_region_notify_pre_apply.  This function
gets the FPGA image info from the overlay and is able
to simplify some of the logic involved.

This is a baby step in refactoring the FPGA region code to
separate out common code from Device Tree overlay support.

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: split out from another patch
v3: update comments
minor changes in flow
v4: no change to this patch in this version of patchset
v5: no change to this patch in this version of patchset
v6: Add Moritz' ack
---
 drivers/fpga/fpga-region.c | 122 +++--
 1 file changed, 73 insertions(+), 49 deletions(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index eaacf50..2a8621d 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -321,33 +321,22 @@ static int child_regions_with_firmware(struct device_node 
*overlay)
 }
 
 /**
- * fpga_region_notify_pre_apply - pre-apply overlay notification
- *
- * @region: FPGA region that the overlay was applied to
- * @nd: overlay notification data
- *
- * Called after when an overlay targeted to a FPGA Region is about to be
- * applied.  Function will check the properties that will be added to the FPGA
- * region.  If the checks pass, it will program the FPGA.
- *
- * The checks are:
- * The overlay must add either firmware-name or external-fpga-config property
- * to the FPGA Region.
- *
- *   firmware-name : program the FPGA
- *   external-fpga-config  : FPGA is already programmed
- *   encrypted-fpga-config : FPGA bitstream is encrypted
+ * of_fpga_region_parse_ov - parse and check overlay applied to region
  *
- * The overlay can add other FPGA regions, but child FPGA regions cannot have a
- * firmware-name property since those regions don't exist yet.
+ * @region: FPGA region
+ * @overlay: overlay applied to the FPGA region
  *
- * If the overlay that breaks the rules, notifier returns an error and the
- * overlay is rejected before it goes into the main tree.
+ * Given an overlay applied to a FPGA region, parse the FPGA image specific
+ * info in the overlay and do some checking.
  *
- * Returns 0 for success or negative error code for failure.
+ * Returns:
+ *   NULL if overlay doesn't direct us to program the FPGA.
+ *   fpga_image_info struct if there is an image to program.
+ *   error code for invalid overlay.
  */
-static int fpga_region_notify_pre_apply(struct fpga_region *region,
-   struct of_overlay_notify_data *nd)
+static struct fpga_image_info *of_fpga_region_parse_ov(
+   struct fpga_region *region,
+   struct device_node *overlay)
 {
struct device *dev = >dev;
struct fpga_image_info *info;
@@ -356,7 +345,7 @@ static int fpga_region_notify_pre_apply(struct fpga_region 
*region,
 
if (region->info) {
dev_err(dev, "Region already has overlay applied.\n");
-   return -EINVAL;
+   return ERR_PTR(-EINVAL);
}
 
/*
@@ -364,67 +353,102 @@ static int fpga_region_notify_pre_apply(struct 
fpga_region *region,
 * firmware-name property (would mean that an FPGA region that has
 * not been added to the live tree yet is doing FPGA programming).
 */
-   ret = child_regions_with_firmware(nd->overlay);
+   ret = child_regions_with_firmware(overlay);
if (ret)
-   return ret;
+   return ERR_PTR(ret);
 
info = fpga_image_info_alloc(dev);
if (!info)
-   return -ENOMEM;
+   return ERR_PTR(-ENOMEM);
 
-   info->overlay = nd->overlay;
+   info->overlay = overlay;
 
/* Read FPGA region properties from the overlay */
-   if (of_property_read_bool(nd->overlay, "partial-fpga-config"))
+   if (of_property_read_bool(overlay, "partial-fpga-config"))
info->flags |= FPGA_MGR_PARTIAL_RECONFIG;
 
-   if (of_property_read_bool(nd->overlay, "external-fpga-config"))
+   if (of_property_read_bool(overlay, "external-fpga-config"))
info->flags |= FPGA_MGR_EXTERNAL_CONFIG;
 
-   if (of_property_read_bool(nd->overlay, "encrypted-fpga-config"))
+   if (of_property_read_bool(overlay, "encrypted-fpga-config"))
info->flags |= FPGA_MGR_ENCRYPTED_BITSTREAM;
 
-   if (!of_property_read_string(nd->overlay, "firmware-name",
+   if (!of_property_read_string(overlay, "firmware-name",
 _name)) {
info->firmware_name = devm_kstrdup(dev, firmware_name,

[PATCH v6 08/18] fpga: region: fix slow warning with more than one overlay

2017-11-15 Thread Alan Tull
When DT overlays are applied, each FPGA region keeps track of the fpga
image info as region->info.  This pointer is assigned only if an
overlay causes the FPGA to be programmed.  As it stands, this pointer
can be overwritten, causing a slow warning later when overlays are
removed.

This patch fixes this by changing the allowed behaviour.  If a region
has received an overlay that programmed the FPGA, reject other
overlays that try to program the FPGA.  To reprogram the FPGA, first
remove the overlay.  This makes sense as removing the overlay also
removes the devices cleanly.  Note that overlays that make DT changes
without reprogramming the FPGA are exempt from this restriction.

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: split out from another patch
v3: better explanation in header
v4: no change to this patch in this version of patchset
v5: no change to this patch in this version of patchset
v6: Add Moritz' ack
---
 drivers/fpga/fpga-region.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index afac543..35af952 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -355,6 +355,11 @@ static int fpga_region_notify_pre_apply(struct fpga_region 
*region,
const char *firmware_name;
int ret;
 
+   if (region->info) {
+   dev_err(dev, "Region already has overlay applied.\n");
+   return -EINVAL;
+   }
+
/*
 * Reject overlay if child FPGA Regions added in the overlay have
 * firmware-name property (would mean that an FPGA region that has
-- 
2.7.4



[PATCH v6 12/18] fpga: region: rename some functions prior to moving

2017-11-15 Thread Alan Tull
Rename some functions that will be moved to
of-fpga-region.c.  Also change some parameters
and export a function to help with refactoring.

This is a step towards the larger goal of separating
device tree support from FPGA region common code.

* fpga_region_get_manager -> of_fpga_region_get_mgr

* add 'of_' prefix to the following:
  * fpga_region_find
  * fpga_region_get_bridges
  * fpga_region_notify_pre_apply
  * fpga_region_notify_post_remove),
  * fpga_region_probe/remove

Parameter changes:
* of_fpga_region_find
  change parameter to be the device node of the region.
* of_fpga_region_get_bridges
  change second parameter to FPGA image info.

Export of_fpga_region_find as well.

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: split out from another patch
v3: no changes in patch for this version of patchset
v4: no change to this patch in this version of patchset
v5: no change to this patch in this version of patchset
v6: Add Moritz' ack
---
 drivers/fpga/fpga-region.c | 60 --
 1 file changed, 31 insertions(+), 29 deletions(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 402d0b6..92ab216 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -42,12 +42,14 @@ static int fpga_region_of_node_match(struct device *dev, 
const void *data)
 }
 
 /**
- * fpga_region_find - find FPGA region
+ * of_fpga_region_find - find FPGA region
  * @np: device node of FPGA Region
+ *
  * Caller will need to put_device(>dev) when done.
+ *
  * Returns FPGA Region struct or NULL
  */
-static struct fpga_region *fpga_region_find(struct device_node *np)
+static struct fpga_region *of_fpga_region_find(struct device_node *np)
 {
struct device *dev;
 
@@ -107,7 +109,7 @@ static void fpga_region_put(struct fpga_region *region)
 }
 
 /**
- * fpga_region_get_manager - get reference for FPGA manager
+ * of_fpga_region_get_mgr - get reference for FPGA manager
  * @np: device node of FPGA region
  *
  * Get FPGA Manager from "fpga-mgr" property or from ancestor region.
@@ -116,7 +118,7 @@ static void fpga_region_put(struct fpga_region *region)
  *
  * Return: fpga manager struct or IS_ERR() condition containing error code.
  */
-static struct fpga_manager *fpga_region_get_manager(struct device_node *np)
+static struct fpga_manager *of_fpga_region_get_mgr(struct device_node *np)
 {
struct device_node  *mgr_node;
struct fpga_manager *mgr;
@@ -139,9 +141,9 @@ static struct fpga_manager *fpga_region_get_manager(struct 
device_node *np)
 }
 
 /**
- * fpga_region_get_bridges - create a list of bridges
+ * of_fpga_region_get_bridges - create a list of bridges
  * @region: FPGA region
- * @overlay: device node of the overlay
+ * @info: FPGA image info
  *
  * Create a list of bridges including the parent bridge and the bridges
  * specified by "fpga-bridges" property.  Note that the
@@ -154,8 +156,8 @@ static struct fpga_manager *fpga_region_get_manager(struct 
device_node *np)
  * Return 0 for success (even if there are no bridges specified)
  * or -EBUSY if any of the bridges are in use.
  */
-static int fpga_region_get_bridges(struct fpga_region *region,
-  struct device_node *overlay)
+static int of_fpga_region_get_bridges(struct fpga_region *region,
+ struct fpga_image_info *info)
 {
struct device *dev = >dev;
struct device_node *region_np = dev->of_node;
@@ -163,7 +165,7 @@ static int fpga_region_get_bridges(struct fpga_region 
*region,
int i, ret;
 
/* If parent is a bridge, add to list */
-   ret = of_fpga_bridge_get_to_list(region_np->parent, region->info,
+   ret = of_fpga_bridge_get_to_list(region_np->parent, info,
 >bridge_list);
 
/* -EBUSY means parent is a bridge that is under use. Give up. */
@@ -175,8 +177,8 @@ static int fpga_region_get_bridges(struct fpga_region 
*region,
parent_br = region_np->parent;
 
/* If overlay has a list of bridges, use it. */
-   if (of_parse_phandle(overlay, "fpga-bridges", 0))
-   np = overlay;
+   if (of_parse_phandle(info->overlay, "fpga-bridges", 0))
+   np = info->overlay;
else
np = region_np;
 
@@ -227,7 +229,7 @@ int fpga_region_program_fpga(struct fpga_region *region)
goto err_put_region;
}
 
-   ret = fpga_region_get_bridges(region, info->overlay);
+   ret = of_fpga_region_get_bridges(region, info);
if (ret) {
dev_err(dev, "failed to get FPGA bridges\n");
goto err_unlock_mgr;
@@ -397,7 +399,7 @@ static struct fpga_image_info *of_fpga_region_parse_ov(
 }
 
 /**
- * fpga_region_notify_pre_apply - pre-apply overlay notification

[PATCH v6 00/18] patches for FPGA

2017-11-15 Thread Alan Tull
Hi Greg,

Please take these patches for FPGA that have been reviewed on
the mailing list.  They include some needed FPGA API changes
plus bug fixes. They apply cleanly on next-20171113.

Alan

Alan Tull (18):
  fpga: bridge: support getting bridge from device
  fpga: mgr: API change to replace fpga load functions with single
function
  fpga: mgr: separate getting/locking FPGA manager
  fpga: region: use dev_err instead of pr_err
  fpga: region: remove unneeded of_node_get and put
  fpga: region: get mgr early on
  fpga: region: check for child regions before allocing image info
  fpga: region: fix slow warning with more than one overlay
  fpga: region: use image info as parameter for programming region
  fpga: region: separate out code that parses the overlay
  fpga: region: add fpga-region.h header
  fpga: region: rename some functions prior to moving
  fpga: region: add register/unregister functions
  fpga: region: add fpga_region_class_find
  fpga: region: move device tree support to of-fpga-region.c
  fpga: of-fpga-region: accept overlays that don't program FPGA
  fpga: clean up fpga Kconfig
  fpga: add attribute groups

 Documentation/fpga/fpga-mgr.txt| 132 +-
 Documentation/fpga/fpga-region.txt |  95 +++
 Documentation/fpga/overview.txt|  23 ++
 drivers/fpga/Kconfig   | 103 
 drivers/fpga/Makefile  |   1 +
 drivers/fpga/fpga-bridge.c | 111 +++--
 drivers/fpga/fpga-mgr.c| 121 +++--
 drivers/fpga/fpga-region.c | 464 --
 drivers/fpga/of-fpga-region.c  | 497 +
 include/linux/fpga/fpga-bridge.h   |  14 +-
 include/linux/fpga/fpga-mgr.h  |  39 ++-
 include/linux/fpga/fpga-region.h   |  40 +++
 12 files changed, 1044 insertions(+), 596 deletions(-)
 create mode 100644 Documentation/fpga/fpga-region.txt
 create mode 100644 Documentation/fpga/overview.txt
 create mode 100644 drivers/fpga/of-fpga-region.c
 create mode 100644 include/linux/fpga/fpga-region.h

-- 
2.7.4



[PATCH v6 01/18] fpga: bridge: support getting bridge from device

2017-11-15 Thread Alan Tull
Add two functions for getting the FPGA bridge from the device
rather than device tree node.  This is to enable writing code
that will support using FPGA bridges without device tree.
Rename one old function to make it clear that it is device
tree-ish.  This leaves us with 3 functions for getting a bridge:

* fpga_bridge_get
  Get the bridge given the device.

* fpga_bridges_get_to_list
  Given the device, get the bridge and add it to a list.

* of_fpga_bridges_get_to_list
  Renamed from priviously existing fpga_bridges_get_to_list.
  Given the device node, get the bridge and add it to a list.

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: use list_for_each_entry
static the bridge_list_lock
update copyright and author email
v3: no change to this patch in this version of patchset
v4: no change to this patch in this version of patchset
v5: fpga-bridge.h - move #ifndef before #includes
make __fpga_bridge_get static
v6: Add Moritz' ack
---
 drivers/fpga/fpga-bridge.c   | 110 +++
 drivers/fpga/fpga-region.c   |  11 ++--
 include/linux/fpga/fpga-bridge.h |  12 +++--
 3 files changed, 103 insertions(+), 30 deletions(-)

diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
index 9651aa5..0dfe9d7 100644
--- a/drivers/fpga/fpga-bridge.c
+++ b/drivers/fpga/fpga-bridge.c
@@ -2,6 +2,7 @@
  * FPGA Bridge Framework Driver
  *
  *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
+ *  Copyright (C) 2017 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -70,29 +71,12 @@ int fpga_bridge_disable(struct fpga_bridge *bridge)
 }
 EXPORT_SYMBOL_GPL(fpga_bridge_disable);
 
-/**
- * of_fpga_bridge_get - get an exclusive reference to a fpga bridge
- *
- * @np: node pointer of a FPGA bridge
- * @info: fpga image specific information
- *
- * Return fpga_bridge struct if successful.
- * Return -EBUSY if someone already has a reference to the bridge.
- * Return -ENODEV if @np is not a FPGA Bridge.
- */
-struct fpga_bridge *of_fpga_bridge_get(struct device_node *np,
-  struct fpga_image_info *info)
-
+static struct fpga_bridge *__fpga_bridge_get(struct device *dev,
+struct fpga_image_info *info)
 {
-   struct device *dev;
struct fpga_bridge *bridge;
int ret = -ENODEV;
 
-   dev = class_find_device(fpga_bridge_class, NULL, np,
-   fpga_bridge_of_node_match);
-   if (!dev)
-   goto err_dev;
-
bridge = to_fpga_bridge(dev);
if (!bridge)
goto err_dev;
@@ -117,8 +101,58 @@ struct fpga_bridge *of_fpga_bridge_get(struct device_node 
*np,
put_device(dev);
return ERR_PTR(ret);
 }
+
+/**
+ * of_fpga_bridge_get - get an exclusive reference to a fpga bridge
+ *
+ * @np: node pointer of a FPGA bridge
+ * @info: fpga image specific information
+ *
+ * Return fpga_bridge struct if successful.
+ * Return -EBUSY if someone already has a reference to the bridge.
+ * Return -ENODEV if @np is not a FPGA Bridge.
+ */
+struct fpga_bridge *of_fpga_bridge_get(struct device_node *np,
+  struct fpga_image_info *info)
+{
+   struct device *dev;
+
+   dev = class_find_device(fpga_bridge_class, NULL, np,
+   fpga_bridge_of_node_match);
+   if (!dev)
+   return ERR_PTR(-ENODEV);
+
+   return __fpga_bridge_get(dev, info);
+}
 EXPORT_SYMBOL_GPL(of_fpga_bridge_get);
 
+static int fpga_bridge_dev_match(struct device *dev, const void *data)
+{
+   return dev->parent == data;
+}
+
+/**
+ * fpga_bridge_get - get an exclusive reference to a fpga bridge
+ * @dev:   parent device that fpga bridge was registered with
+ *
+ * Given a device, get an exclusive reference to a fpga bridge.
+ *
+ * Return: fpga manager struct or IS_ERR() condition containing error code.
+ */
+struct fpga_bridge *fpga_bridge_get(struct device *dev,
+   struct fpga_image_info *info)
+{
+   struct device *bridge_dev;
+
+   bridge_dev = class_find_device(fpga_bridge_class, NULL, dev,
+  fpga_bridge_dev_match);
+   if (!bridge_dev)
+   return ERR_PTR(-ENODEV);
+
+   return __fpga_bridge_get(bridge_dev, info);
+}
+EXPORT_SYMBOL_GPL(fpga_bridge_get);
+
 /**
  * fpga_bridge_put - release a reference to a bridge
  *
@@ -206,7 +240,7 @@ void fpga_bridges_put(struct list_head *bridge_list)
 EXPORT_SYMBOL_GPL(fpga_bridges_put);
 
 /**
- * fpga_bridges_get_to_list - get a bridge, add it to a list
+ * of_fpga_bridge_get_to_list - get a bridge, add it to a list
  *
  * @np: node pointer of a FPGA bridge
  * @info: fpga image specific information
@@ 

[PATCH v6 14/18] fpga: region: add fpga_region_class_find

2017-11-15 Thread Alan Tull
Add a function for searching the fpga-region class.  This
will be useful when device tree code is no longer in the
same file that declares the fpga-region class.  Another
step in separating common FPGA region code from device
tree support.

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: split out from another patch
v3: add Moritz' ack
v4: no change to this patch in this version of patchset
v5: no change to this patch in this version of patchset
v6: no change to this patch in this version of patchset
---
 drivers/fpga/fpga-region.c   | 23 +++
 include/linux/fpga/fpga-region.h |  5 -
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 76db81d..5c086957 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -30,6 +30,20 @@
 static DEFINE_IDA(fpga_region_ida);
 static struct class *fpga_region_class;
 
+struct fpga_region *fpga_region_class_find(
+   struct device *start, const void *data,
+   int (*match)(struct device *, const void *))
+{
+   struct device *dev;
+
+   dev = class_find_device(fpga_region_class, start, data, match);
+   if (!dev)
+   return NULL;
+
+   return to_fpga_region(dev);
+}
+EXPORT_SYMBOL_GPL(fpga_region_class_find);
+
 static const struct of_device_id fpga_region_of_match[] = {
{ .compatible = "fpga-region", },
{},
@@ -51,14 +65,7 @@ static int fpga_region_of_node_match(struct device *dev, 
const void *data)
  */
 static struct fpga_region *of_fpga_region_find(struct device_node *np)
 {
-   struct device *dev;
-
-   dev = class_find_device(fpga_region_class, NULL, np,
-   fpga_region_of_node_match);
-   if (!dev)
-   return NULL;
-
-   return to_fpga_region(dev);
+   return fpga_region_class_find(NULL, np, fpga_region_of_node_match);
 }
 
 /**
diff --git a/include/linux/fpga/fpga-region.h b/include/linux/fpga/fpga-region.h
index 8c8a3249f..7048449 100644
--- a/include/linux/fpga/fpga-region.h
+++ b/include/linux/fpga/fpga-region.h
@@ -27,8 +27,11 @@ struct fpga_region {
 
 #define to_fpga_region(d) container_of(d, struct fpga_region, dev)
 
-int fpga_region_program_fpga(struct fpga_region *region);
+struct fpga_region *fpga_region_class_find(
+   struct device *start, const void *data,
+   int (*match)(struct device *, const void *));
 
+int fpga_region_program_fpga(struct fpga_region *region);
 int fpga_region_register(struct device *dev, struct fpga_region *region);
 int fpga_region_unregister(struct fpga_region *region);
 
-- 
2.7.4



[PATCH v6 03/18] fpga: mgr: separate getting/locking FPGA manager

2017-11-15 Thread Alan Tull
Previously when the user gets a FPGA manager, it was locked
and nobody else could use it for programming.

This commit makes it straightforward to save a reference to an
FPGA manager and only lock it when programming the FPGA.

Add functions that get an FPGA manager's mutex for exclusive use:
* fpga_mgr_lock
* fpga_mgr_unlock

The following functions no longer lock an FPGA manager's mutex:
* of_fpga_mgr_get
* fpga_mgr_get
* fpga_mgr_put

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: add static for __fpga_mgr_get
function documentation corrections
use dev_err
v3: bisectibility fix
v4: add API doc updates that were originally in a separate patch
v5: no change to this patch in this version of patchset
v6: Add Moritz' ack
---
 Documentation/fpga/fpga-mgr.txt | 35 ---
 drivers/fpga/fpga-mgr.c | 52 -
 drivers/fpga/fpga-region.c  | 14 +--
 include/linux/fpga/fpga-mgr.h   |  3 +++
 4 files changed, 77 insertions(+), 27 deletions(-)

diff --git a/Documentation/fpga/fpga-mgr.txt b/Documentation/fpga/fpga-mgr.txt
index 6ebc714..cc6413e 100644
--- a/Documentation/fpga/fpga-mgr.txt
+++ b/Documentation/fpga/fpga-mgr.txt
@@ -48,8 +48,20 @@ To get/put a reference to a FPGA manager:
struct fpga_manager *fpga_mgr_get(struct device *dev);
void fpga_mgr_put(struct fpga_manager *mgr);
 
-Given a DT node or device, get an exclusive reference to a FPGA manager.
-fpga_mgr_put releases the reference.
+Given a DT node or device, get a reference to a FPGA manager.  This pointer
+can be saved until you are ready to program the FPGA.  fpga_mgr_put releases
+the reference.
+
+
+To get exclusive control of a FPGA manager:
+---
+
+   int fpga_mgr_lock(struct fpga_manager *mgr);
+   void fpga_mgr_unlock(struct fpga_manager *mgr);
+
+The user should call fpga_mgr_lock and verify that it returns 0 before
+attempting to program the FPGA.  Likewise, the user should call
+fpga_mgr_unlock when done programming the FPGA.
 
 
 To register or unregister the low level FPGA-specific driver:
@@ -67,13 +79,21 @@ device."
 
 How to write an image buffer to a supported FPGA
 
-/* Include to get the API */
 #include 
 
 struct fpga_manager *mgr;
 struct fpga_image_info *info;
 int ret;
 
+/*
+ * Get a reference to FPGA manager.  The manager is not locked, so you can
+ * hold onto this reference without it preventing programming.
+ *
+ * This example uses the device node of the manager.  Alternatively, use
+ * fpga_mgr_get(dev) instead if you have the device.
+ */
+mgr = of_fpga_mgr_get(mgr_node);
+
 /* struct with information about the FPGA image to program. */
 info = fpga_image_info_alloc(dev);
 
@@ -99,17 +119,14 @@ if (image is in a scatter gather table) {
 
 }
 
-/*
- * 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);
+/* Get exclusive control of FPGA manager */
+ret = fpga_mgr_lock(mgr);
 
 /* Load the buffer to the FPGA */
 ret = fpga_mgr_buf_load(mgr, , buf, count);
 
 /* Release the FPGA manager */
+fpga_mgr_unlock(mgr);
 fpga_mgr_put(mgr);
 
 /* Deallocate the image info if you're done with it */
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index a8dd549..d27e8d2 100644
--- a/drivers/fpga/fpga-mgr.c
+++ b/drivers/fpga/fpga-mgr.c
@@ -410,28 +410,19 @@ ATTRIBUTE_GROUPS(fpga_mgr);
 static struct fpga_manager *__fpga_mgr_get(struct device *dev)
 {
struct fpga_manager *mgr;
-   int ret = -ENODEV;
 
mgr = to_fpga_manager(dev);
if (!mgr)
goto err_dev;
 
-   /* Get exclusive use of fpga manager */
-   if (!mutex_trylock(>ref_mutex)) {
-   ret = -EBUSY;
-   goto err_dev;
-   }
-
if (!try_module_get(dev->parent->driver->owner))
-   goto err_ll_mod;
+   goto err_dev;
 
return mgr;
 
-err_ll_mod:
-   mutex_unlock(>ref_mutex);
 err_dev:
put_device(dev);
-   return ERR_PTR(ret);
+   return ERR_PTR(-ENODEV);
 }
 
 static int fpga_mgr_dev_match(struct device *dev, const void *data)
@@ -440,10 +431,10 @@ static int fpga_mgr_dev_match(struct device *dev, const 
void *data)
 }
 
 /**
- * fpga_mgr_get - get an exclusive reference to a fpga mgr
+ * fpga_mgr_get - get a reference to a fpga mgr
  * @dev:   parent device that fpga mgr was registered with
  *
- * Given a device, get an exclusive reference to a fpga mgr.
+ * Given a device, get a reference to a fpga mgr.
  *
  * Return: fpga manager struct or IS_ERR() condition containing error code.
  */
@@ -464,10 +455,10 @@ static int fpga_mgr_of_node_match(struct device *dev, 
const void *data)
 }

[PATCH v6 02/18] fpga: mgr: API change to replace fpga load functions with single function

2017-11-15 Thread Alan Tull
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 <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: add fpga_image_info_alloc/free
update copyright and author email
v3: fix bisectibility
v4: fix return value of fpga_image_info_alloc()
save device in struct fpga_image_info
remove device param from fpga_image_info_free()
squash in the documentation patch minus stuff about locking
which is included in the next patch
v5: fpga-mgr.h - move #ifndef before #includes
v6: Add Moritz' ack
---
 Documentation/fpga/fpga-mgr.txt| 119 -
 Documentation/fpga/fpga-region.txt |  95 +
 Documentation/fpga/overview.txt|  23 +++
 drivers/fpga/fpga-mgr.c|  68 +
 drivers/fpga/fpga-region.c |  43 +-
 include/linux/fpga/fpga-mgr.h  |  30 ++
 6 files changed, 273 insertions(+), 105 deletions(-)
 create mode 100644 Documentation/fpga/fpga-region.txt
 create mode 100644 Documentation/fpga/overview.txt

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 @@ hidden away in a low level driver which registers a set of 
ops with the core.
 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:
--
-
-   int fpga_mgr_buf_load(struct fpga_manager *mgr,
- struct fpga_image_info *info,
- const char *buf, size_t count);
-
-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);
+To program the FPGA:
+
 
-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_load(struct fpga_manager *mgr,
+ struct fpga_image_info *info);
 
-   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

[PATCH v6 04/18] fpga: region: use dev_err instead of pr_err

2017-11-15 Thread Alan Tull
Use dev_err messages instead of pr_err.

Also s/>dev/dev/ in two places where we already
have dev = >dev.

Signed-off-by: Alan Tull <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
---
v2: new in this version of the patchset
v3: for bisectability some changes moved to earlier patches
v4: no change to this patch in this version of patchset
v5: Add Moritz' ack
v6: No change in v6 of patchset
---
 drivers/fpga/fpga-region.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 1e1640a..6b4f9ab 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -102,7 +102,7 @@ static struct fpga_region *fpga_region_get(struct 
fpga_region *region)
return ERR_PTR(-ENODEV);
}
 
-   dev_dbg(>dev, "get\n");
+   dev_dbg(dev, "get\n");
 
return region;
 }
@@ -116,7 +116,7 @@ static void fpga_region_put(struct fpga_region *region)
 {
struct device *dev = >dev;
 
-   dev_dbg(>dev, "put\n");
+   dev_dbg(dev, "put\n");
 
module_put(dev->parent->driver->owner);
of_node_put(dev->of_node);
@@ -239,13 +239,13 @@ static int fpga_region_program_fpga(struct fpga_region 
*region,
 
region = fpga_region_get(region);
if (IS_ERR(region)) {
-   pr_err("failed to get fpga region\n");
+   dev_err(dev, "failed to get FPGA region\n");
return PTR_ERR(region);
}
 
mgr = fpga_region_get_manager(region);
if (IS_ERR(mgr)) {
-   pr_err("failed to get fpga region manager\n");
+   dev_err(dev, "failed to get FPGA manager\n");
ret = PTR_ERR(mgr);
goto err_put_region;
}
@@ -258,25 +258,25 @@ static int fpga_region_program_fpga(struct fpga_region 
*region,
 
ret = fpga_region_get_bridges(region, overlay);
if (ret) {
-   pr_err("failed to get fpga region bridges\n");
+   dev_err(dev, "failed to get FPGA bridges\n");
goto err_unlock_mgr;
}
 
ret = fpga_bridges_disable(>bridge_list);
if (ret) {
-   pr_err("failed to disable region bridges\n");
+   dev_err(dev, "failed to disable bridges\n");
goto err_put_br;
}
 
ret = fpga_mgr_load(mgr, region->info);
if (ret) {
-   pr_err("failed to load fpga image\n");
+   dev_err(dev, "failed to load FPGA image\n");
goto err_put_br;
}
 
ret = fpga_bridges_enable(>bridge_list);
if (ret) {
-   pr_err("failed to enable region bridges\n");
+   dev_err(dev, "failed to enable region bridges\n");
goto err_put_br;
}
 
@@ -407,7 +407,7 @@ static int fpga_region_notify_pre_apply(struct fpga_region 
*region,
 
/* If FPGA was externally programmed, don't specify firmware */
if ((info->flags & FPGA_MGR_EXTERNAL_CONFIG) && info->firmware_name) {
-   pr_err("error: specified firmware and external-fpga-config");
+   dev_err(dev, "error: specified firmware and 
external-fpga-config");
fpga_image_info_free(info);
return -EINVAL;
}
@@ -420,7 +420,7 @@ static int fpga_region_notify_pre_apply(struct fpga_region 
*region,
 
/* If we got this far, we should be programming the FPGA */
if (!info->firmware_name) {
-   pr_err("should specify firmware-name or 
external-fpga-config\n");
+   dev_err(dev, "should specify firmware-name or 
external-fpga-config\n");
fpga_image_info_free(info);
return -EINVAL;
}
-- 
2.7.4



[PATCH 1/3] fpga: fpga-mgr: remove unnecessary code in __fpga_mgr_get

2017-11-15 Thread Alan Tull
From: "Gustavo A. R. Silva" <garsi...@embeddedor.com>

Notice that mgr = to_fpga_manager(dev); expands to:

mgr = container_of(dev, struct fpga_manager, dev);

and container_of is never null, so this null check is
unnecessary.

Addresses-Coverity-ID: 1397916
Signed-off-by: Gustavo A. R. Silva <garsi...@embeddedor.com>
Signed-off-by: Alan Tull <at...@kernel.org>
---
 drivers/fpga/fpga-mgr.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index 1fd5494..0b7664d 100644
--- a/drivers/fpga/fpga-mgr.c
+++ b/drivers/fpga/fpga-mgr.c
@@ -412,8 +412,6 @@ static struct fpga_manager *__fpga_mgr_get(struct device 
*dev)
struct fpga_manager *mgr;
 
mgr = to_fpga_manager(dev);
-   if (!mgr)
-   goto err_dev;
 
if (!try_module_get(dev->parent->driver->owner))
goto err_dev;
-- 
2.7.4



[PATCH 3/3] fpga: region: release of_parse_phandle nodes after use

2017-11-15 Thread Alan Tull
From: Ian Abbott <abbo...@mev.co.uk>

Both fpga_region_get_manager() and fpga_region_get_bridges() call
of_parse_phandle(), but nothing calls of_node_put() on the returned
struct device_node pointers.  Make sure to do that to stop their
reference counters getting out of whack.

Fixes: 0fa20cdfcc1f ("fpga: fpga-region: device tree control for FPGA")
Cc: <sta...@vger.kernel.org> # 4.10+
Signed-off-by: Ian Abbott <abbo...@mev.co.uk>
Signed-off-by: Alan Tull <at...@kernel.org>
---
 drivers/fpga/of-fpga-region.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index a0c13cb..7dfaa95 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -73,6 +73,7 @@ static struct fpga_manager *of_fpga_region_get_mgr(struct 
device_node *np)
mgr_node = of_parse_phandle(np, "fpga-mgr", 0);
if (mgr_node) {
mgr = of_fpga_mgr_get(mgr_node);
+   of_node_put(mgr_node);
of_node_put(np);
return mgr;
}
@@ -120,10 +121,13 @@ static int of_fpga_region_get_bridges(struct fpga_region 
*region)
parent_br = region_np->parent;
 
/* If overlay has a list of bridges, use it. */
-   if (of_parse_phandle(info->overlay, "fpga-bridges", 0))
+   br = of_parse_phandle(info->overlay, "fpga-bridges", 0);
+   if (br) {
+   of_node_put(br);
np = info->overlay;
-   else
+   } else {
np = region_np;
+   }
 
for (i = 0; ; i++) {
br = of_parse_phandle(np, "fpga-bridges", i);
@@ -131,12 +135,15 @@ static int of_fpga_region_get_bridges(struct fpga_region 
*region)
break;
 
/* If parent bridge is in list, skip it. */
-   if (br == parent_br)
+   if (br == parent_br) {
+   of_node_put(br);
continue;
+   }
 
/* If node is a bridge, get it and add to list */
ret = of_fpga_bridge_get_to_list(br, info,
 >bridge_list);
+   of_node_put(br);
 
/* If any of the bridges are in use, give up */
if (ret == -EBUSY) {
-- 
2.7.4



[PATCH 2/3] fpga: fpga-bridge: remove unnecessary null check in of_fpga_bridge_get

2017-11-15 Thread Alan Tull
From: "Gustavo A. R. Silva" <garsi...@embeddedor.com>

Notice that bridge = to_fpga_bridge(dev); expands to:

bridge = container_of(dev, struct fpga_bridge, dev);

and container_of is never null, so this null check is
unnecessary.

Addresses-Coverity-ID: 1397912
Reported-by: Alan Tull <at...@kernel.org>
Signed-off-by: Gustavo A. R. Silva <garsi...@embeddedor.com>
Reviewed-by: Moritz Fischer <m...@kernel.org>
Signed-off-by: Alan Tull <at...@kernel.org>
---
 drivers/fpga/fpga-bridge.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
index 4c48dd6..038b10b 100644
--- a/drivers/fpga/fpga-bridge.c
+++ b/drivers/fpga/fpga-bridge.c
@@ -78,8 +78,6 @@ static struct fpga_bridge *__fpga_bridge_get(struct device 
*dev,
int ret = -ENODEV;
 
bridge = to_fpga_bridge(dev);
-   if (!bridge)
-   goto err_dev;
 
bridge->info = info;
 
-- 
2.7.4



[PATCH v2 0/5] fpga: don't use drvdata in common fpga code

2017-11-15 Thread Alan Tull
This patch set goes on top of v6 of the non-dt support patchset that has
been acked and I've asked Greg KH to send upstream.

This patchset changes the fpga_*_register functions to not set drvdata,
and changes parameters for register/unregister functions.  Also a
bug fix due to changes in the DT overlay code.

Setting drvdata is fine for DT based devices, that will have one
manager, bridge, or region device per platform device.  PCIe based
devices may have multiple FPGA mgr/bridge/regions under one pcie
device.  Without these changes, PCIe-based solutions have to create an
extra device for each child mgr/bridge/region to hold drvdata.

Also changing the fpga_*_register/unregister functions to take the
corresponding struct as the only parameter wherever they weren't already.

* int fpga_bridge_register(struct fpga_bridge *br)
* int fpga_mgr_register(struct fpga_manager *mgr)
* int fpga_region_register(struct fpga_region *region)
* void fpga_bridge_unregister(struct fpga_bridge *br)
* void fpga_mgr_unregister(struct fpga_manager *mgr)
* int fpga_region_unregister(struct fpga_region *region)

Other changes:

- Callers of fpga_(bridge|mgr)_register, are changed to alloc the
bridge/mgr struct and partly fill it, adding name, ops and priv.
- Caller uses devm for allocating the mgr/bridge structures.
- Change the FPGA Region DT notifier to return NOTIFY_STOP if
the overlay should be accepted.

I posted a branch to the linux-fpga repo on kernel.org which has both
the v6 non-DT support patchset and this v2 patchset for convenience.
Branch name is next-20171113-non-dt-support-v6+v2

Alan

Alan Tull (5):
  fpga: region: don't use drvdata in common fpga code
  fpga: manager: don't use drvdata in common fpga code
  fpga: bridge: don't use drvdata in common fpga code
  fpga: region: change fpga_region_register to have one param
  fpga: region: return NOTIFY_STOP if overlay shoud be accepted

 Documentation/fpga/fpga-mgr.txt | 24 -
 Documentation/fpga/fpga-region.txt  |  3 +--
 drivers/fpga/altera-cvp.c   | 18 ++---
 drivers/fpga/altera-fpga2sdram.c| 20 +++---
 drivers/fpga/altera-freeze-bridge.c | 18 ++---
 drivers/fpga/altera-hps2fpga.c  | 16 ---
 drivers/fpga/altera-pr-ip-core.c| 17 ++--
 drivers/fpga/altera-ps-spi.c| 18 ++---
 drivers/fpga/fpga-bridge.c  | 53 ++---
 drivers/fpga/fpga-mgr.c | 49 +-
 drivers/fpga/fpga-region.c  | 13 ++---
 drivers/fpga/ice40-spi.c| 20 +++---
 drivers/fpga/of-fpga-region.c   |  9 ---
 drivers/fpga/socfpga-a10.c  | 16 ---
 drivers/fpga/socfpga.c  | 18 ++---
 drivers/fpga/ts73xx-fpga.c  | 18 ++---
 drivers/fpga/xilinx-pr-decoupler.c  | 15 ---
 drivers/fpga/xilinx-spi.c   | 18 ++---
 drivers/fpga/zynq-fpga.c| 16 ---
 include/linux/fpga/fpga-bridge.h|  7 ++---
 include/linux/fpga/fpga-mgr.h   |  8 +++---
 include/linux/fpga/fpga-region.h|  4 ++-
 22 files changed, 270 insertions(+), 128 deletions(-)

-- 
2.7.4



[PATCH v2 5/5] fpga: region: return NOTIFY_STOP if overlay shoud be accepted

2017-11-15 Thread Alan Tull
Recent changes to the Device Tree overlay notifier code have changed
how notifier return codes are interpreted, requiring a NOTIFY_STOP to
signal that the overlay should be accepted.  This commit makes the
appropriate change to the FPGA region's Device Tree overlay notifier.

Fixes: 24789c5ce5a3 ("of: overlay: detect cases where device tree may become 
corrupt")
Signed-off-by: Alan Tull <at...@kernel.org>
---
v2: Added in v2 of this patchset.  Tested on linux-next/master.
---
 drivers/fpga/of-fpga-region.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index 276ffe2..a0c13cb 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -349,7 +349,8 @@ static void of_fpga_region_notify_post_remove(struct 
fpga_region *region,
  * This notifier handles programming a FPGA when a "firmware-name" property is
  * added to a fpga-region.
  *
- * Returns NOTIFY_OK or error if FPGA programming fails.
+ * Returns NOTIFY_OK if this notification isn't about this region or
+ * NOTIFY_STOP if the overaly is to be accepted or error if FPGA programming 
fails.
  */
 static int of_fpga_region_notify(struct notifier_block *nb,
 unsigned long action, void *arg)
@@ -395,7 +396,7 @@ static int of_fpga_region_notify(struct notifier_block *nb,
if (ret)
return notifier_from_errno(ret);
 
-   return NOTIFY_OK;
+   return NOTIFY_STOP;
 }
 
 static struct notifier_block fpga_region_of_nb = {
-- 
2.7.4



[PATCH v2 1/5] fpga: region: don't use drvdata in common fpga code

2017-11-15 Thread Alan Tull
Part of patchset that changes the following fpga_*_register
functions to not set drvdata:
* fpga_region_register.
* fpga_mgr_register
* fpga_bridge_register

The rationale is that setting drvdata is fine for DT based devices
that will have one manager, bridge, or region per platform device.
However PCIe based devices may have multiple FPGA mgr/bridge/regions
under one PCIe device.  Without these changes, the PCIe solution has
to create an extra device for each child mgr/bridge/region to hold
drvdata.

Signed-off-by: Alan Tull <at...@kernel.org>
Reported-by: Jiuyue Ma <majiu...@huawei.com>
---
v2: No change to this patch in v2 of patchset
---
 drivers/fpga/fpga-region.c| 1 -
 drivers/fpga/of-fpga-region.c | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index edab2a2..ebe1f87 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -178,7 +178,6 @@ int fpga_region_register(struct device *dev, struct 
fpga_region *region)
region->dev.parent = dev;
region->dev.of_node = dev->of_node;
region->dev.id = id;
-   dev_set_drvdata(dev, region);
 
ret = dev_set_name(>dev, "region%d", id);
if (ret)
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index c6b2119..3079ed8 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -431,6 +431,7 @@ static int of_fpga_region_probe(struct platform_device 
*pdev)
goto eprobe_mgr_put;
 
of_platform_populate(np, fpga_region_of_match, NULL, >dev);
+   dev_set_drvdata(dev, region);
 
dev_info(dev, "FPGA Region probed\n");
 
-- 
2.7.4



[PATCH 0/3] more patches for FPGA

2017-11-15 Thread Alan Tull
Hi Greg,

Please take these three patches for FPGA.  They go on top of my
"[PATCH v6 00/18] patches for FPGA" patch set I sent earlier
today.  Sorry I didn't think of sending them all together at the
time.

These are fixes for FPGA that have been reviewed on
the mailing list.

I had to rebase the "fpga: region: release of_parse_phandle nodes
after use" patch to apply on top of my patchset.

Alan

Gustavo A. R. Silva (2):
  fpga: fpga-mgr: remove unnecessary code in __fpga_mgr_get
  fpga: fpga-bridge: remove unnecessary null check in of_fpga_bridge_get

Ian Abbott (1):
  fpga: region: release of_parse_phandle nodes after use

 drivers/fpga/fpga-bridge.c|  2 --
 drivers/fpga/fpga-mgr.c   |  2 --
 drivers/fpga/of-fpga-region.c | 13 ++---
 3 files changed, 10 insertions(+), 7 deletions(-)

-- 
2.7.4



[PATCH v2 3/5] fpga: bridge: don't use drvdata in common fpga code

2017-11-15 Thread Alan Tull
Changes to the fpga bridge code to not use drvdata in common code.

Change fpga_bridge_register to not set drvdata.

Change the register/unregister functions parameters to take the
bridge struct:
* int fpga_bridge_register(struct fpga_bridge *bridge);
* void fpga_bridge_unregister(struct fpga_bridge *bridge);

Change the drivers that call fpga_bridge_register to alloc the struct
fpga_bridge (using devm_kzalloc) and partly fill it, adding name,
ops, parent device, and priv.

The rationale is that setting drvdata is fine for DT based devices
that will have one manager, bridge, or region per platform device.
However PCIe based devices may have multiple FPGA mgr/bridge/regions
under one pcie device.  Without these changes, the PCIe solution has
to create an extra device for each child mgr/bridge/region to hold
drvdata.

Signed-off-by: Alan Tull <at...@kernel.org>
Reported-by: Jiuyue Ma <majiu...@huawei.com>
---
v2: change fpga_bridge_register to not need parent device param
fix undeclared - s/dev/>dev/
---
 drivers/fpga/altera-fpga2sdram.c| 20 +++---
 drivers/fpga/altera-freeze-bridge.c | 18 ++---
 drivers/fpga/altera-hps2fpga.c  | 16 ---
 drivers/fpga/fpga-bridge.c  | 53 ++---
 drivers/fpga/xilinx-pr-decoupler.c  | 15 ---
 include/linux/fpga/fpga-bridge.h|  7 ++---
 6 files changed, 80 insertions(+), 49 deletions(-)

diff --git a/drivers/fpga/altera-fpga2sdram.c b/drivers/fpga/altera-fpga2sdram.c
index d4eeb74..84effb0 100644
--- a/drivers/fpga/altera-fpga2sdram.c
+++ b/drivers/fpga/altera-fpga2sdram.c
@@ -106,10 +106,15 @@ static int alt_fpga_bridge_probe(struct platform_device 
*pdev)
 {
struct device *dev = >dev;
struct alt_fpga2sdram_data *priv;
+   struct fpga_bridge *br;
u32 enable;
struct regmap *sysmgr;
int ret = 0;
 
+   br = devm_kzalloc(dev, sizeof(*br), GFP_KERNEL);
+   if (!br)
+   return -ENOMEM;
+
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -131,8 +136,13 @@ static int alt_fpga_bridge_probe(struct platform_device 
*pdev)
/* Get f2s bridge configuration saved in handoff register */
regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, >mask);
 
-   ret = fpga_bridge_register(dev, F2S_BRIDGE_NAME,
-  _fpga2sdram_br_ops, priv);
+   br->name = F2S_BRIDGE_NAME;
+   br->br_ops = _fpga2sdram_br_ops;
+   br->priv = priv;
+   br->parent = dev;
+   platform_set_drvdata(pdev, br);
+
+   ret = fpga_bridge_register(br);
if (ret)
return ret;
 
@@ -146,7 +156,7 @@ static int alt_fpga_bridge_probe(struct platform_device 
*pdev)
 (enable ? "enabling" : "disabling"));
ret = _alt_fpga2sdram_enable_set(priv, enable);
if (ret) {
-   fpga_bridge_unregister(>dev);
+   fpga_bridge_unregister(br);
return ret;
}
}
@@ -157,7 +167,9 @@ static int alt_fpga_bridge_probe(struct platform_device 
*pdev)
 
 static int alt_fpga_bridge_remove(struct platform_device *pdev)
 {
-   fpga_bridge_unregister(>dev);
+   struct fpga_bridge *br = platform_get_drvdata(pdev);
+
+   fpga_bridge_unregister(br);
 
return 0;
 }
diff --git a/drivers/fpga/altera-freeze-bridge.c 
b/drivers/fpga/altera-freeze-bridge.c
index 6159cfcf..b49a8a3 100644
--- a/drivers/fpga/altera-freeze-bridge.c
+++ b/drivers/fpga/altera-freeze-bridge.c
@@ -219,6 +219,7 @@ static int altera_freeze_br_probe(struct platform_device 
*pdev)
 {
struct device *dev = >dev;
struct device_node *np = pdev->dev.of_node;
+   struct fpga_bridge *br;
void __iomem *base_addr;
struct altera_freeze_br_data *priv;
struct resource *res;
@@ -227,6 +228,10 @@ static int altera_freeze_br_probe(struct platform_device 
*pdev)
if (!np)
return -ENODEV;
 
+   br = devm_kzalloc(dev, sizeof(*br), GFP_KERNEL);
+   if (!br)
+   return -ENOMEM;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base_addr = devm_ioremap_resource(dev, res);
if (IS_ERR(base_addr))
@@ -254,13 +259,20 @@ static int altera_freeze_br_probe(struct platform_device 
*pdev)
 
priv->base_addr = base_addr;
 
-   return fpga_bridge_register(dev, FREEZE_BRIDGE_NAME,
-   _freeze_br_br_ops, priv);
+   br->name = FREEZE_BRIDGE_NAME;
+   br->br_ops = _freeze_br_br_ops;
+   br->priv = priv;
+   br->parent = dev;
+   platform_set_drvdata(pdev, br);
+
+   return fpga_bridge_register(br);
 }
 
 static int altera_freeze_br_remove(struct platform_devic

[PATCH v2 4/5] fpga: region: change fpga_region_register to have one param

2017-11-15 Thread Alan Tull
Change fpga_region_register to only take one parameter:

  int fpga_region_register(struct fpga_region *region)

The parent dev is added to struct fpga_region.

This make it similar to fpga_bridge_register and fpga_mgr_register
which also just take their respective struct as a param.

Signed-off-by: Alan Tull <at...@kernel.org>
---
v2: This patch added in this version of the patchset
---
 Documentation/fpga/fpga-region.txt |  3 +--
 drivers/fpga/fpga-region.c | 12 +---
 drivers/fpga/of-fpga-region.c  |  3 ++-
 include/linux/fpga/fpga-region.h   |  4 +++-
 4 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/Documentation/fpga/fpga-region.txt 
b/Documentation/fpga/fpga-region.txt
index 139a02b..d38fa3b 100644
--- a/Documentation/fpga/fpga-region.txt
+++ b/Documentation/fpga/fpga-region.txt
@@ -42,8 +42,7 @@ The FPGA region API
 To register or unregister a region:
 ---
 
-   int fpga_region_register(struct device *dev,
-struct fpga_region *region);
+   int fpga_region_register(struct fpga_region *region);
int fpga_region_unregister(struct fpga_region *region);
 
 An example of usage can be seen in the probe function of [3]
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index ebe1f87..84360fd 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -162,10 +162,16 @@ int fpga_region_program_fpga(struct fpga_region *region)
 }
 EXPORT_SYMBOL_GPL(fpga_region_program_fpga);
 
-int fpga_region_register(struct device *dev, struct fpga_region *region)
+int fpga_region_register(struct fpga_region *region)
 {
+   struct device *parent = region->parent;
int id, ret = 0;
 
+   if (!parent) {
+   pr_err("Attempt to register fpga region without parent\n");
+   return -EINVAL;
+   }
+
id = ida_simple_get(_region_ida, 0, 0, GFP_KERNEL);
if (id < 0)
return id;
@@ -175,8 +181,8 @@ int fpga_region_register(struct device *dev, struct 
fpga_region *region)
device_initialize(>dev);
region->dev.groups = region->groups;
region->dev.class = fpga_region_class;
-   region->dev.parent = dev;
-   region->dev.of_node = dev->of_node;
+   region->dev.parent = parent;
+   region->dev.of_node = parent->of_node;
region->dev.id = id;
 
ret = dev_set_name(>dev, "region%d", id);
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index 3079ed8..276ffe2 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -422,11 +422,12 @@ static int of_fpga_region_probe(struct platform_device 
*pdev)
}
 
region->mgr = mgr;
+   region->parent = dev;
 
/* Specify how to get bridges for this type of region. */
region->get_bridges = of_fpga_region_get_bridges;
 
-   ret = fpga_region_register(dev, region);
+   ret = fpga_region_register(region);
if (ret)
goto eprobe_mgr_put;
 
diff --git a/include/linux/fpga/fpga-region.h b/include/linux/fpga/fpga-region.h
index b652031..423c87e 100644
--- a/include/linux/fpga/fpga-region.h
+++ b/include/linux/fpga/fpga-region.h
@@ -8,6 +8,7 @@
 /**
  * struct fpga_region - FPGA Region structure
  * @dev: FPGA Region device
+ * @parent: parent device
  * @mutex: enforces exclusive reference to region
  * @bridge_list: list of FPGA bridges specified in region
  * @mgr: FPGA manager
@@ -18,6 +19,7 @@
  */
 struct fpga_region {
struct device dev;
+   struct device *parent;
struct mutex mutex; /* for exclusive reference to region */
struct list_head bridge_list;
struct fpga_manager *mgr;
@@ -34,7 +36,7 @@ struct fpga_region *fpga_region_class_find(
int (*match)(struct device *, const void *));
 
 int fpga_region_program_fpga(struct fpga_region *region);
-int fpga_region_register(struct device *dev, struct fpga_region *region);
+int fpga_region_register(struct fpga_region *region);
 int fpga_region_unregister(struct fpga_region *region);
 
 #endif /* _FPGA_REGION_H */
-- 
2.7.4



[PATCH v2 2/5] fpga: manager: don't use drvdata in common fpga code

2017-11-15 Thread Alan Tull
Changes to the fpga manager code to not use drvdata in common
code.

Change fpga_mgr_register to not set or use drvdata.

Change the register/unregister function parameters to take the mgr
struct:
* int fpga_mgr_register(struct fpga_manager *mgr);
* void fpga_mgr_unregister(struct fpga_manager *mgr);

Change the drivers that call fpga_mgr_register to alloc the struct
fpga_manager (using devm_kzalloc) and partly fill it, adding name,
ops, parent device, and priv.

The rationale is that setting drvdata is fine for DT based devices
that will have one manager, bridge, or region per platform device.
However PCIe based devices may have multiple FPGA mgr/bridge/regions
under one pcie device.  Without these changes, the PCIe solution has
to create an extra device for each child mgr/bridge/region to hold
drvdata.

Signed-off-by: Alan Tull <at...@kernel.org>
Reported-by: Jiuyue Ma <majiu...@huawei.com>
---
v2: change fpga_mgr_register to not need parent device param
---
 Documentation/fpga/fpga-mgr.txt  | 24 ++--
 drivers/fpga/altera-cvp.c| 18 +++
 drivers/fpga/altera-pr-ip-core.c | 17 --
 drivers/fpga/altera-ps-spi.c | 18 ---
 drivers/fpga/fpga-mgr.c  | 49 
 drivers/fpga/ice40-spi.c | 20 
 drivers/fpga/socfpga-a10.c   | 16 ++---
 drivers/fpga/socfpga.c   | 18 ---
 drivers/fpga/ts73xx-fpga.c   | 18 ---
 drivers/fpga/xilinx-spi.c| 18 ---
 drivers/fpga/zynq-fpga.c | 16 ++---
 include/linux/fpga/fpga-mgr.h|  8 +++
 12 files changed, 171 insertions(+), 69 deletions(-)

diff --git a/Documentation/fpga/fpga-mgr.txt b/Documentation/fpga/fpga-mgr.txt
index cc6413e..5b8b274 100644
--- a/Documentation/fpga/fpga-mgr.txt
+++ b/Documentation/fpga/fpga-mgr.txt
@@ -67,11 +67,9 @@ fpga_mgr_unlock when done programming the FPGA.
 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);
+   int fpga_mgr_register(struct fpga_manager *mgr);
 
-   void fpga_mgr_unregister(struct device *dev);
+   void fpga_mgr_unregister(struct fpga_manager *mgr);
 
 Use of these two functions is described below in "How To Support a new FPGA
 device."
@@ -148,8 +146,13 @@ static int socfpga_fpga_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
struct socfpga_fpga_priv *priv;
+   struct fpga_manager *mgr;
int ret;
 
+   mgr = devm_kzalloc(dev, sizeof(*mgr), GFP_KERNEL);
+   if (!mgr)
+   return -ENOMEM;
+
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -157,13 +160,20 @@ static int socfpga_fpga_probe(struct platform_device 
*pdev)
/* ... do ioremaps, get interrupts, etc. and save
   them in priv... */
 
-   return fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager",
-_fpga_ops, priv);
+   mgr->name = "Altera SOCFPGA FPGA Manager";
+   mgr->mops = _fpga_ops;
+   mgr->priv = priv;
+   mgr->parent = dev;
+   platform_set_drvdata(pdev, mgr);
+
+   return fpga_mgr_register(mgr);
 }
 
 static int socfpga_fpga_remove(struct platform_device *pdev)
 {
-   fpga_mgr_unregister(>dev);
+   struct fpga_manager *mgr = platform_get_drvdata(pdev);
+
+   fpga_mgr_unregister(mgr);
 
return 0;
 }
diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
index 00e73d2..384c99d 100644
--- a/drivers/fpga/altera-cvp.c
+++ b/drivers/fpga/altera-cvp.c
@@ -403,6 +403,7 @@ static int altera_cvp_probe(struct pci_dev *pdev,
const struct pci_device_id *dev_id)
 {
struct altera_cvp_conf *conf;
+   struct fpga_manager *mgr;
u16 cmd, val;
int ret;
 
@@ -421,6 +422,10 @@ static int altera_cvp_probe(struct pci_dev *pdev,
if (!conf)
return -ENOMEM;
 
+   mgr = devm_kzalloc(>dev, sizeof(*mgr), GFP_KERNEL);
+   if (!mgr)
+   return -ENOMEM;
+
/*
 * Enable memory BAR access. We cannot use pci_enable_device() here
 * because it will make the driver unusable with FPGA devices that
@@ -454,8 +459,13 @@ static int altera_cvp_probe(struct pci_dev *pdev,
snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s @%s",
 ALTERA_CVP_MGR_NAME, pci_name(pdev));
 
-   ret = fpga_mgr_register(>dev, conf->mgr_name,
-   _cvp_ops, conf);
+   mgr->name = conf->mgr_name;
+   mgr->mops = _cvp_ops;
+   mgr->priv = conf;

Re: [PATCH v5 00/18] Enable upper layers using FPGA region w/o device tree

2017-11-15 Thread Alan Tull
On Wed, Nov 15, 2017 at 9:53 AM, Moritz Fischer <m...@kernel.org> wrote:
> On Tue, Oct 17, 2017 at 04:20:13PM -0500, Alan Tull wrote:
>> * Change the fpga-mgr API to have one fpga_mgr_load function
>>   instead of three.
>>
>> * Separate common FPGA region code from Device Tree support
>>
>> * Expose API functions for FPGA regions
>>
>> * Add API functions for bridges where DT is not used.
>>
>> * clean up drivers/fpga/Kconfig
>>
>> * add attribute groups when registering a fpga manager, bridge, or region.
>>
>> Needed because the current FPGA layer has a couple of problems:
>>
>> * We now have 3 functions for programming a FPGA, depending on whether
>> the image is in a sg list, a buffer, or firmware.  So upper layers
>> have to be written assuming where the image will be or will have to
>> write extra code to maintain flexibility.
>>
>> * users who aren't using device tree are left to write their
>> own code that is essentially a rewrite of FPGA region.
>>
>> v5 changes are small:
>> * add back in fpga_mgr_put in of_fpga_region_remove
>> * make __fpga_bridge_get static
>> * move #ifndef before #includes in headers
>> * Spelling fixes and other nits
>>
>> Alan Tull (18):
>>   fpga: bridge: support getting bridge from device
>>   fpga: mgr: API change to replace fpga load functions with single
>> function
>>   fpga: mgr: separate getting/locking FPGA manager
>>   fpga: region: use dev_err instead of pr_err
>>   fpga: region: remove unneeded of_node_get and put
>>   fpga: region: get mgr early on
>>   fpga: region: check for child regions before allocing image info
>>   fpga: region: fix slow warning with more than one overlay
>>   fpga: region: use image info as parameter for programming region
>>   fpga: region: separate out code that parses the overlay
>>   fpga: region: add fpga-region.h header
>>   fpga: region: rename some functions prior to moving
>>   fpga: region: add register/unregister functions
>>   fpga: region: add fpga_region_class_find
>>   fpga: region: move device tree support to of-fpga-region.c
>>   fpga: of-fpga-region: accept overlays that don't program FPGA
>>   fpga: clean up fpga Kconfig
>>   fpga: add attribute groups
>
> Anyways, feel free to add my Acked-by's to the series.

Thanks!

> I have tried to /
> done my change with bridge locking on top of this, but it became quickly
> ugly. Let's get this stuff merged, and I'll try with a follow up patch.

Sounds like a plan!  I've asked Greg to take the patchset.  I'll post
v2 of my 'don't use drvdata in FPGA common code' set that goes on top
of it.  I posted a branch to linux-fpga which has both patchsets for
convenience.  Branch name is next-20171113-non-dt-support-v6+v2

Alan


[RFC 0/2] of: Add whitelist

2017-11-27 Thread Alan Tull
Here's a proposal for a whitelist to lock down the dynamic device tree.

For an overlay to be accepted, all of its targets are required to be
on a target node whitelist.

Currently the only way I have to get on the whitelist is calling a
function to add a node.  That works for fpga regions, but I think
other uses will need a way of having adding specific nodes from the
base device tree, such as by adding a property like 'allow-overlay;'
or 'allow-overlay = "okay";' If that is acceptable, I could use some
advice on where that particular code should go.

Alan

Alan Tull (2):
  of: overlay: add whitelist
  fpga: of region: add of-fpga-region to whitelist

 drivers/fpga/of-fpga-region.c |  9 ++
 drivers/of/overlay.c  | 73 +++
 include/linux/of.h| 12 +++
 3 files changed, 94 insertions(+)

-- 
2.7.4



[RFC 2/2] fpga: of region: add of-fpga-region to whitelist

2017-11-27 Thread Alan Tull
During each FPGA region's probe, add to whitelist.  Remove
during driver remove.

Signed-off-by: Alan Tull <at...@kernel.org>
---
 drivers/fpga/of-fpga-region.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index 7dfaa95..abb57a9 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -435,6 +435,10 @@ static int of_fpga_region_probe(struct platform_device 
*pdev)
/* Specify how to get bridges for this type of region. */
region->get_bridges = of_fpga_region_get_bridges;
 
+   ret = of_add_whitelist_node(np);
+   if (ret)
+   goto eprobe_wl_err;
+
ret = fpga_region_register(region);
if (ret)
goto eprobe_mgr_put;
@@ -447,6 +451,8 @@ static int of_fpga_region_probe(struct platform_device 
*pdev)
return 0;
 
 eprobe_mgr_put:
+   of_remove_whitelist_node(np);
+eprobe_wl_err:
fpga_mgr_put(mgr);
return ret;
 }
@@ -454,7 +460,10 @@ static int of_fpga_region_probe(struct platform_device 
*pdev)
 static int of_fpga_region_remove(struct platform_device *pdev)
 {
struct fpga_region *region = platform_get_drvdata(pdev);
+   struct device *dev = >dev;
+   struct device_node *np = dev->of_node;
 
+   of_remove_whitelist_node(np);
fpga_region_unregister(region);
fpga_mgr_put(region->mgr);
 
-- 
2.7.4



[RFC 1/2] of: overlay: add whitelist

2017-11-27 Thread Alan Tull
Add simple whitelist.  When an overlay is submitted, if any target in
the overlay is not in the whitelist, the overlay is rejected.  Drivers
that support dynamic configuration can register their device node with:

  int of_add_whitelist_node(struct device_node *np)

and remove themselves with:

  void of_remove_whitelist_node(struct device_node *np)

Signed-off-by: Alan Tull <at...@kernel.org>
---
 drivers/of/overlay.c | 73 
 include/linux/of.h   | 12 +
 2 files changed, 85 insertions(+)

diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index c150abb..5f952a1 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "of_private.h"
 
@@ -646,6 +647,74 @@ static void free_overlay_changeset(struct 
overlay_changeset *ovcs)
kfree(ovcs);
 }
 
+/* lock for adding/removing device nodes to the whitelist */
+static spinlock_t whitelist_lock;
+
+static struct list_head whitelist_list = LIST_HEAD_INIT(whitelist_list);
+
+struct dt_overlay_whitelist {
+   struct device_node *np;
+   struct list_head node;
+};
+
+int of_add_whitelist_node(struct device_node *np)
+{
+   unsigned long flags;
+   struct dt_overlay_whitelist *wln;
+
+   wln = kzalloc(sizeof(*wln), GFP_KERNEL);
+   if (!wln)
+   return -ENOMEM;
+
+   wln->np = np;
+
+   spin_lock_irqsave(_lock, flags);
+   list_add(>node, _list);
+   spin_unlock_irqrestore(_lock, flags);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(of_add_whitelist_node);
+
+void of_remove_whitelist_node(struct device_node *np)
+{
+   struct dt_overlay_whitelist *wln;
+   unsigned long flags;
+
+   list_for_each_entry(wln, _list, node) {
+   if (np == wln->np) {
+   spin_lock_irqsave(_lock, flags);
+   list_del(>node);
+   spin_unlock_irqrestore(_lock, flags);
+   kfree(wln);
+   return;
+   }
+   }
+}
+EXPORT_SYMBOL_GPL(of_remove_whitelist_node);
+
+static int of_check_whitelist(struct overlay_changeset *ovcs)
+{
+   struct dt_overlay_whitelist *wln;
+   struct device_node *target;
+   int i;
+
+   for (i = 0; i < ovcs->count; i++) {
+   target = ovcs->fragments[i].target;
+   if (!of_node_cmp(target->name, "__symbols__"))
+   continue;
+
+   list_for_each_entry(wln, _list, node)
+   if (target == wln->np)
+   break;
+
+   if (target != wln->np)
+   return -ENODEV;
+   }
+
+   return 0;
+}
+
 /**
  * of_overlay_apply() - Create and apply an overlay changeset
  * @tree:  Expanded overlay device tree
@@ -717,6 +786,10 @@ int of_overlay_apply(struct device_node *tree, int 
*ovcs_id)
if (ret)
goto err_free_overlay_changeset;
 
+   ret = of_check_whitelist(ovcs);
+   if (ret)
+   goto err_free_overlay_changeset;
+
ret = overlay_notify(ovcs, OF_OVERLAY_PRE_APPLY);
if (ret) {
pr_err("overlay changeset pre-apply notify error %d\n", ret);
diff --git a/include/linux/of.h b/include/linux/of.h
index d3dea1d..5bf652a1 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -1364,6 +1364,9 @@ int of_overlay_remove_all(void);
 int of_overlay_notifier_register(struct notifier_block *nb);
 int of_overlay_notifier_unregister(struct notifier_block *nb);
 
+int of_add_whitelist_node(struct device_node *np);
+void of_remove_whitelist_node(struct device_node *np);
+
 #else
 
 static inline int of_overlay_apply(struct device_node *tree, int *ovcs_id)
@@ -1391,6 +1394,15 @@ static inline int of_overlay_notifier_unregister(struct 
notifier_block *nb)
return 0;
 }
 
+static inline int of_add_whitelist_node(struct device_node *np)
+{
+   return 0;
+}
+
+static inline void of_remove_whitelist_node(struct device_node *np)
+{
+}
+
 #endif
 
 #endif /* _LINUX_OF_H */
-- 
2.7.4



Re: [PATCH v3 00/21] Intel FPGA Device Drivers

2017-11-27 Thread Alan Tull
On Mon, Nov 27, 2017 at 12:42 AM, Wu Hao <hao...@intel.com> wrote:

> This patch series depends on the below patchset from Alan Tull.
> [PATCH v2 0/5] fpga: don't use drvdata in common fpga code[1]
>
> [1] https://marc.info/?l=linux-fpga=151077942606263=2

Hi Hao,

Thanks for basing your v3 on my latest patches.  I'll be looking at them.

Alan


Re: [RFC 1/2] of: overlay: add whitelist

2017-11-28 Thread Alan Tull
On Tue, Nov 28, 2017 at 9:15 AM, Rob Herring <r...@kernel.org> wrote:
> On Mon, Nov 27, 2017 at 02:58:03PM -0600, Alan Tull wrote:
>> Add simple whitelist.  When an overlay is submitted, if any target in
>> the overlay is not in the whitelist, the overlay is rejected.  Drivers
>> that support dynamic configuration can register their device node with:
>>
>>   int of_add_whitelist_node(struct device_node *np)
>>
>> and remove themselves with:
>>
>>   void of_remove_whitelist_node(struct device_node *np)
>
> I think these should be named for what they do, not how it is
> implemented.

Sure, such as of_node_overlay_enable and of_node_overlay_disable?

>
>>
>> Signed-off-by: Alan Tull <at...@kernel.org>
>> ---
>>  drivers/of/overlay.c | 73 
>> 
>>  include/linux/of.h   | 12 +
>>  2 files changed, 85 insertions(+)
>>
>> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
>> index c150abb..5f952a1 100644
>> --- a/drivers/of/overlay.c
>> +++ b/drivers/of/overlay.c
>> @@ -21,6 +21,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>
>>  #include "of_private.h"
>>
>> @@ -646,6 +647,74 @@ static void free_overlay_changeset(struct 
>> overlay_changeset *ovcs)
>>   kfree(ovcs);
>>  }
>>
>> +/* lock for adding/removing device nodes to the whitelist */
>> +static spinlock_t whitelist_lock;
>> +
>> +static struct list_head whitelist_list = LIST_HEAD_INIT(whitelist_list);
>> +
>> +struct dt_overlay_whitelist {
>> + struct device_node *np;
>> + struct list_head node;
>> +};
>
> Can't we just add a flags bit in device_node.flags? That would be much
> simpler.

Yes, much simpler.  Such as:

#define OF_OVERLAY_ENABLED 5 /* allow DT overlay targeting this node */

>
>> +
>> +int of_add_whitelist_node(struct device_node *np)
>> +{
>> + unsigned long flags;
>> + struct dt_overlay_whitelist *wln;
>> +
>> + wln = kzalloc(sizeof(*wln), GFP_KERNEL);
>> + if (!wln)
>> + return -ENOMEM;
>> +
>> + wln->np = np;
>> +
>> + spin_lock_irqsave(_lock, flags);
>> + list_add(>node, _list);
>> + spin_unlock_irqrestore(_lock, flags);
>> +
>> + return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(of_add_whitelist_node);
>> +
>> +void of_remove_whitelist_node(struct device_node *np)
>> +{
>> + struct dt_overlay_whitelist *wln;
>> + unsigned long flags;
>> +
>> + list_for_each_entry(wln, _list, node) {
>> + if (np == wln->np) {
>> + spin_lock_irqsave(_lock, flags);
>> + list_del(>node);
>> + spin_unlock_irqrestore(_lock, flags);
>> + kfree(wln);
>> + return;
>> + }
>> + }
>> +}
>> +EXPORT_SYMBOL_GPL(of_remove_whitelist_node);
>> +
>> +static int of_check_whitelist(struct overlay_changeset *ovcs)
>> +{
>> + struct dt_overlay_whitelist *wln;
>> + struct device_node *target;
>> + int i;
>> +
>> + for (i = 0; i < ovcs->count; i++) {
>> + target = ovcs->fragments[i].target;
>> + if (!of_node_cmp(target->name, "__symbols__"))
>> + continue;
>> +
>> + list_for_each_entry(wln, _list, node)
>> + if (target == wln->np)
>> + break;
>> +
>> + if (target != wln->np)
>> + return -ENODEV;
>> + }
>> +
>> + return 0;
>> +}
>> +
>>  /**
>>   * of_overlay_apply() - Create and apply an overlay changeset
>>   * @tree:Expanded overlay device tree
>> @@ -717,6 +786,10 @@ int of_overlay_apply(struct device_node *tree, int 
>> *ovcs_id)
>>   if (ret)
>>   goto err_free_overlay_changeset;
>>
>> + ret = of_check_whitelist(ovcs);
>> + if (ret)
>> + goto err_free_overlay_changeset;
>
> This will break you until the next patch and breaks any other users. I
> think this is now just the unittest as tilcdc overlay is getting
> removed.
>
> You have to make this chunk the last patch in the series.

I'd rather squash the two patches.  In either case, the contents of
second patch are dependent on stuff in char-misc-testing today, so it
won't be able to apply yet on linux-next or anywhere else.

Thanks
Alan

>
> Rob


Re: [RFC 0/2] of: Add whitelist

2017-11-29 Thread Alan Tull
On Wed, Nov 29, 2017 at 7:31 AM, Rob Herring <robh...@kernel.org> wrote:
> On Wed, Nov 29, 2017 at 3:20 AM, Frank Rowand <frowand.l...@gmail.com> wrote:
>> On 11/27/17 15:58, Alan Tull wrote:
>>> Here's a proposal for a whitelist to lock down the dynamic device tree.
>>>
>>> For an overlay to be accepted, all of its targets are required to be
>>> on a target node whitelist.
>>>
>>> Currently the only way I have to get on the whitelist is calling a
>>> function to add a node.  That works for fpga regions, but I think
>>> other uses will need a way of having adding specific nodes from the
>>> base device tree, such as by adding a property like 'allow-overlay;'
>>> or 'allow-overlay = "okay";' If that is acceptable, I could use some
>>> advice on where that particular code should go.
>>>
>>> Alan
>>>
>>> Alan Tull (2):
>>>   of: overlay: add whitelist
>>>   fpga: of region: add of-fpga-region to whitelist
>>>
>>>  drivers/fpga/of-fpga-region.c |  9 ++
>>>  drivers/of/overlay.c  | 73 
>>> +++
>>>  include/linux/of.h| 12 +++
>>>  3 files changed, 94 insertions(+)
>>>
>>
>> The plan was to use connectors to restrict where an overlay could be applied.
>> I would prefer not to have multiple methods for accomplishing the same thing
>> unless there is a compelling reason to do so.
>
> Connector nodes need a mechanism to enable themselves, too. I don't
> think connector nodes are going to solve every usecase.
>
> Rob

The two methods I'm suggesting are intended to handle different cases.
  There will exist some drivers that by their nature will want every
instance to be enabled for overlays, such as fpga regions.  The other
case is where drivers could support overlays but that's not the
widespread use for them.  So no need to enable every instance of that
driver for overlays.  In that case the DT property provides some
granularity, only enabling overlays for specific instances of that
driver, leaving the rest of the DT locked down.

If we only want one method, I would choose having the DT property only
and not exporting the functions.  Users would have to add the property
for every FPGA region but that's not really painful.  This would have
the benefit of still keeping the DT locked down unless someone
specifically wanted to enable some regions for overlays for their
particular use.

Alan


[PATCH 0/2] of: dynamic: restrict overlay by targets

2017-12-04 Thread Alan Tull
Restrict which nodes are valid targets for a DT overlay.

Add a flag bit to struct device_node allowing nodes to be marked as
valid target for overlays.

A driver that is always intended to handle DT overlays can
enable overlays by calling a function for its DT node.

For individual nodes that need to be opened up for a specific use,
adding the property "overlay-allowed" enables overlays targeting
that node.  I'll need to document the DT property, not sure where
specifically.  New file bindings/overlay.txt?

This patchset differs from the RFC:
* Added a flag bit and got rid of the whitelist
* Renamed the functions that enable a node
* Added a DT property

Alan Tull (2):
  of: overlay: add flag enabling overlays and enable fpga-region
overlays
  of: dynamic: add overlay-allowed DT property

 drivers/fpga/of-fpga-region.c |  4 
 drivers/of/base.c |  4 ++--
 drivers/of/dynamic.c  |  3 +++
 drivers/of/fdt.c  |  3 +++
 drivers/of/of_private.h   |  2 ++
 drivers/of/overlay.c  | 26 ++
 include/linux/of.h| 19 +++
 7 files changed, 59 insertions(+), 2 deletions(-)

-- 
2.7.4



Re: [PATCH v2 0/5] fpga: don't use drvdata in common fpga code

2017-12-04 Thread Alan Tull
On Wed, Nov 15, 2017 at 2:51 PM, Alan Tull <at...@kernel.org> wrote:

Gentle reminder, this patch set is pretty straightforward, could use
some reviewing.

Alan

> This patch set goes on top of v6 of the non-dt support patchset that has
> been acked and I've asked Greg KH to send upstream.
>
> This patchset changes the fpga_*_register functions to not set drvdata,
> and changes parameters for register/unregister functions.  Also a
> bug fix due to changes in the DT overlay code.
>
> Setting drvdata is fine for DT based devices, that will have one
> manager, bridge, or region device per platform device.  PCIe based
> devices may have multiple FPGA mgr/bridge/regions under one pcie
> device.  Without these changes, PCIe-based solutions have to create an
> extra device for each child mgr/bridge/region to hold drvdata.
>
> Also changing the fpga_*_register/unregister functions to take the
> corresponding struct as the only parameter wherever they weren't already.
>
> * int fpga_bridge_register(struct fpga_bridge *br)
> * int fpga_mgr_register(struct fpga_manager *mgr)
> * int fpga_region_register(struct fpga_region *region)
> * void fpga_bridge_unregister(struct fpga_bridge *br)
> * void fpga_mgr_unregister(struct fpga_manager *mgr)
> * int fpga_region_unregister(struct fpga_region *region)
>
> Other changes:
>
> - Callers of fpga_(bridge|mgr)_register, are changed to alloc the
> bridge/mgr struct and partly fill it, adding name, ops and priv.
> - Caller uses devm for allocating the mgr/bridge structures.
> - Change the FPGA Region DT notifier to return NOTIFY_STOP if
> the overlay should be accepted.
>
> I posted a branch to the linux-fpga repo on kernel.org which has both
> the v6 non-DT support patchset and this v2 patchset for convenience.
> Branch name is next-20171113-non-dt-support-v6+v2
>
> Alan
>
> Alan Tull (5):
>   fpga: region: don't use drvdata in common fpga code
>   fpga: manager: don't use drvdata in common fpga code
>   fpga: bridge: don't use drvdata in common fpga code
>   fpga: region: change fpga_region_register to have one param
>   fpga: region: return NOTIFY_STOP if overlay shoud be accepted
>
>  Documentation/fpga/fpga-mgr.txt | 24 -
>  Documentation/fpga/fpga-region.txt  |  3 +--
>  drivers/fpga/altera-cvp.c   | 18 ++---
>  drivers/fpga/altera-fpga2sdram.c| 20 +++---
>  drivers/fpga/altera-freeze-bridge.c | 18 ++---
>  drivers/fpga/altera-hps2fpga.c  | 16 ---
>  drivers/fpga/altera-pr-ip-core.c| 17 ++--
>  drivers/fpga/altera-ps-spi.c| 18 ++---
>  drivers/fpga/fpga-bridge.c  | 53 
> ++---
>  drivers/fpga/fpga-mgr.c | 49 +-
>  drivers/fpga/fpga-region.c  | 13 ++---
>  drivers/fpga/ice40-spi.c| 20 +++---
>  drivers/fpga/of-fpga-region.c   |  9 ---
>  drivers/fpga/socfpga-a10.c  | 16 ---
>  drivers/fpga/socfpga.c  | 18 ++---
>  drivers/fpga/ts73xx-fpga.c  | 18 ++---
>  drivers/fpga/xilinx-pr-decoupler.c  | 15 ---
>  drivers/fpga/xilinx-spi.c   | 18 ++---
>  drivers/fpga/zynq-fpga.c| 16 ---
>  include/linux/fpga/fpga-bridge.h|  7 ++---
>  include/linux/fpga/fpga-mgr.h   |  8 +++---
>  include/linux/fpga/fpga-region.h|  4 ++-
>  22 files changed, 270 insertions(+), 128 deletions(-)
>
> --
> 2.7.4
>


Re: [PATCH v3 02/21] fpga: mgr: add region_id to fpga_image_info

2017-12-04 Thread Alan Tull
On Wed, Nov 29, 2017 at 12:11 AM, Moritz Fischer <m...@kernel.org> wrote:
> Hi Hao,
>
> On Mon, Nov 27, 2017 at 02:42:09PM +0800, Wu Hao wrote:
>> This patch adds region_id to fpga_image_info data structure, it
>> allows driver to pass region id information to fpga-mgr via
>> fpga_image_info for fpga reconfiguration function.
>>
>> Signed-off-by: Wu Hao <hao...@intel.com>
> Acked-by: Moritz Fischer <m...@kernel.org>

Acked-by: Alan Tull <at...@kernel.org>

>> 
>> v3: add one line comment for region_id
>> ---
>>  include/linux/fpga/fpga-mgr.h | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
>> index 1ad4822..6e98b66 100644
>> --- a/include/linux/fpga/fpga-mgr.h
>> +++ b/include/linux/fpga/fpga-mgr.h
>> @@ -88,6 +88,7 @@ enum fpga_mgr_states {
>>   * @sgt: scatter/gather table containing FPGA image
>>   * @buf: contiguous buffer containing FPGA image
>>   * @count: size of buf
>> + * @region_id: id of target region
>>   * @dev: device that owns this
>>   * @overlay: Device Tree overlay
>>   */
>> @@ -100,6 +101,7 @@ struct fpga_image_info {
>>   struct sg_table *sgt;
>>   const char *buf;
>>   size_t count;
>> + int region_id;
>>   struct device *dev;
>>  #ifdef CONFIG_OF
>>   struct device_node *overlay;
>> --
>> 1.8.3.1
>>
>
> Moritz


[PATCH 1/2] of: overlay: add flag enabling overlays and enable fpga-region overlays

2017-12-04 Thread Alan Tull
Add a flag to struct device_node marking the node as a valid target
for device tree overlays.  When an overlay is submitted, if any target
in the overlay is not enabled for overlays, the overlay is rejected.
Drivers that support dynamic configuration can enable/disable their
device node with:

  void of_node_overlay_enable(struct device_node *np)
  void of_node_overlay_disable(struct device_node *np)

During each FPGA region's probe, enable its node for overlays.

Signed-off-by: Alan Tull <at...@kernel.org>
---
v1: (changes from the rfc)
Add a flag instead of implementing a list
rename functions for what they do, not how they're implemented
squash with patch that enables fpga-region nodes
add a helpful error message
---
 drivers/fpga/of-fpga-region.c |  4 
 drivers/of/overlay.c  | 26 ++
 include/linux/of.h| 19 +++
 3 files changed, 49 insertions(+)

diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index 119ff75..8633eea 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -438,6 +438,7 @@ static int of_fpga_region_probe(struct platform_device 
*pdev)
goto eprobe_mgr_put;
 
of_platform_populate(np, fpga_region_of_match, NULL, >dev);
+   of_node_overlay_enable(np);
 
dev_info(dev, "FPGA Region probed\n");
 
@@ -451,7 +452,10 @@ static int of_fpga_region_probe(struct platform_device 
*pdev)
 static int of_fpga_region_remove(struct platform_device *pdev)
 {
struct fpga_region *region = platform_get_drvdata(pdev);
+   struct device *dev = >dev;
+   struct device_node *np = dev->of_node;
 
+   of_node_overlay_disable(np);
fpga_region_unregister(region);
fpga_mgr_put(region->mgr);
 
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 53bc9e3..a9758d6 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "of_private.h"
 
@@ -646,6 +647,27 @@ static void free_overlay_changeset(struct 
overlay_changeset *ovcs)
kfree(ovcs);
 }
 
+static int of_overlay_check_targets(struct overlay_changeset *ovcs)
+{
+   struct device_node *target;
+   int i;
+
+   for (i = 0; i < ovcs->count; i++) {
+   target = ovcs->fragments[i].target;
+
+   if (!of_node_cmp(target->name, "__symbols__"))
+   continue;
+
+   if (!of_node_check_flag(target, OF_OVERLAY_ENABLED)) {
+   pr_err("Overlays not enabled for target %pOF\n",
+  target);
+   return -EPERM;
+   }
+   }
+
+   return 0;
+}
+
 /**
  * of_overlay_apply() - Create and apply an overlay changeset
  * @tree:  Expanded overlay device tree
@@ -717,6 +739,10 @@ int of_overlay_apply(struct device_node *tree, int 
*ovcs_id)
if (ret)
goto err_free_overlay_changeset;
 
+   ret = of_overlay_check_targets(ovcs);
+   if (ret)
+   goto err_free_overlay_changeset;
+
ret = overlay_notify(ovcs, OF_OVERLAY_PRE_APPLY);
if (ret) {
pr_err("overlay changeset pre-apply notify error %d\n", ret);
diff --git a/include/linux/of.h b/include/linux/of.h
index d3dea1d..16a2cae 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -147,6 +147,7 @@ extern raw_spinlock_t devtree_lock;
 #define OF_DETACHED2 /* node has been detached from the device tree */
 #define OF_POPULATED   3 /* device already created for the node */
 #define OF_POPULATED_BUS   4 /* of_platform_populate recursed to children 
of this node */
+#define OF_OVERLAY_ENABLED 5 /* allow DT overlay targeting this node */
 
 #define OF_BAD_ADDR((u64)-1)
 
@@ -1364,6 +1365,16 @@ int of_overlay_remove_all(void);
 int of_overlay_notifier_register(struct notifier_block *nb);
 int of_overlay_notifier_unregister(struct notifier_block *nb);
 
+static inline void of_node_overlay_enable(struct device_node *np)
+{
+   of_node_set_flag(np, OF_OVERLAY_ENABLED);
+}
+
+static inline void of_node_overlay_disable(struct device_node *np)
+{
+   of_node_clear_flag(np, OF_OVERLAY_ENABLED);
+}
+
 #else
 
 static inline int of_overlay_apply(struct device_node *tree, int *ovcs_id)
@@ -1391,6 +1402,14 @@ static inline int of_overlay_notifier_unregister(struct 
notifier_block *nb)
return 0;
 }
 
+static inline void of_node_overlay_enable(struct device_node *np)
+{
+}
+
+static inline void of_node_overlay_disable(struct device_node *np)
+{
+}
+
 #endif
 
 #endif /* _LINUX_OF_H */
-- 
2.7.4



[PATCH 2/2] of: dynamic: add overlay-allowed DT property

2017-12-04 Thread Alan Tull
Allow DT nodes to be marked as valid targets for DT
overlays by the added "overlay-allowed" property.

Signed-off-by: Alan Tull <at...@kernel.org>
---
 drivers/of/base.c   | 4 ++--
 drivers/of/dynamic.c| 3 +++
 drivers/of/fdt.c| 3 +++
 drivers/of/of_private.h | 2 ++
 4 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index 26618ba..ac6b326 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -116,8 +116,8 @@ void __init of_core_init(void)
proc_symlink("device-tree", NULL, 
"/sys/firmware/devicetree/base");
 }
 
-static struct property *__of_find_property(const struct device_node *np,
-  const char *name, int *lenp)
+struct property *__of_find_property(const struct device_node *np,
+   const char *name, int *lenp)
 {
struct property *pp;
 
diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index ab988d8..fae9b85 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -207,6 +207,9 @@ static void __of_attach_node(struct device_node *np)
np->name = __of_get_property(np, "name", NULL) ? : "";
np->type = __of_get_property(np, "device_type", NULL) ? : "";
 
+   if (__of_find_property(np, "overlay-allowed", NULL))
+   of_node_set_flag(np, OF_OVERLAY_ENABLED);
+
phandle = __of_get_property(np, "phandle", );
if (!phandle)
phandle = __of_get_property(np, "linux,phandle", );
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 4675e5a..9237f30 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -323,6 +323,9 @@ static bool populate_node(const void *blob,
np->name = "";
if (!np->type)
np->type = "";
+
+   if (of_find_property(np, "overlay-allowed", NULL))
+   of_node_set_flag(np, OF_OVERLAY_ENABLED);
}
 
*pnp = np;
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 92a9a36..75fcba3 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -115,6 +115,8 @@ struct device_node *__of_find_node_by_path(struct 
device_node *parent,
 struct device_node *__of_find_node_by_full_path(struct device_node *node,
const char *path);
 
+extern struct property *__of_find_property(const struct device_node *np,
+  const char *name, int *lenp);
 extern const void *__of_get_property(const struct device_node *np,
 const char *name, int *lenp);
 extern int __of_add_property(struct device_node *np, struct property *prop);
-- 
2.7.4



Re: [PATCH v3 08/21] fpga: add Intel FPGA DFL PCIe device

2017-12-04 Thread Alan Tull
On Mon, Nov 27, 2017 at 9:15 PM, Wu Hao  wrote:
> On Mon, Nov 27, 2017 at 10:28:04AM +, David Laight wrote:
>> From: Wu Hao
>> > Sent: 27 November 2017 06:42
>> > From: Zhang Yi 
>> >
>> > The Intel FPGA device appears as a PCIe device on the system. This patch
>> > implements the basic framework of the driver for Intel PCIe device which
>> > is located between CPU and Accelerated Function Units (AFUs), and has
>> > the Device Feature List (DFL) implemented in its MMIO space.
>>
>> This ought to have a better name than 'Intel FPGA'.
>> An fpga can be used for all sorts of things, this looks like
>> a very specific architecture using a common VHDL environment to
>> allow certain types of user VHDL be accessed over PCIe.
>
> Hi David
>
> This patch adds a pcie device driver for Intel FPGA devices which implements
> the DFL, e.g Intel Server Platform with In-package FPGA and Intel FPGA PCIe
> Acceleration Cards. They are pcie devices, and all have DFL implemented in
> the MMIO space, so we would like to use one kernel driver to handle them.
>
> With this full patchset, it just provides user the interfaces to configure
> and access the FPGA accelerators on Intel DFL based FPGA devices. For sure,
> users can develop and build their own logics via tools provided by Intel,
> program them to accelerators on these Intel FPGA devices, and access them
> for their workloads.

I don't see anything Intel specific here.  This could all be named dfl-*

Alan

>
> Thanks
> Hao


Re: [PATCH v3 01/21] docs: fpga: add a document for Intel FPGA driver overview

2017-12-04 Thread Alan Tull
On Mon, Nov 27, 2017 at 12:42 AM, Wu Hao  wrote:
> Add a document for Intel FPGA driver overview.
>
> Signed-off-by: Enno Luebbers 
> Signed-off-by: Xiao Guangrong 
> Signed-off-by: Wu Hao 
> 
> v2: added FME fpga-mgr/bridge/region platform driver to driver organization.
> updated open discussion per current implementation.
> fixed some typos.
> v3: use FPGA base region as container device instead of fpga-dev class.
> split common enumeration code from pcie driver to functions exposed by
> device feature list framework.
> update FME performance reporting which supports both integrated (iperf/)
> and discrete (dperf/) FPGA solutions.
> ---
>  Documentation/fpga/intel-fpga.txt | 261 
> ++
>  1 file changed, 261 insertions(+)
>  create mode 100644 Documentation/fpga/intel-fpga.txt
>
> diff --git a/Documentation/fpga/intel-fpga.txt 
> b/Documentation/fpga/intel-fpga.txt
> new file mode 100644
> index 000..0754733
> --- /dev/null
> +++ b/Documentation/fpga/intel-fpga.txt
> @@ -0,0 +1,261 @@
> +===
> +Intel FPGA driver Overview

This doesn't look Intel specific to me.  This could all be 'DFL FPGA Framework'

> +---
> +Enno Luebbers 
> +Xiao Guangrong 
> +Wu Hao 
> +
> +The Intel FPGA driver provides interfaces for userspace applications to
> +configure, enumerate, open, and access FPGA accelerators on platforms 
> equipped
> +with Intel(R) FPGA PCIe based solutions and enables system level management
> +functions such as FPGA reconfiguration, power management, and virtualization.
> +
> +HW Architecture
> +===
> +From the OS's point of view, the FPGA hardware appears as a regular PCIe 
> device.
> +The FPGA device memory is organized using a predefined data structure (Device
> +Feature List). Features supported by the particular FPGA device are exposed
> +through these data structures, as illustrated below:
> +
> +  +---+  +-+
> +  |  PF   |  | VF  |
> +  +---+  +-+
> +  ^^ ^  ^
> +  || |  |
> ++-||-|--|---+
> +| || |  |   |
> +|  +-+ +---+ +---+  +---+   |
> +|  | FME | | Port0 | | Port1 |  | Port2 |   |
> +|  +-+ +---+ +---+  +---+   |
> +|  ^ ^  ^   |
> +|  | |  |   |
> +|  +---+ +--+   +---+   |
> +|  |  AFU  | |  AFU |   |  AFU  |   |
> +|  +---+ +--+   +---+   |
> +|   |
> +| FPGA PCIe Device  |
> ++---+
> +
> +The driver supports PCIe SR-IOV to create virtual functions (VFs) which can 
> be
> +used to assign individual accelerators to virtual machines.
> +
> +FME (FPGA Management Engine)
> +
> +The FPGA Management Engine performs power and thermal management, error
> +reporting, reconfiguration, performance reporting for integrated and discrete
> +solution, and other infrastructure functions. Each FPGA has one FME, which is
> +always accessed through the physical function (PF).
> +
> +User-space applications can acquire exclusive access to the FME using open(),
> +and release it using close().
> +
> +The following functions are exposed through ioctls:
> +
> +   Get driver API version (FPGA_GET_API_VERSION)
> +   Check for extensions (FPGA_CHECK_EXTENSION)
> +   Assign port to PF (FPGA_FME_PORT_ASSIGN)
> +   Release port from PF (FPGA_FME_PORT_RELEASE)
> +   Program bitstream (FPGA_FME_PORT_PR)
> +
> +More functions are exposed through sysfs
> +(/sys/class/fpga_region/regionX/fpga-dfl-fme.n/):

I see that /sys/class/fpga/* has changed to /sys/class/fpga_region/*
now as requested (thanks!).  It looks like it ended up being pretty
straightforward (so far, just diffing this doc with the previous v2).

> +
> +   Read bitstream ID (bitstream_id)
> +   Read bitstream metadata (bitstream_metadata)
> +   Read number of ports (ports_num)
> +   Read socket ID (socket_id)
> +   Read performance counters (iperf/ and dperf/)
> +   Power management (power_mgmt/)
> +   Thermal management (thermal_mgmt/)
> +   Error reporting (errors/)
> +
> +PORT
> +
> +A port represents the interface 

Re: [PATCH v3 03/21] fpga: mgr: add status for fpga-manager

2017-12-04 Thread Alan Tull
On Mon, Nov 27, 2017 at 12:42 AM, Wu Hao  wrote:

Hi Hao,

mgr->status isn't used anywhere except in status_show.  So we don't
need to add status to the fpga_manager struct.  Also don't need the
inline function to update it.  Just read the status in status_show, if
that ops exists.  If mops->status is NULL, return an error, as below.
This will simplify things and make sure that status_show gets status
that is not stale at all.

> This patch adds status to fpga-manager data structure, to allow
> driver to store full/partial reconfiguration errors and other
> status information, and adds one status callback to fpga_manager_ops
> to allow fpga_manager to collect latest status when failures are
> detected.
>
> The following sysfs file is created:
> * /sys/class/fpga_manager//status
>   Return status of fpga manager, including reconfiguration errors.
>
> Signed-off-by: Wu Hao 
> 
> v3: add one line description for status
> add status callback function to fpga_manager_ops
> update fpga-mgr status if any failure or during initialization
> s/INCOMPATIBLE_BS_ERR/INCOMPATIBLE_IMAGE_ERR/
> ---
>  Documentation/ABI/testing/sysfs-class-fpga-manager | 10 
>  drivers/fpga/fpga-mgr.c| 28 
> ++
>  include/linux/fpga/fpga-mgr.h  | 17 +
>  3 files changed, 55 insertions(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-class-fpga-manager 
> b/Documentation/ABI/testing/sysfs-class-fpga-manager
> index 23056c5..01db14d 100644
> --- a/Documentation/ABI/testing/sysfs-class-fpga-manager
> +++ b/Documentation/ABI/testing/sysfs-class-fpga-manager
> @@ -35,3 +35,13 @@ Description: Read fpga manager state as a string.
> * write complete= Doing post programming steps
> * write complete error  = Error while doing post programming
> * operating = FPGA is programmed and operating
> +
> +What:  /sys/class/fpga_manager//status
> +Date:  November 2017
> +KernelVersion: 4.15
> +Contact:   Wu Hao 
> +Description:   Read fpga manager status as a string.
> +   If FPGA programming operation fails, it could be due to crc
> +   error or incompatible bitstream image. The intent of this
> +   interface is to provide more detailed information for FPGA
> +   programming errors to userspace.
> diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
> index 1fd5494..8b583ba 100644
> --- a/drivers/fpga/fpga-mgr.c
> +++ b/drivers/fpga/fpga-mgr.c
> @@ -88,6 +88,7 @@ static int fpga_mgr_write_init_buf(struct fpga_manager *mgr,
> if (ret) {
> dev_err(>dev, "Error preparing FPGA for writing\n");
> mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR;
> +   fpga_mgr_update_status(mgr);

Remove these fpga_mgr_update_status

> return ret;
> }
>
> @@ -148,6 +149,7 @@ static int fpga_mgr_write_complete(struct fpga_manager 
> *mgr,
> if (ret) {
> dev_err(>dev, "Error after writing image data to 
> FPGA\n");
> mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
> +   fpga_mgr_update_status(mgr);
> return ret;
> }
> mgr->state = FPGA_MGR_STATE_OPERATING;
> @@ -225,6 +227,7 @@ static int fpga_mgr_buf_load_mapped(struct fpga_manager 
> *mgr,
> if (ret) {
> dev_err(>dev, "Error while writing image data to 
> FPGA\n");
> mgr->state = FPGA_MGR_STATE_WRITE_ERR;
> +   fpga_mgr_update_status(mgr);
> return ret;
> }
>
> @@ -397,12 +400,36 @@ static ssize_t state_show(struct device *dev,
> return sprintf(buf, "%s\n", state_str[mgr->state]);
>  }
>
> +static ssize_t status_show(struct device *dev,
> +  struct device_attribute *attr, char *buf)
> +{
> +   struct fpga_manager *mgr = to_fpga_manager(dev);
> +   int len = 0;

u64 status;

if (!mgr->mops->status)
return -ENOENT;

status = mgr->mops->status(mgr);

> +
> +   if (mgr->status & FPGA_MGR_STATUS_OPERATION_ERR)

if (status & ...)

> +   len += sprintf(buf + len, "reconfig operation error\n");
> +   if (mgr->status & FPGA_MGR_STATUS_CRC_ERR)
> +   len += sprintf(buf + len, "reconfig CRC error\n");
> +   if (mgr->status & FPGA_MGR_STATUS_INCOMPATIBLE_IMAGE_ERR)
> +   len += sprintf(buf + len, "reconfig incompatible image\n");
> +   if (mgr->status & FPGA_MGR_STATUS_IP_PROTOCOL_ERR)
> +   len += sprintf(buf + len, "reconfig IP protocol error\n");
> +   if (mgr->status & FPGA_MGR_STATUS_FIFO_OVERFLOW_ERR)
> +   len += sprintf(buf + len, "reconfig fifo overflow error\n");
> +   if (mgr->status & FPGA_MGR_STATUS_SECURE_LOAD_ERR)
> +   len += sprintf(buf + len, "reconfig 

Re: [PATCH 2/2] of: dynamic: add overlay-allowed DT property

2017-12-04 Thread Alan Tull
On Mon, Dec 4, 2017 at 2:04 PM, Rob Herring <robh...@kernel.org> wrote:
> On Mon, Dec 4, 2017 at 1:13 PM, Alan Tull <at...@kernel.org> wrote:
>> Allow DT nodes to be marked as valid targets for DT
>> overlays by the added "overlay-allowed" property.
>
> Why do you need a property for this? I'm not all that keen on putting
> this policy into the DT. It can change over time in the kernel. For
> example, as we define use cases that work, then we can loosen
> restrictions in the kernel.

For FPGA regions, I don't need it.  Yes, if the other patch is
accepted, I'm sure we will hear more from people who will need some
specific loosening.  I was trying to anticipate that, but I don't have
a specific need.

Alan

>
> Rob


Re: [PATCH v2 1/5] fpga: region: don't use drvdata in common fpga code

2017-12-04 Thread Alan Tull
On Mon, Dec 4, 2017 at 3:32 PM, Moritz Fischer <m...@kernel.org> wrote:
> On Wed, Nov 15, 2017 at 02:51:48PM -0600, Alan Tull wrote:
>> Part of patchset that changes the following fpga_*_register
>> functions to not set drvdata:
>> * fpga_region_register.
>> * fpga_mgr_register
>> * fpga_bridge_register
>>
>> The rationale is that setting drvdata is fine for DT based devices
>> that will have one manager, bridge, or region per platform device.
>> However PCIe based devices may have multiple FPGA mgr/bridge/regions
>> under one PCIe device.  Without these changes, the PCIe solution has
>> to create an extra device for each child mgr/bridge/region to hold
>> drvdata.
>>
>> Signed-off-by: Alan Tull <at...@kernel.org>
>> Reported-by: Jiuyue Ma <majiu...@huawei.com>
> Acked-by: Moritz Fischer <m...@kernel.org>

Thanks!
Alan


Re: [PATCH v3 03/21] fpga: mgr: add status for fpga-manager

2017-12-12 Thread Alan Tull
On Mon, Nov 27, 2017 at 12:42 AM, Wu Hao  wrote:
> This patch adds status to fpga-manager data structure, to allow
> driver to store full/partial reconfiguration errors and other
> status information, and adds one status callback to fpga_manager_ops
> to allow fpga_manager to collect latest status when failures are
> detected.
>
> The following sysfs file is created:
> * /sys/class/fpga_manager//status
>   Return status of fpga manager, including reconfiguration errors.
>
> Signed-off-by: Wu Hao 
> 
> v3: add one line description for status
> add status callback function to fpga_manager_ops
> update fpga-mgr status if any failure or during initialization
> s/INCOMPATIBLE_BS_ERR/INCOMPATIBLE_IMAGE_ERR/
> ---
>  Documentation/ABI/testing/sysfs-class-fpga-manager | 10 
>  drivers/fpga/fpga-mgr.c| 28 
> ++
>  include/linux/fpga/fpga-mgr.h  | 17 +
>  3 files changed, 55 insertions(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-class-fpga-manager 
> b/Documentation/ABI/testing/sysfs-class-fpga-manager
> index 23056c5..01db14d 100644
> --- a/Documentation/ABI/testing/sysfs-class-fpga-manager
> +++ b/Documentation/ABI/testing/sysfs-class-fpga-manager
> @@ -35,3 +35,13 @@ Description: Read fpga manager state as a string.
> * write complete= Doing post programming steps
> * write complete error  = Error while doing post programming
> * operating = FPGA is programmed and operating
> +
> +What:  /sys/class/fpga_manager//status
> +Date:  November 2017
> +KernelVersion: 4.15
> +Contact:   Wu Hao 
> +Description:   Read fpga manager status as a string.
> +   If FPGA programming operation fails, it could be due to crc
> +   error or incompatible bitstream image. The intent of this
> +   interface is to provide more detailed information for FPGA
> +   programming errors to userspace.

Hi Hao,

Please also add a list of status strings that can be given, such as
"reconfig operation error"  I understand that this list may grow
somewhat in the future.

Alan

> diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
> index 1fd5494..8b583ba 100644
> --- a/drivers/fpga/fpga-mgr.c
> +++ b/drivers/fpga/fpga-mgr.c
> @@ -88,6 +88,7 @@ static int fpga_mgr_write_init_buf(struct fpga_manager *mgr,
> if (ret) {
> dev_err(>dev, "Error preparing FPGA for writing\n");
> mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR;
> +   fpga_mgr_update_status(mgr);
> return ret;
> }
>
> @@ -148,6 +149,7 @@ static int fpga_mgr_write_complete(struct fpga_manager 
> *mgr,
> if (ret) {
> dev_err(>dev, "Error after writing image data to 
> FPGA\n");
> mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
> +   fpga_mgr_update_status(mgr);
> return ret;
> }
> mgr->state = FPGA_MGR_STATE_OPERATING;
> @@ -225,6 +227,7 @@ static int fpga_mgr_buf_load_mapped(struct fpga_manager 
> *mgr,
> if (ret) {
> dev_err(>dev, "Error while writing image data to 
> FPGA\n");
> mgr->state = FPGA_MGR_STATE_WRITE_ERR;
> +   fpga_mgr_update_status(mgr);
> return ret;
> }
>
> @@ -397,12 +400,36 @@ static ssize_t state_show(struct device *dev,
> return sprintf(buf, "%s\n", state_str[mgr->state]);
>  }
>
> +static ssize_t status_show(struct device *dev,
> +  struct device_attribute *attr, char *buf)
> +{
> +   struct fpga_manager *mgr = to_fpga_manager(dev);
> +   int len = 0;
> +
> +   if (mgr->status & FPGA_MGR_STATUS_OPERATION_ERR)
> +   len += sprintf(buf + len, "reconfig operation error\n");
> +   if (mgr->status & FPGA_MGR_STATUS_CRC_ERR)
> +   len += sprintf(buf + len, "reconfig CRC error\n");
> +   if (mgr->status & FPGA_MGR_STATUS_INCOMPATIBLE_IMAGE_ERR)
> +   len += sprintf(buf + len, "reconfig incompatible image\n");
> +   if (mgr->status & FPGA_MGR_STATUS_IP_PROTOCOL_ERR)
> +   len += sprintf(buf + len, "reconfig IP protocol error\n");
> +   if (mgr->status & FPGA_MGR_STATUS_FIFO_OVERFLOW_ERR)
> +   len += sprintf(buf + len, "reconfig fifo overflow error\n");
> +   if (mgr->status & FPGA_MGR_STATUS_SECURE_LOAD_ERR)
> +   len += sprintf(buf + len, "reconfig secure load error\n");
> +
> +   return len;
> +}


Re: [PATCH 2/3] fpga: manager: don't use drvdata in common fpga code

2017-11-13 Thread Alan Tull
On Tue, Oct 31, 2017 at 9:22 PM, Alan Tull <at...@kernel.org> wrote:

Any further comments on v5?  I'm getting ready to send v6.  If I do it
today, most of these patches will have no changes (again), the only
changes will be in the patches that move drvdata out of the common
code.

I've gone to a lot of trouble to break out functional patches to make
them easy to review and to keep what I was trying to accomplish clear
here.  I think this stuff is necessary going forward.  If this stuff
doesn't have errors, let's move forward and make whatever changes we
want to make on top of this.

Alan

> On Tue, Oct 31, 2017 at 8:34 PM, Moritz Fischer <m...@kernel.org> wrote:
>> On Tue, Oct 31, 2017 at 04:45:54PM -0500, Alan Tull wrote:
>>> On Tue, Oct 31, 2017 at 3:59 PM, Moritz Fischer <m...@kernel.org> wrote:
>>> > On Tue, Oct 31, 2017 at 08:42:14PM +, Alan Tull wrote:
>>> >> Changes to the fpga manager code to not use drvdata in common
>>> >> code.
>>> >>
>>> >> Change fpga_mgr_register to not set or use drvdata.
>>> >>
>>> >> Change the register/unregister function parameters to take the mgr
>>> >> struct:
>>> >> * int fpga_mgr_register(struct device *dev,
>>> >> struct fpga_manager *mgr);
>>> >> * void fpga_mgr_unregister(struct fpga_manager *mgr);
>>> >>
>>> >> Change the drivers that call fpga_mgr_register to alloc the struct
>>> >> fpga_manager (using devm_kzalloc) and partly fill it, adding name,
>>> >> ops, and priv.
>>> >>
>>> >> The rationale is that setting drvdata is fine for DT based devices
>>> >> that will have one manager, bridge, or region per platform device.
>>> >> However PCIe based devices may have multiple FPGA mgr/bridge/regions
>>> >> under one pcie device.  Without these changes, the PCIe solution has
>>> >> to create an extra device for each child mgr/bridge/region to hold
>>> >> drvdata.
>>> >
>>> > This looks very common, in fact several subsystems provide this two step
>>> > way of registering things.
>>> >
>>> > - Allocate fpga_mgr via fpga_mgr_alloc() where you pass in the size of
>>> >   the private data
>>> > - Fill in some fields
>>> > - fpga_mgr_register() where you pass in the fpga_mgr as suggested
>>> >
>>> > See for example the alloc_etherdev() for ethernet devices.
>>> >
>>>
>>> Yes, I considered it when I was writing this.  I've seen it both ways.
>>> In the case you mention, they've got reasons they absolutely needed to
>>> do it that way.  alloc_etherdev() calls eventually to
>>> alloc_netdev_mqs() which is about 100 lines of alloc'ing and
>>> initializing a network device struct.
>>
>> Yeah, sure. I looked around some more. Other subsystems just alloc
>> manually, seems fine with me.
>>>
>>> > The benefit of the API you proposed is that one could embed the fpga_mgr
>>> > struct inside of another struct and get to the container via
>>> > container_of() I guess ...
>>>
>>> Yes, let's keep it simple for now, as that gives us greater
>>> flexibility.  We can add alloc functions when it becomes clear that it
>>> won't get in the way of someone's use.
>>
>> Agreed.
>>>
>>> Alan
>>>
>>> >
>>> >>
>>> >> Signed-off-by: Alan Tull <at...@kernel.org>
>>> >> Reported-by: Jiuyue Ma <majiu...@huawei.com>
>>> >> ---
>>> >>  Documentation/fpga/fpga-mgr.txt  | 23 ---
>>> >>  drivers/fpga/altera-cvp.c| 17 +
>>> >>  drivers/fpga/altera-pr-ip-core.c | 16 ++--
>>> >>  drivers/fpga/altera-ps-spi.c | 17 ++---
>>> >>  drivers/fpga/fpga-mgr.c  | 28 +++-
>>> >>  drivers/fpga/ice40-spi.c | 19 +++
>>> >>  drivers/fpga/socfpga-a10.c   | 15 ---
>>> >>  drivers/fpga/socfpga.c   | 17 ++---
>>> >>  drivers/fpga/ts73xx-fpga.c   | 17 ++---
>>> >>  drivers/fpga/xilinx-spi.c| 17 ++---
>>> >>  drivers/fpga/zynq-fpga.c | 15 ---
>>> >>  include/linux/fpga/fpga-mgr.h|  6 ++
>>> >>  12 files changed, 147 insertio

Re: [PATCH v5 18/18] fpga: add attribute groups

2017-11-15 Thread Alan Tull
On Wed, Nov 15, 2017 at 9:46 AM, Moritz Fischer <m...@kernel.org> wrote:

Hi Moritz,

Thanks!

Alan

> On Tue, Oct 17, 2017 at 04:20:31PM -0500, Alan Tull wrote:
>> Make it easy to add attributes to low level FPGA drivers the right
>> way.  Add attribute groups pointers to structures that are used when
>> registering a manager, bridge, or group.  When the low level driver
>> registers, set the device attribute group.  The attributes are
>> created in device_add.
>>
>> Signed-off-by: Alan Tull <at...@kernel.org>
> Acked-by: Moritz Fischer <m...@kernel.org>


Re: [PATCH v3 09/21] fpga: intel-dfl-pci: add enumeration for feature devices

2017-12-07 Thread Alan Tull
On Mon, Nov 27, 2017 at 12:42 AM, Wu Hao  wrote:

> +/* enumerate feature devices under pci device */
> +static int cci_enumerate_feature_devs(struct pci_dev *pcidev)
> +{
> +   struct cci_drvdata *drvdata = pci_get_drvdata(pcidev);
> +   struct fpga_cdev *cdev;
> +   struct fpga_enum_info *info;
> +   resource_size_t start, len;
> +   void __iomem *base;
> +   int port_num, bar, i, ret = 0;
> +   u32 offset;
> +   u64 v;
> +
> +   /* allocate enumeration info via pci_dev */
> +   info = fpga_enum_info_alloc(>dev);
> +   if (!info)
> +   return -ENOMEM;
> +
> +   /* start to find Device Feature List from Bar 0 */
> +   base = cci_pci_ioremap_bar(pcidev, 0);
> +   if (!base) {
> +   ret = -ENOMEM;
> +   goto enum_info_free_exit;
> +   }
> +
> +   /*
> +* PF device has FME and Ports/AFUs, and VF device only has 1 
> Port/AFU.
> +* check them and add related "Device Feature List" info for the next
> +* step enumeration.
> +*/
> +   if (feature_is_fme(base)) {
> +   start = pci_resource_start(pcidev, 0);
> +   len = pci_resource_len(pcidev, 0);
> +
> +   fpga_enum_info_add_dfl(info, start, len, base);
> +
> +   /*
> +* find more Device Feature Lists (e.g Ports) per information
> +* indicated by FME module.
> +*/
> +   v = readq(base + FME_HDR_CAP);
> +   port_num = FIELD_GET(FME_CAP_NUM_PORTS, v);
> +
> +   WARN_ON(port_num > MAX_FPGA_PORT_NUM);
> +
> +   for (i = 0; i < port_num; i++) {
> +   v = readq(base + FME_HDR_PORT_OFST(i));
> +
> +   /* skip ports which are not implemented. */
> +   if (!(v & FME_PORT_OFST_IMP))
> +   continue;
> +
> +   /*
> +* add Port's Device Feature List information for next
> +* step enumeration.
> +*/
> +   bar = FIELD_GET(FME_PORT_OFST_BAR_ID, v);
> +   offset = FIELD_GET(FME_PORT_OFST_DFH_OFST, v);
> +   base = cci_pci_ioremap_bar(pcidev, bar);
> +   if (!base)
> +   continue;
> +
> +   start = pci_resource_start(pcidev, bar) + offset;
> +   len = pci_resource_len(pcidev, bar) - offset;
> +
> +   fpga_enum_info_add_dfl(info, start, len, base + 
> offset);
> +   }
> +   } else if (feature_is_port(base)) {
> +   start = pci_resource_start(pcidev, 0);
> +   len = pci_resource_len(pcidev, 0);
> +
> +   fpga_enum_info_add_dfl(info, start, len, base);
> +   } else {
> +   ret = -ENODEV;
> +   goto enum_info_free_exit;
> +   }
> +
> +   /* start enumeration with prepared enumeration information */
> +   cdev = fpga_enumerate_feature_devs(info);

Hi Hao,

I appreciate you separating the DFL enumeration code from this PCIe
module.  This made the pcie part quite small.  It should work for
embedded platforms just by adding a platform device whose function is
to find the DFL structures at some address and then call these same
fpga_enum_info_add_dfl adn fpga_enumerate_feature_devs functions.

Alan

> +   if (IS_ERR(cdev)) {
> +   dev_err(>dev, "Enumeration failure\n");
> +   ret = PTR_ERR(cdev);
> +   goto enum_info_free_exit;
> +   }
> +
> +   drvdata->cdev = cdev;
> +
> +enum_info_free_exit:
> +   fpga_enum_info_free(info);
> +
> +   return ret;
> +}
> +
>  static
>  int cci_pci_probe(struct pci_dev *pcidev, const struct pci_device_id 
> *pcidevid)
>  {
> @@ -84,9 +264,22 @@ int cci_pci_probe(struct pci_dev *pcidev, const struct 
> pci_device_id *pcidevid)
> goto release_region_exit;
> }
>
> -   /* TODO: create and add the platform device per feature list */
> -   return 0;
> +   ret = cci_init_drvdata(pcidev);
> +   if (ret) {
> +   dev_err(>dev, "Fail to init drvdata %d.\n", ret);
> +   goto release_region_exit;
> +   }
> +
> +   ret = cci_enumerate_feature_devs(pcidev);
> +   if (ret) {
> +   dev_err(>dev, "enumeration failure %d.\n", ret);
> +   goto remove_drvdata_exit;
> +   }
> +
> +   return ret;
>
> +remove_drvdata_exit:
> +   cci_remove_drvdata(pcidev);
>  release_region_exit:
> pci_release_regions(pcidev);
>  disable_error_report_exit:
> @@ -97,6 +290,8 @@ int cci_pci_probe(struct pci_dev *pcidev, const struct 
> pci_device_id *pcidevid)
>
>  static void cci_pci_remove(struct pci_dev *pcidev)
>  {
> +   cci_remove_feature_devs(pcidev);
> +   cci_remove_drvdata(pcidev);
> 

Re: [RFC 0/2] of: Add whitelist

2017-12-05 Thread Alan Tull
On Thu, Nov 30, 2017 at 6:18 AM, Frank Rowand <frowand.l...@gmail.com> wrote:
> On 11/29/17 08:31, Rob Herring wrote:
>> On Wed, Nov 29, 2017 at 3:20 AM, Frank Rowand <frowand.l...@gmail.com> wrote:
>>> On 11/27/17 15:58, Alan Tull wrote:
>>>> Here's a proposal for a whitelist to lock down the dynamic device tree.
>>>>
>>>> For an overlay to be accepted, all of its targets are required to be
>>>> on a target node whitelist.
>>>>
>>>> Currently the only way I have to get on the whitelist is calling a
>>>> function to add a node.  That works for fpga regions, but I think
>>>> other uses will need a way of having adding specific nodes from the
>>>> base device tree, such as by adding a property like 'allow-overlay;'
>>>> or 'allow-overlay = "okay";' If that is acceptable, I could use some
>>>> advice on where that particular code should go.
>>>>
>>>> Alan
>>>>
>>>> Alan Tull (2):
>>>>   of: overlay: add whitelist
>>>>   fpga: of region: add of-fpga-region to whitelist
>>>>
>>>>  drivers/fpga/of-fpga-region.c |  9 ++
>>>>  drivers/of/overlay.c  | 73 
>>>> +++
>>>>  include/linux/of.h| 12 +++
>>>>  3 files changed, 94 insertions(+)
>>>>
>>>
>>> The plan was to use connectors to restrict where an overlay could be 
>>> applied.
>>> I would prefer not to have multiple methods for accomplishing the same thing
>>> unless there is a compelling reason to do so.
>>
>> Connector nodes need a mechanism to enable themselves, too. I don't
>> think connector nodes are going to solve every usecase.
>>
>> Rob
>>
>
> The overlay code related to connectors does not exist yet, so my comment
> is going to be theoretical.
>
> I would expect the overlay code to check that the target of the overlay
> fragment is a connector node, so there is no need to explicitly "enable"
> applying an overlay to a connector node.

This will depend on how connectors are implemented.  My proposal in v1
is that device nodes can have a flag bit.  If its not set, then an
overlay that contains fragments that target that node can't be
applied.  There's probably other ways a connector node could be marked
as different from other nodes, but a flag bit seems simple.  The
advantage to this scheme is that it gives me something I can use while
connectors don't exist yet and it will still will be useful later for
the implementation of connectors (giving connector drivers a way of
marking their device nodes as valid targets).

>
> -Frank


Re: [RFC 0/2] of: Add whitelist

2017-12-05 Thread Alan Tull
On Thu, Nov 30, 2017 at 6:46 AM, Frank Rowand <frowand.l...@gmail.com> wrote:
> On 11/29/17 11:11, Alan Tull wrote:
>> On Wed, Nov 29, 2017 at 7:31 AM, Rob Herring <robh...@kernel.org> wrote:
>>> On Wed, Nov 29, 2017 at 3:20 AM, Frank Rowand <frowand.l...@gmail.com> 
>>> wrote:
>>>> On 11/27/17 15:58, Alan Tull wrote:
>>>>> Here's a proposal for a whitelist to lock down the dynamic device tree.
>>>>>
>>>>> For an overlay to be accepted, all of its targets are required to be
>>>>> on a target node whitelist.
>>>>>
>>>>> Currently the only way I have to get on the whitelist is calling a
>>>>> function to add a node.  That works for fpga regions, but I think
>>>>> other uses will need a way of having adding specific nodes from the
>>>>> base device tree, such as by adding a property like 'allow-overlay;'
>>>>> or 'allow-overlay = "okay";' If that is acceptable, I could use some
>>>>> advice on where that particular code should go.
>>>>>
>>>>> Alan
>>>>>
>>>>> Alan Tull (2):
>>>>>   of: overlay: add whitelist
>>>>>   fpga: of region: add of-fpga-region to whitelist
>>>>>
>>>>>  drivers/fpga/of-fpga-region.c |  9 ++
>>>>>  drivers/of/overlay.c  | 73 
>>>>> +++
>>>>>  include/linux/of.h| 12 +++
>>>>>  3 files changed, 94 insertions(+)
>>>>>
>>>>
>>>> The plan was to use connectors to restrict where an overlay could be 
>>>> applied.
>>>> I would prefer not to have multiple methods for accomplishing the same 
>>>> thing
>>>> unless there is a compelling reason to do so.
>>>
>>> Connector nodes need a mechanism to enable themselves, too. I don't
>>> think connector nodes are going to solve every usecase.
>>>
>>> Rob
>>
>> The two methods I'm suggesting are intended to handle different cases.
>>   There will exist some drivers that by their nature will want every
>> instance to be enabled for overlays, such as fpga regions.  The other
>> case is where drivers could support overlays but that's not the
>> widespread use for them.  So no need to enable every instance of that
>> driver for overlays.
>
> I understand what the paragraph, to this point, means.  But I had to
> read it several times to understand it because the way the concept is
> phrased clashed with my mental model.

Hi Frank,

I see where my explanation is confusing things.  I was talking about
two methods for marking a node as being a valid target for an overlay
(use a function or add a DT property).  I'll drop the idea of using a
DT property to enable a node for overlays and only focus on my
proposal of a function to enable nodes.

>
> The device node is not an instance of a driver, which is why I was
> getting confused.  (Yes, I do understand that the paragraph is talking
> about multiple device nodes that are bound to the same driver, but
> my mental model is tied to the device node, not to the driver.)
>
> If each of the device nodes in question is a connector, then each of
> the nodes will bind to a connector driver, based on the value of the
> compatible property.  (This is of course a theoretical assumption on
> my part since the connectors are not yet implemented.)
>
> If the connector node is an fpga, or an fpga region (I may be getting
> my terminology wrong here - please correct as needed) then an fpga
> overlay could be applied to the node.

We're still pre-connector currently, but yes I want to mark FPGA
regions as being valid targets.  Then I can use Pantelis' configfs
interface to apply overlays while leaving the rest of the DT locked
down.  That's the FPGA use of this patch in the pre-connector era of
things.

>
> If I understand what you are saying, there will be some fpga connector
> nodes for which the usage at a given moment might be programmed to
> function in a manner that will not be described by an overlay, but
> at a different moment in time may be programmed in a way that needs
> to be described by an overlay.  So there may be some times that it
> is valid to apply an overlay to the connector node and times that
> it is not valid to apply an overlay to the connector node.

I think connectors would likely always be valid targets (but I could
be wrong) and other nodes would not be valid targets.  The DT needs a
way to mark some nodes as valid targets, currently it doesn't have a
way of doing that.  Every 

Re: [PATCH 0/2] of: dynamic: restrict overlay by targets

2017-12-05 Thread Alan Tull
On Mon, Dec 4, 2017 at 7:14 PM, Frank Rowand <frowand.l...@gmail.com> wrote:
> Hi Alan,
>
> In the RFC thread "of: Add whitelist", I did not understand the use case and
> asked you some questions (30 Nov 2017 07:46:36 -0500), that you seem to have
> overlooked (or my mail server failed to deliver your answer to me).  Can you
> please answer that question so I can better understand this patch set is
> needed for.

Hi Frank,

Sorry I missed those, I've replied to the original questions now.

Alan

>
> Thanks,
>
> Frank
>
>
> On 12/04/17 14:13, Alan Tull wrote:
>> Restrict which nodes are valid targets for a DT overlay.
>>
>> Add a flag bit to struct device_node allowing nodes to be marked as
>> valid target for overlays.
>>
>> A driver that is always intended to handle DT overlays can
>> enable overlays by calling a function for its DT node.
>>
>> For individual nodes that need to be opened up for a specific use,
>> adding the property "overlay-allowed" enables overlays targeting
>> that node.  I'll need to document the DT property, not sure where
>> specifically.  New file bindings/overlay.txt?
>>
>> This patchset differs from the RFC:
>> * Added a flag bit and got rid of the whitelist
>> * Renamed the functions that enable a node
>> * Added a DT property
>>
>> Alan Tull (2):
>>   of: overlay: add flag enabling overlays and enable fpga-region
>> overlays
>>   of: dynamic: add overlay-allowed DT property
>>
>>  drivers/fpga/of-fpga-region.c |  4 
>>  drivers/of/base.c |  4 ++--
>>  drivers/of/dynamic.c  |  3 +++
>>  drivers/of/fdt.c  |  3 +++
>>  drivers/of/of_private.h   |  2 ++
>>  drivers/of/overlay.c  | 26 ++
>>  include/linux/of.h| 19 +++
>>  7 files changed, 59 insertions(+), 2 deletions(-)
>>
>


Re: [PATCH v3 08/21] fpga: add Intel FPGA DFL PCIe device

2017-12-05 Thread Alan Tull
On Mon, Dec 4, 2017 at 9:33 PM, Wu Hao <hao...@intel.com> wrote:
> On Mon, Dec 04, 2017 at 01:46:59PM -0600, Alan Tull wrote:
>> On Mon, Nov 27, 2017 at 9:15 PM, Wu Hao <hao...@intel.com> wrote:
>> > On Mon, Nov 27, 2017 at 10:28:04AM +, David Laight wrote:
>> >> From: Wu Hao
>> >> > Sent: 27 November 2017 06:42
>> >> > From: Zhang Yi <yi.z.zh...@intel.com>
>> >> >
>> >> > The Intel FPGA device appears as a PCIe device on the system. This patch
>> >> > implements the basic framework of the driver for Intel PCIe device which
>> >> > is located between CPU and Accelerated Function Units (AFUs), and has
>> >> > the Device Feature List (DFL) implemented in its MMIO space.
>> >>
>> >> This ought to have a better name than 'Intel FPGA'.
>> >> An fpga can be used for all sorts of things, this looks like
>> >> a very specific architecture using a common VHDL environment to
>> >> allow certain types of user VHDL be accessed over PCIe.
>> >
>> > Hi David
>> >
>> > This patch adds a pcie device driver for Intel FPGA devices which 
>> > implements
>> > the DFL, e.g Intel Server Platform with In-package FPGA and Intel FPGA PCIe
>> > Acceleration Cards. They are pcie devices, and all have DFL implemented in
>> > the MMIO space, so we would like to use one kernel driver to handle them.
>> >
>> > With this full patchset, it just provides user the interfaces to configure
>> > and access the FPGA accelerators on Intel DFL based FPGA devices. For sure,
>> > users can develop and build their own logics via tools provided by Intel,
>> > program them to accelerators on these Intel FPGA devices, and access them
>> > for their workloads.
>>
>> I don't see anything Intel specific here.  This could all be named dfl-*
>
> The maybe some device specific things, e.g Intel FPGA devices supported by 
> this
> driver always have FME DFL at the beginning on the BAR0 for PF device.
>
> But I think this should be the right direction for better code reuse, it could
> save efforts for other vendors who want to use DFL and follow the same way.
>
> Thanks for the comments. I will rename this driver in the next version.

Thanks!

Regarding file names, it seems like the files added to drivers/fpga
could be uniformly named dfl-*.[ch].  Some are fpga-dfl-*.[ch] while
other are currently dfl-*.[ch] currently.

Alan

>
> Hao


Re: [PATCH v2 5/5] fpga: region: return NOTIFY_STOP if overlay shoud be accepted

2017-12-08 Thread Alan Tull
On Thu, Dec 7, 2017 at 5:27 PM, Moritz Fischer <m...@kernel.org> wrote:
> On Wed, Nov 15, 2017 at 02:51:52PM -0600, Alan Tull wrote:
>> Recent changes to the Device Tree overlay notifier code have changed
>> how notifier return codes are interpreted, requiring a NOTIFY_STOP to
>> signal that the overlay should be accepted.  This commit makes the
>> appropriate change to the FPGA region's Device Tree overlay notifier.
>>
>> Fixes: 24789c5ce5a3 ("of: overlay: detect cases where device tree may become 
>> corrupt")
>> Signed-off-by: Alan Tull <at...@kernel.org>
> Reviewed-by: Moritz Fischer <m...@kernel.org>

Thanks!
Alan


[PATCH] patch for FPGA

2017-12-08 Thread Alan Tull
Hi Greg,

Please take this one small fix for fpga.  It's been reviewed on
the mailing list.  It applies cleanly on linux-next/master.

Thanks,
Alan

Alexey Khoroshilov (1):
  fpga: socfpga-a10: disable clk on error in socfpga_a10_fpga_probe()

 drivers/fpga/socfpga-a10.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

-- 
2.7.4



[PATCH] fpga: socfpga-a10: disable clk on error in socfpga_a10_fpga_probe()

2017-12-08 Thread Alan Tull
From: Alexey Khoroshilov <khoroshi...@ispras.ru>

If fpga_mgr_register() fails, a clock is left undisabled.

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
Reviewed-by: Moritz Fischer <m...@kernel.org>
Signed-off-by: Alan Tull <at...@kernel.org>
---
 drivers/fpga/socfpga-a10.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c
index f8770af..a46e343 100644
--- a/drivers/fpga/socfpga-a10.c
+++ b/drivers/fpga/socfpga-a10.c
@@ -519,8 +519,14 @@ static int socfpga_a10_fpga_probe(struct platform_device 
*pdev)
return -EBUSY;
}
 
-   return fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager",
+   ret = fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager",
 _a10_fpga_mgr_ops, priv);
+   if (ret) {
+   clk_disable_unprepare(priv->clk);
+   return ret;
+   }
+
+   return 0;
 }
 
 static int socfpga_a10_fpga_remove(struct platform_device *pdev)
-- 
2.7.4



Re: [PATCH] fpga: socfpga-a10: disable clk on error in socfpga_a10_fpga_probe()

2017-12-04 Thread Alan Tull
On Fri, Dec 1, 2017 at 7:21 PM, Moritz Fischer <m...@kernel.org> wrote:

Hi Alexey,

Thanks for the fix!

Alan

> Hi Alexey,
>
> On Fri, Dec 01, 2017 at 11:26:24PM +0300, Alexey Khoroshilov wrote:
>> If fpga_mgr_register() fails, a clock is left undisabled.
>>
>> Found by Linux Driver Verification project (linuxtesting.org).
>>
>> Signed-off-by: Alexey Khoroshilov <khoroshi...@ispras.ru>
> Reviewed-by: Moritz Fischer <m...@kernel.org>

Acked-by: Alan Tull <at...@kernel.org>

>> ---
>>  drivers/fpga/socfpga-a10.c | 8 +++-
>>  1 file changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c
>> index f8770af0f6b5..a46e343a5b72 100644
>> --- a/drivers/fpga/socfpga-a10.c
>> +++ b/drivers/fpga/socfpga-a10.c
>> @@ -519,8 +519,14 @@ static int socfpga_a10_fpga_probe(struct 
>> platform_device *pdev)
>>   return -EBUSY;
>>   }
>>
>> - return fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager",
>> + ret = fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager",
>>_a10_fpga_mgr_ops, priv);
>> + if (ret) {
>> + clk_disable_unprepare(priv->clk);
>> + return ret;
>> + }
>> +
>> + return 0;
>>  }
>>
>>  static int socfpga_a10_fpga_remove(struct platform_device *pdev)
>> --
>> 2.7.4
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-fpga" in
>> the body of a message to majord...@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
> Thanks for your patch,
>
> Moritz


Re: [RFC 0/2] of: Add whitelist

2017-12-07 Thread Alan Tull
On Wed, Dec 6, 2017 at 5:56 AM, Frank Rowand <frowand.l...@gmail.com> wrote:
> On 12/05/17 11:33, Alan Tull wrote:
>> On Thu, Nov 30, 2017 at 6:46 AM, Frank Rowand <frowand.l...@gmail.com> wrote:
>>> On 11/29/17 11:11, Alan Tull wrote:
>>>> On Wed, Nov 29, 2017 at 7:31 AM, Rob Herring <robh...@kernel.org> wrote:
>>>>> On Wed, Nov 29, 2017 at 3:20 AM, Frank Rowand <frowand.l...@gmail.com> 
>>>>> wrote:
>>>>>> On 11/27/17 15:58, Alan Tull wrote:
>>>>>>> Here's a proposal for a whitelist to lock down the dynamic device tree.
>>>>>>>
>>>>>>> For an overlay to be accepted, all of its targets are required to be
>>>>>>> on a target node whitelist.
>>>>>>>
>>>>>>> Currently the only way I have to get on the whitelist is calling a
>>>>>>> function to add a node.  That works for fpga regions, but I think
>>>>>>> other uses will need a way of having adding specific nodes from the
>>>>>>> base device tree, such as by adding a property like 'allow-overlay;'
>>>>>>> or 'allow-overlay = "okay";' If that is acceptable, I could use some
>>>>>>> advice on where that particular code should go.
>>>>>>>
>>>>>>> Alan
>>>>>>>
>>>>>>> Alan Tull (2):
>>>>>>>   of: overlay: add whitelist
>>>>>>>   fpga: of region: add of-fpga-region to whitelist
>>>>>>>
>>>>>>>  drivers/fpga/of-fpga-region.c |  9 ++
>>>>>>>  drivers/of/overlay.c  | 73 
>>>>>>> +++
>>>>>>>  include/linux/of.h| 12 +++
>>>>>>>  3 files changed, 94 insertions(+)
>>>>>>>
>>>>>>
>>>>>> The plan was to use connectors to restrict where an overlay could be 
>>>>>> applied.
>>>>>> I would prefer not to have multiple methods for accomplishing the same 
>>>>>> thing
>>>>>> unless there is a compelling reason to do so.
>>>>>
>>>>> Connector nodes need a mechanism to enable themselves, too. I don't
>>>>> think connector nodes are going to solve every usecase.
>>>>>
>>>>> Rob
>>>>
>>>> The two methods I'm suggesting are intended to handle different cases.
>>>>   There will exist some drivers that by their nature will want every
>>>> instance to be enabled for overlays, such as fpga regions.  The other
>>>> case is where drivers could support overlays but that's not the
>>>> widespread use for them.  So no need to enable every instance of that
>>>> driver for overlays.
>>>
>>> I understand what the paragraph, to this point, means.  But I had to
>>> read it several times to understand it because the way the concept is
>>> phrased clashed with my mental model.
>>
>> Hi Frank,
>>
>> I see where my explanation is confusing things.  I was talking about
>> two methods for marking a node as being a valid target for an overlay
>> (use a function or add a DT property).  I'll drop the idea of using a
>> DT property to enable a node for overlays and only focus on my
>> proposal of a function to enable nodes.
>>
>>>
>>> The device node is not an instance of a driver, which is why I was
>>> getting confused.  (Yes, I do understand that the paragraph is talking
>>> about multiple device nodes that are bound to the same driver, but
>>> my mental model is tied to the device node, not to the driver.)
>>>
>>> If each of the device nodes in question is a connector, then each of
>>> the nodes will bind to a connector driver, based on the value of the
>>> compatible property.  (This is of course a theoretical assumption on
>>> my part since the connectors are not yet implemented.)
>>>
>>> If the connector node is an fpga, or an fpga region (I may be getting
>>> my terminology wrong here - please correct as needed) then an fpga
>>> overlay could be applied to the node.
>>
>> We're still pre-connector currently, but yes I want to mark FPGA
>> regions as being valid targets.  Then I can use Pantelis' configfs
>> interface to apply overlays while leaving the rest of the DT locked
>> down.  That's the FPGA use of this patch in 

Re: [PATCH v3 08/21] fpga: add Intel FPGA DFL PCIe device

2017-12-06 Thread Alan Tull
On Wed, Dec 6, 2017 at 10:28 AM, David Laight <david.lai...@aculab.com> wrote:
> From: Alan Tull
>> Sent: 06 December 2017 15:30
>> On Wed, Dec 6, 2017 at 3:44 AM, David Laight <david.lai...@aculab.com> wrote:
>> > From: Wu Hao
>> >> Sent: 06 December 2017 05:30
>> > ...
>> >> > Regarding file names, it seems like the files added to drivers/fpga
>> >> > could be uniformly named dfl-*.[ch].  Some are fpga-dfl-*.[ch] while
>> >> > other are currently dfl-*.[ch] currently.
>> >
>> > They don't even want to do into a drivers/fgpa directory.
>> > Maybe drivers/dfl or drivers/dfl/intel
>>
>> It's plugged into the fpga framework in drivers/fpga.  This patchset
>> also handles reprogramming the fpga, not just the dfl style
>> enumeration.  But your points about this being not just for FPGA are
>> interesting to me.  Do you have a use for this that isn't
>> FPGA-centric?
>
> That all just seems wrong to me.
> If you've managed to invent some common code for reprogramming fpga
> I'd have though it would be library functions.

Why don't you familiarize yourself with the fpga framework before
commenting on it? ;)

>
> The driver ought to sit somewhere related to its functionality.
>
> Our fpga loads from a serial EEPROM, the image is about 6.5MB.
> We can rewrite it from userspace by mmap()ing part of one of the BARs
> to access some very locally written (by me) VHDL that does most of
> the required bit-banging for 32it word accesses.

The fpga framework is intended to handle cases where the it is desired
to reprogram the fpga a lot without having to reboot.  It doesn't
sound like that is your use case.

> You really wouldn't want to load 6.5MB into kernel space!

No, and there have been proposals, shot down so far regarding
streaming firmware images a page at a time.

>
> We also had to solve the problem of 9 separate driver modules that
> want to access different parts of the BARs.
> I think we have 46 separate slaves in the fpgas BARs (most are in 1 BAR).
> Some of these are common between different boards (or completely different
> memory maps for the same board.
>
> I can imagine some generic method of having a 'board' driver for a
> specific PCI-id that knows the BAR offsets of various functions so that
> other sub-drivers could be loaded to access those functions.
> But that is some kind of pseudo-bus not fpga specific in any way.
>
> David
>


Re: [PATCH v3 08/21] fpga: add Intel FPGA DFL PCIe device

2017-12-06 Thread Alan Tull
On Wed, Dec 6, 2017 at 3:44 AM, David Laight  wrote:
> From: Wu Hao
>> Sent: 06 December 2017 05:30
> ...
>> > Regarding file names, it seems like the files added to drivers/fpga
>> > could be uniformly named dfl-*.[ch].  Some are fpga-dfl-*.[ch] while
>> > other are currently dfl-*.[ch] currently.
>
> They don't even want to do into a drivers/fgpa directory.
> Maybe drivers/dfl or drivers/dfl/intel

It's plugged into the fpga framework in drivers/fpga.  This patchset
also handles reprogramming the fpga, not just the dfl style
enumeration.  But your points about this being not just for FPGA are
interesting to me.  Do you have a use for this that isn't
FPGA-centric?

Alan

>
> David
>


Re: [PATCH] fpga: fpga-bridge: remove unnecessary null check in of_fpga_bridge_get

2017-10-30 Thread Alan Tull
On Sat, Oct 28, 2017 at 12:15 PM, Moritz Fischer <m...@kernel.org> wrote:

Hi Gustavo,

Thanks!

Alan

> On Fri, Oct 27, 2017 at 08:19:51PM +, Gustavo A. R. Silva wrote:
>> Notice that bridge = to_fpga_bridge(dev); expands to:
>>
>> bridge = container_of(dev, struct fpga_bridge, dev);
>>
>> and container_of is never null, so this null check is
>> unnecessary.
>>
>> Addresses-Coverity-ID: 1397912
>> Reported-by: Alan Tull <at...@kernel.org>
>> Signed-off-by: Gustavo A. R. Silva <garsi...@embeddedor.com>
> Reviewed-by: Moritz Fischer <m...@kernel.org>

Signed-off-by: Alan Tull <at...@kernel.org>

>> ---
>>  drivers/fpga/fpga-bridge.c | 2 --
>>  1 file changed, 2 deletions(-)
>>
>> diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
>> index 9651aa5..409d1ac 100644
>> --- a/drivers/fpga/fpga-bridge.c
>> +++ b/drivers/fpga/fpga-bridge.c
>> @@ -94,8 +94,6 @@ struct fpga_bridge *of_fpga_bridge_get(struct device_node 
>> *np,
>>   goto err_dev;
>>
>>   bridge = to_fpga_bridge(dev);
>> - if (!bridge)
>> - goto err_dev;
>>
>>   bridge->info = info;
>>
>> --
>> 2.7.4
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-fpga" in
>> the body of a message to majord...@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
> Thanks for the fix,
>
> Moritz


Re: [PATCH 2/3] fpga: manager: don't use drvdata in common fpga code

2017-10-31 Thread Alan Tull
On Tue, Oct 31, 2017 at 3:59 PM, Moritz Fischer <m...@kernel.org> wrote:
> On Tue, Oct 31, 2017 at 08:42:14PM +0000, Alan Tull wrote:
>> Changes to the fpga manager code to not use drvdata in common
>> code.
>>
>> Change fpga_mgr_register to not set or use drvdata.
>>
>> Change the register/unregister function parameters to take the mgr
>> struct:
>> * int fpga_mgr_register(struct device *dev,
>> struct fpga_manager *mgr);
>> * void fpga_mgr_unregister(struct fpga_manager *mgr);
>>
>> Change the drivers that call fpga_mgr_register to alloc the struct
>> fpga_manager (using devm_kzalloc) and partly fill it, adding name,
>> ops, and priv.
>>
>> The rationale is that setting drvdata is fine for DT based devices
>> that will have one manager, bridge, or region per platform device.
>> However PCIe based devices may have multiple FPGA mgr/bridge/regions
>> under one pcie device.  Without these changes, the PCIe solution has
>> to create an extra device for each child mgr/bridge/region to hold
>> drvdata.
>
> This looks very common, in fact several subsystems provide this two step
> way of registering things.
>
> - Allocate fpga_mgr via fpga_mgr_alloc() where you pass in the size of
>   the private data
> - Fill in some fields
> - fpga_mgr_register() where you pass in the fpga_mgr as suggested
>
> See for example the alloc_etherdev() for ethernet devices.
>

Yes, I considered it when I was writing this.  I've seen it both ways.
In the case you mention, they've got reasons they absolutely needed to
do it that way.  alloc_etherdev() calls eventually to
alloc_netdev_mqs() which is about 100 lines of alloc'ing and
initializing a network device struct.

> The benefit of the API you proposed is that one could embed the fpga_mgr
> struct inside of another struct and get to the container via
> container_of() I guess ...

Yes, let's keep it simple for now, as that gives us greater
flexibility.  We can add alloc functions when it becomes clear that it
won't get in the way of someone's use.

Alan

>
>>
>> Signed-off-by: Alan Tull <at...@kernel.org>
>> Reported-by: Jiuyue Ma <majiu...@huawei.com>
>> ---
>>  Documentation/fpga/fpga-mgr.txt  | 23 ---
>>  drivers/fpga/altera-cvp.c| 17 +
>>  drivers/fpga/altera-pr-ip-core.c | 16 ++--
>>  drivers/fpga/altera-ps-spi.c | 17 ++---
>>  drivers/fpga/fpga-mgr.c  | 28 +++-
>>  drivers/fpga/ice40-spi.c | 19 +++
>>  drivers/fpga/socfpga-a10.c   | 15 ---
>>  drivers/fpga/socfpga.c   | 17 ++---
>>  drivers/fpga/ts73xx-fpga.c   | 17 ++---
>>  drivers/fpga/xilinx-spi.c| 17 ++---
>>  drivers/fpga/zynq-fpga.c | 15 ---
>>  include/linux/fpga/fpga-mgr.h|  6 ++
>>  12 files changed, 147 insertions(+), 60 deletions(-)
>>
>> diff --git a/Documentation/fpga/fpga-mgr.txt 
>> b/Documentation/fpga/fpga-mgr.txt
>> index cc6413e..7e5e5c8 100644
>> --- a/Documentation/fpga/fpga-mgr.txt
>> +++ b/Documentation/fpga/fpga-mgr.txt
>> @@ -67,11 +67,9 @@ fpga_mgr_unlock when done programming the FPGA.
>>  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);
>> + int fpga_mgr_register(struct device *dev, struct fpga_manager *mgr);
>>
>> - void fpga_mgr_unregister(struct device *dev);
>> + void fpga_mgr_unregister(struct fpga_manager *mgr);
>>
>>  Use of these two functions is described below in "How To Support a new FPGA
>>  device."
>> @@ -148,8 +146,13 @@ static int socfpga_fpga_probe(struct platform_device 
>> *pdev)
>>  {
>>   struct device *dev = >dev;
>>   struct socfpga_fpga_priv *priv;
>> + struct fpga_manager *mgr;
>>   int ret;
>>
>> + mgr = devm_kzalloc(dev, sizeof(*mgr), GFP_KERNEL);
>> + if (!mgr)
>> + return -ENOMEM;
>> +
>>   priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>>   if (!priv)
>>   return -ENOMEM;
>> @@ -157,13 +160,19 @@ static int socfpga_fpga_probe(struct platform_device 
>> *pdev)
>>   /* ... do ioremaps, get interrupts, etc. and save
>>  them in priv... */
>

[PATCH 1/3] fpga: region: don't use drvdata in common fpga code

2017-10-31 Thread Alan Tull
Part of patchset that changes the following fpga_*_register
functions to not set drvdata:
* fpga_region_register.
* fpga_mgr_register
* fpga_bridge_register

The rationale is that setting drvdata is fine for DT based devices
that will have one manager, bridge, or region per platform device.
However PCIe based devices may have multiple FPGA mgr/bridge/regions
under one PCIe device.  Without these changes, the PCIe solution has
to create an extra device for each child mgr/bridge/region to hold
drvdata.

Signed-off-by: Alan Tull <at...@kernel.org>
Reported-by: Jiuyue Ma <majiu...@huawei.com>
---
 drivers/fpga/fpga-region.c| 1 -
 drivers/fpga/of-fpga-region.c | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index edab2a2..ebe1f87 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -178,7 +178,6 @@ int fpga_region_register(struct device *dev, struct 
fpga_region *region)
region->dev.parent = dev;
region->dev.of_node = dev->of_node;
region->dev.id = id;
-   dev_set_drvdata(dev, region);
 
ret = dev_set_name(>dev, "region%d", id);
if (ret)
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index c6b2119..3079ed8 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -431,6 +431,7 @@ static int of_fpga_region_probe(struct platform_device 
*pdev)
goto eprobe_mgr_put;
 
of_platform_populate(np, fpga_region_of_match, NULL, >dev);
+   dev_set_drvdata(dev, region);
 
dev_info(dev, "FPGA Region probed\n");
 
-- 
2.7.4



[PATCH 2/3] fpga: manager: don't use drvdata in common fpga code

2017-10-31 Thread Alan Tull
Changes to the fpga manager code to not use drvdata in common
code.

Change fpga_mgr_register to not set or use drvdata.

Change the register/unregister function parameters to take the mgr
struct:
* int fpga_mgr_register(struct device *dev,
struct fpga_manager *mgr);
* void fpga_mgr_unregister(struct fpga_manager *mgr);

Change the drivers that call fpga_mgr_register to alloc the struct
fpga_manager (using devm_kzalloc) and partly fill it, adding name,
ops, and priv.

The rationale is that setting drvdata is fine for DT based devices
that will have one manager, bridge, or region per platform device.
However PCIe based devices may have multiple FPGA mgr/bridge/regions
under one pcie device.  Without these changes, the PCIe solution has
to create an extra device for each child mgr/bridge/region to hold
drvdata.

Signed-off-by: Alan Tull <at...@kernel.org>
Reported-by: Jiuyue Ma <majiu...@huawei.com>
---
 Documentation/fpga/fpga-mgr.txt  | 23 ---
 drivers/fpga/altera-cvp.c| 17 +
 drivers/fpga/altera-pr-ip-core.c | 16 ++--
 drivers/fpga/altera-ps-spi.c | 17 ++---
 drivers/fpga/fpga-mgr.c  | 28 +++-
 drivers/fpga/ice40-spi.c | 19 +++
 drivers/fpga/socfpga-a10.c   | 15 ---
 drivers/fpga/socfpga.c   | 17 ++---
 drivers/fpga/ts73xx-fpga.c   | 17 ++---
 drivers/fpga/xilinx-spi.c| 17 ++---
 drivers/fpga/zynq-fpga.c | 15 ---
 include/linux/fpga/fpga-mgr.h|  6 ++
 12 files changed, 147 insertions(+), 60 deletions(-)

diff --git a/Documentation/fpga/fpga-mgr.txt b/Documentation/fpga/fpga-mgr.txt
index cc6413e..7e5e5c8 100644
--- a/Documentation/fpga/fpga-mgr.txt
+++ b/Documentation/fpga/fpga-mgr.txt
@@ -67,11 +67,9 @@ fpga_mgr_unlock when done programming the FPGA.
 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);
+   int fpga_mgr_register(struct device *dev, struct fpga_manager *mgr);
 
-   void fpga_mgr_unregister(struct device *dev);
+   void fpga_mgr_unregister(struct fpga_manager *mgr);
 
 Use of these two functions is described below in "How To Support a new FPGA
 device."
@@ -148,8 +146,13 @@ static int socfpga_fpga_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
struct socfpga_fpga_priv *priv;
+   struct fpga_manager *mgr;
int ret;
 
+   mgr = devm_kzalloc(dev, sizeof(*mgr), GFP_KERNEL);
+   if (!mgr)
+   return -ENOMEM;
+
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -157,13 +160,19 @@ static int socfpga_fpga_probe(struct platform_device 
*pdev)
/* ... do ioremaps, get interrupts, etc. and save
   them in priv... */
 
-   return fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager",
-_fpga_ops, priv);
+   mgr->name = "Altera SOCFPGA FPGA Manager";
+   mgr->mops = _fpga_ops;
+   mgr->priv = priv;
+   platform_set_drvdata(pdev, mgr);
+
+   return fpga_mgr_register(dev, mgr);
 }
 
 static int socfpga_fpga_remove(struct platform_device *pdev)
 {
-   fpga_mgr_unregister(>dev);
+   struct fpga_manager *mgr = platform_get_drvdata(pdev);
+
+   fpga_mgr_unregister(mgr);
 
return 0;
 }
diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
index 00e73d2..63320ad 100644
--- a/drivers/fpga/altera-cvp.c
+++ b/drivers/fpga/altera-cvp.c
@@ -403,6 +403,7 @@ static int altera_cvp_probe(struct pci_dev *pdev,
const struct pci_device_id *dev_id)
 {
struct altera_cvp_conf *conf;
+   struct fpga_manager *mgr;
u16 cmd, val;
int ret;
 
@@ -421,6 +422,10 @@ static int altera_cvp_probe(struct pci_dev *pdev,
if (!conf)
return -ENOMEM;
 
+   mgr = devm_kzalloc(>dev, sizeof(*mgr), GFP_KERNEL);
+   if (!mgr)
+   return -ENOMEM;
+
/*
 * Enable memory BAR access. We cannot use pci_enable_device() here
 * because it will make the driver unusable with FPGA devices that
@@ -454,8 +459,12 @@ static int altera_cvp_probe(struct pci_dev *pdev,
snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s @%s",
 ALTERA_CVP_MGR_NAME, pci_name(pdev));
 
-   ret = fpga_mgr_register(>dev, conf->mgr_name,
-   _cvp_ops, conf);
+   mgr->name = conf->mgr_name;
+   mgr->mops = _cvp_ops;
+   mgr->priv = conf;
+   pci_set_drvdata(p

[PATCH 3/3] fpga: bridge: don't use drvdata in common fpga code

2017-10-31 Thread Alan Tull
Changes to the fpga bridge code to not use drvdata in common code.

Change fpga_bridge_register to not set drvdata.

Change the register/unregister functions parameters to take the
bridge struct:
* int fpga_bridge_register(struct device *dev,
   struct fpga_bridge *bridge);
* void fpga_bridge_unregister(struct fpga_bridge *bridge);

Change the drivers that call fpga_bridge_register to alloc the struct
fpga_bridge (using devm_kzalloc) and partly fill it, adding name,
ops, and priv.

The rationale is that setting drvdata is fine for DT based devices
that will have one manager, bridge, or region per platform device.
However PCIe based devices may have multiple FPGA mgr/bridge/regions
under one pcie device.  Without these changes, the PCIe solution has
to create an extra device for each child mgr/bridge/region to hold
drvdata.

Signed-off-by: Alan Tull <at...@kernel.org>
Reported-by: Jiuyue Ma <majiu...@huawei.com>
---
 drivers/fpga/altera-fpga2sdram.c| 19 +++
 drivers/fpga/altera-freeze-bridge.c | 17 ++---
 drivers/fpga/altera-hps2fpga.c  | 15 ---
 drivers/fpga/fpga-bridge.c  | 30 +++---
 drivers/fpga/xilinx-pr-decoupler.c  | 14 +++---
 include/linux/fpga/fpga-bridge.h|  5 ++---
 6 files changed, 61 insertions(+), 39 deletions(-)

diff --git a/drivers/fpga/altera-fpga2sdram.c b/drivers/fpga/altera-fpga2sdram.c
index d4eeb74..73c7bf6 100644
--- a/drivers/fpga/altera-fpga2sdram.c
+++ b/drivers/fpga/altera-fpga2sdram.c
@@ -106,10 +106,15 @@ static int alt_fpga_bridge_probe(struct platform_device 
*pdev)
 {
struct device *dev = >dev;
struct alt_fpga2sdram_data *priv;
+   struct fpga_bridge *br;
u32 enable;
struct regmap *sysmgr;
int ret = 0;
 
+   br = devm_kzalloc(dev, sizeof(*br), GFP_KERNEL);
+   if (!br)
+   return -ENOMEM;
+
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -131,8 +136,12 @@ static int alt_fpga_bridge_probe(struct platform_device 
*pdev)
/* Get f2s bridge configuration saved in handoff register */
regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, >mask);
 
-   ret = fpga_bridge_register(dev, F2S_BRIDGE_NAME,
-  _fpga2sdram_br_ops, priv);
+   br->name = F2S_BRIDGE_NAME;
+   br->br_ops = _fpga2sdram_br_ops;
+   br->priv = priv;
+   platform_set_drvdata(pdev, br);
+
+   ret = fpga_bridge_register(dev, br);
if (ret)
return ret;
 
@@ -146,7 +155,7 @@ static int alt_fpga_bridge_probe(struct platform_device 
*pdev)
 (enable ? "enabling" : "disabling"));
ret = _alt_fpga2sdram_enable_set(priv, enable);
if (ret) {
-   fpga_bridge_unregister(>dev);
+   fpga_bridge_unregister(br);
return ret;
}
}
@@ -157,7 +166,9 @@ static int alt_fpga_bridge_probe(struct platform_device 
*pdev)
 
 static int alt_fpga_bridge_remove(struct platform_device *pdev)
 {
-   fpga_bridge_unregister(>dev);
+   struct fpga_bridge *br = platform_get_drvdata(pdev);
+
+   fpga_bridge_unregister(br);
 
return 0;
 }
diff --git a/drivers/fpga/altera-freeze-bridge.c 
b/drivers/fpga/altera-freeze-bridge.c
index 6159cfcf..5fd424b 100644
--- a/drivers/fpga/altera-freeze-bridge.c
+++ b/drivers/fpga/altera-freeze-bridge.c
@@ -219,6 +219,7 @@ static int altera_freeze_br_probe(struct platform_device 
*pdev)
 {
struct device *dev = >dev;
struct device_node *np = pdev->dev.of_node;
+   struct fpga_bridge *br;
void __iomem *base_addr;
struct altera_freeze_br_data *priv;
struct resource *res;
@@ -227,6 +228,10 @@ static int altera_freeze_br_probe(struct platform_device 
*pdev)
if (!np)
return -ENODEV;
 
+   br = devm_kzalloc(dev, sizeof(*br), GFP_KERNEL);
+   if (!br)
+   return -ENOMEM;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base_addr = devm_ioremap_resource(dev, res);
if (IS_ERR(base_addr))
@@ -254,13 +259,19 @@ static int altera_freeze_br_probe(struct platform_device 
*pdev)
 
priv->base_addr = base_addr;
 
-   return fpga_bridge_register(dev, FREEZE_BRIDGE_NAME,
-   _freeze_br_br_ops, priv);
+   br->name = FREEZE_BRIDGE_NAME;
+   br->br_ops = _freeze_br_br_ops;
+   br->priv = priv;
+   platform_set_drvdata(pdev, br);
+
+   return fpga_bridge_register(dev, br);
 }
 
 static int altera_freeze_br_remove(struct platform_device *pdev)
 {
-   fpga_bridge_unregister(>dev);
+   struct fpga_bridge *br = platform_get_drvdata(pdev

[PATCH 0/3] fpga: don't use drvdata in common fpga code

2017-10-31 Thread Alan Tull
This patch set goes on top of the non-dt set that's been on
the list since March.  

This patchset changes the following fpga_*_register functions to not
set drvdata:
* fpga_region_register.
* fpga_mgr_register
* fpga_bridge_register

Setting drvdata is fine for DT based devices, that will have one
manager, bridge, or region device per platform device.  PCIe based
devices may have multiple FPGA mgr/bridge/regions under one pcie
device.  Without these changes, PCIe-based solutions have to create an
extra device for each child mgr/bridge/region to hold drvdata.

Other changes:

- pass mgr to fpga_mgr_register/unregister instead of dev.
- pass bridge to fpga_bridge_register/unregister.
- Callers of fpga_bridge/mgr_register, are changed to alloc the
bridge/mgr struct and partly fill it, adding name, ops and priv.
- Caller uses devm for allocating the mgr/bridge structures.
- The caller can set drvdata if desired.

Alan

Alan Tull (3):
  fpga: region: don't use drvdata in common fpga code
  fpga: manager: don't use drvdata in common fpga code
  fpga: bridge: don't use drvdata in common fpga code

 Documentation/fpga/fpga-mgr.txt | 23 ---
 drivers/fpga/altera-cvp.c   | 17 +
 drivers/fpga/altera-fpga2sdram.c| 19 +++
 drivers/fpga/altera-freeze-bridge.c | 17 ++---
 drivers/fpga/altera-hps2fpga.c  | 15 ---
 drivers/fpga/altera-pr-ip-core.c| 16 ++--
 drivers/fpga/altera-ps-spi.c| 17 ++---
 drivers/fpga/fpga-bridge.c  | 30 +++---
 drivers/fpga/fpga-mgr.c | 28 +++-
 drivers/fpga/fpga-region.c  |  1 -
 drivers/fpga/ice40-spi.c| 19 +++
 drivers/fpga/of-fpga-region.c   |  1 +
 drivers/fpga/socfpga-a10.c  | 15 ---
 drivers/fpga/socfpga.c  | 17 ++---
 drivers/fpga/ts73xx-fpga.c  | 17 ++---
 drivers/fpga/xilinx-pr-decoupler.c  | 14 +++---
 drivers/fpga/xilinx-spi.c   | 17 ++---
 drivers/fpga/zynq-fpga.c| 15 ---
 include/linux/fpga/fpga-bridge.h|  5 ++---
 include/linux/fpga/fpga-mgr.h   |  6 ++
 20 files changed, 209 insertions(+), 100 deletions(-)

-- 
2.7.4



Re: [PATCH 3/3] fpga: bridge: don't use drvdata in common fpga code

2017-10-31 Thread Alan Tull
On Tue, Oct 31, 2017 at 3:42 PM, Alan Tull <at...@kernel.org> wrote:
> Changes to the fpga bridge code to not use drvdata in common code.
>
> Change fpga_bridge_register to not set drvdata.
>
> Change the register/unregister functions parameters to take the
> bridge struct:
> * int fpga_bridge_register(struct device *dev,
>struct fpga_bridge *bridge);
> * void fpga_bridge_unregister(struct fpga_bridge *bridge);
>
> Change the drivers that call fpga_bridge_register to alloc the struct
> fpga_bridge (using devm_kzalloc) and partly fill it, adding name,
> ops, and priv.
>
> The rationale is that setting drvdata is fine for DT based devices
> that will have one manager, bridge, or region per platform device.
> However PCIe based devices may have multiple FPGA mgr/bridge/regions
> under one pcie device.  Without these changes, the PCIe solution has
> to create an extra device for each child mgr/bridge/region to hold
> drvdata.
>
> Signed-off-by: Alan Tull <at...@kernel.org>
> Reported-by: Jiuyue Ma <majiu...@huawei.com>
> ---
>  drivers/fpga/altera-fpga2sdram.c| 19 +++
>  drivers/fpga/altera-freeze-bridge.c | 17 ++---
>  drivers/fpga/altera-hps2fpga.c  | 15 ---
>  drivers/fpga/fpga-bridge.c  | 30 +++---
>  drivers/fpga/xilinx-pr-decoupler.c  | 14 +++---
>  include/linux/fpga/fpga-bridge.h|  5 ++---
>  6 files changed, 61 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/fpga/altera-fpga2sdram.c 
> b/drivers/fpga/altera-fpga2sdram.c
> index d4eeb74..73c7bf6 100644
> --- a/drivers/fpga/altera-fpga2sdram.c
> +++ b/drivers/fpga/altera-fpga2sdram.c
> @@ -106,10 +106,15 @@ static int alt_fpga_bridge_probe(struct platform_device 
> *pdev)
>  {
> struct device *dev = >dev;
> struct alt_fpga2sdram_data *priv;
> +   struct fpga_bridge *br;
> u32 enable;
> struct regmap *sysmgr;
> int ret = 0;
>
> +   br = devm_kzalloc(dev, sizeof(*br), GFP_KERNEL);
> +   if (!br)
> +   return -ENOMEM;
> +
> priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> if (!priv)
> return -ENOMEM;
> @@ -131,8 +136,12 @@ static int alt_fpga_bridge_probe(struct platform_device 
> *pdev)
> /* Get f2s bridge configuration saved in handoff register */
> regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, >mask);
>
> -   ret = fpga_bridge_register(dev, F2S_BRIDGE_NAME,
> -  _fpga2sdram_br_ops, priv);
> +   br->name = F2S_BRIDGE_NAME;
> +   br->br_ops = _fpga2sdram_br_ops;
> +   br->priv = priv;
> +   platform_set_drvdata(pdev, br);
> +
> +   ret = fpga_bridge_register(dev, br);
> if (ret)
> return ret;
>
> @@ -146,7 +155,7 @@ static int alt_fpga_bridge_probe(struct platform_device 
> *pdev)
>  (enable ? "enabling" : "disabling"));
> ret = _alt_fpga2sdram_enable_set(priv, enable);
> if (ret) {
> -   fpga_bridge_unregister(>dev);
> +   fpga_bridge_unregister(br);
> return ret;
> }
> }
> @@ -157,7 +166,9 @@ static int alt_fpga_bridge_probe(struct platform_device 
> *pdev)
>
>  static int alt_fpga_bridge_remove(struct platform_device *pdev)
>  {
> -   fpga_bridge_unregister(>dev);
> +   struct fpga_bridge *br = platform_get_drvdata(pdev);
> +
> +   fpga_bridge_unregister(br);
>
> return 0;
>  }
> diff --git a/drivers/fpga/altera-freeze-bridge.c 
> b/drivers/fpga/altera-freeze-bridge.c
> index 6159cfcf..5fd424b 100644
> --- a/drivers/fpga/altera-freeze-bridge.c
> +++ b/drivers/fpga/altera-freeze-bridge.c
> @@ -219,6 +219,7 @@ static int altera_freeze_br_probe(struct platform_device 
> *pdev)
>  {
> struct device *dev = >dev;
> struct device_node *np = pdev->dev.of_node;
> +   struct fpga_bridge *br;
> void __iomem *base_addr;
> struct altera_freeze_br_data *priv;
> struct resource *res;
> @@ -227,6 +228,10 @@ static int altera_freeze_br_probe(struct platform_device 
> *pdev)
> if (!np)
> return -ENODEV;
>
> +   br = devm_kzalloc(dev, sizeof(*br), GFP_KERNEL);
> +   if (!br)
> +   return -ENOMEM;
> +
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> base_addr = devm_ioremap_resour

Re: [PATCH 2/3] fpga: manager: don't use drvdata in common fpga code

2017-10-31 Thread Alan Tull
On Tue, Oct 31, 2017 at 8:34 PM, Moritz Fischer <m...@kernel.org> wrote:
> On Tue, Oct 31, 2017 at 04:45:54PM -0500, Alan Tull wrote:
>> On Tue, Oct 31, 2017 at 3:59 PM, Moritz Fischer <m...@kernel.org> wrote:
>> > On Tue, Oct 31, 2017 at 08:42:14PM +, Alan Tull wrote:
>> >> Changes to the fpga manager code to not use drvdata in common
>> >> code.
>> >>
>> >> Change fpga_mgr_register to not set or use drvdata.
>> >>
>> >> Change the register/unregister function parameters to take the mgr
>> >> struct:
>> >> * int fpga_mgr_register(struct device *dev,
>> >> struct fpga_manager *mgr);
>> >> * void fpga_mgr_unregister(struct fpga_manager *mgr);
>> >>
>> >> Change the drivers that call fpga_mgr_register to alloc the struct
>> >> fpga_manager (using devm_kzalloc) and partly fill it, adding name,
>> >> ops, and priv.
>> >>
>> >> The rationale is that setting drvdata is fine for DT based devices
>> >> that will have one manager, bridge, or region per platform device.
>> >> However PCIe based devices may have multiple FPGA mgr/bridge/regions
>> >> under one pcie device.  Without these changes, the PCIe solution has
>> >> to create an extra device for each child mgr/bridge/region to hold
>> >> drvdata.
>> >
>> > This looks very common, in fact several subsystems provide this two step
>> > way of registering things.
>> >
>> > - Allocate fpga_mgr via fpga_mgr_alloc() where you pass in the size of
>> >   the private data
>> > - Fill in some fields
>> > - fpga_mgr_register() where you pass in the fpga_mgr as suggested
>> >
>> > See for example the alloc_etherdev() for ethernet devices.
>> >
>>
>> Yes, I considered it when I was writing this.  I've seen it both ways.
>> In the case you mention, they've got reasons they absolutely needed to
>> do it that way.  alloc_etherdev() calls eventually to
>> alloc_netdev_mqs() which is about 100 lines of alloc'ing and
>> initializing a network device struct.
>
> Yeah, sure. I looked around some more. Other subsystems just alloc
> manually, seems fine with me.
>>
>> > The benefit of the API you proposed is that one could embed the fpga_mgr
>> > struct inside of another struct and get to the container via
>> > container_of() I guess ...
>>
>> Yes, let's keep it simple for now, as that gives us greater
>> flexibility.  We can add alloc functions when it becomes clear that it
>> won't get in the way of someone's use.
>
> Agreed.
>>
>> Alan
>>
>> >
>> >>
>> >> Signed-off-by: Alan Tull <at...@kernel.org>
>> >> Reported-by: Jiuyue Ma <majiu...@huawei.com>
>> >> ---
>> >>  Documentation/fpga/fpga-mgr.txt  | 23 ---
>> >>  drivers/fpga/altera-cvp.c| 17 +
>> >>  drivers/fpga/altera-pr-ip-core.c | 16 ++--
>> >>  drivers/fpga/altera-ps-spi.c | 17 ++---
>> >>  drivers/fpga/fpga-mgr.c  | 28 +++-
>> >>  drivers/fpga/ice40-spi.c | 19 +++
>> >>  drivers/fpga/socfpga-a10.c   | 15 ---
>> >>  drivers/fpga/socfpga.c   | 17 ++---
>> >>  drivers/fpga/ts73xx-fpga.c   | 17 ++---
>> >>  drivers/fpga/xilinx-spi.c| 17 ++---
>> >>  drivers/fpga/zynq-fpga.c | 15 ---
>> >>  include/linux/fpga/fpga-mgr.h|  6 ++
>> >>  12 files changed, 147 insertions(+), 60 deletions(-)
>> >>
>> >> diff --git a/Documentation/fpga/fpga-mgr.txt 
>> >> b/Documentation/fpga/fpga-mgr.txt
>> >> index cc6413e..7e5e5c8 100644
>> >> --- a/Documentation/fpga/fpga-mgr.txt
>> >> +++ b/Documentation/fpga/fpga-mgr.txt
>> >> @@ -67,11 +67,9 @@ fpga_mgr_unlock when done programming the FPGA.
>> >>  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);
>> >> + int fpga_mgr_register(struct device *dev, struct fpga_manager *mgr);
&

Re: [PATCH v5 19/28] fpga: dfl: fme-mgr: add compat_id support

2018-05-07 Thread Alan Tull
On Tue, May 1, 2018 at 9:50 PM, Wu Hao <hao...@intel.com> wrote:

Hi Hao,

> This patch adds compat_id support to fme manager driver, it
> reads the ID from the hardware register. And it could be used
> for compatibility check before partial reconfiguration.
>
> Signed-off-by: Wu Hao <hao...@intel.com>
Acked-by: Alan Tull <at...@kernel.org>

> ---
>  drivers/fpga/dfl-fme-mgr.c | 15 +++
>  1 file changed, 15 insertions(+)
>
> diff --git a/drivers/fpga/dfl-fme-mgr.c b/drivers/fpga/dfl-fme-mgr.c
> index 1c5bc5a..afcdb39 100644
> --- a/drivers/fpga/dfl-fme-mgr.c
> +++ b/drivers/fpga/dfl-fme-mgr.c
> @@ -272,9 +272,17 @@ static u64 fme_mgr_status(struct fpga_manager *mgr)
> .status = fme_mgr_status,
>  };
>
> +static void fme_mgr_get_compat_id(void __iomem *fme_pr,
> + struct fpga_compat_id *id)
> +{
> +   id->id_l = readq(fme_pr + FME_PR_INTFC_ID_L);
> +   id->id_h = readq(fme_pr + FME_PR_INTFC_ID_H);
> +}
> +
>  static int fme_mgr_probe(struct platform_device *pdev)
>  {
> struct dfl_fme_mgr_pdata *pdata = dev_get_platdata(>dev);
> +   struct fpga_compat_id *compat_id;
> struct device *dev = >dev;
> struct fme_mgr_priv *priv;
> struct fpga_manager *mgr;
> @@ -295,11 +303,18 @@ static int fme_mgr_probe(struct platform_device *pdev)
> return PTR_ERR(priv->ioaddr);
> }
>
> +   compat_id = devm_kzalloc(dev, sizeof(*compat_id), GFP_KERNEL);
> +   if (!compat_id)
> +   return -ENOMEM;
> +
> +   fme_mgr_get_compat_id(priv->ioaddr, compat_id);
> +
> mgr = fpga_mgr_create(dev, "DFL FME FPGA Manager",
>   _mgr_ops, priv);
> if (!mgr)
> return -ENOMEM;
>
> +   mgr->compat_id = compat_id;
> platform_set_drvdata(pdev, mgr);
>
> ret = fpga_mgr_register(mgr);
> --
> 1.8.3.1
>


Re: [PATCH v5 22/28] fpga: dfl: fme-region: add support for compat_id

2018-05-07 Thread Alan Tull
On Tue, May 1, 2018 at 9:50 PM, Wu Hao <hao...@intel.com> wrote:

Hi Hao,

> This patch adds compat_id support, it reuses fme manager's
> compat id, as the per region compat id is actually from the
> fme manager's register.
>
> Signed-off-by: Wu Hao <hao...@intel.com>
Acked-by: Alan Tull <at...@kernel.org>

> ---
> v5: reuse fme manager's compat_id as per region compat_id
> ---
>  drivers/fpga/dfl-fme-region.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/fpga/dfl-fme-region.c b/drivers/fpga/dfl-fme-region.c
> index 696b313..b82a381 100644
> --- a/drivers/fpga/dfl-fme-region.c
> +++ b/drivers/fpga/dfl-fme-region.c
> @@ -45,6 +45,7 @@ static int fme_region_probe(struct platform_device *pdev)
> }
>
> region->priv = pdata;
> +   region->compat_id = mgr->compat_id;
> platform_set_drvdata(pdev, region);
>
> ret = fpga_region_register(region);
> --
> 1.8.3.1
>


Re: [PATCH v5 05/28] fpga: region: add compat_id support

2018-05-07 Thread Alan Tull
On Tue, May 1, 2018 at 9:50 PM, Wu Hao <hao...@intel.com> wrote:

Hi Hao,

Thanks for making the requested changes.  Looks good.

> This patch introduces a compat_id pointer member and sysfs interface
> for each fpga region, similar as compat_id for fpga manager, it allows
> applications to read the per region compat_id for compatibility
> checking before other actions on this fpga-region (e.g PR).
>
> Signed-off-by: Wu Hao <hao...@intel.com>
Acked-by: Alan Tull <at...@kernel.org>

> ---
> v5: use pointer for compat_id as it's optional to implement.
> ---
>  Documentation/ABI/testing/sysfs-class-fpga-region |  9 +
>  drivers/fpga/fpga-region.c| 22 ++
>  include/linux/fpga/fpga-region.h  |  2 ++
>  3 files changed, 33 insertions(+)
>  create mode 100644 Documentation/ABI/testing/sysfs-class-fpga-region
>
> diff --git a/Documentation/ABI/testing/sysfs-class-fpga-region 
> b/Documentation/ABI/testing/sysfs-class-fpga-region
> new file mode 100644
> index 000..9618f74
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-class-fpga-region
> @@ -0,0 +1,9 @@
> +What:  /sys/class/fpga_region//compat_id
> +Date:  May 2018
> +KernelVersion: 4.17
> +Contact:   Wu Hao <hao...@intel.com>
> +Description:   FPGA region id for compatibility check, e.g compatibility
> +   of the FPGA reconfiguration hardware and image. This value
> +   is defined or calculated by the layer that is creating the
> +   FPGA region. This interface returns the compat_id value or
> +   just error code -ENOENT in case compat_id is not used.
> diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
> index d6a9dd2..6929178 100644
> --- a/drivers/fpga/fpga-region.c
> +++ b/drivers/fpga/fpga-region.c
> @@ -162,6 +162,27 @@ int fpga_region_program_fpga(struct fpga_region *region)
>  }
>  EXPORT_SYMBOL_GPL(fpga_region_program_fpga);
>
> +static ssize_t compat_id_show(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> +   struct fpga_region *region = to_fpga_region(dev);
> +
> +   if (!region->compat_id)
> +   return -ENOENT;
> +
> +   return sprintf(buf, "%016llx%016llx\n",
> +  (unsigned long long)region->compat_id->id_h,
> +  (unsigned long long)region->compat_id->id_l);
> +}
> +
> +static DEVICE_ATTR_RO(compat_id);
> +
> +static struct attribute *fpga_region_attrs[] = {
> +   _attr_compat_id.attr,
> +   NULL,
> +};
> +ATTRIBUTE_GROUPS(fpga_region);
> +
>  /**
>   * fpga_region_create - alloc and init a struct fpga_region
>   * @dev: device parent
> @@ -262,6 +283,7 @@ static int __init fpga_region_init(void)
> if (IS_ERR(fpga_region_class))
> return PTR_ERR(fpga_region_class);
>
> +   fpga_region_class->dev_groups = fpga_region_groups;
> fpga_region_class->dev_release = fpga_region_dev_release;
>
> return 0;
> diff --git a/include/linux/fpga/fpga-region.h 
> b/include/linux/fpga/fpga-region.h
> index f2e215b..e8ad979 100644
> --- a/include/linux/fpga/fpga-region.h
> +++ b/include/linux/fpga/fpga-region.h
> @@ -12,6 +12,7 @@
>   * @bridge_list: list of FPGA bridges specified in region
>   * @mgr: FPGA manager
>   * @info: FPGA image info
> + * @compat_id: FPGA region id for compatibility check.
>   * @priv: private data
>   * @get_bridges: optional function to get bridges to a list
>   */
> @@ -21,6 +22,7 @@ struct fpga_region {
> struct list_head bridge_list;
> struct fpga_manager *mgr;
> struct fpga_image_info *info;
> +   struct fpga_compat_id *compat_id;
> void *priv;
> int (*get_bridges)(struct fpga_region *region);
>  };
> --
> 1.8.3.1
>


Re: [PATCH v5 04/28] fpga: mgr: add compat_id support

2018-05-07 Thread Alan Tull
On Tue, May 1, 2018 at 9:50 PM, Wu Hao <hao...@intel.com> wrote:

Hi Hao,

Looks good!

> This patch introduces compat_id support to fpga manager, it adds
> a fpga_compat_id pointer to fpga manager data structure to allow
> fpga manager drivers to save the compatibility id. This compat_id
> could be used for compatibility checking before doing partial
> reconfiguration to associated fpga regions.
>
> Signed-off-by: Wu Hao <hao...@intel.com>
Acked-by: Alan Tull <at...@kernel.org>

> ---
>  include/linux/fpga/fpga-mgr.h | 13 +
>  1 file changed, 13 insertions(+)
>
> diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
> index 802eac8..f163f22 100644
> --- a/include/linux/fpga/fpga-mgr.h
> +++ b/include/linux/fpga/fpga-mgr.h
> @@ -147,11 +147,23 @@ struct fpga_manager_ops {
>  #define FPGA_MGR_STATUS_FIFO_OVERFLOW_ERR  BIT(4)
>
>  /**
> + * struct fpga_compat_id - id for compatibility check
> + *
> + * @id_h: high 64bit of the compat_id
> + * @id_l: low 64bit of the compat_id
> + */
> +struct fpga_compat_id {
> +   u64 id_h;
> +   u64 id_l;
> +};
> +
> +/**
>   * struct fpga_manager - fpga manager structure
>   * @name: name of low level fpga manager
>   * @dev: fpga manager device
>   * @ref_mutex: only allows one reference to fpga manager
>   * @state: state of fpga manager
> + * @compat_id: FPGA manager id for compatibility check.
>   * @mops: pointer to struct of fpga manager ops
>   * @priv: low level driver private date
>   */
> @@ -160,6 +172,7 @@ struct fpga_manager {
> struct device dev;
> struct mutex ref_mutex;
> enum fpga_mgr_states state;
> +   struct fpga_compat_id *compat_id;
> const struct fpga_manager_ops *mops;
> void *priv;
>  };
> --
> 1.8.3.1
>


Re: [PATCH 2/4] fpga: manager: change api, don't use drvdata

2018-04-27 Thread Alan Tull
On Fri, Apr 27, 2018 at 1:26 PM, Florian Fainelli <f.faine...@gmail.com> wrote:
> On 04/26/2018 06:26 PM, Moritz Fischer wrote:
>> From: Alan Tull <at...@kernel.org>
>>
>> Change fpga_mgr_register to not set or use drvdata.  This supports
>> the case where a PCIe device has more than one manager.
>>
>> Add fpga_mgr_create/free functions.  Change fpga_mgr_register and
>> fpga_mgr_unregister functions to take the mgr struct as their only
>> parameter.
>>
>>   struct fpga_manager *fpga_mgr_create(struct device *dev,
>> const char *name,
>> const struct fpga_manager_ops *mops,
>> void *priv);
>>   void fpga_mgr_free(struct fpga_manager *mgr);
>>   int fpga_mgr_register(struct fpga_manager *mgr);
>>   void fpga_mgr_unregister(struct fpga_manager *mgr);
>>
>> Update the drivers that call fpga_mgr_register with the new API.
>
> Apologies for chiming in so late, this commit does not make it clear
> that fpga_mgr_unregister() now also free the 'mgr' argument by calling
> fpga_mgr_free(), this is kind of detail, but an API should make that
> clear IMHO.

If people follow the usage information, in
Documentation/fpga/fpga-mgr.txt, they'll do the right thing.  But I
can add a patch that clarifies the description of fpga_mgr_unregister
in fpga-mgr.c that it "unregisters and frees" the manager.

>
> Thanks
> --
> Florian


Re: [PATCH 00/14] fpga api changes and kernel-doc fixup

2018-05-17 Thread Alan Tull
On Thu, May 17, 2018 at 2:04 AM, Greg Kroah-Hartman
<gre...@linuxfoundation.org> wrote:
> On Wed, May 16, 2018 at 06:49:53PM -0500, Alan Tull wrote:
>> I'm posting these all together because they are interdependent.
>>
>> Patches 1-4 are a repost of v4 of the FPGA api change.
>>
>> Patch 5 is a repost of adding SPDX to my fpga code
>>
>> Patch 6-12 update the fpga kernel-doc documentation and move
>> existing .txt fpga documentation to driver-api ReST documents.
>>
>> Patch 13 is a minor documentation fix
>>
>> Patch 14 updates MAINTAINERS for the new driver-api/fpga directory
>
> Are these just for review, or do you feel they are good enough for me to
> queue up for 4.18-rc1 now?

I think the first five are good to go, but that's your call.

Patches 1-4 are the API reworked following your suggestions.

Patch 5 (SPDX) = I haven't heard any feedback on, but I think it's good.

So I think patches 1-5 are good (if you agree).  The rest are new to
the mailing list and haven't been reviewed/acked by anybody else yet.

I generally avoid posting reviewed/unreviewed patches together, sorry.
I just didn't want to open the possibility of patches being applied
out of order and the issues that can cause.

Alan

>
> thanks,
>
> greg k-h


[PATCH 13/14] fpga: clarify that unregister functions also free

2018-05-16 Thread Alan Tull
The following functions also free the struct.  Add that
fact to the function documentation.
 - fpga_mgr_free
 - fpga_bridge_free
 - fpga_region_free

Signed-off-by: Alan Tull <at...@kernel.org>
---
 drivers/fpga/fpga-bridge.c | 2 +-
 drivers/fpga/fpga-mgr.c| 2 +-
 drivers/fpga/fpga-region.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
index 4b207a7..24b8f98 100644
--- a/drivers/fpga/fpga-bridge.c
+++ b/drivers/fpga/fpga-bridge.c
@@ -412,7 +412,7 @@ int fpga_bridge_register(struct fpga_bridge *bridge)
 EXPORT_SYMBOL_GPL(fpga_bridge_register);
 
 /**
- * fpga_bridge_unregister - unregister a fpga bridge driver
+ * fpga_bridge_unregister - unregister and free a fpga bridge
  * @bridge:FPGA bridge struct created by fpga_bridge_create
  */
 void fpga_bridge_unregister(struct fpga_bridge *bridge)
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index 5fffeef..c1564cf 100644
--- a/drivers/fpga/fpga-mgr.c
+++ b/drivers/fpga/fpga-mgr.c
@@ -633,7 +633,7 @@ int fpga_mgr_register(struct fpga_manager *mgr)
 EXPORT_SYMBOL_GPL(fpga_mgr_register);
 
 /**
- * fpga_mgr_unregister - unregister a FPGA manager
+ * fpga_mgr_unregister - unregister and free a FPGA manager
  * @mgr:   fpga manager struct
  */
 void fpga_mgr_unregister(struct fpga_manager *mgr)
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 112fa3a..6d214d7 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -232,7 +232,7 @@ int fpga_region_register(struct fpga_region *region)
 EXPORT_SYMBOL_GPL(fpga_region_register);
 
 /**
- * fpga_region_unregister - unregister a FPGA region
+ * fpga_region_unregister - unregister and free a FPGA region
  * @region: FPGA region
  */
 void fpga_region_unregister(struct fpga_region *region)
-- 
2.7.4



[PATCH 04/14] fpga: region: change api, add fpga_region_create/free

2018-05-16 Thread Alan Tull
Add fpga_region_create/free API functions.

Change fpga_region_register to take FPGA region struct as the only
parameter.  Change fpga_region_unregister to return void.

  struct fpga_region *fpga_region_create(struct device *dev,
struct fpga_manager *mgr,
int (*get_bridges)(struct fpga_region *));
  void fpga_region_free(struct fpga_region *region);
  int fpga_region_register(struct fpga_region *region);
  void fpga_region_unregister(struct fpga_region *region);

Remove groups storage from struct fpga_region, it's not
needed.  Callers can just "region->dev.groups = groups;"
after calling fpga_region_create.

Update the drivers that call fpga_region_register with the new API.

Signed-off-by: Alan Tull <at...@kernel.org>
Signed-off-by: Moritz Fischer <m...@kernel.org>
---
 Documentation/fpga/fpga-region.txt |  3 +-
 drivers/fpga/fpga-region.c | 68 ++
 drivers/fpga/of-fpga-region.c  | 13 +++-
 include/linux/fpga/fpga-region.h   | 11 +++---
 4 files changed, 68 insertions(+), 27 deletions(-)

diff --git a/Documentation/fpga/fpga-region.txt 
b/Documentation/fpga/fpga-region.txt
index 139a02b..d38fa3b 100644
--- a/Documentation/fpga/fpga-region.txt
+++ b/Documentation/fpga/fpga-region.txt
@@ -42,8 +42,7 @@ The FPGA region API
 To register or unregister a region:
 ---
 
-   int fpga_region_register(struct device *dev,
-struct fpga_region *region);
+   int fpga_region_register(struct fpga_region *region);
int fpga_region_unregister(struct fpga_region *region);
 
 An example of usage can be seen in the probe function of [3]
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index f634a8e..b3ba3e40 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -167,18 +167,36 @@ int fpga_region_program_fpga(struct fpga_region *region)
 }
 EXPORT_SYMBOL_GPL(fpga_region_program_fpga);
 
-int fpga_region_register(struct device *dev, struct fpga_region *region)
+/**
+ * fpga_region_create - alloc and init a struct fpga_region
+ * @dev: device parent
+ * @mgr: manager that programs this region
+ * @get_bridges: optional function to get bridges to a list
+ *
+ * Return: struct fpga_region or NULL
+ */
+struct fpga_region
+*fpga_region_create(struct device *dev,
+   struct fpga_manager *mgr,
+   int (*get_bridges)(struct fpga_region *))
 {
+   struct fpga_region *region;
int id, ret = 0;
 
+   region = kzalloc(sizeof(*region), GFP_KERNEL);
+   if (!region)
+   return NULL;
+
id = ida_simple_get(_region_ida, 0, 0, GFP_KERNEL);
if (id < 0)
-   return id;
+   goto err_free;
 
+   region->mgr = mgr;
+   region->get_bridges = get_bridges;
mutex_init(>mutex);
INIT_LIST_HEAD(>bridge_list);
+
device_initialize(>dev);
-   region->dev.groups = region->groups;
region->dev.class = fpga_region_class;
region->dev.parent = dev;
region->dev.of_node = dev->of_node;
@@ -188,23 +206,47 @@ int fpga_region_register(struct device *dev, struct 
fpga_region *region)
if (ret)
goto err_remove;
 
-   ret = device_add(>dev);
-   if (ret)
-   goto err_remove;
-
-   return 0;
+   return region;
 
 err_remove:
ida_simple_remove(_region_ida, id);
-   return ret;
+err_free:
+   kfree(region);
+
+   return NULL;
+}
+EXPORT_SYMBOL_GPL(fpga_region_create);
+
+/**
+ * fpga_region_free - free a struct fpga_region
+ * @region: FPGA region created by fpga_region_create
+ */
+void fpga_region_free(struct fpga_region *region)
+{
+   ida_simple_remove(_region_ida, region->dev.id);
+   kfree(region);
+}
+EXPORT_SYMBOL_GPL(fpga_region_free);
+
+/*
+ * fpga_region_register - register a FPGA region
+ * @region: FPGA region created by fpga_region_create
+ * Return: 0 or -errno
+ */
+int fpga_region_register(struct fpga_region *region)
+{
+   return device_add(>dev);
+
 }
 EXPORT_SYMBOL_GPL(fpga_region_register);
 
-int fpga_region_unregister(struct fpga_region *region)
+/*
+ * fpga_region_unregister - unregister a FPGA region
+ * @region: FPGA region
+ */
+void fpga_region_unregister(struct fpga_region *region)
 {
device_unregister(>dev);
-
-   return 0;
 }
 EXPORT_SYMBOL_GPL(fpga_region_unregister);
 
@@ -212,7 +254,7 @@ static void fpga_region_dev_release(struct device *dev)
 {
struct fpga_region *region = to_fpga_region(dev);
 
-   ida_simple_remove(_region_ida, region->dev.id);
+   fpga_region_free(region);
 }
 
 /**
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index 35e7e8c..9d681a1 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -422

[PATCH 00/14] fpga api changes and kernel-doc fixup

2018-05-16 Thread Alan Tull
I'm posting these all together because they are interdependent.

Patches 1-4 are a repost of v4 of the FPGA api change.

Patch 5 is a repost of adding SPDX to my fpga code

Patch 6-12 update the fpga kernel-doc documentation and move
existing .txt fpga documentation to driver-api ReST documents.

Patch 13 is a minor documentation fix

Patch 14 updates MAINTAINERS for the new driver-api/fpga directory

Alan Tull (14):
  fpga: region: don't use drvdata in common fpga code
  fpga: manager: change api, don't use drvdata
  fpga: bridge: change api, don't use drvdata
  fpga: region: change api, add fpga_region_create/free
  fpga: use SPDX
  fpga: mgr: kernel-doc fixes
  fpga: bridge: kernel-doc fixes
  fpga: region: kernel-doc fixes
  Documentation: fpga: move fpga overview to driver-api
  documentation: fpga: move fpga-mgr.txt to driver-api
  documentation: fpga: add bridge document to driver-api
  documentation: fpga: move fpga-region.txt to driver-api
  fpga: clarify that unregister functions also free
  MAINTAINERS: Add driver-api/fpga path

 Documentation/driver-api/fpga/fpga-bridge.rst |  49 ++
 Documentation/driver-api/fpga/fpga-mgr.rst| 220 ++
 Documentation/driver-api/fpga/fpga-region.rst | 102 
 Documentation/driver-api/fpga/index.rst   |  13 ++
 Documentation/driver-api/fpga/intro.rst   |  54 +++
 Documentation/driver-api/index.rst|   1 +
 Documentation/fpga/fpga-mgr.txt   | 199 ---
 Documentation/fpga/fpga-region.txt|  95 ---
 Documentation/fpga/overview.txt   |  23 ---
 MAINTAINERS   |   1 +
 drivers/fpga/altera-cvp.c |  19 ++-
 drivers/fpga/altera-fpga2sdram.c  |  34 ++--
 drivers/fpga/altera-freeze-bridge.c   |  35 ++--
 drivers/fpga/altera-hps2fpga.c|  37 +++--
 drivers/fpga/altera-pr-ip-core-plat.c |  13 +-
 drivers/fpga/altera-pr-ip-core.c  |  31 ++--
 drivers/fpga/altera-ps-spi.c  |  20 ++-
 drivers/fpga/fpga-bridge.c|  86 +-
 drivers/fpga/fpga-mgr.c   | 129 +--
 drivers/fpga/fpga-region.c|  86 ++
 drivers/fpga/ice40-spi.c  |  21 ++-
 drivers/fpga/machxo2-spi.c|  20 ++-
 drivers/fpga/of-fpga-region.c |  28 +---
 drivers/fpga/socfpga-a10.c|  28 ++--
 drivers/fpga/socfpga.c|  32 ++--
 drivers/fpga/ts73xx-fpga.c|  20 ++-
 drivers/fpga/xilinx-pr-decoupler.c|  22 ++-
 drivers/fpga/xilinx-spi.c |  20 ++-
 drivers/fpga/zynq-fpga.c  |  14 +-
 include/linux/fpga/altera-pr-ip-core.h|  13 +-
 include/linux/fpga/fpga-bridge.h  |   9 +-
 include/linux/fpga/fpga-mgr.h |  23 +--
 include/linux/fpga/fpga-region.h  |  13 +-
 33 files changed, 890 insertions(+), 620 deletions(-)
 create mode 100644 Documentation/driver-api/fpga/fpga-bridge.rst
 create mode 100644 Documentation/driver-api/fpga/fpga-mgr.rst
 create mode 100644 Documentation/driver-api/fpga/fpga-region.rst
 create mode 100644 Documentation/driver-api/fpga/index.rst
 create mode 100644 Documentation/driver-api/fpga/intro.rst
 delete mode 100644 Documentation/fpga/fpga-mgr.txt
 delete mode 100644 Documentation/fpga/fpga-region.txt
 delete mode 100644 Documentation/fpga/overview.txt

-- 
2.7.4



[PATCH 14/14] MAINTAINERS: Add driver-api/fpga path

2018-05-16 Thread Alan Tull
Add Documentation/driver-api/fpga path to MAINTAINERS file
for fpga.

Signed-off-by: Alan Tull <at...@kernel.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ce5062..febeecd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5612,6 +5612,7 @@ S:Maintained
 T: git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git
 Q: http://patchwork.kernel.org/project/linux-fpga/list/
 F: Documentation/fpga/
+F: Documentation/driver-api/fpga/
 F: Documentation/devicetree/bindings/fpga/
 F: drivers/fpga/
 F: include/linux/fpga/
-- 
2.7.4



[PATCH 02/14] fpga: manager: change api, don't use drvdata

2018-05-16 Thread Alan Tull
Change fpga_mgr_register to not set or use drvdata.  This supports
the case where a PCIe device has more than one manager.

Add fpga_mgr_create/free functions.  Change fpga_mgr_register and
fpga_mgr_unregister functions to take the mgr struct as their only
parameter.

  struct fpga_manager *fpga_mgr_create(struct device *dev,
const char *name,
const struct fpga_manager_ops *mops,
void *priv);
  void fpga_mgr_free(struct fpga_manager *mgr);
  int fpga_mgr_register(struct fpga_manager *mgr);
  void fpga_mgr_unregister(struct fpga_manager *mgr);

Update the drivers that call fpga_mgr_register with the new API.

Signed-off-by: Alan Tull <at...@kernel.org>
[Moritz: Fixup whitespace issue]
Reported-by: Jiuyue Ma <majiu...@huawei.com>
Signed-off-by: Moritz Fischer <m...@kernel.org>
---
 Documentation/fpga/fpga-mgr.txt  | 35 +-
 drivers/fpga/altera-cvp.c| 19 +++---
 drivers/fpga/altera-pr-ip-core.c | 18 --
 drivers/fpga/altera-ps-spi.c | 20 +--
 drivers/fpga/fpga-mgr.c  | 78 ++--
 drivers/fpga/ice40-spi.c | 21 ---
 drivers/fpga/machxo2-spi.c   | 20 ---
 drivers/fpga/socfpga-a10.c   | 14 ++--
 drivers/fpga/socfpga.c   | 19 --
 drivers/fpga/ts73xx-fpga.c   | 20 +--
 drivers/fpga/xilinx-spi.c| 20 +--
 drivers/fpga/zynq-fpga.c | 14 ++--
 include/linux/fpga/fpga-mgr.h| 10 +++---
 13 files changed, 237 insertions(+), 71 deletions(-)

diff --git a/Documentation/fpga/fpga-mgr.txt b/Documentation/fpga/fpga-mgr.txt
index cc6413e..86b6df6 100644
--- a/Documentation/fpga/fpga-mgr.txt
+++ b/Documentation/fpga/fpga-mgr.txt
@@ -63,17 +63,23 @@ The user should call fpga_mgr_lock and verify that it 
returns 0 before
 attempting to program the FPGA.  Likewise, the user should call
 fpga_mgr_unlock when done programming the FPGA.
 
+To alloc/free a FPGA manager struct:
+
+
+   struct fpga_manager *fpga_mgr_create(struct device *dev,
+const char *name,
+const struct fpga_manager_ops 
*mops,
+void *priv);
+   void fpga_mgr_free(struct fpga_manager *mgr);
 
 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);
+   int fpga_mgr_register(struct fpga_manager *mgr);
 
-   void fpga_mgr_unregister(struct device *dev);
+   void fpga_mgr_unregister(struct fpga_manager *mgr);
 
-Use of these two functions is described below in "How To Support a new FPGA
+Use of these functions is described below in "How To Support a new FPGA
 device."
 
 
@@ -148,6 +154,7 @@ static int socfpga_fpga_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
struct socfpga_fpga_priv *priv;
+   struct fpga_manager *mgr;
int ret;
 
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -157,13 +164,25 @@ static int socfpga_fpga_probe(struct platform_device 
*pdev)
/* ... do ioremaps, get interrupts, etc. and save
   them in priv... */
 
-   return fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager",
-_fpga_ops, priv);
+   mgr = fpga_mgr_create(dev, "Altera SOCFPGA FPGA Manager",
+ _fpga_ops, priv);
+   if (!mgr)
+   return -ENOMEM;
+
+   platform_set_drvdata(pdev, mgr);
+
+   ret = fpga_mgr_register(mgr);
+   if (ret)
+   fpga_mgr_free(mgr);
+
+   return ret;
 }
 
 static int socfpga_fpga_remove(struct platform_device *pdev)
 {
-   fpga_mgr_unregister(>dev);
+   struct fpga_manager *mgr = platform_get_drvdata(pdev);
+
+   fpga_mgr_unregister(mgr);
 
return 0;
 }
diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
index 77b04e4..dd4edd8 100644
--- a/drivers/fpga/altera-cvp.c
+++ b/drivers/fpga/altera-cvp.c
@@ -401,6 +401,7 @@ static int altera_cvp_probe(struct pci_dev *pdev,
const struct pci_device_id *dev_id)
 {
struct altera_cvp_conf *conf;
+   struct fpga_manager *mgr;
u16 cmd, val;
int ret;
 
@@ -452,16 +453,24 @@ static int altera_cvp_probe(struct pci_dev *pdev,
snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s @%s",
 ALTERA_CVP_MGR_NAME, pci_name(pdev));
 
-   ret = fpga_mgr_register(>dev, conf->mgr_name,
-   _cvp_ops, conf);
-   if (ret)
+   mgr = fpga_mgr_create(>

[PATCH 08/14] fpga: region: kernel-doc fixes

2018-05-16 Thread Alan Tull
Fix formatting and some cleanup for the kernel-doc documentation in
fpga-region.c

Signed-off-by: Alan Tull <at...@kernel.org>
---
 drivers/fpga/fpga-region.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 0878f62..112fa3a 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -81,13 +81,16 @@ static void fpga_region_put(struct fpga_region *region)
 
 /**
  * fpga_region_program_fpga - program FPGA
+ *
  * @region: FPGA region
+ *
  * Program an FPGA using fpga image info (region->info).
  * If the region has a get_bridges function, the exclusive reference for the
  * bridges will be held if programming succeeds.  This is intended to prevent
  * reprogramming the region until the caller considers it safe to do so.
  * The caller will need to call fpga_bridges_put() before attempting to
  * reprogram the region.
+ *
  * Return 0 for success or negative error code.
  */
 int fpga_region_program_fpga(struct fpga_region *region)
@@ -216,7 +219,7 @@ void fpga_region_free(struct fpga_region *region)
 }
 EXPORT_SYMBOL_GPL(fpga_region_free);
 
-/*
+/**
  * fpga_region_register - register a FPGA region
  * @region: FPGA region created by fpga_region_create
  * Return: 0 or -errno
@@ -228,7 +231,7 @@ int fpga_region_register(struct fpga_region *region)
 }
 EXPORT_SYMBOL_GPL(fpga_region_register);
 
-/*
+/**
  * fpga_region_unregister - unregister a FPGA region
  * @region: FPGA region
  */
-- 
2.7.4



[PATCH 01/14] fpga: region: don't use drvdata in common fpga code

2018-05-16 Thread Alan Tull
Changes to fpga_region_register function to not set drvdata.

Setting drvdata is fine for DT based devices that will have one region
per platform device.  However PCIe based devices may have multiple
FPGA regions under one PCIe device.  Without these changes, the PCIe
solution has to create an extra device for each child region to hold
drvdata.

Signed-off-by: Alan Tull <at...@kernel.org>
Reported-by: Jiuyue Ma <majiu...@huawei.com>
Signed-off-by: Moritz Fischer <m...@kernel.org>
---
 drivers/fpga/fpga-region.c| 1 -
 drivers/fpga/of-fpga-region.c | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index cb0603e..f634a8e 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -183,7 +183,6 @@ int fpga_region_register(struct device *dev, struct 
fpga_region *region)
region->dev.parent = dev;
region->dev.of_node = dev->of_node;
region->dev.id = id;
-   dev_set_drvdata(dev, region);
 
ret = dev_set_name(>dev, "region%d", id);
if (ret)
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index 119ff75..35e7e8c 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -438,6 +438,7 @@ static int of_fpga_region_probe(struct platform_device 
*pdev)
goto eprobe_mgr_put;
 
of_platform_populate(np, fpga_region_of_match, NULL, >dev);
+   dev_set_drvdata(dev, region);
 
dev_info(dev, "FPGA Region probed\n");
 
-- 
2.7.4



[PATCH 05/14] fpga: use SPDX

2018-05-16 Thread Alan Tull
Replace GPLv2 boilerplate with SPDX in FPGA code that came from me or
from Altera.

Signed-off-by: Alan Tull <at...@kernel.org>
---
 drivers/fpga/altera-fpga2sdram.c   | 13 +
 drivers/fpga/altera-freeze-bridge.c| 13 +
 drivers/fpga/altera-hps2fpga.c | 13 +
 drivers/fpga/altera-pr-ip-core-plat.c  | 13 +
 drivers/fpga/altera-pr-ip-core.c   | 13 +
 drivers/fpga/fpga-bridge.c | 13 +
 drivers/fpga/fpga-mgr.c| 13 +
 drivers/fpga/fpga-region.c | 14 +-
 drivers/fpga/of-fpga-region.c  | 14 +-
 drivers/fpga/socfpga-a10.c | 14 +-
 drivers/fpga/socfpga.c | 13 +
 include/linux/fpga/altera-pr-ip-core.h | 13 +
 include/linux/fpga/fpga-mgr.h  | 13 +
 include/linux/fpga/fpga-region.h   |  2 ++
 14 files changed, 15 insertions(+), 159 deletions(-)

diff --git a/drivers/fpga/altera-fpga2sdram.c b/drivers/fpga/altera-fpga2sdram.c
index 5a29ab6..23660cc 100644
--- a/drivers/fpga/altera-fpga2sdram.c
+++ b/drivers/fpga/altera-fpga2sdram.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * FPGA to SDRAM Bridge Driver for Altera SoCFPGA Devices
  *
  *  Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
diff --git a/drivers/fpga/altera-freeze-bridge.c 
b/drivers/fpga/altera-freeze-bridge.c
index fa4b693..ffd586c 100644
--- a/drivers/fpga/altera-freeze-bridge.c
+++ b/drivers/fpga/altera-freeze-bridge.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * FPGA Freeze Bridge Controller
  *
  *  Copyright (C) 2016 Altera Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include 
 #include 
diff --git a/drivers/fpga/altera-hps2fpga.c b/drivers/fpga/altera-hps2fpga.c
index e4d39f0..a974d3f 100644
--- a/drivers/fpga/altera-hps2fpga.c
+++ b/drivers/fpga/altera-hps2fpga.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * FPGA to/from HPS Bridge Driver for Altera SoCFPGA Devices
  *
@@ -6,18 +7,6 @@
  * Includes this patch from the mailing list:
  *   fpga: altera-hps2fpga: fix HPS2FPGA bridge visibility to L3 masters
  *   Signed-off-by: Anatolij Gustschin <ag...@denx.de>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
diff --git a/drivers/fpga/altera-pr-ip-core-plat.c 
b/drivers/fpga/altera-pr-ip-core-plat.c
index 8fb36b8..b293d83 100644
--- a/drivers/fpga/altera-pr-ip-core-plat.c
+++ b/drivers/fpga/altera-pr-ip-core-plat.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Driver for Altera Partial Reconfiguration IP Core
  *
@@ -5,18 +6,6 @@
  *
  * Based on socfpga-a10.c Copyright (C) 2015-2016 Altera Corporation
  *  by Alan Tull <at...@opensource.altera.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FO

[PATCH 06/14] fpga: mgr: kernel-doc fixes

2018-05-16 Thread Alan Tull
Clean up the kernel-doc documentation in fpga-mgr.c and fix the
following warnings when documentation is built:

./drivers/fpga/fpga-mgr.c:252: warning: Function parameter or member
'info' not described in 'fpga_mgr_buf_load'

./drivers/fpga/fpga-mgr.c:252: warning: Excess function parameter
'flags' description in 'fpga_mgr_buf_load'

Signed-off-by: Alan Tull <at...@kernel.org>
---
 drivers/fpga/fpga-mgr.c | 38 +-
 1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index 151ac36..5fffeef 100644
--- a/drivers/fpga/fpga-mgr.c
+++ b/drivers/fpga/fpga-mgr.c
@@ -21,6 +21,12 @@
 static DEFINE_IDA(fpga_mgr_ida);
 static struct class *fpga_mgr_class;
 
+/**
+ * fpga_image_info_alloc - Allocate a FPGA image info struct
+ * @dev: owning device
+ *
+ * Return: struct fpga_image_info or NULL
+ */
 struct fpga_image_info *fpga_image_info_alloc(struct device *dev)
 {
struct fpga_image_info *info;
@@ -39,6 +45,10 @@ struct fpga_image_info *fpga_image_info_alloc(struct device 
*dev)
 }
 EXPORT_SYMBOL_GPL(fpga_image_info_alloc);
 
+/**
+ * fpga_image_info_free - Free a FPGA image info struct
+ * @info: FPGA image info struct to free
+ */
 void fpga_image_info_free(struct fpga_image_info *info)
 {
struct device *dev;
@@ -223,7 +233,7 @@ static int fpga_mgr_buf_load_mapped(struct fpga_manager 
*mgr,
 /**
  * fpga_mgr_buf_load - load fpga from image in buffer
  * @mgr:   fpga manager
- * @flags: flags setting fpga confuration modes
+ * @info:  fpga image info
  * @buf:   buffer contain fpga image
  * @count: byte count of buf
  *
@@ -332,6 +342,16 @@ static int fpga_mgr_firmware_load(struct fpga_manager *mgr,
return ret;
 }
 
+/**
+ * fpga_mgr_load - load FPGA from scatter/gather table, buffer, or firmware
+ * @mgr:   fpga manager
+ * @info:  fpga image information.
+ *
+ * Load the FPGA from an image which is indicated in @info.  If successful, the
+ * FPGA ends up in operating mode.
+ *
+ * Return: 0 on success, negative error code otherwise.
+ */
 int fpga_mgr_load(struct fpga_manager *mgr, struct fpga_image_info *info)
 {
if (info->sgt)
@@ -418,11 +438,9 @@ static int fpga_mgr_dev_match(struct device *dev, const 
void *data)
 }
 
 /**
- * fpga_mgr_get - get a reference to a fpga mgr
+ * fpga_mgr_get - Given a device, get a reference to a fpga mgr.
  * @dev:   parent device that fpga mgr was registered with
  *
- * Given a device, get a reference to a fpga mgr.
- *
  * Return: fpga manager struct or IS_ERR() condition containing error code.
  */
 struct fpga_manager *fpga_mgr_get(struct device *dev)
@@ -442,10 +460,9 @@ static int fpga_mgr_of_node_match(struct device *dev, 
const void *data)
 }
 
 /**
- * of_fpga_mgr_get - get a reference to a fpga mgr
- * @node:  device node
+ * of_fpga_mgr_get - Given a device node, get a reference to a fpga mgr.
  *
- * Given a device node, get a reference to a fpga mgr.
+ * @node:  device node
  *
  * Return: fpga manager struct or IS_ERR() condition containing error code.
  */
@@ -478,7 +495,10 @@ EXPORT_SYMBOL_GPL(fpga_mgr_put);
  * @mgr:   fpga manager
  *
  * Given a pointer to FPGA Manager (from fpga_mgr_get() or
- * of_fpga_mgr_put()) attempt to get the mutex.
+ * of_fpga_mgr_put()) attempt to get the mutex. The user should call
+ * fpga_mgr_lock() and verify that it returns 0 before attempting to
+ * program the FPGA.  Likewise, the user should call fpga_mgr_unlock
+ * when done programming the FPGA.
  *
  * Return: 0 for success or -EBUSY
  */
@@ -494,7 +514,7 @@ int fpga_mgr_lock(struct fpga_manager *mgr)
 EXPORT_SYMBOL_GPL(fpga_mgr_lock);
 
 /**
- * fpga_mgr_unlock - Unlock FPGA manager
+ * fpga_mgr_unlock - Unlock FPGA manager after done programming
  * @mgr:   fpga manager
  */
 void fpga_mgr_unlock(struct fpga_manager *mgr)
-- 
2.7.4



[PATCH 07/14] fpga: bridge: kernel-doc fixes

2018-05-16 Thread Alan Tull
Fix the following warnings when documentation is built:

./drivers/fpga/fpga-bridge.c:143: warning: Function parameter or
member 'info' not described in 'fpga_bridge_get'

./drivers/fpga/fpga-bridge.c:1: warning: no structured comments found

Signed-off-by: Alan Tull <at...@kernel.org>
---
 drivers/fpga/fpga-bridge.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
index 164eb55..4b207a7 100644
--- a/drivers/fpga/fpga-bridge.c
+++ b/drivers/fpga/fpga-bridge.c
@@ -121,6 +121,7 @@ static int fpga_bridge_dev_match(struct device *dev, const 
void *data)
 /**
  * fpga_bridge_get - get an exclusive reference to a fpga bridge
  * @dev:   parent device that fpga bridge was registered with
+ * @info:  fpga manager info
  *
  * Given a device, get an exclusive reference to a fpga bridge.
  *
-- 
2.7.4



[PATCH 10/14] documentation: fpga: move fpga-mgr.txt to driver-api

2018-05-16 Thread Alan Tull
Move Documentation/fpga/fpga-mgr.txt to driver-api/fpga/fpga-mgr.rst
and:
 - Add to driver-api/fpga/index.rst
 - Format changes so documentation builds cleanly.
 - Minor rewrites that make the doc flow better as ReST documentation.
   - Such as moving API reference to end of doc
 - Change API reference section to refer to kernel-doc documentation in
   fpga-mgr.c driver code rather than statically defining each function.

Signed-off-by: Alan Tull <at...@kernel.org>
---
 Documentation/driver-api/fpga/fpga-mgr.rst | 220 +
 Documentation/driver-api/fpga/index.rst|   1 +
 Documentation/fpga/fpga-mgr.txt| 218 
 3 files changed, 221 insertions(+), 218 deletions(-)
 create mode 100644 Documentation/driver-api/fpga/fpga-mgr.rst
 delete mode 100644 Documentation/fpga/fpga-mgr.txt

diff --git a/Documentation/driver-api/fpga/fpga-mgr.rst 
b/Documentation/driver-api/fpga/fpga-mgr.rst
new file mode 100644
index 000..bcf2dd2
--- /dev/null
+++ b/Documentation/driver-api/fpga/fpga-mgr.rst
@@ -0,0 +1,220 @@
+FPGA Manager
+
+
+Overview
+
+
+The FPGA manager core exports a set of functions for programming an FPGA with
+an image.  The API is manufacturer agnostic.  All manufacturer specifics are
+hidden away in a low level driver which registers a set of ops with the core.
+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.
+
+How to support a new FPGA device
+
+
+To add another FPGA manager, write a driver that implements a set of ops.  The
+probe function calls fpga_mgr_register(), such as::
+
+   static const struct fpga_manager_ops socfpga_fpga_ops = {
+   .write_init = socfpga_fpga_ops_configure_init,
+   .write = socfpga_fpga_ops_configure_write,
+   .write_complete = socfpga_fpga_ops_configure_complete,
+   .state = socfpga_fpga_ops_state,
+   };
+
+   static int socfpga_fpga_probe(struct platform_device *pdev)
+   {
+   struct device *dev = >dev;
+   struct socfpga_fpga_priv *priv;
+   struct fpga_manager *mgr;
+   int ret;
+
+   priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+   if (!priv)
+   return -ENOMEM;
+
+   /*
+* do ioremaps, get interrupts, etc. and save
+* them in priv
+*/
+
+   mgr = fpga_mgr_create(dev, "Altera SOCFPGA FPGA Manager",
+ _fpga_ops, priv);
+   if (!mgr)
+   return -ENOMEM;
+
+   platform_set_drvdata(pdev, mgr);
+
+   ret = fpga_mgr_register(mgr);
+   if (ret)
+   fpga_mgr_free(mgr);
+
+   return ret;
+   }
+
+   static int socfpga_fpga_remove(struct platform_device *pdev)
+   {
+   struct fpga_manager *mgr = platform_get_drvdata(pdev);
+
+   fpga_mgr_unregister(mgr);
+
+   return 0;
+   }
+
+
+The ops will implement whatever device specific register writes are needed to
+do the programming sequence for this particular FPGA.  These ops return 0 for
+success or negative error codes otherwise.
+
+The programming sequence is::
+ 1. .write_init
+ 2. .write or .write_sg (may be called once or multiple times)
+ 3. .write_complete
+
+The .write_init function will prepare the FPGA to receive the image data.  The
+buffer passed into .write_init will be atmost .initial_header_size bytes long,
+if the whole bitstream is not immediately available then the core code will
+buffer up at least this much before starting.
+
+The .write function writes a buffer to the FPGA. The buffer may be contain the
+whole FPGA image or may be a smaller chunk of an FPGA image.  In the latter
+case, this function is called multiple times for successive chunks. This 
interface
+is suitable for drivers which use PIO.
+
+The .write_sg version behaves the same as .write except the input is a sg_table
+scatter list. This interface is suitable for drivers which use DMA.
+
+The .write_complete function is called after all the image has been written
+to put the FPGA into operating mode.
+
+The ops include a .state function which will rea

[PATCH 09/14] Documentation: fpga: move fpga overview to driver-api

2018-05-16 Thread Alan Tull
Start of moving Documentation/fpga/*.txt to driver-api, including:
 - Add new directory driver-api/fpga
 - Add new file driver-api/fpga/index.rst
 - Add driver-api/fpga to driver-api/index.rst
 - Move Documentation/fpga/overview.txt to driver-api/fpga/intro.rst
 - Formatting and rewrites so that intro.rst will build cleanly
   and form a good introduction to the rest of the docs to be added.

Signed-off-by: Alan Tull <at...@kernel.org>
---
 Documentation/driver-api/fpga/index.rst | 10 ++
 Documentation/driver-api/fpga/intro.rst | 54 +
 Documentation/driver-api/index.rst  |  1 +
 Documentation/fpga/overview.txt | 23 --
 4 files changed, 65 insertions(+), 23 deletions(-)
 create mode 100644 Documentation/driver-api/fpga/index.rst
 create mode 100644 Documentation/driver-api/fpga/intro.rst
 delete mode 100644 Documentation/fpga/overview.txt

diff --git a/Documentation/driver-api/fpga/index.rst 
b/Documentation/driver-api/fpga/index.rst
new file mode 100644
index 000..71e568a
--- /dev/null
+++ b/Documentation/driver-api/fpga/index.rst
@@ -0,0 +1,10 @@
+==
+FPGA Subsystem
+==
+
+:Author: Alan Tull
+
+.. toctree::
+   :maxdepth: 2
+
+   intro
diff --git a/Documentation/driver-api/fpga/intro.rst 
b/Documentation/driver-api/fpga/intro.rst
new file mode 100644
index 000..51cd81d
--- /dev/null
+++ b/Documentation/driver-api/fpga/intro.rst
@@ -0,0 +1,54 @@
+Introduction
+
+
+The FPGA subsystem supports reprogramming FPGAs dynamically under
+Linux.  Some of the core intentions of the FPGA subsystems are:
+
+* The FPGA subsystem is vendor agnostic.
+
+* The FPGA subsystem separates upper layers (userspace interfaces and
+  enumeration) from lower layers that know how to program a specific
+  FPGA.
+
+* Code should not be shared between upper and lower layers.  This
+  should go without saying.  If that seems necessary, there's probably
+  framework functionality that that can be added that will benefit
+  other users.  Write the linux-fpga mailing list and maintainers and
+  seek out a solution that expands the framework for broad reuse.
+
+* Generally, when adding code, think of the future.  Plan for re-use.
+
+The framework in the kernel is divided into:
+
+FPGA Manager
+
+
+If you are adding a new FPGA or a new method of programming a FPGA,
+this is the subsystem for you.  Low level FPGA manager drivers contain
+the knowledge of how to program a specific device.  This subsystem
+includes the framework in fpga-mgr.c and the low level drivers that
+are registered with it.
+
+FPGA Bridge
+---
+
+FPGA Bridges prevent spurious signals from going out of a FPGA or a
+region of a FPGA during programming.  They are disabled before
+programming begins and re-enabled afterwards.  An FPGA bridge may be
+actual hard hardware that gates a bus to a cpu or a soft ("freeze")
+bridge in FPGA fabric that surrounds a partial reconfiguration region
+of an FPGA.  This subsystem includes fpga-bridge.c and the low level
+drivers that are registered with it.
+
+FPGA Region
+---
+
+If you are adding a new interface to the FPGA framework, add it on top
+of a FPGA region to allow the most reuse of your interface.
+
+The FPGA Region framework (fpga-region.c) associates managers and
+bridges as reconfigurable regions.  A region may refer to the whole
+FPGA in full reconfiguration or to a partial reconfiguration region.
+
+The Device Tree FPGA Region support (of-fpga-region.c) handles
+reprogramming FPGAs when device tree overlays are applied.
diff --git a/Documentation/driver-api/index.rst 
b/Documentation/driver-api/index.rst
index 7b12b6b..6d9f2f9 100644
--- a/Documentation/driver-api/index.rst
+++ b/Documentation/driver-api/index.rst
@@ -52,6 +52,7 @@ available subsections can be seen below.
dmaengine/index
slimbus
soundwire/index
+   fpga/index
 
 .. only::  subproject and html
 
diff --git a/Documentation/fpga/overview.txt b/Documentation/fpga/overview.txt
deleted file mode 100644
index 0f1236e..000
--- a/Documentation/fpga/overview.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Linux kernel FPGA support
-
-Alan Tull 2017
-
-The main point of this project has been to separate the out the upper layers
-that know when to reprogram a FPGA from the lower layers that know how to
-reprogram a specific FPGA device.  The intention is to make this manufacturer
-agnostic, understanding that of course the FPGA images are very device specific
-themselves.
-
-The framework in the kernel includes:
-* low level FPGA manager drivers that know how to program a specific device
-* the fpga-mgr framework they are registered with
-* low level FPGA bridge drivers for hard/soft bridges which are intended to
-  be disable during FPGA programming
-* the fpga-bridge framework they are registered with
-* the fpga-region framework which associates and controls managers and bridges
-  as reconfigurable regions
-* th

[PATCH 03/14] fpga: bridge: change api, don't use drvdata

2018-05-16 Thread Alan Tull
Change fpga_bridge_register to not set drvdata.  This is to support
the case where a PCIe device can have more than one bridge.

Add API functions to create/free the fpga bridge struct. Change
fpga_bridge_register/unregister to take FPGA bridge struct as
the only parameter.

  struct fpga_bridge
  *fpga_bridge_create(struct device *dev, const char *name,
  const struct fpga_bridge_ops *br_ops,
  void *priv);
  void fpga_bridge_free(struct fpga_bridge *br);
  int fpga_bridge_register(struct fpga_bridge *br);
  void fpga_bridge_unregister(struct fpga_bridge *br);

Update the drivers that call fpga_bridge_register with the new API.

Signed-off-by: Alan Tull <at...@kernel.org>
Reported-by: Jiuyue Ma <majiu...@huawei.com>
Signed-off-by: Moritz Fischer <m...@kernel.org>
---
 drivers/fpga/altera-fpga2sdram.c| 21 ---
 drivers/fpga/altera-freeze-bridge.c | 22 ++--
 drivers/fpga/altera-hps2fpga.c  | 24 ++---
 drivers/fpga/fpga-bridge.c  | 70 -
 drivers/fpga/xilinx-pr-decoupler.c  | 22 +---
 include/linux/fpga/fpga-bridge.h|  9 +++--
 6 files changed, 123 insertions(+), 45 deletions(-)

diff --git a/drivers/fpga/altera-fpga2sdram.c b/drivers/fpga/altera-fpga2sdram.c
index d4eeb74..5a29ab6 100644
--- a/drivers/fpga/altera-fpga2sdram.c
+++ b/drivers/fpga/altera-fpga2sdram.c
@@ -106,6 +106,7 @@ static int alt_fpga_bridge_probe(struct platform_device 
*pdev)
 {
struct device *dev = >dev;
struct alt_fpga2sdram_data *priv;
+   struct fpga_bridge *br;
u32 enable;
struct regmap *sysmgr;
int ret = 0;
@@ -131,10 +132,18 @@ static int alt_fpga_bridge_probe(struct platform_device 
*pdev)
/* Get f2s bridge configuration saved in handoff register */
regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, >mask);
 
-   ret = fpga_bridge_register(dev, F2S_BRIDGE_NAME,
-  _fpga2sdram_br_ops, priv);
-   if (ret)
+   br = fpga_bridge_create(dev, F2S_BRIDGE_NAME,
+   _fpga2sdram_br_ops, priv);
+   if (!br)
+   return -ENOMEM;
+
+   platform_set_drvdata(pdev, br);
+
+   ret = fpga_bridge_register(br);
+   if (ret) {
+   fpga_bridge_free(br);
return ret;
+   }
 
dev_info(dev, "driver initialized with handoff %08x\n", priv->mask);
 
@@ -146,7 +155,7 @@ static int alt_fpga_bridge_probe(struct platform_device 
*pdev)
 (enable ? "enabling" : "disabling"));
ret = _alt_fpga2sdram_enable_set(priv, enable);
if (ret) {
-   fpga_bridge_unregister(>dev);
+   fpga_bridge_unregister(br);
return ret;
}
}
@@ -157,7 +166,9 @@ static int alt_fpga_bridge_probe(struct platform_device 
*pdev)
 
 static int alt_fpga_bridge_remove(struct platform_device *pdev)
 {
-   fpga_bridge_unregister(>dev);
+   struct fpga_bridge *br = platform_get_drvdata(pdev);
+
+   fpga_bridge_unregister(br);
 
return 0;
 }
diff --git a/drivers/fpga/altera-freeze-bridge.c 
b/drivers/fpga/altera-freeze-bridge.c
index 6159cfcf..fa4b693 100644
--- a/drivers/fpga/altera-freeze-bridge.c
+++ b/drivers/fpga/altera-freeze-bridge.c
@@ -221,8 +221,10 @@ static int altera_freeze_br_probe(struct platform_device 
*pdev)
struct device_node *np = pdev->dev.of_node;
void __iomem *base_addr;
struct altera_freeze_br_data *priv;
+   struct fpga_bridge *br;
struct resource *res;
u32 status, revision;
+   int ret;
 
if (!np)
return -ENODEV;
@@ -254,13 +256,27 @@ static int altera_freeze_br_probe(struct platform_device 
*pdev)
 
priv->base_addr = base_addr;
 
-   return fpga_bridge_register(dev, FREEZE_BRIDGE_NAME,
-   _freeze_br_br_ops, priv);
+   br = fpga_bridge_create(dev, FREEZE_BRIDGE_NAME,
+   _freeze_br_br_ops, priv);
+   if (!br)
+   return -ENOMEM;
+
+   platform_set_drvdata(pdev, br);
+
+   ret = fpga_bridge_register(br);
+   if (ret) {
+   fpga_bridge_free(br);
+   return ret;
+   }
+
+   return 0;
 }
 
 static int altera_freeze_br_remove(struct platform_device *pdev)
 {
-   fpga_bridge_unregister(>dev);
+   struct fpga_bridge *br = platform_get_drvdata(pdev);
+
+   fpga_bridge_unregister(br);
 
return 0;
 }
diff --git a/drivers/fpga/altera-hps2fpga.c b/drivers/fpga/altera-hps2fpga.c
index 406d2f1..e4d39f0 100644
--- a/drivers/fpga/altera-hps2fpga.c
+++ b/drivers/fpga/altera-hps2fpga.c
@@ -139,6 +139,7 @@ static int alt_fpga_bridge_probe(struct p

[PATCH 12/14] documentation: fpga: move fpga-region.txt to driver-api

2018-05-16 Thread Alan Tull
Move Documentation/fpga/fpga-region.txt to
driver-api/fpga/fpga-region.rst.  Including:
 - Add it to driver-api/fpga/index.rst
 - Formatting changes to build cleanly as ReST documentation
 - Some rewrites for better flow as a ReST doc such as moving
   API reference to the end of the doc
 - Rewrite API reference section to refer to kernel-doc
   documentation in fpga-region.c driver code

Signed-off-by: Alan Tull <at...@kernel.org>
---
 Documentation/driver-api/fpga/fpga-region.rst | 102 ++
 Documentation/driver-api/fpga/index.rst   |   1 +
 Documentation/fpga/fpga-region.txt|  94 
 3 files changed, 103 insertions(+), 94 deletions(-)
 create mode 100644 Documentation/driver-api/fpga/fpga-region.rst
 delete mode 100644 Documentation/fpga/fpga-region.txt

diff --git a/Documentation/driver-api/fpga/fpga-region.rst 
b/Documentation/driver-api/fpga/fpga-region.rst
new file mode 100644
index 000..f89e4a3
--- /dev/null
+++ b/Documentation/driver-api/fpga/fpga-region.rst
@@ -0,0 +1,102 @@
+FPGA Region
+===
+
+Overview
+
+
+This document is meant to be an brief overview of the FPGA region API usage.  A
+more conceptual look at regions can be found in the Device Tree binding
+document [#f1]_.
+
+For the purposes of this API document, let's just say that a region associates
+an FPGA Manager and a bridge (or bridges) with a reprogrammable region of an
+FPGA or the whole FPGA.  The API provides a way to register a region and to
+program a region.
+
+Currently the only layer above fpga-region.c in the kernel is the Device Tree
+support (of-fpga-region.c) described in [#f1]_.  The DT support layer uses 
regions
+to program the FPGA and then DT to handle enumeration.  The common region code
+is intended to be used by other schemes that have other ways of accomplishing
+enumeration after programming.
+
+An fpga-region can be set up to know the following things:
+
+ * which FPGA manager to use to do the programming
+
+ * which bridges to disable before programming and enable afterwards.
+
+Additional info needed to program the FPGA image is passed in the struct
+fpga_image_info including:
+
+ * pointers to the image as either a scatter-gather buffer, a contiguous
+   buffer, or the name of firmware file
+
+ * flags indicating specifics such as whether the image if for partial
+   reconfiguration.
+
+How to program a FPGA using a region
+
+
+First, allocate the info struct::
+
+   info = fpga_image_info_alloc(dev);
+   if (!info)
+   return -ENOMEM;
+
+Set flags as needed, i.e.::
+
+   info->flags |= FPGA_MGR_PARTIAL_RECONFIG;
+
+Point to your FPGA image, such as::
+
+   info->sgt = 
+
+Add info to region and do the programming::
+
+   region->info = info;
+   ret = fpga_region_program_fpga(region);
+
+:c:func:`fpga_region_program_fpga()` operates on info passed in the
+fpga_image_info (region->info).  This function will attempt to:
+
+ * lock the region's mutex
+ * lock 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
+ * re-enable the bridges
+ * release the locks
+
+Then you will want to enumerate whatever hardware has appeared in the FPGA.
+
+How to add a new FPGA region
+
+
+An example of usage can be seen in the probe function of [#f2]_.
+
+.. [#f1] ../devicetree/bindings/fpga/fpga-region.txt
+.. [#f2] ../../drivers/fpga/of-fpga-region.c
+
+API to program a FGPA
+-
+
+.. kernel-doc:: drivers/fpga/fpga-region.c
+   :functions: fpga_region_program_fpga
+
+API to add a new FPGA region
+
+
+.. kernel-doc:: include/linux/fpga/fpga-region.h
+   :functions: fpga_region
+
+.. kernel-doc:: drivers/fpga/fpga-region.c
+   :functions: fpga_region_create
+
+.. kernel-doc:: drivers/fpga/fpga-region.c
+   :functions: fpga_region_free
+
+.. kernel-doc:: drivers/fpga/fpga-region.c
+   :functions: fpga_region_register
+
+.. kernel-doc:: drivers/fpga/fpga-region.c
+   :functions: fpga_region_unregister
diff --git a/Documentation/driver-api/fpga/index.rst 
b/Documentation/driver-api/fpga/index.rst
index 968bbbf..c51e5eb 100644
--- a/Documentation/driver-api/fpga/index.rst
+++ b/Documentation/driver-api/fpga/index.rst
@@ -10,3 +10,4 @@ FPGA Subsystem
intro
fpga-mgr
fpga-bridge
+   fpga-region
diff --git a/Documentation/fpga/fpga-region.txt 
b/Documentation/fpga/fpga-region.txt
deleted file mode 100644
index d38fa3b..000
--- a/Documentation/fpga/fpga-region.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-FPGA Regions
-
-Alan Tull 2017
-
-CONTENTS
- - Introduction
- - The FPGA region API
- - Usage example
-
-Introduction
-
-
-This document is meant to be an brief overview of the FPGA region API usage.  A
-more conceptual look at regions can be found in [1].
-
-For the purposes of this A

[PATCH 11/14] documentation: fpga: add bridge document to driver-api

2018-05-16 Thread Alan Tull
Add a new document to driver-api/fpga that documents the
fpga bridge API and add it to driver-api/fpga/index.rst

Signed-off-by: Alan Tull <at...@kernel.org>
---
 Documentation/driver-api/fpga/fpga-bridge.rst | 49 +++
 Documentation/driver-api/fpga/index.rst   |  1 +
 2 files changed, 50 insertions(+)
 create mode 100644 Documentation/driver-api/fpga/fpga-bridge.rst

diff --git a/Documentation/driver-api/fpga/fpga-bridge.rst 
b/Documentation/driver-api/fpga/fpga-bridge.rst
new file mode 100644
index 000..2c2aaca
--- /dev/null
+++ b/Documentation/driver-api/fpga/fpga-bridge.rst
@@ -0,0 +1,49 @@
+FPGA Bridge
+===
+
+API to implement a new FPGA bridge
+~~
+
+.. kernel-doc:: include/linux/fpga/fpga-bridge.h
+   :functions: fpga_bridge
+
+.. kernel-doc:: include/linux/fpga/fpga-bridge.h
+   :functions: fpga_bridge_ops
+
+.. kernel-doc:: drivers/fpga/fpga-bridge.c
+   :functions: fpga_bridge_create
+
+.. kernel-doc:: drivers/fpga/fpga-bridge.c
+   :functions: fpga_bridge_free
+
+.. kernel-doc:: drivers/fpga/fpga-bridge.c
+   :functions: fpga_bridge_register
+
+.. kernel-doc:: drivers/fpga/fpga-bridge.c
+   :functions: fpga_bridge_unregister
+
+API to control an FPGA bridge
+~
+
+You probably won't need these directly.  FPGA regions should handle this.
+
+.. kernel-doc:: drivers/fpga/fpga-bridge.c
+   :functions: of_fpga_bridge_get
+
+.. kernel-doc:: drivers/fpga/fpga-bridge.c
+   :functions: fpga_bridge_get
+
+.. kernel-doc:: drivers/fpga/fpga-bridge.c
+   :functions: fpga_bridge_put
+
+.. kernel-doc:: drivers/fpga/fpga-bridge.c
+   :functions: fpga_bridge_get_to_list
+
+.. kernel-doc:: drivers/fpga/fpga-bridge.c
+   :functions: of_fpga_bridge_get_to_list
+
+.. kernel-doc:: drivers/fpga/fpga-bridge.c
+   :functions: fpga_bridge_enable
+
+.. kernel-doc:: drivers/fpga/fpga-bridge.c
+   :functions: fpga_bridge_disable
diff --git a/Documentation/driver-api/fpga/index.rst 
b/Documentation/driver-api/fpga/index.rst
index 34b2075..968bbbf 100644
--- a/Documentation/driver-api/fpga/index.rst
+++ b/Documentation/driver-api/fpga/index.rst
@@ -9,3 +9,4 @@ FPGA Subsystem
 
intro
fpga-mgr
+   fpga-bridge
-- 
2.7.4



Re: [PATCH v5 04/28] fpga: mgr: add compat_id support

2018-05-21 Thread Alan Tull
On Sun, May 20, 2018 at 10:03 PM, Wu Hao <hao...@intel.com> wrote:
> On Mon, May 07, 2018 at 04:09:06PM -0500, Alan Tull wrote:
>> On Tue, May 1, 2018 at 9:50 PM, Wu Hao <hao...@intel.com> wrote:
>>
>> Hi Hao,
>>
>> Looks good!
>>
>> > This patch introduces compat_id support to fpga manager, it adds
>> > a fpga_compat_id pointer to fpga manager data structure to allow
>> > fpga manager drivers to save the compatibility id. This compat_id
>> > could be used for compatibility checking before doing partial
>> > reconfiguration to associated fpga regions.
>> >
>> > Signed-off-by: Wu Hao <hao...@intel.com>
>> Acked-by: Alan Tull <at...@kernel.org>
>
> Hi Alan
>
> Thanks a lot for the acked-by.
>
> Did you get a chance to look into other patches?

What I'm looking for mostly is: is it clear that this code was written
to be reused.  What do you think?  Was it?  Is there a way that intent
could be made clear in the code?  This patchset has a history of being
a one-off solution for a single platform, doing things to work around
the FPGA framework instead of doing what the framework was intended to
do.  The FPGA framework was written so that any FPGA could be used
with interface.  Currently in the upstream that means any of the
supported FPGAs can be programmed with the same of-fpga-region code.
It didn't have to get rewritten for each fpga.

This patchset adds 5000 lines and I understand that another 4000 is
coming to add to this.  Has that been written so that the upper layer
can be reused?  Or will the 'reusable' version be another huge
patchset?  Do you see my point?  Up to this point I've been trying to
help figure out what changes could make this reusable.  If you could
get with someone to take responsibility for architecting this patchset
to be clearly reusable, that could speed things up.

If there are improvements to the current FPGA framework that can help
this work, I'm interested and open to suggestions/code in that
direction..

Alan

>
> Thanks
> Hao


Re: [PATCH v5 20/28] fpga: dfl: add fpga bridge platform driver for FME

2018-05-23 Thread Alan Tull
On Wed, May 23, 2018 at 10:28 AM, Wu Hao <hao...@intel.com> wrote:
> On Wed, May 23, 2018 at 10:15:00AM -0500, Alan Tull wrote:
>> On Tue, May 1, 2018 at 9:50 PM, Wu Hao <hao...@intel.com> wrote:
>>
>> Hi Hao,
>>
>> > This patch adds fpga bridge platform driver for FPGA Management Engine.
>> > It implements the enable_set callback for fpga bridge.
>> >
>> > Signed-off-by: Tim Whisonant <tim.whison...@intel.com>
>> > Signed-off-by: Enno Luebbers <enno.luebb...@intel.com>
>> > Signed-off-by: Shiva Rao <shiva@intel.com>
>> > Signed-off-by: Christopher Rauer <christopher.ra...@intel.com>
>> > Signed-off-by: Wu Hao <hao...@intel.com>
>> > Acked-by: Alan Tull <at...@kernel.org>
>> > Acked-by: Moritz Fischer <m...@kernel.org>
>> > ---
>> > v3: rename driver to fpga-dfl-fme-br
>> > remove useless dev_dbg in probe function.
>> > rebased due to fpga api change.
>> > v4: rename to dfl-fme-br and fix SPDX license issue
>> > include dfl-fme-pr.h instead of dfl-fme.h
>> > add Acked-by from Alan and Moritz
>> > v5: rebase due to API changes.
>> > defer port and its ops finding when really need.
>> > ---
>> >  drivers/fpga/Kconfig  |   6 +++
>> >  drivers/fpga/Makefile |   1 +
>> >  drivers/fpga/dfl-fme-br.c | 114 
>> > ++
>> >  3 files changed, 121 insertions(+)
>> >  create mode 100644 drivers/fpga/dfl-fme-br.c
>> >
>> > diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
>> > index 89f76e8..a8f939a 100644
>> > --- a/drivers/fpga/Kconfig
>> > +++ b/drivers/fpga/Kconfig
>> > @@ -156,6 +156,12 @@ config FPGA_DFL_FME_MGR
>> > help
>> >   Say Y to enable FPGA Manager driver for FPGA Management Engine.
>> >
>> > +config FPGA_DFL_FME_BRIDGE
>> > +   tristate "FPGA DFL FME Bridge Driver"
>> > +   depends on FPGA_DFL_FME
>> > +   help
>> > + Say Y to enable FPGA Bridge driver for FPGA Management Engine.
>> > +
>> >  config FPGA_DFL_PCI
>> > tristate "FPGA Device Feature List (DFL) PCIe Device Driver"
>> > depends on PCI && FPGA_DFL
>> > diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
>> > index f82814a..75096e9 100644
>> > --- a/drivers/fpga/Makefile
>> > +++ b/drivers/fpga/Makefile
>> > @@ -32,6 +32,7 @@ obj-$(CONFIG_OF_FPGA_REGION)  += of-fpga-region.o
>> >  obj-$(CONFIG_FPGA_DFL) += dfl.o
>> >  obj-$(CONFIG_FPGA_DFL_FME) += dfl-fme.o
>> >  obj-$(CONFIG_FPGA_DFL_FME_MGR) += dfl-fme-mgr.o
>> > +obj-$(CONFIG_FPGA_DFL_FME_BRIDGE)  += dfl-fme-br.o
>> >
>> >  dfl-fme-objs := dfl-fme-main.o dfl-fme-pr.o
>> >
>> > diff --git a/drivers/fpga/dfl-fme-br.c b/drivers/fpga/dfl-fme-br.c
>> > new file mode 100644
>> > index 000..5c51b08
>> > --- /dev/null
>> > +++ b/drivers/fpga/dfl-fme-br.c
>> > @@ -0,0 +1,114 @@
>> > +// SPDX-License-Identifier: GPL-2.0
>> > +/*
>> > + * FPGA Bridge Driver for FPGA Management Engine (FME)
>> > + *
>> > + * Copyright (C) 2017 Intel Corporation, Inc.
>> > + *
>> > + * Authors:
>> > + *   Wu Hao <hao...@intel.com>
>> > + *   Joseph Grecco <joe.gre...@intel.com>
>> > + *   Enno Luebbers <enno.luebb...@intel.com>
>> > + *   Tim Whisonant <tim.whison...@intel.com>
>> > + *   Ananda Ravuri <ananda.rav...@intel.com>
>> > + *   Henry Mitchel <henry.mitc...@intel.com>
>> > + */
>> > +
>> > +#include 
>> > +#include 
>> > +
>> > +#include "dfl.h"
>> > +#include "dfl-fme-pr.h"
>> > +
>> > +struct fme_br_priv {
>> > +   struct dfl_fme_br_pdata *pdata;
>> > +   struct dfl_fpga_port_ops *port_ops;
>> > +   struct platform_device *port_pdev;
>> > +};
>> > +
>> > +static int fme_bridge_enable_set(struct fpga_bridge *bridge, bool enable)
>> > +{
>> > +   struct fme_br_priv *priv = bridge->priv;
>> > +   struct platform_device *port_pdev;
>> > +   struct dfl_fpga_port_ops *ops;
>> > +
>> > +   if (!priv->port_pdev) {
>> > +   port_pdev = dfl_fpga_cdev_find_

Re: [PATCH v5 20/28] fpga: dfl: add fpga bridge platform driver for FME

2018-05-24 Thread Alan Tull
On Wed, May 23, 2018 at 6:42 PM, Wu Hao <hao...@intel.com> wrote:
> On Wed, May 23, 2018 at 04:06:17PM -0500, Alan Tull wrote:
>> On Wed, May 23, 2018 at 10:28 AM, Wu Hao <hao...@intel.com> wrote:
>> > On Wed, May 23, 2018 at 10:15:00AM -0500, Alan Tull wrote:
>> >> On Tue, May 1, 2018 at 9:50 PM, Wu Hao <hao...@intel.com> wrote:
>> >>
>> >> Hi Hao,
>> >>
>> >> > This patch adds fpga bridge platform driver for FPGA Management Engine.
>> >> > It implements the enable_set callback for fpga bridge.
>> >> >
>> >> > Signed-off-by: Tim Whisonant <tim.whison...@intel.com>
>> >> > Signed-off-by: Enno Luebbers <enno.luebb...@intel.com>
>> >> > Signed-off-by: Shiva Rao <shiva@intel.com>
>> >> > Signed-off-by: Christopher Rauer <christopher.ra...@intel.com>
>> >> > Signed-off-by: Wu Hao <hao...@intel.com>
>> >> > Acked-by: Alan Tull <at...@kernel.org>
>> >> > Acked-by: Moritz Fischer <m...@kernel.org>
>> >> > ---
>> >> > v3: rename driver to fpga-dfl-fme-br
>> >> > remove useless dev_dbg in probe function.
>> >> > rebased due to fpga api change.
>> >> > v4: rename to dfl-fme-br and fix SPDX license issue
>> >> > include dfl-fme-pr.h instead of dfl-fme.h
>> >> > add Acked-by from Alan and Moritz
>> >> > v5: rebase due to API changes.
>> >> > defer port and its ops finding when really need.
>> >> > ---
>> >> >  drivers/fpga/Kconfig  |   6 +++
>> >> >  drivers/fpga/Makefile |   1 +
>> >> >  drivers/fpga/dfl-fme-br.c | 114 
>> >> > ++
>> >> >  3 files changed, 121 insertions(+)
>> >> >  create mode 100644 drivers/fpga/dfl-fme-br.c
>> >> >
>> >> > diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
>> >> > index 89f76e8..a8f939a 100644
>> >> > --- a/drivers/fpga/Kconfig
>> >> > +++ b/drivers/fpga/Kconfig
>> >> > @@ -156,6 +156,12 @@ config FPGA_DFL_FME_MGR
>> >> > help
>> >> >   Say Y to enable FPGA Manager driver for FPGA Management 
>> >> > Engine.
>> >> >
>> >> > +config FPGA_DFL_FME_BRIDGE
>> >> > +   tristate "FPGA DFL FME Bridge Driver"
>> >> > +   depends on FPGA_DFL_FME
>> >> > +   help
>> >> > + Say Y to enable FPGA Bridge driver for FPGA Management Engine.
>> >> > +
>> >> >  config FPGA_DFL_PCI
>> >> > tristate "FPGA Device Feature List (DFL) PCIe Device Driver"
>> >> > depends on PCI && FPGA_DFL
>> >> > diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
>> >> > index f82814a..75096e9 100644
>> >> > --- a/drivers/fpga/Makefile
>> >> > +++ b/drivers/fpga/Makefile
>> >> > @@ -32,6 +32,7 @@ obj-$(CONFIG_OF_FPGA_REGION)  += 
>> >> > of-fpga-region.o
>> >> >  obj-$(CONFIG_FPGA_DFL) += dfl.o
>> >> >  obj-$(CONFIG_FPGA_DFL_FME) += dfl-fme.o
>> >> >  obj-$(CONFIG_FPGA_DFL_FME_MGR) += dfl-fme-mgr.o
>> >> > +obj-$(CONFIG_FPGA_DFL_FME_BRIDGE)  += dfl-fme-br.o
>> >> >
>> >> >  dfl-fme-objs := dfl-fme-main.o dfl-fme-pr.o
>> >> >
>> >> > diff --git a/drivers/fpga/dfl-fme-br.c b/drivers/fpga/dfl-fme-br.c
>> >> > new file mode 100644
>> >> > index 000..5c51b08
>> >> > --- /dev/null
>> >> > +++ b/drivers/fpga/dfl-fme-br.c
>> >> > @@ -0,0 +1,114 @@
>> >> > +// SPDX-License-Identifier: GPL-2.0
>> >> > +/*
>> >> > + * FPGA Bridge Driver for FPGA Management Engine (FME)
>> >> > + *
>> >> > + * Copyright (C) 2017 Intel Corporation, Inc.
>> >> > + *
>> >> > + * Authors:
>> >> > + *   Wu Hao <hao...@intel.com>
>> >> > + *   Joseph Grecco <joe.gre...@intel.com>
>> >> > + *   Enno Luebbers <enno.luebb...@intel.com>
>> >> > + *   Tim Whisonant <tim.whison...@intel.com>
>> >> > + *   Ananda Ravuri <ananda.rav...@intel.com>

Re: [PATCH v5 20/28] fpga: dfl: add fpga bridge platform driver for FME

2018-05-23 Thread Alan Tull
On Tue, May 1, 2018 at 9:50 PM, Wu Hao <hao...@intel.com> wrote:

Hi Hao,

> This patch adds fpga bridge platform driver for FPGA Management Engine.
> It implements the enable_set callback for fpga bridge.
>
> Signed-off-by: Tim Whisonant <tim.whison...@intel.com>
> Signed-off-by: Enno Luebbers <enno.luebb...@intel.com>
> Signed-off-by: Shiva Rao <shiva@intel.com>
> Signed-off-by: Christopher Rauer <christopher.ra...@intel.com>
> Signed-off-by: Wu Hao <hao...@intel.com>
> Acked-by: Alan Tull <at...@kernel.org>
> Acked-by: Moritz Fischer <m...@kernel.org>
> ---
> v3: rename driver to fpga-dfl-fme-br
> remove useless dev_dbg in probe function.
> rebased due to fpga api change.
> v4: rename to dfl-fme-br and fix SPDX license issue
> include dfl-fme-pr.h instead of dfl-fme.h
> add Acked-by from Alan and Moritz
> v5: rebase due to API changes.
> defer port and its ops finding when really need.
> ---
>  drivers/fpga/Kconfig  |   6 +++
>  drivers/fpga/Makefile |   1 +
>  drivers/fpga/dfl-fme-br.c | 114 
> ++
>  3 files changed, 121 insertions(+)
>  create mode 100644 drivers/fpga/dfl-fme-br.c
>
> diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
> index 89f76e8..a8f939a 100644
> --- a/drivers/fpga/Kconfig
> +++ b/drivers/fpga/Kconfig
> @@ -156,6 +156,12 @@ config FPGA_DFL_FME_MGR
> help
>   Say Y to enable FPGA Manager driver for FPGA Management Engine.
>
> +config FPGA_DFL_FME_BRIDGE
> +   tristate "FPGA DFL FME Bridge Driver"
> +   depends on FPGA_DFL_FME
> +   help
> + Say Y to enable FPGA Bridge driver for FPGA Management Engine.
> +
>  config FPGA_DFL_PCI
> tristate "FPGA Device Feature List (DFL) PCIe Device Driver"
> depends on PCI && FPGA_DFL
> diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
> index f82814a..75096e9 100644
> --- a/drivers/fpga/Makefile
> +++ b/drivers/fpga/Makefile
> @@ -32,6 +32,7 @@ obj-$(CONFIG_OF_FPGA_REGION)  += of-fpga-region.o
>  obj-$(CONFIG_FPGA_DFL) += dfl.o
>  obj-$(CONFIG_FPGA_DFL_FME) += dfl-fme.o
>  obj-$(CONFIG_FPGA_DFL_FME_MGR) += dfl-fme-mgr.o
> +obj-$(CONFIG_FPGA_DFL_FME_BRIDGE)  += dfl-fme-br.o
>
>  dfl-fme-objs := dfl-fme-main.o dfl-fme-pr.o
>
> diff --git a/drivers/fpga/dfl-fme-br.c b/drivers/fpga/dfl-fme-br.c
> new file mode 100644
> index 000..5c51b08
> --- /dev/null
> +++ b/drivers/fpga/dfl-fme-br.c
> @@ -0,0 +1,114 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * FPGA Bridge Driver for FPGA Management Engine (FME)
> + *
> + * Copyright (C) 2017 Intel Corporation, Inc.
> + *
> + * Authors:
> + *   Wu Hao <hao...@intel.com>
> + *   Joseph Grecco <joe.gre...@intel.com>
> + *   Enno Luebbers <enno.luebb...@intel.com>
> + *   Tim Whisonant <tim.whison...@intel.com>
> + *   Ananda Ravuri <ananda.rav...@intel.com>
> + *   Henry Mitchel <henry.mitc...@intel.com>
> + */
> +
> +#include 
> +#include 
> +
> +#include "dfl.h"
> +#include "dfl-fme-pr.h"
> +
> +struct fme_br_priv {
> +   struct dfl_fme_br_pdata *pdata;
> +   struct dfl_fpga_port_ops *port_ops;
> +   struct platform_device *port_pdev;
> +};
> +
> +static int fme_bridge_enable_set(struct fpga_bridge *bridge, bool enable)
> +{
> +   struct fme_br_priv *priv = bridge->priv;
> +   struct platform_device *port_pdev;
> +   struct dfl_fpga_port_ops *ops;
> +
> +   if (!priv->port_pdev) {
> +   port_pdev = dfl_fpga_cdev_find_port(priv->pdata->cdev,
> +   >pdata->port_id,
> +   dfl_fpga_check_port_id);
> +   if (!port_pdev)
> +   return -ENODEV;
> +
> +   priv->port_pdev = port_pdev;
> +   }
> +
> +   if (priv->port_pdev && !priv->port_ops) {
> +   ops = dfl_fpga_get_port_ops(priv->port_pdev);
> +   if (!ops || !ops->enable_set)
> +   return -ENOENT;
> +
> +   priv->port_ops = ops;
> +   }

This is saving some pointers.  Is it possible that the port_pdev or
port_ops could go away?

Also, the port ops routines probably should be named
dfl_fpga_port_ops_get/find_port/etc

Alan

> +
> +   return priv->port_ops->enable_set(priv->port_pdev, enable);
> +}
> +
> +static const struct fpga_bridge_ops fme_bridge_ops = {
> +   .enabl

Re: [PATCH v6 07/29] fpga: dfl: add chardev support for feature devices

2018-06-12 Thread Alan Tull
On Tue, Jun 12, 2018 at 5:10 AM, Wu Hao  wrote:
> For feature devices drivers, both the FPGA Management Engine (FME) and
> Accelerated Function Unit (AFU) driver need to expose user interfaces via
> the device file, for example, mmap and ioctls.
>
> This patch adds chardev support in the dfl driver for feature devices,
> FME and AFU. It reserves the chardev regions for FME and AFU, and provide
> interfaces for FME and AFU driver to register their device file operations.
>
> Signed-off-by: Tim Whisonant 
> Signed-off-by: Enno Luebbers 
> Signed-off-by: Shiva Rao 
> Signed-off-by: Christopher Rauer 
> Signed-off-by: Zhang Yi 
> Signed-off-by: Xiao Guangrong 
> Signed-off-by: Wu Hao 
Acked-by: Alan Tull 

> ---
> v2: rebased
> v3: move chardev support to fpga-dfl framework
> v4: rebase, and add more comments in code.
> v5: rebase, and add dfl_ prefix to APIs and data structures.
> v6: add index in dfl_devs to link to dfl_chrdevs.
> improve naming on APIs.


Re: [PATCH v6 03/29] fpga: mgr: add status for fpga-manager

2018-06-12 Thread Alan Tull
On Tue, Jun 12, 2018 at 5:10 AM, Wu Hao  wrote:

Hi Hao,

>  Documentation/ABI/testing/sysfs-class-fpga-manager | 24 +++
>  drivers/fpga/fpga-mgr.c| 28 
> ++
>  include/linux/fpga/fpga-mgr.h  |  9 +++
>  3 files changed, 61 insertions(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-class-fpga-manager 
> b/Documentation/ABI/testing/sysfs-class-fpga-manager
> index 23056c5..2aadf59 100644
> --- a/Documentation/ABI/testing/sysfs-class-fpga-manager
> +++ b/Documentation/ABI/testing/sysfs-class-fpga-manager
> @@ -35,3 +35,27 @@ Description: Read fpga manager state as a string.
> * write complete= Doing post programming steps
> * write complete error  = Error while doing post programming
> * operating = FPGA is programmed and operating
> +
> +What:  /sys/class/fpga_manager//status
> +Date:  June 2018
> +KernelVersion: 4.18

4.19

Greg is queuing new functionality for 4.19 after 4.18-rc1 is done.

> +Contact:   Wu Hao 
> +Description:   Read fpga manager status as a string.


Re: [PATCH v6 06/29] fpga: add device feature list support

2018-06-12 Thread Alan Tull
On Tue, Jun 12, 2018 at 5:10 AM, Wu Hao  wrote:
> Device Feature List (DFL) defines a feature list structure that creates
> a link list of feature headers within the MMIO space to provide an
> extensible way of adding features. This patch introduces a kernel module
> to provide basic infrastructure to support FPGA devices which implement
> the Device Feature List.
>
> Usually there will be different features and their sub features linked into
> the DFL. This code provides common APIs for feature enumeration, it creates
> a container device (FPGA base region), walks through the DFLs and creates
> platform devices for feature devices (Currently it only supports two
> different feature devices, FPGA Management Engine (FME) and Port which
> the Accelerator Function Unit (AFU) connected to). In order to enumerate
> the DFLs, the common APIs required low level driver to provide necessary
> enumeration information (e.g address for each device feature list for
> given device) and fill it to the dfl_fpga_enum_info data structure. Please
> refer to below description for APIs added for enumeration.
>
> Functions for enumeration information preparation:
>  *dfl_fpga_enum_info_alloc
>allocate enumeration information data structure.
>
>  *dfl_fpga_enum_info_add_dfl
>add a device feature list to dfl_fpga_enum_info data structure.
>
>  *dfl_fpga_enum_info_free
>free dfl_fpga_enum_info data structure and related resources.
>
> Functions for feature device enumeration:
>  *dfl_fpga_feature_devs_enumerate
>enumerate feature devices and return container device.
>
>  *dfl_fpga_feature_devs_remove
>remove feature devices under given container device.
>
> Signed-off-by: Tim Whisonant 
> Signed-off-by: Enno Luebbers 
> Signed-off-by: Shiva Rao 
> Signed-off-by: Christopher Rauer 
> Signed-off-by: Zhang Yi 
> Signed-off-by: Xiao Guangrong 
> Signed-off-by: Wu Hao 
Acked-by: Alan Tull 

> ---
> v3: split from another patch.
> separate dfl enumeration code from original pcie driver.
> provide common data structures and APIs for enumeration.
> update device feature list parsing process according to latest hw.
> add dperf/iperf/hssi sub feature placeholder according to latest hw.
> remove build_info_add_sub_feature and other small functions.
> replace *_feature_num function with macro.
> remove writeq/readq.
> v4: fix SPDX license issue
> rename files to dfl.[ch], fix typo and add more comments.
> remove static feature_info tables for FME and Port.
> remove check on next_afu link list as only FIU has next_afu ptr.
> remove unused macro in header file.
> add more comments for functions.
> v5: add "dfl_" prefix to functions and data structures.
> remove port related functions from DFL framework.
> use BIT_ULL for 64bit register definition.
> save dfl_fpga_cdev in pdata for feature platform devices.
> rebase due to fpga region api changes.
> v6: update time in copyright and improve function name.
> introduce dfl_devs table to save feature device info.


Re: [PATCH v5 07/28] fpga: dfl: add chardev support for feature devices

2018-06-07 Thread Alan Tull
On Wed, Jun 6, 2018 at 7:24 AM, Wu Hao  wrote:

Hi Hao,

One more...

>> > +static dev_t dfl_get_devt(enum dfl_fpga_devt_type type, int id)
>> > +{
>> > +   WARN_ON(type >= DFL_FPGA_DEVT_MAX);
>> > +
>> > +   return MKDEV(MAJOR(dfl_chrdevs[type].devt), id);
>> > +}
>> > +
>> > +/**
>> > + * dfl_fpga_register_dev_ops - register cdev ops for feature dev
>> > + *
>> > + * @pdev: feature dev.
>> > + * @fops: file operations for feature dev's cdev.
>> > + * @owner: owning module/driver.
>> > + *
>> > + * Return: 0 on success, negative error code otherwise.
>> > + */
>> > +int dfl_fpga_register_dev_ops(struct platform_device *pdev,
>> > + const struct file_operations *fops,
>> > + struct module *owner)
>> > +{
>> > +   struct dfl_feature_platform_data *pdata = 
>> > dev_get_platdata(>dev);
>> > +
>> > +   cdev_init(>cdev, fops);
>> > +   pdata->cdev.owner = owner;
>> > +
>> > +   /*
>> > +* set parent to the feature device so that its refcount is
>> > +* decreased after the last refcount of cdev is gone, that
>> > +* makes sure the feature device is valid during device
>> > +* file's life-cycle.
>> > +*/
>> > +   pdata->cdev.kobj.parent = >dev.kobj;
>> > +
>> > +   return cdev_add(>cdev, pdev->dev.devt, 1);
>> > +}
>> > +EXPORT_SYMBOL_GPL(dfl_fpga_register_dev_ops);
>> > +
>> > +/**
>> > + * dfl_fpga_unregister_dev_ops - unregister cdev ops for feature dev
>> > + * @pdev: feature dev.
>> > + */
>> > +void dfl_fpga_unregister_dev_ops(struct platform_device *pdev)
>> > +{
>> > +   struct dfl_feature_platform_data *pdata = 
>> > dev_get_platdata(>dev);
>> > +
>> > +   cdev_del(>cdev);
>> > +}
>> > +EXPORT_SYMBOL_GPL(dfl_fpga_unregister_dev_ops);

How about dfl_fpga_dev_ops_register/unregister?

Thanks,
Alan


Re: [RFC PATCH] of: overlay: update phandle cache on overlay apply and remove

2018-06-18 Thread Alan Tull
On Sun, Jun 17, 2018 at 11:03 AM,   wrote:

Hi Frank,

Thanks again for the fast response while traveling.  The RFC looks
good in my testing and review.

> From: Frank Rowand 
>
> A comment in the review of the patch adding the phandle cache said that
> the cache would have to be updated when modules are applied and removed.
> This patch implements the cache updates.
>
> Fixes: 0b3ce78e90fc ("of: cache phandle nodes to reduce cost of 
> of_find_node_by_phandle()")
> Reported-by: Alan Tull 
> Suggested-by: Alan Tull 
> Signed-off-by: Frank Rowand 
Tested-by: Alan Tull 
Reviewed-by: Alan Tull 

> ---
>
> Compiles for one configuration.
> NOT boot tested.
> Not run through my normal process to check for new warnings, etc.
>
> It is late, I'm tired, my brain is fuzzy.  I need to review this more to have
> any confidence in it.  But I wanted to get a version out for Alan to see (and
> test if he wants).
>
>  drivers/of/base.c   |  6 +++---
>  drivers/of/of_private.h |  2 ++
>  drivers/of/overlay.c| 12 
>  3 files changed, 17 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 848f549164cd..466e3c8582f0 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -102,7 +102,7 @@ static u32 phandle_cache_mask;
>   *   - the phandle lookup overhead reduction provided by the cache
>   * will likely be less
>   */
> -static void of_populate_phandle_cache(void)
> +void of_populate_phandle_cache(void)
>  {
> unsigned long flags;
> u32 cache_entries;
> @@ -134,8 +134,7 @@ static void of_populate_phandle_cache(void)
> raw_spin_unlock_irqrestore(_lock, flags);
>  }
>
> -#ifndef CONFIG_MODULES
> -static int __init of_free_phandle_cache(void)
> +int of_free_phandle_cache(void)
>  {
> unsigned long flags;
>
> @@ -148,6 +147,7 @@ static int __init of_free_phandle_cache(void)
>
> return 0;
>  }
> +#if !defined(CONFIG_MODULES)
>  late_initcall_sync(of_free_phandle_cache);
>  #endif
>
> diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
> index 891d780c076a..216175d11d3d 100644
> --- a/drivers/of/of_private.h
> +++ b/drivers/of/of_private.h
> @@ -79,6 +79,8 @@ int of_resolve_phandles(struct device_node *tree);
>  #if defined(CONFIG_OF_OVERLAY)
>  void of_overlay_mutex_lock(void);
>  void of_overlay_mutex_unlock(void);
> +int of_free_phandle_cache(void);
> +void of_populate_phandle_cache(void);
>  #else
>  static inline void of_overlay_mutex_lock(void) {};
>  static inline void of_overlay_mutex_unlock(void) {};
> diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
> index 7baa53e5b1d7..3f76e58fbec4 100644
> --- a/drivers/of/overlay.c
> +++ b/drivers/of/overlay.c
> @@ -804,6 +804,8 @@ static int of_overlay_apply(const void *fdt, struct 
> device_node *tree,
> goto err_free_overlay_changeset;
> }
>
> +   of_populate_phandle_cache();
> +
> ret = __of_changeset_apply_notify(>cset);
> if (ret)
> pr_err("overlay changeset entry notify error %d\n", ret);
> @@ -1046,8 +1048,18 @@ int of_overlay_remove(int *ovcs_id)
>
> list_del(>ovcs_list);
>
> +   /*
> +* Empty and disable phandle cache.  Must empty here so that
> +* changeset notifiers do not use stale cache entry for a removed
> +* phandle.
> +*/
> +   of_free_phandle_cache();
> +
> ret_apply = 0;
> ret = __of_changeset_revert_entries(>cset, _apply);
> +
> +   of_populate_phandle_cache();
> +
> if (ret) {
> if (ret_apply)
> devicetree_state_flags |= DTSF_REVERT_FAIL;
> --
> Frank Rowand 
>


Re: [PATCH v6 29/29] MAINTAINERS: add entry for FPGA DFL drivers

2018-06-12 Thread Alan Tull
On Tue, Jun 12, 2018 at 5:10 AM, Wu Hao  wrote:
> Add entry for FPGA Device Feature List (DFL) drivers.
>
> Signed-off-by: Wu Hao 
Acked-by: Alan Tull 

> ---
>  MAINTAINERS | 8 
>  1 file changed, 8 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 448957c..98fc5ea 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -5619,6 +5619,14 @@ F:   drivers/fpga/
>  F: include/linux/fpga/
>  W: http://www.rocketboards.org
>
> +FPGA DFL DRIVERS
> +M: Wu Hao 
> +L: linux-f...@vger.kernel.org
> +S: Maintained
> +F: Documentation/fpga/dfl.txt
> +F: include/uapi/linux/fpga-dfl.h
> +F: drivers/fpga/dfl*
> +
>  FPU EMULATOR
>  M: Bill Metzenthen 
>  W: http://floatingpoint.sourceforge.net/emulator/index.html
> --
> 1.8.3.1
>


<    1   2   3   4   5   6   7   8   9   10   >