net: phy: dp83640: improve phydev and driver removal handling
Once the last user of a clock 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. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Link: https://patch.msgid.link/6d4e80e7-c684-4d95-abbd-ea62b79a9a8a@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>pull/1354/merge
parent
7e554f317b
commit
42e2a9e11a
|
|
@ -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)
|
static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
|
||||||
{
|
{
|
||||||
INIT_LIST_HEAD(&clock->list);
|
INIT_LIST_HEAD(&clock->list);
|
||||||
|
|
@ -1479,6 +1455,7 @@ static void dp83640_remove(struct phy_device *phydev)
|
||||||
struct dp83640_clock *clock;
|
struct dp83640_clock *clock;
|
||||||
struct list_head *this, *next;
|
struct list_head *this, *next;
|
||||||
struct dp83640_private *tmp, *dp83640 = phydev->priv;
|
struct dp83640_private *tmp, *dp83640 = phydev->priv;
|
||||||
|
bool remove_clock = false;
|
||||||
|
|
||||||
if (phydev->mdio.addr == BROADCAST_ADDR)
|
if (phydev->mdio.addr == BROADCAST_ADDR)
|
||||||
return;
|
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);
|
dp83640_clock_put(clock);
|
||||||
kfree(dp83640);
|
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 = DP83640_PHY_ID,
|
||||||
.phy_id_mask = 0xfffffff0,
|
.phy_id_mask = 0xfffffff0,
|
||||||
.name = "NatSemi DP83640",
|
.name = "NatSemi DP83640",
|
||||||
|
|
@ -1521,26 +1514,15 @@ static struct phy_driver dp83640_driver = {
|
||||||
.config_init = dp83640_config_init,
|
.config_init = dp83640_config_init,
|
||||||
.config_intr = dp83640_config_intr,
|
.config_intr = dp83640_config_intr,
|
||||||
.handle_interrupt = dp83640_handle_interrupt,
|
.handle_interrupt = dp83640_handle_interrupt,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init dp83640_init(void)
|
module_phy_driver(dp83640_driver);
|
||||||
{
|
|
||||||
return phy_driver_register(&dp83640_driver, THIS_MODULE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __exit dp83640_exit(void)
|
|
||||||
{
|
|
||||||
dp83640_free_clocks();
|
|
||||||
phy_driver_unregister(&dp83640_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
MODULE_DESCRIPTION("National Semiconductor DP83640 PHY driver");
|
MODULE_DESCRIPTION("National Semiconductor DP83640 PHY driver");
|
||||||
MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>");
|
MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
module_init(dp83640_init);
|
|
||||||
module_exit(dp83640_exit);
|
|
||||||
|
|
||||||
static const struct mdio_device_id __maybe_unused dp83640_tbl[] = {
|
static const struct mdio_device_id __maybe_unused dp83640_tbl[] = {
|
||||||
{ DP83640_PHY_ID, 0xfffffff0 },
|
{ DP83640_PHY_ID, 0xfffffff0 },
|
||||||
{ }
|
{ }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue