> -----Original Message----- > From: Stuart Yoder > Sent: Thursday, November 03, 2016 4:38 PM > To: Ruxandra Ioana Radulescu <ruxandra.radulescu@xxxxxxx> > Subject: FW: [PATCH 8/9] bus: fsl-mc: dpio: add the DPAA2 DPIO object > driver > > > > -----Original Message----- > From: Stuart Yoder [mailto:stuart.yoder@xxxxxxx] > Sent: Friday, October 21, 2016 9:02 AM > To: gregkh@xxxxxxxxxxxxxxxxxxx > Cc: German Rivera <german.rivera@xxxxxxx>; devel@xxxxxxxxxxxxxxxxxxxx; > linux-kernel@xxxxxxxxxxxxxxx; agraf@xxxxxxx; arnd@xxxxxxxx; Leo Li > <leoyang.li@xxxxxxx>; Roy Pledge <roy.pledge@xxxxxxx>; Haiying Wang > <haiying.wang@xxxxxxx>; Stuart Yoder <stuart.yoder@xxxxxxx> > Subject: [PATCH 8/9] bus: fsl-mc: dpio: add the DPAA2 DPIO object driver > > From: Roy Pledge <roy.pledge@xxxxxxx> > > The DPIO driver registers with the fsl-mc bus to handle bus-related > events for DPIO objects. Key responsibility is mapping I/O > regions, setting up interrupt handlers, and calling the DPIO > service initialization during probe. > > Signed-off-by: Roy Pledge <roy.pledge@xxxxxxx> > Signed-off-by: Haiying Wang <haiying.wang@xxxxxxx> > Signed-off-by: Stuart Yoder <stuart.yoder@xxxxxxx> > --- > drivers/bus/fsl-mc/dpio/Makefile | 2 +- > drivers/bus/fsl-mc/dpio/dpio-driver.c | 289 > ++++++++++++++++++++++++++++++++++ > 2 files changed, 290 insertions(+), 1 deletion(-) > create mode 100644 drivers/bus/fsl-mc/dpio/dpio-driver.c > > diff --git a/drivers/bus/fsl-mc/dpio/Makefile b/drivers/bus/fsl- > mc/dpio/Makefile > index 0778da7..837d330 100644 > --- a/drivers/bus/fsl-mc/dpio/Makefile > +++ b/drivers/bus/fsl-mc/dpio/Makefile > @@ -6,4 +6,4 @@ subdir-ccflags-y := -Werror > > obj-$(CONFIG_FSL_MC_DPIO) += fsl-mc-dpio.o > > -fsl-mc-dpio-objs := dpio.o qbman-portal.o dpio-service.o > +fsl-mc-dpio-objs := dpio.o qbman-portal.o dpio-service.o dpio-driver.o > diff --git a/drivers/bus/fsl-mc/dpio/dpio-driver.c b/drivers/bus/fsl- > mc/dpio/dpio-driver.c > new file mode 100644 > index 0000000..ad04a2c > --- /dev/null > +++ b/drivers/bus/fsl-mc/dpio/dpio-driver.c > @@ -0,0 +1,289 @@ > +/* > + * Copyright 2014-2016 Freescale Semiconductor Inc. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * * Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * * Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the > distribution. > + * * Neither the name of Freescale Semiconductor nor the > + * names of its contributors may be used to endorse or promote > products > + * derived from this software without specific prior written permission. > + * > + * ALTERNATIVELY, this software may be distributed under the terms of the > + * GNU General Public License ("GPL") as published by the Free Software > + * Foundation, either version 2 of that License or (at your option) any > + * later version. > + * > + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND > ANY > + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, > THE IMPLIED > + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > PURPOSE ARE > + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR > ANY > + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > CONSEQUENTIAL DAMAGES > + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE > GOODS OR SERVICES; > + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > HOWEVER CAUSED AND > + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, > OR TORT > + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF > THE USE OF THIS > + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include <linux/types.h> > +#include <linux/init.h> > +#include <linux/module.h> > +#include <linux/platform_device.h> > +#include <linux/interrupt.h> > +#include <linux/msi.h> > +#include <linux/dma-mapping.h> > +#include <linux/delay.h> > + > +#include <linux/fsl/mc.h> > +#include <linux/fsl/dpaa2-io.h> > + > +#include "qbman-portal.h" > +#include "dpio.h" > +#include "dpio-cmd.h" > + > +MODULE_LICENSE("Dual BSD/GPL"); > +MODULE_AUTHOR("Freescale Semiconductor, Inc"); > +MODULE_DESCRIPTION("DPIO Driver"); > + > +struct dpio_priv { > + struct dpaa2_io *io; > +}; > + > +static irqreturn_t dpio_irq_handler(int irq_num, void *arg) > +{ > + struct device *dev = (struct device *)arg; > + struct dpio_priv *priv = dev_get_drvdata(dev); > + > + return dpaa2_io_irq(priv->io); > +} > + > +static void unregister_dpio_irq_handlers(struct fsl_mc_device *dpio_dev) > +{ > + struct fsl_mc_device_irq *irq; > + > + irq = dpio_dev->irqs[0]; > + > + /* clear the affinity hint */ > + irq_set_affinity_hint(irq->msi_desc->irq, NULL); > +} > + > +static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int > cpu) > +{ > + struct dpio_priv *priv; > + int error; > + struct fsl_mc_device_irq *irq; > + cpumask_t mask; > + > + priv = dev_get_drvdata(&dpio_dev->dev); > + > + irq = dpio_dev->irqs[0]; > + error = devm_request_irq(&dpio_dev->dev, > + irq->msi_desc->irq, > + dpio_irq_handler, > + 0, > + dev_name(&dpio_dev->dev), > + &dpio_dev->dev); > + if (error < 0) { > + dev_err(&dpio_dev->dev, > + "devm_request_irq() failed: %d\n", > + error); > + return error; > + } > + > + /* set the affinity hint */ > + cpumask_clear(&mask); > + cpumask_set_cpu(cpu, &mask); > + if (irq_set_affinity_hint(irq->msi_desc->irq, &mask)) > + dev_err(&dpio_dev->dev, > + "irq_set_affinity failed irq %d cpu %d\n", > + irq->msi_desc->irq, cpu); > + > + return 0; > +} > + > +static int dpaa2_dpio_probe(struct fsl_mc_device *dpio_dev) > +{ > + struct dpio_attr dpio_attrs; > + struct dpaa2_io_desc desc; > + struct dpio_priv *priv; > + int err = -ENOMEM; > + struct device *dev = &dpio_dev->dev; > + static int next_cpu = -1; > + > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + goto err_priv_alloc; > + > + dev_set_drvdata(dev, priv); > + > + err = fsl_mc_portal_allocate(dpio_dev, 0, &dpio_dev->mc_io); > + if (err) { > + dev_dbg(dev, "MC portal allocation failed\n"); > + err = -EPROBE_DEFER; > + goto err_mcportal; > + } > + > + err = dpio_open(dpio_dev->mc_io, 0, dpio_dev->obj_desc.id, > + &dpio_dev->mc_handle); > + if (err) { > + dev_err(dev, "dpio_open() failed\n"); > + goto err_open; > + } > + > + err = dpio_get_attributes(dpio_dev->mc_io, 0, dpio_dev- > >mc_handle, > + &dpio_attrs); > + if (err) { > + dev_err(dev, "dpio_get_attributes() failed %d\n", err); > + goto err_get_attr; > + } > + desc.qman_version = dpio_attrs.qbman_version; > + > + err = dpio_enable(dpio_dev->mc_io, 0, dpio_dev->mc_handle); > + if (err) { > + dev_err(dev, "dpio_enable() failed %d\n", err); > + goto err_get_attr; > + } > + > + /* initialize DPIO descriptor */ > + desc.receives_notifications = dpio_attrs.num_priorities ? 1 : 0; > + desc.has_8prio = dpio_attrs.num_priorities == 8 ? 1 : 0; > + desc.dpio_id = dpio_dev->obj_desc.id; > + > + /* get the cpu to use for the affinity hint */ > + if (next_cpu == -1) > + next_cpu = cpumask_first(cpu_online_mask); > + else > + next_cpu = cpumask_next(next_cpu, cpu_online_mask); > + desc.cpu = next_cpu; What happens if there's more DPIOs than cores and cpumask_next returns nr_cpu_ids? Thanks, Ioana _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel