Commit 3c4de5a0 authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents ca8b6e04 9728e1a7
...@@ -308,3 +308,8 @@ SLAVE DMA ENGINE ...@@ -308,3 +308,8 @@ SLAVE DMA ENGINE
SPI SPI
devm_spi_register_master() 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) ...@@ -321,15 +321,14 @@ static int davinci_mdio_probe(struct platform_device *pdev)
struct phy_device *phy; struct phy_device *phy;
int ret, addr; int ret, addr;
data = kzalloc(sizeof(*data), GFP_KERNEL); data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
data->bus = mdiobus_alloc(); data->bus = devm_mdiobus_alloc(dev);
if (!data->bus) { if (!data->bus) {
dev_err(dev, "failed to alloc mii bus\n"); dev_err(dev, "failed to alloc mii bus\n");
ret = -ENOMEM; return -ENOMEM;
goto bail_out;
} }
if (dev->of_node) { if (dev->of_node) {
...@@ -349,12 +348,9 @@ static int davinci_mdio_probe(struct platform_device *pdev) ...@@ -349,12 +348,9 @@ static int davinci_mdio_probe(struct platform_device *pdev)
data->bus->parent = dev; data->bus->parent = dev;
data->bus->priv = data; data->bus->priv = data;
/* Select default pin state */
pinctrl_pm_select_default_state(&pdev->dev);
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&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)) { if (IS_ERR(data->clk)) {
dev_err(dev, "failed to get device clock\n"); dev_err(dev, "failed to get device clock\n");
ret = PTR_ERR(data->clk); ret = PTR_ERR(data->clk);
...@@ -367,24 +363,9 @@ static int davinci_mdio_probe(struct platform_device *pdev) ...@@ -367,24 +363,9 @@ static int davinci_mdio_probe(struct platform_device *pdev)
spin_lock_init(&data->lock); spin_lock_init(&data->lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) { data->regs = devm_ioremap_resource(dev, res);
dev_err(dev, "could not find register map resource\n"); if (IS_ERR(data->regs)) {
ret = -ENOENT; ret = PTR_ERR(data->regs);
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;
goto bail_out; goto bail_out;
} }
...@@ -406,16 +387,9 @@ static int davinci_mdio_probe(struct platform_device *pdev) ...@@ -406,16 +387,9 @@ static int davinci_mdio_probe(struct platform_device *pdev)
return 0; return 0;
bail_out: bail_out:
if (data->bus)
mdiobus_free(data->bus);
if (data->clk)
clk_put(data->clk);
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
kfree(data);
return ret; return ret;
} }
...@@ -423,18 +397,12 @@ static int davinci_mdio_remove(struct platform_device *pdev) ...@@ -423,18 +397,12 @@ static int davinci_mdio_remove(struct platform_device *pdev)
{ {
struct davinci_mdio_data *data = platform_get_drvdata(pdev); struct davinci_mdio_data *data = platform_get_drvdata(pdev);
if (data->bus) { if (data->bus)
mdiobus_unregister(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_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
kfree(data);
return 0; return 0;
} }
......
...@@ -69,6 +69,73 @@ struct mii_bus *mdiobus_alloc_size(size_t size) ...@@ -69,6 +69,73 @@ struct mii_bus *mdiobus_alloc_size(size_t size)
} }
EXPORT_SYMBOL(mdiobus_alloc_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 * mdiobus_release - mii_bus device release callback
* @d: the target struct device that contains the mii_bus * @d: the target struct device that contains the mii_bus
......
...@@ -198,6 +198,13 @@ static inline struct mii_bus *mdiobus_alloc(void) ...@@ -198,6 +198,13 @@ static inline struct mii_bus *mdiobus_alloc(void)
int mdiobus_register(struct mii_bus *bus); int mdiobus_register(struct mii_bus *bus);
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);
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); struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum); int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum);
int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val); int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment