spin_unlock(&iort_fwnode_lock);
 }
 
+/**
+ * iort_get_iort_node() - Retrieve iort_node associated with an fwnode
+ *
+ * @fwnode: fwnode associated with device to be looked-up
+ *
+ * Returns: iort_node pointer on success, NULL on failure
+ */
+static inline struct acpi_iort_node *iort_get_iort_node(
+                       struct fwnode_handle *fwnode)
+{
+       struct iort_fwnode *curr;
+       struct acpi_iort_node *iort_node = NULL;
+
+       spin_lock(&iort_fwnode_lock);
+       list_for_each_entry(curr, &iort_fwnode_list, list) {
+               if (curr->fwnode == fwnode) {
+                       iort_node = curr->iort_node;
+                       break;
+               }
+       }
+       spin_unlock(&iort_fwnode_lock);
+
+       return iort_node;
+}
+
 typedef acpi_status (*iort_find_node_callback)
        (struct acpi_iort_node *node, void *context);
 
 {
        struct pci_bus *pbus;
 
-       if (!dev_is_pci(dev))
+       if (!dev_is_pci(dev)) {
+               struct acpi_iort_node *node;
+               /*
+                * scan iort_fwnode_list to see if it's an iort platform
+                * device (such as SMMU, PMCG),its iort node already cached
+                * and associated with fwnode when iort platform devices
+                * were initialized.
+                */
+               node = iort_get_iort_node(dev->fwnode);
+               if (node)
+                       return node;
+
+               /*
+                * if not, then it should be a platform device defined in
+                * DSDT/SSDT (with Named Component node in IORT)
+                */
                return iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
                                      iort_match_node_callback, dev);
+       }
 
        /* Find a PCI root bus */
        pbus = to_pci_dev(dev)->bus;