Commit 6539c44d08ac2eea693b6163135169b9c8c18bb1

Authored by David S. Miller
1 parent 772801ef75

net: Allow FIXED_PHY to be modular.

Otherwise we get things like:

warning: (NET_DSA_BCM_SF2 && BCMGENET && SYSTEMPORT) selects FIXED_PHY which has unmet direct dependencies (NETDEVICES && PHYLIB=y)

In order to make this work we have to rename fixed.c to fixed_phy.c
because the regulator drivers already have a module named "fixed.o".

Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 5 changed files with 341 additions and 341 deletions Side-by-side Diff

drivers/net/phy/Kconfig
... ... @@ -119,8 +119,8 @@
119 119 Supports the KSZ9021, VSC8201, KS8001 PHYs.
120 120  
121 121 config FIXED_PHY
122   - bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
123   - depends on PHYLIB=y
  122 + tristate "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
  123 + depends on PHYLIB
124 124 ---help---
125 125 Adds the platform "fixed" MDIO Bus to cover the boards that use
126 126 PHYs that are not connected to the real MDIO bus.
drivers/net/phy/Makefile
... ... @@ -17,7 +17,7 @@
17 17 obj-$(CONFIG_ICPLUS_PHY) += icplus.o
18 18 obj-$(CONFIG_REALTEK_PHY) += realtek.o
19 19 obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
20   -obj-$(CONFIG_FIXED_PHY) += fixed.o
  20 +obj-$(CONFIG_FIXED_PHY) += fixed_phy.o
