123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- #include <linux/device.h>
- #include <linux/of_mdio.h>
- #include <linux/phy.h>
- #include <linux/stddef.h>
- struct mdiobus_devres {
- struct mii_bus *mii;
- };
- static void devm_mdiobus_free(struct device *dev, void *this)
- {
- struct mdiobus_devres *dr = this;
- mdiobus_free(dr->mii);
- }
- /**
- * 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.
- *
- * RETURNS:
- * Pointer to allocated mii_bus on success, NULL on out-of-memory error.
- */
- struct mii_bus *devm_mdiobus_alloc_size(struct device *dev, int sizeof_priv)
- {
- struct mdiobus_devres *dr;
- dr = devres_alloc(devm_mdiobus_free, sizeof(*dr), GFP_KERNEL);
- if (!dr)
- return NULL;
- dr->mii = mdiobus_alloc_size(sizeof_priv);
- if (!dr->mii) {
- devres_free(dr);
- return NULL;
- }
- devres_add(dev, dr);
- return dr->mii;
- }
- EXPORT_SYMBOL(devm_mdiobus_alloc_size);
- static void devm_mdiobus_unregister(struct device *dev, void *this)
- {
- struct mdiobus_devres *dr = this;
- mdiobus_unregister(dr->mii);
- }
- static int mdiobus_devres_match(struct device *dev,
- void *this, void *match_data)
- {
- struct mdiobus_devres *res = this;
- struct mii_bus *mii = match_data;
- return mii == res->mii;
- }
- /**
- * __devm_mdiobus_register - Resource-managed variant of mdiobus_register()
- * @dev: Device to register mii_bus for
- * @bus: MII bus structure to register
- * @owner: Owning module
- *
- * Returns 0 on success, negative error number on failure.
- */
- int __devm_mdiobus_register(struct device *dev, struct mii_bus *bus,
- struct module *owner)
- {
- struct mdiobus_devres *dr;
- int ret;
- if (WARN_ON(!devres_find(dev, devm_mdiobus_free,
- mdiobus_devres_match, bus)))
- return -EINVAL;
- dr = devres_alloc(devm_mdiobus_unregister, sizeof(*dr), GFP_KERNEL);
- if (!dr)
- return -ENOMEM;
- ret = __mdiobus_register(bus, owner);
- if (ret) {
- devres_free(dr);
- return ret;
- }
- dr->mii = bus;
- devres_add(dev, dr);
- return 0;
- }
- EXPORT_SYMBOL(__devm_mdiobus_register);
- #if IS_ENABLED(CONFIG_OF_MDIO)
- /**
- * __devm_of_mdiobus_register - Resource managed variant of of_mdiobus_register()
- * @dev: Device to register mii_bus for
- * @mdio: MII bus structure to register
- * @np: Device node to parse
- * @owner: Owning module
- */
- int __devm_of_mdiobus_register(struct device *dev, struct mii_bus *mdio,
- struct device_node *np, struct module *owner)
- {
- struct mdiobus_devres *dr;
- int ret;
- if (WARN_ON(!devres_find(dev, devm_mdiobus_free,
- mdiobus_devres_match, mdio)))
- return -EINVAL;
- dr = devres_alloc(devm_mdiobus_unregister, sizeof(*dr), GFP_KERNEL);
- if (!dr)
- return -ENOMEM;
- ret = __of_mdiobus_register(mdio, np, owner);
- if (ret) {
- devres_free(dr);
- return ret;
- }
- dr->mii = mdio;
- devres_add(dev, dr);
- return 0;
- }
- EXPORT_SYMBOL(__devm_of_mdiobus_register);
- #endif /* CONFIG_OF_MDIO */
- MODULE_LICENSE("GPL");
|