diff options
Diffstat (limited to 'drivers/net/phy/fixed_phy.c')
-rw-r--r-- | drivers/net/phy/fixed_phy.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/net/phy/fixed_phy.c b/drivers/net/phy/fixed_phy.c index b376ada83598..c649c101bbab 100644 --- a/drivers/net/phy/fixed_phy.c +++ b/drivers/net/phy/fixed_phy.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/of.h> | 24 | #include <linux/of.h> |
25 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
26 | #include <linux/seqlock.h> | 26 | #include <linux/seqlock.h> |
27 | #include <linux/idr.h> | ||
27 | 28 | ||
28 | #include "swphy.h" | 29 | #include "swphy.h" |
29 | 30 | ||
@@ -189,6 +190,8 @@ err_regs: | |||
189 | } | 190 | } |
190 | EXPORT_SYMBOL_GPL(fixed_phy_add); | 191 | EXPORT_SYMBOL_GPL(fixed_phy_add); |
191 | 192 | ||
193 | static DEFINE_IDA(phy_fixed_ida); | ||
194 | |||
192 | static void fixed_phy_del(int phy_addr) | 195 | static void fixed_phy_del(int phy_addr) |
193 | { | 196 | { |
194 | struct fixed_mdio_bus *fmb = &platform_fmb; | 197 | struct fixed_mdio_bus *fmb = &platform_fmb; |
@@ -200,14 +203,12 @@ static void fixed_phy_del(int phy_addr) | |||
200 | if (gpio_is_valid(fp->link_gpio)) | 203 | if (gpio_is_valid(fp->link_gpio)) |
201 | gpio_free(fp->link_gpio); | 204 | gpio_free(fp->link_gpio); |
202 | kfree(fp); | 205 | kfree(fp); |
206 | ida_simple_remove(&phy_fixed_ida, phy_addr); | ||
203 | return; | 207 | return; |
204 | } | 208 | } |
205 | } | 209 | } |
206 | } | 210 | } |
207 | 211 | ||
208 | static int phy_fixed_addr; | ||
209 | static DEFINE_SPINLOCK(phy_fixed_addr_lock); | ||
210 | |||
211 | struct phy_device *fixed_phy_register(unsigned int irq, | 212 | struct phy_device *fixed_phy_register(unsigned int irq, |
212 | struct fixed_phy_status *status, | 213 | struct fixed_phy_status *status, |
213 | int link_gpio, | 214 | int link_gpio, |
@@ -222,17 +223,15 @@ struct phy_device *fixed_phy_register(unsigned int irq, | |||
222 | return ERR_PTR(-EPROBE_DEFER); | 223 | return ERR_PTR(-EPROBE_DEFER); |
223 | 224 | ||
224 | /* Get the next available PHY address, up to PHY_MAX_ADDR */ | 225 | /* Get the next available PHY address, up to PHY_MAX_ADDR */ |
225 | spin_lock(&phy_fixed_addr_lock); | 226 | phy_addr = ida_simple_get(&phy_fixed_ida, 0, PHY_MAX_ADDR, GFP_KERNEL); |
226 | if (phy_fixed_addr == PHY_MAX_ADDR) { | 227 | if (phy_addr < 0) |
227 | spin_unlock(&phy_fixed_addr_lock); | 228 | return ERR_PTR(phy_addr); |
228 | return ERR_PTR(-ENOSPC); | ||
229 | } | ||
230 | phy_addr = phy_fixed_addr++; | ||
231 | spin_unlock(&phy_fixed_addr_lock); | ||
232 | 229 | ||
233 | ret = fixed_phy_add(irq, phy_addr, status, link_gpio); | 230 | ret = fixed_phy_add(irq, phy_addr, status, link_gpio); |
234 | if (ret < 0) | 231 | if (ret < 0) { |
232 | ida_simple_remove(&phy_fixed_ida, phy_addr); | ||
235 | return ERR_PTR(ret); | 233 | return ERR_PTR(ret); |
234 | } | ||
236 | 235 | ||
237 | phy = get_phy_device(fmb->mii_bus, phy_addr, false); | 236 | phy = get_phy_device(fmb->mii_bus, phy_addr, false); |
238 | if (IS_ERR(phy)) { | 237 | if (IS_ERR(phy)) { |
@@ -337,6 +336,7 @@ static void __exit fixed_mdio_bus_exit(void) | |||
337 | list_del(&fp->node); | 336 | list_del(&fp->node); |
338 | kfree(fp); | 337 | kfree(fp); |
339 | } | 338 | } |
339 | ida_destroy(&phy_fixed_ida); | ||
340 | } | 340 | } |
341 | module_exit(fixed_mdio_bus_exit); | 341 | module_exit(fixed_mdio_bus_exit); |
342 | 342 | ||