OSDN Git Service

bus: fsl-mc: probe the allocatable objects first
authorGrigore Popescu <grigore.popescu@nxp.com>
Fri, 17 Jul 2020 15:48:00 +0000 (18:48 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Jul 2020 14:54:33 +0000 (16:54 +0200)
Because the DPNIs are probed before DPMCPs and other objects that need
to be allocated, messages like "No more resources of type X left" are
printed by the fsl-mc bus driver. This patch resolves the issue by probing
the allocatable objects first and then any other object that may use
them.

Signed-off-by: Grigore Popescu <grigore.popescu@nxp.com>
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Reviewed-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
Link: https://lore.kernel.org/r/20200717154800.17169-4-ioana.ciornei@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/bus/fsl-mc/dprc-driver.c

index c8b1c38..3512d1b 100644 (file)
@@ -27,7 +27,16 @@ static bool fsl_mc_device_match(struct fsl_mc_device *mc_dev,
 {
        return mc_dev->obj_desc.id == obj_desc->id &&
               strcmp(mc_dev->obj_desc.type, obj_desc->type) == 0;
+}
 
+static bool fsl_mc_obj_desc_is_allocatable(struct fsl_mc_obj_desc *obj)
+{
+       if (strcmp(obj->type, "dpmcp") == 0 ||
+           strcmp(obj->type, "dpcon") == 0 ||
+           strcmp(obj->type, "dpbp") == 0)
+               return true;
+       else
+               return false;
 }
 
 static int __fsl_mc_device_remove_if_not_in_mc(struct device *dev, void *data)
@@ -150,6 +159,27 @@ static void check_plugged_state_change(struct fsl_mc_device *mc_dev,
        }
 }
 
+static void fsl_mc_obj_device_add(struct fsl_mc_device *mc_bus_dev,
+                                 struct fsl_mc_obj_desc *obj_desc)
+{
+       int error;
+       struct fsl_mc_device *child_dev;
+
+       /*
+        * Check if device is already known to Linux:
+        */
+       child_dev = fsl_mc_device_lookup(obj_desc, mc_bus_dev);
+       if (child_dev) {
+               check_plugged_state_change(child_dev, obj_desc);
+               put_device(&child_dev->dev);
+       } else {
+               error = fsl_mc_device_add(obj_desc, NULL, &mc_bus_dev->dev,
+                                         &child_dev);
+               if (error < 0)
+                       return;
+       }
+}
+
 /**
  * dprc_add_new_devices - Adds devices to the logical bus for a DPRC
  *
@@ -166,30 +196,23 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
                                 struct fsl_mc_obj_desc *obj_desc_array,
                                 int num_child_objects_in_mc)
 {
-       int error;
        int i;
 
+       /* probe the allocable objects first */
        for (i = 0; i < num_child_objects_in_mc; i++) {
-               struct fsl_mc_device *child_dev;
                struct fsl_mc_obj_desc *obj_desc = &obj_desc_array[i];
 
-               if (strlen(obj_desc->type) == 0)
-                       continue;
+               if (strlen(obj_desc->type) > 0 &&
+                   fsl_mc_obj_desc_is_allocatable(obj_desc))
+                       fsl_mc_obj_device_add(mc_bus_dev, obj_desc);
+       }
 
-               /*
-                * Check if device is already known to Linux:
-                */
-               child_dev = fsl_mc_device_lookup(obj_desc, mc_bus_dev);
-               if (child_dev) {
-                       check_plugged_state_change(child_dev, obj_desc);
-                       put_device(&child_dev->dev);
-                       continue;
-               }
+       for (i = 0; i < num_child_objects_in_mc; i++) {
+               struct fsl_mc_obj_desc *obj_desc = &obj_desc_array[i];
 
-               error = fsl_mc_device_add(obj_desc, NULL, &mc_bus_dev->dev,
-                                         &child_dev);
-               if (error < 0)
-                       continue;
+               if (strlen(obj_desc->type) > 0 &&
+                   !fsl_mc_obj_desc_is_allocatable(obj_desc))
+                       fsl_mc_obj_device_add(mc_bus_dev, obj_desc);
        }
 }