forked from luck/tmp_suning_uos_patched
Merge branch 'davinci_mdio'
Grygorii Strashko says: ==================== introduce devm_mdiobus_alloc/free and clean up davinci mdio Introduce 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. Clean up Davinci MDIO driver and use new devm API. Changes in v3: - added devm_mdiobus_alloc_size() and devm_mdiobus_alloc() converted to be just a simple wrapper now. Changes in v2: - minor comments taken into account - additional patches added for cleaning up Davinci MDIO driver ==================== Acked-by: Santosh Shilimkar<santosh.shilimkar@ti.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
3c4de5a0a3
@ -308,3 +308,8 @@ SLAVE DMA ENGINE
|
||||
|
||||
SPI
|
||||
devm_spi_register_master()
|
||||
|
||||
MDIO
|
||||
devm_mdiobus_alloc()
|
||||
devm_mdiobus_alloc_size()
|
||||
devm_mdiobus_free()
|
||||
|
@ -321,15 +321,14 @@ static int davinci_mdio_probe(struct platform_device *pdev)
|
||||
struct phy_device *phy;
|
||||
int ret, addr;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
data->bus = mdiobus_alloc();
|
||||
data->bus = devm_mdiobus_alloc(dev);
|
||||
if (!data->bus) {
|
||||
dev_err(dev, "failed to alloc mii bus\n");
|
||||
ret = -ENOMEM;
|
||||
goto bail_out;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (dev->of_node) {
|
||||
@ -349,12 +348,9 @@ static int davinci_mdio_probe(struct platform_device *pdev)
|
||||
data->bus->parent = dev;
|
||||
data->bus->priv = data;
|
||||
|
||||
/* Select default pin state */
|
||||
pinctrl_pm_select_default_state(&pdev->dev);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
data->clk = clk_get(&pdev->dev, "fck");
|
||||
data->clk = devm_clk_get(dev, "fck");
|
||||
if (IS_ERR(data->clk)) {
|
||||
dev_err(dev, "failed to get device clock\n");
|
||||
ret = PTR_ERR(data->clk);
|
||||
@ -367,24 +363,9 @@ static int davinci_mdio_probe(struct platform_device *pdev)
|
||||
spin_lock_init(&data->lock);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(dev, "could not find register map resource\n");
|
||||
ret = -ENOENT;
|
||||
goto bail_out;
|
||||
}
|
||||
|
||||
res = devm_request_mem_region(dev, res->start, resource_size(res),
|
||||
dev_name(dev));
|
||||
if (!res) {
|
||||
dev_err(dev, "could not allocate register map resource\n");
|
||||
ret = -ENXIO;
|
||||
goto bail_out;
|
||||
}
|
||||
|
||||
data->regs = devm_ioremap_nocache(dev, res->start, resource_size(res));
|
||||
if (!data->regs) {
|
||||
dev_err(dev, "could not map mdio registers\n");
|
||||
ret = -ENOMEM;
|
||||
data->regs = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(data->regs)) {
|
||||
ret = PTR_ERR(data->regs);
|
||||
goto bail_out;
|
||||
}
|
||||
|
||||
@ -406,16 +387,9 @@ static int davinci_mdio_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
bail_out:
|
||||
if (data->bus)
|
||||
mdiobus_free(data->bus);
|
||||
|
||||
if (data->clk)
|
||||
clk_put(data->clk);
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
kfree(data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -423,18 +397,12 @@ static int davinci_mdio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct davinci_mdio_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
if (data->bus) {
|
||||
if (data->bus)
|
||||
mdiobus_unregister(data->bus);
|
||||
mdiobus_free(data->bus);
|
||||
}
|
||||
|
||||
if (data->clk)
|
||||
clk_put(data->clk);
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
kfree(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user