staging: fsl-mc: Bind/unbind driver when MC object is plugged/unplugged
authorJ. German Rivera <German.Rivera@freescale.com>
Fri, 27 Mar 2015 21:01:06 +0000 (16:01 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 3 Apr 2015 11:55:03 +0000 (13:55 +0200)
Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/fsl-mc/bus/dprc-driver.c

index f02e5e4d23a5d88a8c41b07adc7231d423ce1cfb..9568eeac75b0654735bcd6aba0039c3f147bdf30 100644 (file)
@@ -111,6 +111,41 @@ static struct fsl_mc_device *fsl_mc_device_lookup(struct dprc_obj_desc
        return dev ? to_fsl_mc_device(dev) : NULL;
 }
 
+/**
+ * check_plugged_state_change - Check change in an MC object's plugged state
+ *
+ * @mc_dev: pointer to the fsl-mc device for a given MC object
+ * @obj_desc: pointer to the MC object's descriptor in the MC
+ *
+ * If the plugged state has changed from unplugged to plugged, the fsl-mc
+ * device is bound to the corresponding device driver.
+ * If the plugged state has changed from plugged to unplugged, the fsl-mc
+ * device is unbound from the corresponding device driver.
+ */
+static void check_plugged_state_change(struct fsl_mc_device *mc_dev,
+                                      struct dprc_obj_desc *obj_desc)
+{
+       int error;
+       uint32_t plugged_flag_at_mc =
+                       (obj_desc->state & DPRC_OBJ_STATE_PLUGGED);
+
+       if (plugged_flag_at_mc !=
+           (mc_dev->obj_desc.state & DPRC_OBJ_STATE_PLUGGED)) {
+               if (plugged_flag_at_mc) {
+                       mc_dev->obj_desc.state |= DPRC_OBJ_STATE_PLUGGED;
+                       error = device_attach(&mc_dev->dev);
+                       if (error < 0) {
+                               dev_err(&mc_dev->dev,
+                                       "device_attach() failed: %d\n",
+                                       error);
+                       }
+               } else {
+                       mc_dev->obj_desc.state &= ~DPRC_OBJ_STATE_PLUGGED;
+                       device_release_driver(&mc_dev->dev);
+               }
+       }
+}
+
 /**
  * dprc_add_new_devices - Adds devices to the logical bus for a DPRC
  *
@@ -142,8 +177,10 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
                 * Check if device is already known to Linux:
                 */
                child_dev = fsl_mc_device_lookup(obj_desc, mc_bus_dev);
-               if (child_dev)
+               if (child_dev) {
+                       check_plugged_state_change(child_dev, obj_desc);
                        continue;
+               }
 
                error = fsl_mc_device_add(obj_desc, mc_io, &mc_bus_dev->dev,
                                          &child_dev);