[RFC] fpga: Pull checks for supported operations into framework

atull atull at opensource.altera.com
Tue Nov 1 12:29:18 PDT 2016


On Mon, 31 Oct 2016, Moritz Fischer wrote:

> Found a couple of issues, will resubmit after cleaning up. Feel free to add
> general feedback on the idea anyways in the meantime. Sorry for double post.

Hi Moritz,

This looks good and useful to me.  One comment below.

> 
> On Sun, Oct 30, 2016 at 11:12 AM, Moritz Fischer
> <moritz.fischer at ettus.com> wrote:
> > Most of the drivers only support a subset of {PARTIAL, FULL}
> > reconfiguration.
> > Pull duplicate checks in each driver into the framework.
> >
> > Signed-off-by: Moritz Fischer <moritz.fischer at ettus.com>
> > Cc: Alan Tull <atull at opensource.altera.com>
> > Cc: Michal Simek <michal.simek at xilinx.com>
> > Cc: Sören Brinkmann <soren.brinkmann at xilinx.com>
> > Cc: linux-kernel at vger.kernel.org
> > Cc: linux-arm-kernel at lists.infradead.org
> > ---
> > Hi all,
> >
> > with the new drivers (ice40, altera-ps-spi) being submitted I've noticed
> > we're duplicating this check over and over again,
> > so I figured we might as well pull it into the framework.
> >
> > I'm not sure if there are gonna be other 'flags' we need to support
> > in the short term (we talked about byte-swapping ...)
> >
> > Note: This patch goes on top of greg's char-misc-testing  that already
> > contains Alan's latest changes to support the A10 and won't apply
> > to master.
> >
> > Cheers,
> >
> > Moritz
> >
> > ---
> >  drivers/fpga/fpga-mgr.c       | 12 ++++++++++++
> >  drivers/fpga/socfpga-a10.c    |  4 +++-
> >  drivers/fpga/socfpga.c        |  3 ++-
> >  drivers/fpga/zynq-fpga.c      |  3 ++-
> >  include/linux/fpga/fpga-mgr.h |  9 +++++++--
> >  5 files changed, 26 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
> > index c58b4c4..85f17d8 100644
> > --- a/drivers/fpga/fpga-mgr.c
> > +++ b/drivers/fpga/fpga-mgr.c
> > @@ -49,6 +49,11 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info,
> >         struct device *dev = &mgr->dev;
> >         int ret;
> >
> > +       if (!(mgr->supported_flags & info->flags)) {
> > +               dev_err(dev, "Unsupported flags passed\n");
> > +               return -ENOTSUPP;
> > +       }
> 
> That condition is obviously garbage ...
> > +
> >         /*
> >          * Call the low level driver's write_init function.  This will do the
> >          * device-specific things to get the FPGA into the state where it is
> > @@ -252,6 +257,7 @@ EXPORT_SYMBOL_GPL(fpga_mgr_put);
> >   */
> >  int fpga_mgr_register(struct device *dev, const char *name,
> >                       const struct fpga_manager_ops *mops,
> > +                     u32 supported_flags,
> >                       void *priv)
> >  {
> >         struct fpga_manager *mgr;
> > @@ -268,6 +274,11 @@ int fpga_mgr_register(struct device *dev, const char *name,
> >                 return -EINVAL;
> >         }
> >
> > +       if (!supported_flags) {
> > +               dev_err(dev, "Attempt to register with no supported flags\n");
> > +               return -EINVAL;
> > +       }
> > +
> >         mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
> >         if (!mgr)
> >                 return -ENOMEM;
> > @@ -282,6 +293,7 @@ int fpga_mgr_register(struct device *dev, const char *name,
> >
> >         mgr->name = name;
> >         mgr->mops = mops;
> > +       mgr->supported_flags = supported_flags;
> >         mgr->priv = priv;
> >
> >         /*
> > diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c
> > index ccd9fb2..e7c82ff 100644
> > --- a/drivers/fpga/socfpga-a10.c
> > +++ b/drivers/fpga/socfpga-a10.c
> > @@ -519,7 +519,9 @@ static int socfpga_a10_fpga_probe(struct platform_device *pdev)
> >         }
> >
> >         return fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager",
> > -                                &socfpga_a10_fpga_mgr_ops, priv);
> > +                                &socfpga_a10_fpga_mgr_ops,
> > +                                FPGA_MGR_PARTIAL_RECONFIG,
> > +                                priv);
> >  }
> >
> >  static int socfpga_a10_fpga_remove(struct platform_device *pdev)
> > diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c
> > index b6672e6..3285b7d 100644
> > --- a/drivers/fpga/socfpga.c
> > +++ b/drivers/fpga/socfpga.c
> > @@ -582,7 +582,8 @@ static int socfpga_fpga_probe(struct platform_device *pdev)
> >                 return ret;
> >
> >         return fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager",
> > -                                &socfpga_fpga_ops, priv);
> > +                                &socfpga_fpga_ops, FPGA_MGR_FULL_RECONFIG,
> > +                                priv);
> >  }
> >
> >  static int socfpga_fpga_remove(struct platform_device *pdev)
> > diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c
> > index 249682e..1dabd25 100644
> > --- a/drivers/fpga/zynq-fpga.c
> > +++ b/drivers/fpga/zynq-fpga.c
> > @@ -413,6 +413,7 @@ static int zynq_fpga_probe(struct platform_device *pdev)
> >         struct zynq_fpga_priv *priv;
> >         struct resource *res;
> >         int err;
> > +       u32 flags = FPGA_MGR_FULL_RECONFIG | FPGA_MGR_PARTIAL_RECONFIG;
> >
> >         priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> >         if (!priv)
> > @@ -465,7 +466,7 @@ static int zynq_fpga_probe(struct platform_device *pdev)
> >         clk_disable(priv->clk);
> >
> >         err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager",
> > -                               &zynq_fpga_ops, priv);
> > +                               &zynq_fpga_ops, flags, priv);
> >         if (err) {
> >                 dev_err(dev, "unable to register FPGA manager");
> >                 clk_unprepare(priv->clk);
> > diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
> > index 040b86d..4f4bcf2 100644
> > --- a/include/linux/fpga/fpga-mgr.h
> > +++ b/include/linux/fpga/fpga-mgr.h
> > @@ -64,9 +64,12 @@ enum fpga_mgr_states {
> >
> >  /*
> >   * FPGA Manager flags
> > + * FPGA_MGR_FULL_RECONFIG: do full reconfiguration if supported
> >   * FPGA_MGR_PARTIAL_RECONFIG: do partial reconfiguration if supported
> >   */
> > -#define FPGA_MGR_PARTIAL_RECONFIG      BIT(0)
> > +#define FPGA_MGR_FULL_RECONFIG         BIT(0)
> > +#define FPGA_MGR_PARTIAL_RECONFIG      BIT(1)
> > +#define FPGA_MGR_EXTERNAL_CONFIG       BIT(2)
> 
> On second thought the FULL_RECONFIG is the same as !PARTIAL_RECONFIG,
> so useless ..

That looks good and doesn't seem useless to me.  A driver may
support PR, FR, or both.  It's nice and clear what
FPGA_MGR_PARTIAL_RECONFIG|FPGA_MGR_FULL_RECONFIG means when
a driver supports both.

> 
> >
> >  /**
> >   * struct fpga_image_info - information specific to a FPGA image
> > @@ -119,6 +122,7 @@ struct fpga_manager {
> >         enum fpga_mgr_states state;
> >         const struct fpga_manager_ops *mops;
> >         void *priv;
> > +       u32 supported_flags;
> >  };
> >
> >  #define to_fpga_manager(d) container_of(d, struct fpga_manager, dev)
> > @@ -135,7 +139,8 @@ struct fpga_manager *of_fpga_mgr_get(struct device_node *node);
> >  void fpga_mgr_put(struct fpga_manager *mgr);
> >
> >  int fpga_mgr_register(struct device *dev, const char *name,
> > -                     const struct fpga_manager_ops *mops, void *priv);
> > +                     const struct fpga_manager_ops *mops, u32 supported_flags,
> > +                     void *priv);
> >
> >  void fpga_mgr_unregister(struct device *dev);
> >
> > --
> > 2.4.11
> >
> 
> Cheers,
> 
> Moritz
> 


More information about the linux-arm-kernel mailing list