aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/fixed_phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy/fixed_phy.c')
-rw-r--r--drivers/net/phy/fixed_phy.c22
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}
190EXPORT_SYMBOL_GPL(fixed_phy_add); 191EXPORT_SYMBOL_GPL(fixed_phy_add);
191 192
193static DEFINE_IDA(phy_fixed_ida);
194
192static void fixed_phy_del(int phy_addr) 195static 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
208static int phy_fixed_addr;
209static DEFINE_SPINLOCK(phy_fixed_addr_lock);
210
211struct phy_device *fixed_phy_register(unsigned int irq, 212struct 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}
341module_exit(fixed_mdio_bus_exit); 341module_exit(fixed_mdio_bus_exit);
342 342