summaryrefslogtreecommitdiff
path: root/drivers/soc/fsl/dpio
diff options
context:
space:
mode:
authorIoana Ciornei <ioana.ciornei@nxp.com>2018-12-10 19:50:19 +0300
committerLi Yang <leoyang.li@nxp.com>2019-01-12 00:06:54 +0300
commit47441f7f73b7cf0c2d6e7d6372f026ea81193fd6 (patch)
tree0ef3b36a3a9afbf4dfa824b08b25bb95cd84fab8 /drivers/soc/fsl/dpio
parentcf9ff75d15a9bbd625519997c2ca864d1fa80227 (diff)
downloadlinux-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.c16
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);