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()
59 * The parent bus' lock is used to order access to the switch_fn.
61 static int mdio_mux_write(struct mii_bus *bus, int phy_id, in mdio_mux_write() argument
64 struct mdio_mux_child_bus *cb = bus->priv; in mdio_mux_write()
65 struct mdio_mux_parent_bus *pb = cb->parent; in mdio_mux_write()
69 mutex_lock_nested(&pb->mii_bus->mdio_lock, MDIO_MUTEX_MUX); in mdio_mux_write()
70 r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data); in mdio_mux_write()
74 pb->current_child = cb->bus_number; in mdio_mux_write()
76 r = pb->mii_bus->write(pb->mii_bus, phy_id, regnum, val); in mdio_mux_write()
78 mutex_unlock(&pb->mii_bus->mdio_lock); in mdio_mux_write()
100 return -ENODEV; in mdio_mux_init()
104 "mdio-parent-bus", 0); in mdio_mux_init()
107 return -ENODEV; in mdio_mux_init()
111 ret_val = -EPROBE_DEFER; in mdio_mux_init()
117 get_device(&parent_bus->dev); in mdio_mux_init()
122 ret_val = -ENOMEM; in mdio_mux_init()
126 pb->switch_data = data; in mdio_mux_init()
127 pb->switch_fn = switch_fn; in mdio_mux_init()
128 pb->current_child = -1; in mdio_mux_init()
129 pb->parent_id = parent_count++; in mdio_mux_init()
130 pb->mii_bus = parent_bus; in mdio_mux_init()
132 ret_val = -ENODEV; in mdio_mux_init()
146 ret_val = -ENOMEM; in mdio_mux_init()
149 cb->bus_number = v; in mdio_mux_init()
150 cb->parent = pb; in mdio_mux_init()
152 cb->mii_bus = mdiobus_alloc(); in mdio_mux_init()
153 if (!cb->mii_bus) { in mdio_mux_init()
154 ret_val = -ENOMEM; in mdio_mux_init()
158 cb->mii_bus->priv = cb; in mdio_mux_init()
160 cb->mii_bus->name = "mdio_mux"; in mdio_mux_init()
161 snprintf(cb->mii_bus->id, MII_BUS_ID_SIZE, "%x.%x", in mdio_mux_init()
162 pb->parent_id, v); in mdio_mux_init()
163 cb->mii_bus->parent = dev; in mdio_mux_init()
164 cb->mii_bus->read = mdio_mux_read; in mdio_mux_init()
165 cb->mii_bus->write = mdio_mux_write; in mdio_mux_init()
166 r = of_mdiobus_register(cb->mii_bus, child_bus_node); in mdio_mux_init()
169 "Error: Failed to register MDIO bus for child %pOF\n", in mdio_mux_init()
171 mdiobus_free(cb->mii_bus); in mdio_mux_init()
174 cb->next = pb->children; in mdio_mux_init()
175 pb->children = cb; in mdio_mux_init()
178 if (pb->children) { in mdio_mux_init()
186 put_device(&parent_bus->dev); in mdio_mux_init()
196 struct mdio_mux_child_bus *cb = pb->children; in mdio_mux_uninit()
199 mdiobus_unregister(cb->mii_bus); in mdio_mux_uninit()
200 mdiobus_free(cb->mii_bus); in mdio_mux_uninit()
201 cb = cb->next; in mdio_mux_uninit()
204 put_device(&pb->mii_bus->dev); in mdio_mux_uninit()