21 21 obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o
22 22 obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o
23 23 obj-$(CONFIG_NATIONAL_PHY) += national.o
drivers/net/phy/fixed.c
1   -/*
2   - * Fixed MDIO bus (MDIO bus emulation with fixed PHYs)
3   - *
4   - * Author: Vitaly Bordug <vbordug@ru.mvista.com>
5   - * Anton Vorontsov <avorontsov@ru.mvista.com>
6   - *
7   - * Copyright (c) 2006-2007 MontaVista Software, Inc.
8   - *
9   - * This program is free software; you can redistribute it and/or modify it
10   - * under the terms of the GNU General Public License as published by the
11   - * Free Software Foundation; either version 2 of the License, or (at your
12   - * option) any later version.
13   - */
14   -
15   -#include <linux/kernel.h>
16   -#include <linux/module.h>
17   -#include <linux/platform_device.h>
18   -#include <linux/list.h>
19   -#include <linux/mii.h>
20   -#include <linux/phy.h>
21   -#include <linux/phy_fixed.h>
22   -#include <linux/err.h>
23   -#include <linux/slab.h>
24   -#include <linux/of.h>
25   -
26   -#define MII_REGS_NUM 29
27   -
28   -struct fixed_mdio_bus {
29   - int irqs[PHY_MAX_ADDR];
30   - struct mii_bus *mii_bus;
31   - struct list_head phys;
32   -};
33   -
34   -struct fixed_phy {
35   - int addr;
36   - u16 regs[MII_REGS_NUM];
37   - struct phy_device *phydev;
38   - struct fixed_phy_status status;
39   - int (*link_update)(struct net_device *, struct fixed_phy_status *);
40   - struct list_head node;
41   -};
42   -
43   -static struct platform_device *pdev;
44   -static struct fixed_mdio_bus platform_fmb = {
45   - .phys = LIST_HEAD_INIT(platform_fmb.phys),
46   -};
47   -
48   -static int fixed_phy_update_regs(struct fixed_phy *fp)
49   -{
50   - u16 bmsr = BMSR_ANEGCAPABLE;
51   - u16 bmcr = 0;
52   - u16 lpagb = 0;
53   - u16 lpa = 0;
54   -
55   - if (fp->status.duplex) {
56   - bmcr |= BMCR_FULLDPLX;
57   -
58   - switch (fp->status.speed) {
59   - case 1000:
60   - bmsr |= BMSR_ESTATEN;
61   - bmcr |= BMCR_SPEED1000;
62   - lpagb |= LPA_1000FULL;
63   - break;
64   - case 100:
65   - bmsr |= BMSR_100FULL;
66   - bmcr |= BMCR_SPEED100;
67   - lpa |= LPA_100FULL;
68   - break;
69   - case 10:
70   - bmsr |= BMSR_10FULL;
71   - lpa |= LPA_10FULL;
72   - break;
73   - default:
74   - pr_warn("fixed phy: unknown speed\n");
75   - return -EINVAL;
76   - }
77   - } else {
78   - switch (fp->status.speed) {
79   - case 1000:
80   - bmsr |= BMSR_ESTATEN;
81   - bmcr |= BMCR_SPEED1000;
82   - lpagb |= LPA_1000HALF;
83   - break;
84   - case 100:
85   - bmsr |= BMSR_100HALF;
86   - bmcr |= BMCR_SPEED100;
87   - lpa |= LPA_100HALF;
88   - break;
89   - case 10:
90   - bmsr |= BMSR_10HALF;
91   - lpa |= LPA_10HALF;
92   - break;
93   - default:
94   - pr_warn("fixed phy: unknown speed\n");
95   - return -EINVAL;
96   - }
97   - }
98   -
99   - if (fp->status.link)
100   - bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;
101   -
102   - if (fp->status.pause)
103   - lpa |= LPA_PAUSE_CAP;
104   -
105   - if (fp->status.asym_pause)
106   - lpa |= LPA_PAUSE_ASYM;
107   -
108   - fp->regs[MII_PHYSID1] = 0;
109   - fp->regs[MII_PHYSID2] = 0;
110   -
111   - fp->regs[MII_BMSR] = bmsr;
112   - fp->regs[MII_BMCR] = bmcr;
113   - fp->regs[MII_LPA] = lpa;
114   - fp->regs[MII_STAT1000] = lpagb;
115   -
116   - return 0;
117   -}
118   -
119   -static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
120   -{
121   - struct fixed_mdio_bus *fmb = bus->priv;
122   - struct fixed_phy *fp;
123   -
124   - if (reg_num >= MII_REGS_NUM)
125   - return -1;
126   -
127   - /* We do not support emulating Clause 45 over Clause 22 register reads
128   - * return an error instead of bogus data.
129   - */
130   - switch (reg_num) {
131   - case MII_MMD_CTRL:
132   - case MII_MMD_DATA:
133   - return -1;
134   - default:
135   - break;
136   - }
137   -
138   - list_for_each_entry(fp, &fmb->phys, node) {
139   - if (fp->addr == phy_addr) {
140   - /* Issue callback if user registered it. */
141   - if (fp->link_update) {
142   - fp->link_update(fp->phydev->attached_dev,
143   - &fp->status);
144   - fixed_phy_update_regs(fp);
145   - }
146   - return fp->regs[reg_num];
147   - }
148   - }
149   -
150   - return 0xFFFF;
151   -}
152   -
153   -static int fixed_mdio_write(struct mii_bus *bus, int phy_addr, int reg_num,
154   - u16 val)
155   -{
156   - return 0;
157   -}
158   -
159   -/*
160   - * If something weird is required to be done with link/speed,
161   - * network driver is able to assign a function to implement this.
162   - * May be useful for PHY's that need to be software-driven.
163   - */
164   -int fixed_phy_set_link_update(struct phy_device *phydev,
165   - int (*link_update)(struct net_device *,
166   - struct fixed_phy_status *))
167   -{
168   - struct fixed_mdio_bus *fmb = &platform_fmb;
169   - struct fixed_phy *fp;
170   -
171   - if (!link_update || !phydev || !phydev->bus)
172   - return -EINVAL;
173   -
174   - list_for_each_entry(fp, &fmb->phys, node) {
175   - if (fp->addr == phydev->addr) {
176   - fp->link_update = link_update;
177   - fp->phydev = phydev;
178   - return 0;
179   - }
180   - }
181   -
182   - return -ENOENT;
183   -}
184   -EXPORT_SYMBOL_GPL(fixed_phy_set_link_update);
185   -
186   -int fixed_phy_add(unsigned int irq, int phy_addr,
187   - struct fixed_phy_status *status)
188   -{
189   - int ret;
190   - struct fixed_mdio_bus *fmb = &platform_fmb;
191   - struct fixed_phy *fp;
192   -
193   - fp = kzalloc(sizeof(*fp), GFP_KERNEL);
194   - if (!fp)
195   - return -ENOMEM;
196   -
197   - memset(fp->regs, 0xFF, sizeof(fp->regs[0]) * MII_REGS_NUM);
198   -
199   - fmb->irqs[phy_addr] = irq;
200   -
201   - fp->addr = phy_addr;
202   - fp->status = *status;
203   -
204   - ret = fixed_phy_update_regs(fp);
205   - if (ret)
206   - goto err_regs;
207   -
208   - list_add_tail(&fp->node, &fmb->phys);
209   -
210   - return 0;
211   -
212   -err_regs:
213   - kfree(fp);
214   - return ret;
215   -}
216   -EXPORT_SYMBOL_GPL(fixed_phy_add);
217   -
218   -void fixed_phy_del(int phy_addr)
219   -{
220   - struct fixed_mdio_bus *fmb = &platform_fmb;
221   - struct fixed_phy *fp, *tmp;
222   -
223   - list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
224   - if (fp->addr == phy_addr) {
225   - list_del(&fp->node);
226   - kfree(fp);
227   - return;
228   - }
229   - }
230   -}
231   -EXPORT_SYMBOL_GPL(fixed_phy_del);
232   -
233   -static int phy_fixed_addr;
234   -static DEFINE_SPINLOCK(phy_fixed_addr_lock);
235   -
236   -struct phy_device *fixed_phy_register(unsigned int irq,
237   - struct fixed_phy_status *status,
238   - struct device_node *np)
239   -{
240   - struct fixed_mdio_bus *fmb = &platform_fmb;
241   - struct phy_device *phy;
242   - int phy_addr;
243   - int ret;
244   -
245   - /* Get the next available PHY address, up to PHY_MAX_ADDR */
246   - spin_lock(&phy_fixed_addr_lock);
247   - if (phy_fixed_addr == PHY_MAX_ADDR) {
248   - spin_unlock(&phy_fixed_addr_lock);
249   - return ERR_PTR(-ENOSPC);
250   - }
251   - phy_addr = phy_fixed_addr++;
252   - spin_unlock(&phy_fixed_addr_lock);
253   -
254   - ret = fixed_phy_add(PHY_POLL, phy_addr, status);
255   - if (ret < 0)
256   - return ERR_PTR(ret);
257   -
258   - phy = get_phy_device(fmb->mii_bus, phy_addr, false);
259   - if (!phy || IS_ERR(phy)) {
260   - fixed_phy_del(phy_addr);
261   - return ERR_PTR(-EINVAL);
262   - }
263   -
264   - of_node_get(np);
265   - phy->dev.of_node = np;
266   -
267   - ret = phy_device_register(phy);
268   - if (ret) {
269   - phy_device_free(phy);
270   - of_node_put(np);
271   - fixed_phy_del(phy_addr);
272   - return ERR_PTR(ret);
273   - }
274   -
275   - return phy;
276   -}
277   -EXPORT_SYMBOL_GPL(fixed_phy_register);
278   -
279   -static int __init fixed_mdio_bus_init(void)
280   -{
281   - struct fixed_mdio_bus *fmb = &platform_fmb;
282   - int ret;
283   -
284   - pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
285   - if (IS_ERR(pdev)) {
286   - ret = PTR_ERR(pdev);
287   - goto err_pdev;
288   - }
289   -
290   - fmb->mii_bus = mdiobus_alloc();
291   - if (fmb->mii_bus == NULL) {
292   - ret = -ENOMEM;
293   - goto err_mdiobus_reg;
294   - }
295   -
296   - snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "fixed-0");
297   - fmb->mii_bus->name = "Fixed MDIO Bus";
298   - fmb->mii_bus->priv = fmb;
299   - fmb->mii_bus->parent = &pdev->dev;
300   - fmb->mii_bus->read = &fixed_mdio_read;
301   - fmb->mii_bus->write = &fixed_mdio_write;
302   - fmb->mii_bus->irq = fmb->irqs;
303   -
304   - ret = mdiobus_register(fmb->mii_bus);
305   - if (ret)
306   - goto err_mdiobus_alloc;
307   -
308   - return 0;
309   -
310   -err_mdiobus_alloc:
311   - mdiobus_free(fmb->mii_bus);
312   -err_mdiobus_reg:
313   - platform_device_unregister(pdev);
314   -err_pdev:
315   - return ret;
316   -}
317   -module_init(fixed_mdio_bus_init);
318   -
319   -static void __exit fixed_mdio_bus_exit(void)
320   -{
321   - struct fixed_mdio_bus *fmb = &platform_fmb;
322   - struct fixed_phy *fp, *tmp;
323   -
324   - mdiobus_unregister(fmb->mii_bus);
325   - mdiobus_free(fmb->mii_bus);
326   - platform_device_unregister(pdev);
327   -
328   - list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
329   - list_del(&fp->node);
330   - kfree(fp);
331   - }
332   -}
333   -module_exit(fixed_mdio_bus_exit);
334   -
335   -MODULE_DESCRIPTION("Fixed MDIO bus (MDIO bus emulation with fixed PHYs)");
336   -MODULE_AUTHOR("Vitaly Bordug");
337   -MODULE_LICENSE("GPL");
drivers/net/phy/fixed_phy.c
  1 +/*
  2 + * Fixed MDIO bus (MDIO bus emulation with fixed PHYs)
  3 + *
  4 + * Author: Vitaly Bordug <vbordug@ru.mvista.com>
  5 + * Anton Vorontsov <avorontsov@ru.mvista.com>
  6 + *
  7 + * Copyright (c) 2006-2007 MontaVista Software, Inc.
  8 + *
  9 + * This program is free software; you can redistribute it and/or modify it
  10 + * under the terms of the GNU General Public License as published by the
  11 + * Free Software Foundation; either version 2 of the License, or (at your
  12 + * option) any later version.
  13 + */
  14 +
  15 +#include <linux/kernel.h>
  16 +#include <linux/module.h>
  17 +#include <linux/platform_device.h>
  18 +#include <linux/list.h>
  19 +#include <linux/mii.h>
  20 +#include <linux/phy.h>
  21 +#include <linux/phy_fixed.h>
  22 +#include <linux/err.h>
  23 +#include <linux/slab.h>
  24 +#include <linux/of.h>
  25 +
  26 +#define MII_REGS_NUM 29
  27 +
  28 +struct fixed_mdio_bus {
  29 + int irqs[PHY_MAX_ADDR];
  30 + struct mii_bus *mii_bus;
  31 + struct list_head phys;
  32 +};
  33 +
  34 +struct fixed_phy {
  35 + int addr;
  36 + u16 regs[MII_REGS_NUM];
  37 + struct phy_device *phydev;
  38 + struct fixed_phy_status status;
  39 + int (*link_update)(struct net_device *, struct fixed_phy_status *);
  40 + struct list_head node;
  41 +};
  42 +
  43 +static struct platform_device *pdev;
  44 +static struct fixed_mdio_bus platform_fmb = {
  45 + .phys = LIST_HEAD_INIT(platform_fmb.phys),
  46 +};
  47 +
  48 +static int fixed_phy_update_regs(struct fixed_phy *fp)
  49 +{
  50 + u16 bmsr = BMSR_ANEGCAPABLE;
  51 + u16 bmcr = 0;
  52 + u16 lpagb = 0;
  53 + u16 lpa = 0;
  54 +
  55 + if (fp->status.duplex) {
  56 + bmcr |= BMCR_FULLDPLX;
  57 +
  58 + switch (fp->status.speed) {
  59 + case 1000:
  60 + bmsr |= BMSR_ESTATEN;
  61 + bmcr |= BMCR_SPEED1000;
  62 + lpagb |= LPA_1000FULL;
  63 + break;
  64 + case 100:
  65 + bmsr |= BMSR_100FULL;
  66 + bmcr |= BMCR_SPEED100;
  67 + lpa |= LPA_100FULL;
  68 + break;
  69 + case 10:
  70 + bmsr |= BMSR_10FULL;
  71 + lpa |= LPA_10FULL;
  72 + break;
  73 + default:
  74 + pr_warn("fixed phy: unknown speed\n");
  75 + return -EINVAL;
  76 + }
  77 + } else {
  78 + switch (fp->status.speed) {
  79 + case 1000:
  80 + bmsr |= BMSR_ESTATEN;
  81 + bmcr |= BMCR_SPEED1000;
  82 + lpagb |= LPA_1000HALF;
  83 + break;
  84 + case 100:
  85 + bmsr |= BMSR_100HALF;
  86 + bmcr |= BMCR_SPEED100;
  87 + lpa |= LPA_100HALF;
  88 + break;
  89 + case 10:
  90 + bmsr |= BMSR_10HALF;
  91 + lpa |= LPA_10HALF;
  92 + break;
  93 + default:
  94 + pr_warn("fixed phy: unknown speed\n");
  95 + return -EINVAL;
  96 + }
  97 + }
  98 +
  99 + if (fp->status.link)
  100 + bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE;
  101 +
  102 + if (fp->status.pause)
  103 + lpa |= LPA_PAUSE_CAP;
  104 +
  105 + if (fp->status.asym_pause)
  106 + lpa |= LPA_PAUSE_ASYM;
  107 +
  108 + fp->regs[MII_PHYSID1] = 0;
  109 + fp->regs[MII_PHYSID2] = 0;
  110 +
  111 + fp->regs[MII_BMSR] = bmsr;
  112 + fp->regs[MII_BMCR] = bmcr;
  113 + fp->regs[MII_LPA] = lpa;
  114 + fp->regs[MII_STAT1000] = lpagb;
  115 +
  116 + return 0;
  117 +}
  118 +
  119 +static int fixed_mdio_read(struct mii_bus *bus, int phy_addr, int reg_num)
  120 +{
  121 + struct fixed_mdio_bus *fmb = bus->priv;
  122 + struct fixed_phy *fp;
  123 +
  124 + if (reg_num >= MII_REGS_NUM)
  125 + return -1;
  126 +
  127 + /* We do not support emulating Clause 45 over Clause 22 register reads
  128 + * return an error instead of bogus data.
  129 + */
  130 + switch (reg_num) {
  131 + case MII_MMD_CTRL:
  132 + case MII_MMD_DATA:
  133 + return -1;
  134 + default:
  135 + break;
  136 + }
  137 +
  138 + list_for_each_entry(fp, &fmb->phys, node) {
  139 + if (fp->addr == phy_addr) {
  140 + /* Issue callback if user registered it. */
  141 + if (fp->link_update) {
  142 + fp->link_update(fp->phydev->attached_dev,
  143 + &fp->status);
  144 + fixed_phy_update_regs(fp);
  145 + }
  146 + return fp->regs[reg_num];
  147 + }
  148 + }
  149 +
  150 + return 0xFFFF;
  151 +}
  152 +
  153 +static int fixed_mdio_write(struct mii_bus *bus, int phy_addr, int reg_num,
  154 + u16 val)
  155 +{
  156 + return 0;
  157 +}
  158 +
  159 +/*
  160 + * If something weird is required to be done with link/speed,
  161 + * network driver is able to assign a function to implement this.
  162 + * May be useful for PHY's that need to be software-driven.
  163 + */
  164 +int fixed_phy_set_link_update(struct phy_device *phydev,
  165 + int (*link_update)(struct net_device *,
  166 + struct fixed_phy_status *))
  167 +{
  168 + struct fixed_mdio_bus *fmb = &platform_fmb;
  169 + struct fixed_phy *fp;
  170 +
  171 + if (!link_update || !phydev || !phydev->bus)
  172 + return -EINVAL;
  173 +
  174 + list_for_each_entry(fp, &fmb->phys, node) {
  175 + if (fp->addr == phydev->addr) {
  176 + fp->link_update = link_update;
  177 + fp->phydev = phydev;
  178 + return 0;
  179 + }
  180 + }
  181 +
  182 + return -ENOENT;
  183 +}
  184 +EXPORT_SYMBOL_GPL(fixed_phy_set_link_update);
  185 +
  186 +int fixed_phy_add(unsigned int irq, int phy_addr,
  187 + struct fixed_phy_status *status)
  188 +{
  189 + int ret;
  190 + struct fixed_mdio_bus *fmb = &platform_fmb;
  191 + struct fixed_phy *fp;
  192 +
  193 + fp = kzalloc(sizeof(*fp), GFP_KERNEL);
  194 + if (!fp)
  195 + return -ENOMEM;
  196 +
  197 + memset(fp->regs, 0xFF, sizeof(fp->regs[0]) * MII_REGS_NUM);
  198 +
  199 + fmb->irqs[phy_addr] = irq;
  200 +
  201 + fp->addr = phy_addr;
  202 + fp->status = *status;
  203 +
  204 + ret = fixed_phy_update_regs(fp);
  205 + if (ret)
  206 + goto err_regs;
  207 +
  208 + list_add_tail(&fp->node, &fmb->phys);
  209 +
  210 + return 0;
  211 +
  212 +err_regs:
  213 + kfree(fp);
  214 + return ret;
  215 +}
  216 +EXPORT_SYMBOL_GPL(fixed_phy_add);
  217 +
  218 +void fixed_phy_del(int phy_addr)
  219 +{
  220 + struct fixed_mdio_bus *fmb = &platform_fmb;
  221 + struct fixed_phy *fp, *tmp;
  222 +
  223 + list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
  224 + if (fp->addr == phy_addr) {
  225 + list_del(&fp->node);
  226 + kfree(fp);
  227 + return;
  228 + }
  229 + }
  230 +}
  231 +EXPORT_SYMBOL_GPL(fixed_phy_del);
  232 +
  233 +static int phy_fixed_addr;
  234 +static DEFINE_SPINLOCK(phy_fixed_addr_lock);
  235 +
  236 +struct phy_device *fixed_phy_register(unsigned int irq,
  237 + struct fixed_phy_status *status,
  238 + struct device_node *np)
  239 +{
  240 + struct fixed_mdio_bus *fmb = &platform_fmb;
  241 + struct phy_device *phy;
  242 + int phy_addr;
  243 + int ret;
  244 +
  245 + /* Get the next available PHY address, up to PHY_MAX_ADDR */
  246 + spin_lock(&phy_fixed_addr_lock);
  247 + if (phy_fixed_addr == PHY_MAX_ADDR) {
  248 + spin_unlock(&phy_fixed_addr_lock);
  249 + return ERR_PTR(-ENOSPC);
  250 + }
  251 + phy_addr = phy_fixed_addr++;
  252 + spin_unlock(&phy_fixed_addr_lock);
  253 +
  254 + ret = fixed_phy_add(PHY_POLL, phy_addr, status);
  255 + if (ret < 0)
  256 + return ERR_PTR(ret);
  257 +
  258 + phy = get_phy_device(fmb->mii_bus, phy_addr, false);
  259 + if (!phy || IS_ERR(phy)) {
  260 + fixed_phy_del(phy_addr);
  261 + return ERR_PTR(-EINVAL);
  262 + }
  263 +
  264 + of_node_get(np);
  265 + phy->dev.of_node = np;
  266 +
  267 + ret = phy_device_register(phy);
  268 + if (ret) {
  269 + phy_device_free(phy);
  270 + of_node_put(np);
  271 + fixed_phy_del(phy_addr);
  272 + return ERR_PTR(ret);
  273 + }
  274 +
  275 + return phy;
  276 +}
  277 +EXPORT_SYMBOL_GPL(fixed_phy_register);
  278 +
  279 +static int __init fixed_mdio_bus_init(void)
  280 +{
  281 + struct fixed_mdio_bus *fmb = &platform_fmb;
  282 + int ret;
  283 +
  284 + pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0);
  285 + if (IS_ERR(pdev)) {
  286 + ret = PTR_ERR(pdev);
  287 + goto err_pdev;
  288 + }
  289 +
  290 + fmb->mii_bus = mdiobus_alloc();
  291 + if (fmb->mii_bus == NULL) {
  292 + ret = -ENOMEM;
  293 + goto err_mdiobus_reg;
  294 + }
  295 +
  296 + snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "fixed-0");
  297 + fmb->mii_bus->name = "Fixed MDIO Bus";
  298 + fmb->mii_bus->priv = fmb;
  299 + fmb->mii_bus->parent = &pdev->dev;
  300 + fmb->mii_bus->read = &fixed_mdio_read;
  301 + fmb->mii_bus->write = &fixed_mdio_write;
  302 + fmb->mii_bus->irq = fmb->irqs;
  303 +
  304 + ret = mdiobus_register(fmb->mii_bus);
  305 + if (ret)
  306 + goto err_mdiobus_alloc;
  307 +
  308 + return 0;
  309 +
  310 +err_mdiobus_alloc:
  311 + mdiobus_free(fmb->mii_bus);
  312 +err_mdiobus_reg:
  313 + platform_device_unregister(pdev);
  314 +err_pdev:
  315 + return ret;
  316 +}
  317 +module_init(fixed_mdio_bus_init);
  318 +
  319 +static void __exit fixed_mdio_bus_exit(void)
  320 +{
  321 + struct fixed_mdio_bus *fmb = &platform_fmb;
  322 + struct fixed_phy *fp, *tmp;
  323 +
  324 + mdiobus_unregister(fmb->mii_bus);
  325 + mdiobus_free(fmb->mii_bus);
  326 + platform_device_unregister(pdev);
  327 +
  328 + list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
  329 + list_del(&fp->node);
  330 + kfree(fp);
  331 + }
  332 +}
  333 +module_exit(fixed_mdio_bus_exit);
  334 +
  335 +MODULE_DESCRIPTION("Fixed MDIO bus (MDIO bus emulation with fixed PHYs)");
  336 +MODULE_AUTHOR("Vitaly Bordug");
  337 +MODULE_LICENSE("GPL");
include/linux/phy_fixed.h
... ... @@ -11,7 +11,7 @@
11 11  
12 12 struct device_node;
13 13  
14   -#ifdef CONFIG_FIXED_PHY
  14 +#if IS_ENABLED(CONFIG_FIXED_PHY)
15 15 extern int fixed_phy_add(unsigned int irq, int phy_id,
16 16 struct fixed_phy_status *status);
17 17 extern struct phy_device *fixed_phy_register(unsigned int irq,