Commit bc992abe authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-phy-stop-exporting-phy_driver_register'

Heiner Kallweit says:

====================
net: phy: stop exporting phy_driver_register

Once the last user of a clock in dp83640 has been removed, the clock should
be removed. So far orphaned clocks are cleaned up in dp83640_free_clocks()
only. Add the logic to remove orphaned clocks in dp83640_remove().
This allows to simplify the code, and use standard macro
module_phy_driver(). dp83640 was the last external user of
phy_driver_register(), so we can stop exporting this function afterwards.
====================

Link: https://patch.msgid.link/b86c2ecc-41f6-4f7f-85db-b7fa684d1fb7@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 7e554f31 092263a0
Loading
Loading
Loading
Loading
+20 −38
Original line number Diff line number Diff line
@@ -953,30 +953,6 @@ static void decode_status_frame(struct dp83640_private *dp83640,
	}
}

static void dp83640_free_clocks(void)
{
	struct dp83640_clock *clock;
	struct list_head *this, *next;

	mutex_lock(&phyter_clocks_lock);

	list_for_each_safe(this, next, &phyter_clocks) {
		clock = list_entry(this, struct dp83640_clock, list);
		if (!list_empty(&clock->phylist)) {
			pr_warn("phy list non-empty while unloading\n");
			BUG();
		}
		list_del(&clock->list);
		mutex_destroy(&clock->extreg_lock);
		mutex_destroy(&clock->clock_lock);
		put_device(&clock->bus->dev);
		kfree(clock->caps.pin_config);
		kfree(clock);
	}

	mutex_unlock(&phyter_clocks_lock);
}

static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
{
	INIT_LIST_HEAD(&clock->list);
@@ -1479,6 +1455,7 @@ static void dp83640_remove(struct phy_device *phydev)
	struct dp83640_clock *clock;
	struct list_head *this, *next;
	struct dp83640_private *tmp, *dp83640 = phydev->priv;
	bool remove_clock = false;

	if (phydev->mdio.addr == BROADCAST_ADDR)
		return;
@@ -1506,11 +1483,27 @@ static void dp83640_remove(struct phy_device *phydev)
		}
	}

	if (!clock->chosen && list_empty(&clock->phylist))
		remove_clock = true;

	dp83640_clock_put(clock);
	kfree(dp83640);

	if (remove_clock) {
		mutex_lock(&phyter_clocks_lock);
		list_del(&clock->list);
		mutex_unlock(&phyter_clocks_lock);

		mutex_destroy(&clock->extreg_lock);
		mutex_destroy(&clock->clock_lock);
		put_device(&clock->bus->dev);
		kfree(clock->caps.pin_config);
		kfree(clock);
	}
}

static struct phy_driver dp83640_driver = {
static struct phy_driver dp83640_driver[] = {
{
	.phy_id		= DP83640_PHY_ID,
	.phy_id_mask	= 0xfffffff0,
	.name		= "NatSemi DP83640",
@@ -1521,26 +1514,15 @@ static struct phy_driver dp83640_driver = {
	.config_init	= dp83640_config_init,
	.config_intr    = dp83640_config_intr,
	.handle_interrupt = dp83640_handle_interrupt,
},
};

static int __init dp83640_init(void)
{
	return phy_driver_register(&dp83640_driver, THIS_MODULE);
}

static void __exit dp83640_exit(void)
{
	dp83640_free_clocks();
	phy_driver_unregister(&dp83640_driver);
}
module_phy_driver(dp83640_driver);

MODULE_DESCRIPTION("National Semiconductor DP83640 PHY driver");
MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>");
MODULE_LICENSE("GPL");

module_init(dp83640_init);
module_exit(dp83640_exit);

static const struct mdio_device_id __maybe_unused dp83640_tbl[] = {
	{ DP83640_PHY_ID, 0xfffffff0 },
	{ }
+2 −2
Original line number Diff line number Diff line
@@ -3544,7 +3544,8 @@ static int phy_remove(struct device *dev)
 * @new_driver: new phy_driver to register
 * @owner: module owning this PHY
 */
int phy_driver_register(struct phy_driver *new_driver, struct module *owner)
static int phy_driver_register(struct phy_driver *new_driver,
			       struct module *owner)
{
	int retval;

@@ -3587,7 +3588,6 @@ int phy_driver_register(struct phy_driver *new_driver, struct module *owner)

	return 0;
}
EXPORT_SYMBOL(phy_driver_register);

int phy_drivers_register(struct phy_driver *new_driver, int n,
			 struct module *owner)
+0 −1
Original line number Diff line number Diff line
@@ -2032,7 +2032,6 @@ static inline int phy_read_status(struct phy_device *phydev)

void phy_driver_unregister(struct phy_driver *drv);
void phy_drivers_unregister(struct phy_driver *drv, int n);
int phy_driver_register(struct phy_driver *new_driver, struct module *owner);
int phy_drivers_register(struct phy_driver *new_driver, int n,
			 struct module *owner);
void phy_error(struct phy_device *phydev);