Lines Matching +full:mdio +full:- +full:parent +full:- +full:bus
1 // SPDX-License-Identifier: GPL-2.0
7 #include <linux/mdio-mux.h>
13 #define DRV_DESCRIPTION "MDIO bus multiplexer driver"
30 struct mdio_mux_parent_bus *parent; member
36 * The parent bus' lock is used to order access to the switch_fn.
38 static int mdio_mux_read(struct mii_bus *bus, int phy_id, int regnum) in mdio_mux_read() argument
40 struct mdio_mux_child_bus *cb = bus->priv; in mdio_mux_read()
41 struct mdio_mux_parent_bus *pb = cb->parent; in mdio_mux_read()
44 mutex_lock_nested(&pb->mii_bus->mdio_lock, MDIO_MUTEX_MUX); in mdio_mux_read()
45 r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data); in mdio_mux_read()
49 pb->current_child = cb->bus_number; in mdio_mux_read()
51 r = pb->mii_bus->read(pb->mii_bus, phy_id, regnum); in mdio_mux_read()
53 mutex_unlock(&pb->mii_bus->mdio_lock); in mdio_mux_read()
58 static int mdio_mux_read_c45(struct mii_bus *bus, int phy_id, int dev_addr, in mdio_mux_read_c45() argument
61 struct mdio_mux_child_bus *cb = bus->priv; in mdio_mux_read_c45()
62 struct mdio_mux_parent_bus *pb = cb->parent; in mdio_mux_read_c45()
65 mutex_lock_nested(&pb->mii_bus->mdio_lock, MDIO_MUTEX_MUX); in mdio_mux_read_c45()
66 r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data); in mdio_mux_read_c45()
70 pb->current_child = cb->bus_number; in mdio_mux_read_c45()
72 r = pb->mii_bus->read_c45(pb->mii_bus, phy_id, dev_addr, regnum); in mdio_mux_read_c45()
74 mutex_unlock(&pb->mii_bus->mdio_lock); in mdio_mux_read_c45()
80 * The parent bus' lock is used to order access to the switch_fn.
82 static int mdio_mux_write(struct mii_bus *bus, int phy_id, in mdio_mux_write() argument
85 struct mdio_mux_child_bus *cb = bus->priv; in mdio_mux_write()
86 struct mdio_mux_parent_bus *pb = cb->parent; in mdio_mux_write()
90 mutex_lock_nested(&pb->mii_bus->mdio_lock, MDIO_MUTEX_MUX); in mdio_mux_write()
91 r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data); in mdio_mux_write()
95 pb->current_child = cb->bus_number; in mdio_mux_write()
97 r = pb->mii_bus->write(pb->mii_bus, phy_id, regnum, val); in mdio_mux_write()
99 mutex_unlock(&pb->mii_bus->mdio_lock); in mdio_mux_write()
104 static int mdio_mux_write_c45(struct mii_bus *bus, int phy_id, int dev_addr, in mdio_mux_write_c45() argument
107 struct mdio_mux_child_bus *cb = bus->priv; in mdio_mux_write_c45()
108 struct mdio_mux_parent_bus *pb = cb->parent; in mdio_mux_write_c45()
112 mutex_lock_nested(&pb->mii_bus->mdio_lock, MDIO_MUTEX_MUX); in mdio_mux_write_c45()
113 r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data); in mdio_mux_write_c45()
117 pb->current_child = cb->bus_number; in mdio_mux_write_c45()
119 r = pb->mii_bus->write_c45(pb->mii_bus, phy_id, dev_addr, regnum, val); in mdio_mux_write_c45()
121 mutex_unlock(&pb->mii_bus->mdio_lock); in mdio_mux_write_c45()
130 struct mdio_mux_child_bus *cb = pb->children; in mdio_mux_uninit_children()
133 mdiobus_unregister(cb->mii_bus); in mdio_mux_uninit_children()
134 mdiobus_free(cb->mii_bus); in mdio_mux_uninit_children()
135 cb = cb->next; in mdio_mux_uninit_children()
154 return -ENODEV; in mdio_mux_init()
158 "mdio-parent-bus", 0); in mdio_mux_init()
161 return -ENODEV; in mdio_mux_init()
165 ret_val = -EPROBE_DEFER; in mdio_mux_init()
171 get_device(&parent_bus->dev); in mdio_mux_init()
176 ret_val = -ENOMEM; in mdio_mux_init()
180 pb->switch_data = data; in mdio_mux_init()
181 pb->switch_fn = switch_fn; in mdio_mux_init()
182 pb->current_child = -1; in mdio_mux_init()
183 pb->parent_id = parent_count++; in mdio_mux_init()
184 pb->mii_bus = parent_bus; in mdio_mux_init()
186 ret_val = -ENODEV; in mdio_mux_init()
200 ret_val = -ENOMEM; in mdio_mux_init()
203 cb->bus_number = v; in mdio_mux_init()
204 cb->parent = pb; in mdio_mux_init()
206 cb->mii_bus = mdiobus_alloc(); in mdio_mux_init()
207 if (!cb->mii_bus) { in mdio_mux_init()
208 ret_val = -ENOMEM; in mdio_mux_init()
211 cb->mii_bus->priv = cb; in mdio_mux_init()
213 cb->mii_bus->name = "mdio_mux"; in mdio_mux_init()
214 snprintf(cb->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x.%x", in mdio_mux_init()
215 cb->mii_bus->name, pb->parent_id, v); in mdio_mux_init()
216 cb->mii_bus->parent = dev; in mdio_mux_init()
217 cb->mii_bus->read = mdio_mux_read; in mdio_mux_init()
218 cb->mii_bus->write = mdio_mux_write; in mdio_mux_init()
219 if (parent_bus->read_c45) in mdio_mux_init()
220 cb->mii_bus->read_c45 = mdio_mux_read_c45; in mdio_mux_init()
221 if (parent_bus->write_c45) in mdio_mux_init()
222 cb->mii_bus->write_c45 = mdio_mux_write_c45; in mdio_mux_init()
223 r = of_mdiobus_register(cb->mii_bus, child_bus_node); in mdio_mux_init()
225 mdiobus_free(cb->mii_bus); in mdio_mux_init()
226 if (r == -EPROBE_DEFER) { in mdio_mux_init()
232 "Error: Failed to register MDIO bus for child %pOF\n", in mdio_mux_init()
235 cb->next = pb->children; in mdio_mux_init()
236 pb->children = cb; in mdio_mux_init()
239 if (pb->children) { in mdio_mux_init()
250 put_device(&parent_bus->dev); in mdio_mux_init()
262 put_device(&pb->mii_bus->dev); in mdio_mux_uninit()