99#include <linux/export.h>
1010#include <linux/kernel.h>
1111#include <linux/of.h>
12+ #include <linux/of_graph.h>
1213#include <linux/of_platform.h>
1314#include <linux/pci.h>
1415#include <linux/pci-pwrctrl.h>
@@ -138,6 +139,48 @@ int devm_pci_pwrctrl_device_set_ready(struct device *dev,
138139}
139140EXPORT_SYMBOL_GPL (devm_pci_pwrctrl_device_set_ready );
140141
142+ /*
143+ * Check whether the pwrctrl device really needs to be created or not. The
144+ * pwrctrl device will only be created if the node satisfies below requirements:
145+ *
146+ * 1. Presence of compatible property with "pci" prefix to match against the
147+ * pwrctrl driver (AND)
148+ * 2. At least one of the power supplies defined in the devicetree node of the
149+ * device (OR) in the remote endpoint parent node to indicate pwrctrl
150+ * requirement.
151+ */
152+ static bool pci_pwrctrl_is_required (struct device_node * np )
153+ {
154+ struct device_node * endpoint ;
155+ const char * compat ;
156+ int ret ;
157+
158+ ret = of_property_read_string (np , "compatible" , & compat );
159+ if (ret < 0 )
160+ return false;
161+
162+ if (!strstarts (compat , "pci" ))
163+ return false;
164+
165+ if (of_pci_supply_present (np ))
166+ return true;
167+
168+ if (of_graph_is_present (np )) {
169+ for_each_endpoint_of_node (np , endpoint ) {
170+ struct device_node * remote __free (device_node ) =
171+ of_graph_get_remote_port_parent (endpoint );
172+ if (remote ) {
173+ if (of_pci_supply_present (remote )) {
174+ of_node_put (endpoint );
175+ return true;
176+ }
177+ }
178+ }
179+ }
180+
181+ return false;
182+ }
183+
141184static int __pci_pwrctrl_power_off_device (struct device * dev )
142185{
143186 struct pci_pwrctrl * pwrctrl = dev_get_drvdata (dev );
@@ -156,6 +199,9 @@ static void pci_pwrctrl_power_off_device(struct device_node *np)
156199 for_each_available_child_of_node_scoped (np , child )
157200 pci_pwrctrl_power_off_device (child );
158201
202+ if (!pci_pwrctrl_is_required (np ))
203+ return ;
204+
159205 pdev = of_find_device_by_node (np );
160206 if (!pdev )
161207 return ;
@@ -212,6 +258,9 @@ static int pci_pwrctrl_power_on_device(struct device_node *np)
212258 return ret ;
213259 }
214260
261+ if (!pci_pwrctrl_is_required (np ))
262+ return 0 ;
263+
215264 pdev = of_find_device_by_node (np );
216265 if (!pdev )
217266 return 0 ;
0 commit comments