forked from Minki/linux
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. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
4406d36dfd
commit
38f961e744
@ -170,7 +170,12 @@ EXPORT_SYMBOL(mdiobus_alloc_size);
|
||||
|
||||
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)
|
||||
@ -210,6 +215,7 @@ struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv)
|
||||
if (bus) {
|
||||
*ptr = bus;
|
||||
devres_add(dev, ptr);
|
||||
bus->is_managed = 1;
|
||||
} else {
|
||||
devres_free(ptr);
|
||||
}
|
||||
|
@ -241,6 +241,9 @@ struct mii_bus {
|
||||
int (*reset)(struct mii_bus *bus);
|
||||
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
|
||||
* 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);
|
||||
#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_free(struct mii_bus *bus);
|
||||
struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv);
|
||||
|
Loading…
Reference in New Issue
Block a user