diff options
Diffstat (limited to 'drivers/net/phy/mdio_bus.c')
-rw-r--r-- | drivers/net/phy/mdio_bus.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 76f54b32a120..2e58aa54484c 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c | |||
@@ -69,6 +69,73 @@ struct mii_bus *mdiobus_alloc_size(size_t size) | |||
69 | } | 69 | } |
70 | EXPORT_SYMBOL(mdiobus_alloc_size); | 70 | EXPORT_SYMBOL(mdiobus_alloc_size); |
71 | 71 | ||
72 | static void _devm_mdiobus_free(struct device *dev, void *res) | ||
73 | { | ||
74 | mdiobus_free(*(struct mii_bus **)res); | ||
75 | } | ||
76 | |||
77 | static int devm_mdiobus_match(struct device *dev, void *res, void *data) | ||
78 | { | ||
79 | struct mii_bus **r = res; | ||
80 | |||
81 | if (WARN_ON(!r || !*r)) | ||
82 | return 0; | ||
83 | |||
84 | return *r == data; | ||
85 | } | ||
86 | |||
87 | /** | ||
88 | * devm_mdiobus_alloc_size - Resource-managed mdiobus_alloc_size() | ||
89 | * @dev: Device to allocate mii_bus for | ||
90 | * @sizeof_priv: Space to allocate for private structure. | ||
91 | * | ||
92 | * Managed mdiobus_alloc_size. mii_bus allocated with this function is | ||
93 | * automatically freed on driver detach. | ||
94 | * | ||
95 | * If an mii_bus allocated with this function needs to be freed separately, | ||
96 | * devm_mdiobus_free() must be used. | ||
97 | * | ||
98 | * RETURNS: | ||
99 | * Pointer to allocated mii_bus on success, NULL on failure. | ||
100 | */ | ||
101 | struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv) | ||
102 | { | ||
103 | struct mii_bus **ptr, *bus; | ||
104 | |||
105 | ptr = devres_alloc(_devm_mdiobus_free, sizeof(*ptr), GFP_KERNEL); | ||
106 | if (!ptr) | ||
107 | return NULL; | ||
108 | |||
109 | /* use raw alloc_dr for kmalloc caller tracing */ | ||
110 | bus = mdiobus_alloc_size(sizeof_priv); | ||
111 | if (bus) { | ||
112 | *ptr = bus; | ||
113 | devres_add(dev, ptr); | ||
114 | } else { | ||
115 | devres_free(ptr); | ||
116 | } | ||
117 | |||
118 | return bus; | ||
119 | } | ||
120 | EXPORT_SYMBOL_GPL(devm_mdiobus_alloc_size); | ||
121 | |||
122 | /** | ||
123 | * devm_mdiobus_free - Resource-managed mdiobus_free() | ||
124 | * @dev: Device this mii_bus belongs to | ||
125 | * @bus: the mii_bus associated with the device | ||
126 | * | ||
127 | * Free mii_bus allocated with devm_mdiobus_alloc_size(). | ||
128 | */ | ||
129 | void devm_mdiobus_free(struct device *dev, struct mii_bus *bus) | ||
130 | { | ||
131 | int rc; | ||
132 | |||
133 | rc = devres_release(dev, _devm_mdiobus_free, | ||
134 | devm_mdiobus_match, bus); | ||
135 | WARN_ON(rc); | ||
136 | } | ||
137 | EXPORT_SYMBOL_GPL(devm_mdiobus_free); | ||
138 | |||
72 | /** | 139 | /** |
73 | * mdiobus_release - mii_bus device release callback | 140 | * mdiobus_release - mii_bus device release callback |
74 | * @d: the target struct device that contains the mii_bus | 141 | * @d: the target struct device that contains the mii_bus |
@@ -233,6 +300,12 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) | |||
233 | if (IS_ERR(phydev) || phydev == NULL) | 300 | if (IS_ERR(phydev) || phydev == NULL) |
234 | return phydev; | 301 | return phydev; |
235 | 302 | ||
303 | /* | ||
304 | * For DT, see if the auto-probed phy has a correspoding child | ||
305 | * in the bus node, and set the of_node pointer in this case. | ||
306 | */ | ||
307 | of_mdiobus_link_phydev(bus, phydev); | ||
308 | |||
236 | err = phy_device_register(phydev); | 309 | err = phy_device_register(phydev); |
237 | if (err) { | 310 | if (err) { |
238 | phy_device_free(phydev); | 311 | phy_device_free(phydev); |