diff options
author | Ioana Ciornei <ioana.ciornei@nxp.com> | 2018-12-10 19:50:19 +0300 |
---|---|---|
committer | Li Yang <leoyang.li@nxp.com> | 2019-01-12 00:06:54 +0300 |
commit | 47441f7f73b7cf0c2d6e7d6372f026ea81193fd6 (patch) | |
tree | 0ef3b36a3a9afbf4dfa824b08b25bb95cd84fab8 /drivers/soc/fsl/dpio | |
parent | cf9ff75d15a9bbd625519997c2ca864d1fa80227 (diff) | |
download | linux-47441f7f73b7cf0c2d6e7d6372f026ea81193fd6.tar.xz |
soc: fsl: dpio: add a device_link at dpaa2_io_service_register
Automatically add a device link between the actual device requesting the
dpaa2_io_service_register and the underlying dpaa2_io used. This link
will ensure that when a DPIO device, which is indirectly used by other
devices, is unbound any consumer devices will be also unbound from their
drivers.
For example, any DPNI, bound to the dpaa2-eth driver, which is using
DPIO devices will be unbound before its supplier device.
Also, add a new parameter to the dpaa2_io_service_[de]register functions
to specify the requesting device (ie the consumer).
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Reviewed-by: Horia Geanta <horia.geanta@nxp.com>
Reviewed-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: Li Yang <leoyang.li@nxp.com>
Diffstat (limited to 'drivers/soc/fsl/dpio')
-rw-r--r-- | drivers/soc/fsl/dpio/dpio-service.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/soc/fsl/dpio/dpio-service.c b/drivers/soc/fsl/dpio/dpio-service.c index 52d800aa4774..bc801934602a 100644 --- a/drivers/soc/fsl/dpio/dpio-service.c +++ b/drivers/soc/fsl/dpio/dpio-service.c @@ -237,6 +237,7 @@ EXPORT_SYMBOL(dpaa2_io_get_cpu); * notifications on the given DPIO service. * @d: the given DPIO service. * @ctx: the notification context. + * @dev: the device that requests the register * * The caller should make the MC command to attach a DPAA2 object to * a DPIO after this function completes successfully. In that way: @@ -251,14 +252,20 @@ EXPORT_SYMBOL(dpaa2_io_get_cpu); * Return 0 for success, or -ENODEV for failure. */ int dpaa2_io_service_register(struct dpaa2_io *d, - struct dpaa2_io_notification_ctx *ctx) + struct dpaa2_io_notification_ctx *ctx, + struct device *dev) { + struct device_link *link; unsigned long irqflags; d = service_select_by_cpu(d, ctx->desired_cpu); if (!d) return -ENODEV; + link = device_link_add(dev, d->dev, DL_FLAG_AUTOREMOVE_CONSUMER); + if (!link) + return -EINVAL; + ctx->dpio_id = d->dpio_desc.dpio_id; ctx->qman64 = (u64)(uintptr_t)ctx; ctx->dpio_private = d; @@ -279,12 +286,14 @@ EXPORT_SYMBOL_GPL(dpaa2_io_service_register); * dpaa2_io_service_deregister - The opposite of 'register'. * @service: the given DPIO service. * @ctx: the notification context. + * @dev: the device that requests to be deregistered * * This function should be called only after sending the MC command to * to detach the notification-producing device from the DPIO. */ void dpaa2_io_service_deregister(struct dpaa2_io *service, - struct dpaa2_io_notification_ctx *ctx) + struct dpaa2_io_notification_ctx *ctx, + struct device *dev) { struct dpaa2_io *d = ctx->dpio_private; unsigned long irqflags; @@ -295,6 +304,9 @@ void dpaa2_io_service_deregister(struct dpaa2_io *service, spin_lock_irqsave(&d->lock_notifications, irqflags); list_del(&ctx->node); spin_unlock_irqrestore(&d->lock_notifications, irqflags); + + if (dev) + device_link_remove(dev, d->dev); } EXPORT_SYMBOL_GPL(dpaa2_io_service_deregister); |