2525
2626MODULE_AUTHOR ("Grant Likely <grant.likely@secretlab.ca>" );
2727MODULE_LICENSE ("GPL" );
28+ MODULE_DESCRIPTION ("OpenFirmware MDIO bus (Ethernet PHY) accessors" );
2829
2930/* Extract the clause 22 phy ID from the compatible string of the form
3031 * ethernet-phy-idAAAA.BBBB */
@@ -131,13 +132,60 @@ bool of_mdiobus_child_is_phy(struct device_node *child)
131132 return true;
132133 }
133134
134- if (!of_find_property (child , "compatible" , NULL ))
135+ if (!of_property_present (child , "compatible" ))
135136 return true;
136137
137138 return false;
138139}
139140EXPORT_SYMBOL (of_mdiobus_child_is_phy );
140141
142+ static int __of_mdiobus_parse_phys (struct mii_bus * mdio , struct device_node * np ,
143+ bool * scanphys )
144+ {
145+ struct device_node * child ;
146+ int addr , rc = 0 ;
147+
148+ /* Loop over the child nodes and register a phy_device for each phy */
149+ for_each_available_child_of_node (np , child ) {
150+ if (of_node_name_eq (child , "ethernet-phy-package" )) {
151+ /* Ignore invalid ethernet-phy-package node */
152+ if (!of_property_present (child , "reg" ))
153+ continue ;
154+
155+ rc = __of_mdiobus_parse_phys (mdio , child , NULL );
156+ if (rc && rc != - ENODEV )
157+ goto exit ;
158+
159+ continue ;
160+ }
161+
162+ addr = of_mdio_parse_addr (& mdio -> dev , child );
163+ if (addr < 0 ) {
164+ /* Skip scanning for invalid ethernet-phy-package node */
165+ if (scanphys )
166+ * scanphys = true;
167+ continue ;
168+ }
169+
170+ if (of_mdiobus_child_is_phy (child ))
171+ rc = of_mdiobus_register_phy (mdio , child , addr );
172+ else
173+ rc = of_mdiobus_register_device (mdio , child , addr );
174+
175+ if (rc == - ENODEV )
176+ dev_err (& mdio -> dev ,
177+ "MDIO device at address %d is missing.\n" ,
178+ addr );
179+ else if (rc )
180+ goto exit ;
181+ }
182+
183+ return 0 ;
184+ exit :
185+ of_node_put (child );
186+ return rc ;
187+ }
188+
141189/**
142190 * __of_mdiobus_register - Register mii_bus and create PHYs from the device tree
143191 * @mdio: pointer to mii_bus structure
@@ -179,33 +227,18 @@ int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np,
179227 return rc ;
180228
181229 /* Loop over the child nodes and register a phy_device for each phy */
182- for_each_available_child_of_node (np , child ) {
183- addr = of_mdio_parse_addr (& mdio -> dev , child );
184- if (addr < 0 ) {
185- scanphys = true;
186- continue ;
187- }
188-
189- if (of_mdiobus_child_is_phy (child ))
190- rc = of_mdiobus_register_phy (mdio , child , addr );
191- else
192- rc = of_mdiobus_register_device (mdio , child , addr );
193-
194- if (rc == - ENODEV )
195- dev_err (& mdio -> dev ,
196- "MDIO device at address %d is missing.\n" ,
197- addr );
198- else if (rc )
199- goto unregister ;
200- }
230+ rc = __of_mdiobus_parse_phys (mdio , np , & scanphys );
231+ if (rc )
232+ goto unregister ;
201233
202234 if (!scanphys )
203235 return 0 ;
204236
205237 /* auto scan for PHYs with empty reg property */
206238 for_each_available_child_of_node (np , child ) {
207- /* Skip PHYs with reg property set */
208- if (of_find_property (child , "reg" , NULL ))
239+ /* Skip PHYs with reg property set or ethernet-phy-package node */
240+ if (of_property_present (child , "reg" ) ||
241+ of_node_name_eq (child , "ethernet-phy-package" ))
209242 continue ;
210243
211244 for (addr = 0 ; addr < PHY_MAX_ADDR ; addr ++ ) {
@@ -226,13 +259,15 @@ int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np,
226259 if (!rc )
227260 break ;
228261 if (rc != - ENODEV )
229- goto unregister ;
262+ goto put_unregister ;
230263 }
231264 }
232265 }
233266
234267 return 0 ;
235268
269+ put_unregister :
270+ of_node_put (child );
236271unregister :
237272 mdiobus_unregister (mdio );
238273 return rc ;
0 commit comments