mdio_bus: implement devm_mdiobus_alloc/devm_mdiobus_free
Add a resource managed devm_mdiobus_alloc[_size]()/devm_mdiobus_free() to automatically clean up MDIO bus alocations made by MDIO drivers, thus leading to simplified MDIO drivers code. Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> Acked-and-tested-by: Lad, Prabhakar <prabhakar.csengg@gmail.com> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
ca8b6e04bc
Коммит
6d48f44b7b
|
@ -308,3 +308,8 @@ SLAVE DMA ENGINE
|
|||
|
||||
SPI
|
||||
devm_spi_register_master()
|
||||
|
||||
MDIO
|
||||
devm_mdiobus_alloc()
|
||||
devm_mdiobus_alloc_size()
|
||||
devm_mdiobus_free()
|
||||
|
|
|
@ -69,6 +69,73 @@ struct mii_bus *mdiobus_alloc_size(size_t size)
|
|||
}
|
||||
EXPORT_SYMBOL(mdiobus_alloc_size);
|
||||
|
||||
static void _devm_mdiobus_free(struct device *dev, void *res)
|
||||
{
|
||||
mdiobus_free(*(struct mii_bus **)res);
|
||||
}
|
||||
|
||||
static int devm_mdiobus_match(struct device *dev, void *res, void *data)
|
||||
{
|
||||
struct mii_bus **r = res;
|
||||
|
||||
if (WARN_ON(!r || !*r))
|
||||
return 0;
|
||||
|
||||
return *r == data;
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_mdiobus_alloc_size - Resource-managed mdiobus_alloc_size()
|
||||
* @dev: Device to allocate mii_bus for
|
||||
* @sizeof_priv: Space to allocate for private structure.
|
||||
*
|
||||
* Managed mdiobus_alloc_size. mii_bus allocated with this function is
|
||||
* automatically freed on driver detach.
|
||||
*
|
||||
* If an mii_bus allocated with this function needs to be freed separately,
|
||||
* devm_mdiobus_free() must be used.
|
||||
*
|
||||
* RETURNS:
|
||||
* Pointer to allocated mii_bus on success, NULL on failure.
|
||||
*/
|
||||
struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv)
|
||||
{
|
||||
struct mii_bus **ptr, *bus;
|
||||
|
||||
ptr = devres_alloc(_devm_mdiobus_free, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
|
||||
/* use raw alloc_dr for kmalloc caller tracing */
|
||||
bus = mdiobus_alloc_size(sizeof_priv);
|
||||
if (bus) {
|
||||
*ptr = bus;
|
||||
devres_add(dev, ptr);
|
||||
} else {
|
||||
devres_free(ptr);
|
||||
}
|
||||
|
||||
return bus;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_mdiobus_alloc);
|
||||
|
||||
/**
|
||||
* devm_mdiobus_free - Resource-managed mdiobus_free()
|
||||
* @dev: Device this mii_bus belongs to
|
||||
* @bus: the mii_bus associated with the device
|
||||
*
|
||||
* Free mii_bus allocated with devm_mdiobus_alloc_size().
|
||||
*/
|
||||
void devm_mdiobus_free(struct device *dev, struct mii_bus *bus)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = devres_release(dev, _devm_mdiobus_free,
|
||||
devm_mdiobus_match, bus);
|
||||
WARN_ON(rc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_mdiobus_free);
|
||||
|
||||
/**
|
||||
* mdiobus_release - mii_bus device release callback
|
||||
* @d: the target struct device that contains the mii_bus
|
||||
|
|
|
@ -198,6 +198,13 @@ static inline struct mii_bus *mdiobus_alloc(void)
|
|||
int mdiobus_register(struct mii_bus *bus);
|
||||
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);
|
||||
static inline struct mii_bus *devm_mdiobus_alloc(struct device *dev)
|
||||
{
|
||||
return devm_mdiobus_alloc_size(dev, 0);
|
||||
}
|
||||
|
||||
void devm_mdiobus_free(struct device *dev, struct mii_bus *bus);
|
||||
struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
|
||||
int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum);
|
||||
int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
|
||||
|
|
Загрузка…
Ссылка в новой задаче