Merge branch 'net-phy-add-device-managed-devm_mdiobus_register'
Heiner Kallweit says: ==================== net: phy: add device-managed devm_mdiobus_register If there's no special ordering requirement for mdiobus_unregister(), then driver code can be simplified by using a device-managed version of mdiobus_register(). Prerequisite is that bus allocation has been done device-managed too. Else mdiobus_free() may be called whilst bus is still registered, resulting in a BUG_ON(). Therefore let devm_mdiobus_register() return -EPERM if bus was allocated non-managed. First user of the new functionality is r8169 driver. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
58989d7cf6
|
@ -5185,20 +5185,18 @@ static int r8169_mdio_register(struct rtl8169_private *tp)
|
||||||
new_bus->read = r8169_mdio_read_reg;
|
new_bus->read = r8169_mdio_read_reg;
|
||||||
new_bus->write = r8169_mdio_write_reg;
|
new_bus->write = r8169_mdio_write_reg;
|
||||||
|
|
||||||
ret = mdiobus_register(new_bus);
|
ret = devm_mdiobus_register(new_bus);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
tp->phydev = mdiobus_get_phy(new_bus, 0);
|
tp->phydev = mdiobus_get_phy(new_bus, 0);
|
||||||
if (!tp->phydev) {
|
if (!tp->phydev) {
|
||||||
mdiobus_unregister(new_bus);
|
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
} else if (!tp->phydev->drv) {
|
} else if (!tp->phydev->drv) {
|
||||||
/* Most chip versions fail with the genphy driver.
|
/* Most chip versions fail with the genphy driver.
|
||||||
* Therefore ensure that the dedicated PHY driver is loaded.
|
* Therefore ensure that the dedicated PHY driver is loaded.
|
||||||
*/
|
*/
|
||||||
dev_err(&pdev->dev, "realtek.ko not loaded, maybe it needs to be added to initramfs?\n");
|
dev_err(&pdev->dev, "realtek.ko not loaded, maybe it needs to be added to initramfs?\n");
|
||||||
mdiobus_unregister(new_bus);
|
|
||||||
return -EUNATCH;
|
return -EUNATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5523,7 +5521,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
|
|
||||||
rc = register_netdev(dev);
|
rc = register_netdev(dev);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto err_mdio_unregister;
|
return rc;
|
||||||
|
|
||||||
netif_info(tp, probe, dev, "%s, %pM, XID %03x, IRQ %d\n",
|
netif_info(tp, probe, dev, "%s, %pM, XID %03x, IRQ %d\n",
|
||||||
rtl_chip_infos[chipset].name, dev->dev_addr, xid,
|
rtl_chip_infos[chipset].name, dev->dev_addr, xid,
|
||||||
|
@ -5542,10 +5540,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
pm_runtime_put_sync(&pdev->dev);
|
pm_runtime_put_sync(&pdev->dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_mdio_unregister:
|
|
||||||
mdiobus_unregister(tp->phydev->mdio.bus);
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pci_driver rtl8169_pci_driver = {
|
static struct pci_driver rtl8169_pci_driver = {
|
||||||
|
|
|
@ -170,7 +170,12 @@ EXPORT_SYMBOL(mdiobus_alloc_size);
|
||||||
|
|
||||||
static void _devm_mdiobus_free(struct device *dev, void *res)
|
static void _devm_mdiobus_free(struct device *dev, void *res)
|
||||||
{
|
{
|
||||||
mdiobus_free(*(struct mii_bus **)res);
|
struct mii_bus *bus = *(struct mii_bus **)res;
|
||||||
|
|
||||||
|
if (bus->is_managed_registered && bus->state == MDIOBUS_REGISTERED)
|
||||||
|
mdiobus_unregister(bus);
|
||||||
|
|
||||||
|
mdiobus_free(bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int devm_mdiobus_match(struct device *dev, void *res, void *data)
|
static int devm_mdiobus_match(struct device *dev, void *res, void *data)
|
||||||
|
@ -210,6 +215,7 @@ struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv)
|
||||||
if (bus) {
|
if (bus) {
|
||||||
*ptr = bus;
|
*ptr = bus;
|
||||||
devres_add(dev, ptr);
|
devres_add(dev, ptr);
|
||||||
|
bus->is_managed = 1;
|
||||||
} else {
|
} else {
|
||||||
devres_free(ptr);
|
devres_free(ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,6 +241,9 @@ struct mii_bus {
|
||||||
int (*reset)(struct mii_bus *bus);
|
int (*reset)(struct mii_bus *bus);
|
||||||
struct mdio_bus_stats stats[PHY_MAX_ADDR];
|
struct mdio_bus_stats stats[PHY_MAX_ADDR];
|
||||||
|
|
||||||
|
unsigned int is_managed:1; /* is device-managed */
|
||||||
|
unsigned int is_managed_registered:1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A lock to ensure that only one thing can read/write
|
* A lock to ensure that only one thing can read/write
|
||||||
* the MDIO bus at a time
|
* the MDIO bus at a time
|
||||||
|
@ -286,6 +289,20 @@ static inline struct mii_bus *mdiobus_alloc(void)
|
||||||
|
|
||||||
int __mdiobus_register(struct mii_bus *bus, struct module *owner);
|
int __mdiobus_register(struct mii_bus *bus, struct module *owner);
|
||||||
#define mdiobus_register(bus) __mdiobus_register(bus, THIS_MODULE)
|
#define mdiobus_register(bus) __mdiobus_register(bus, THIS_MODULE)
|
||||||
|
static inline int devm_mdiobus_register(struct mii_bus *bus)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!bus->is_managed)
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
ret = mdiobus_register(bus);
|
||||||
|
if (!ret)
|
||||||
|
bus->is_managed_registered = 1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void mdiobus_unregister(struct mii_bus *bus);
|
void mdiobus_unregister(struct mii_bus *bus);
|
||||||
void mdiobus_free(struct mii_bus *bus);
|
void mdiobus_free(struct mii_bus *bus);
|
||||||
struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv);
|
struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv);
|
||||||
|
|
Loading…
Reference in New Issue