Merge branch 'genphy-ability'

Heiner Kallweit says:

====================
net: phy: use generic PHY ability readers if callback get_features isn't set

Meanwhile we have generic functions for reading the abilities of
Clause 22 / 45 PHY's. This allows to use them as fallback in case
callback get_features isn't set. Benefit is the reduction of
boilerplate code in PHY drivers.

v2:
- adjust a comment in patch 1 to match the code
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2019-04-04 17:55:37 -07:00
commit 29502bb127
2 changed files with 12 additions and 17 deletions

View File

@ -2143,12 +2143,17 @@ static int phy_probe(struct device *dev)
*/ */
if (phydrv->features) { if (phydrv->features) {
linkmode_copy(phydev->supported, phydrv->features); linkmode_copy(phydev->supported, phydrv->features);
} else { } else if (phydrv->get_features) {
err = phydrv->get_features(phydev); err = phydrv->get_features(phydev);
if (err) } else if (phydev->is_c45) {
goto out; err = genphy_c45_pma_read_abilities(phydev);
} else {
err = genphy_read_abilities(phydev);
} }
if (err)
goto out;
of_set_phy_supported(phydev); of_set_phy_supported(phydev);
linkmode_copy(phydev->advertising, phydev->supported); linkmode_copy(phydev->advertising, phydev->supported);
@ -2216,11 +2221,11 @@ int phy_driver_register(struct phy_driver *new_driver, struct module *owner)
int retval; int retval;
/* Either the features are hard coded, or dynamically /* Either the features are hard coded, or dynamically
* determine. It cannot be both or neither * determined. It cannot be both.
*/ */
if (WARN_ON((!new_driver->features && !new_driver->get_features) || if (WARN_ON(new_driver->features && new_driver->get_features)) {
(new_driver->features && new_driver->get_features))) { pr_err("%s: features and get_features must not both be set\n",
pr_err("%s: Driver features are missing\n", new_driver->name); new_driver->name);
return -EINVAL; return -EINVAL;
} }

View File

@ -199,11 +199,9 @@ static struct phy_driver realtek_drvs[] = {
{ {
PHY_ID_MATCH_EXACT(0x00008201), PHY_ID_MATCH_EXACT(0x00008201),
.name = "RTL8201CP Ethernet", .name = "RTL8201CP Ethernet",
.get_features = genphy_read_abilities,
}, { }, {
PHY_ID_MATCH_EXACT(0x001cc816), PHY_ID_MATCH_EXACT(0x001cc816),
.name = "RTL8201F Fast Ethernet", .name = "RTL8201F Fast Ethernet",
.get_features = genphy_read_abilities,
.ack_interrupt = &rtl8201_ack_interrupt, .ack_interrupt = &rtl8201_ack_interrupt,
.config_intr = &rtl8201_config_intr, .config_intr = &rtl8201_config_intr,
.suspend = genphy_suspend, .suspend = genphy_suspend,
@ -213,14 +211,12 @@ static struct phy_driver realtek_drvs[] = {
}, { }, {
PHY_ID_MATCH_EXACT(0x001cc910), PHY_ID_MATCH_EXACT(0x001cc910),
.name = "RTL8211 Gigabit Ethernet", .name = "RTL8211 Gigabit Ethernet",
.get_features = genphy_read_abilities,
.config_aneg = rtl8211_config_aneg, .config_aneg = rtl8211_config_aneg,
.read_mmd = &genphy_read_mmd_unsupported, .read_mmd = &genphy_read_mmd_unsupported,
.write_mmd = &genphy_write_mmd_unsupported, .write_mmd = &genphy_write_mmd_unsupported,
}, { }, {
PHY_ID_MATCH_EXACT(0x001cc912), PHY_ID_MATCH_EXACT(0x001cc912),
.name = "RTL8211B Gigabit Ethernet", .name = "RTL8211B Gigabit Ethernet",
.get_features = genphy_read_abilities,
.ack_interrupt = &rtl821x_ack_interrupt, .ack_interrupt = &rtl821x_ack_interrupt,
.config_intr = &rtl8211b_config_intr, .config_intr = &rtl8211b_config_intr,
.read_mmd = &genphy_read_mmd_unsupported, .read_mmd = &genphy_read_mmd_unsupported,
@ -230,14 +226,12 @@ static struct phy_driver realtek_drvs[] = {
}, { }, {
PHY_ID_MATCH_EXACT(0x001cc913), PHY_ID_MATCH_EXACT(0x001cc913),
.name = "RTL8211C Gigabit Ethernet", .name = "RTL8211C Gigabit Ethernet",
.get_features = genphy_read_abilities,
.config_init = rtl8211c_config_init, .config_init = rtl8211c_config_init,
.read_mmd = &genphy_read_mmd_unsupported, .read_mmd = &genphy_read_mmd_unsupported,
.write_mmd = &genphy_write_mmd_unsupported, .write_mmd = &genphy_write_mmd_unsupported,
}, { }, {
PHY_ID_MATCH_EXACT(0x001cc914), PHY_ID_MATCH_EXACT(0x001cc914),
.name = "RTL8211DN Gigabit Ethernet", .name = "RTL8211DN Gigabit Ethernet",
.get_features = genphy_read_abilities,
.ack_interrupt = rtl821x_ack_interrupt, .ack_interrupt = rtl821x_ack_interrupt,
.config_intr = rtl8211e_config_intr, .config_intr = rtl8211e_config_intr,
.suspend = genphy_suspend, .suspend = genphy_suspend,
@ -245,7 +239,6 @@ static struct phy_driver realtek_drvs[] = {
}, { }, {
PHY_ID_MATCH_EXACT(0x001cc915), PHY_ID_MATCH_EXACT(0x001cc915),
.name = "RTL8211E Gigabit Ethernet", .name = "RTL8211E Gigabit Ethernet",
.get_features = genphy_read_abilities,
.ack_interrupt = &rtl821x_ack_interrupt, .ack_interrupt = &rtl821x_ack_interrupt,
.config_intr = &rtl8211e_config_intr, .config_intr = &rtl8211e_config_intr,
.suspend = genphy_suspend, .suspend = genphy_suspend,
@ -253,7 +246,6 @@ static struct phy_driver realtek_drvs[] = {
}, { }, {
PHY_ID_MATCH_EXACT(0x001cc916), PHY_ID_MATCH_EXACT(0x001cc916),
.name = "RTL8211F Gigabit Ethernet", .name = "RTL8211F Gigabit Ethernet",
.get_features = genphy_read_abilities,
.config_init = &rtl8211f_config_init, .config_init = &rtl8211f_config_init,
.ack_interrupt = &rtl8211f_ack_interrupt, .ack_interrupt = &rtl8211f_ack_interrupt,
.config_intr = &rtl8211f_config_intr, .config_intr = &rtl8211f_config_intr,
@ -264,7 +256,6 @@ static struct phy_driver realtek_drvs[] = {
}, { }, {
PHY_ID_MATCH_EXACT(0x001cc800), PHY_ID_MATCH_EXACT(0x001cc800),
.name = "Generic Realtek PHY", .name = "Generic Realtek PHY",
.get_features = genphy_read_abilities,
.suspend = genphy_suspend, .suspend = genphy_suspend,
.resume = genphy_resume, .resume = genphy_resume,
.read_page = rtl821x_read_page, .read_page = rtl821x_read_page,
@ -272,7 +263,6 @@ static struct phy_driver realtek_drvs[] = {
}, { }, {
PHY_ID_MATCH_EXACT(0x001cc961), PHY_ID_MATCH_EXACT(0x001cc961),
.name = "RTL8366RB Gigabit Ethernet", .name = "RTL8366RB Gigabit Ethernet",
.get_features = genphy_read_abilities,
.config_init = &rtl8366rb_config_init, .config_init = &rtl8366rb_config_init,
/* These interrupts are handled by the irq controller /* These interrupts are handled by the irq controller
* embedded inside the RTL8366RB, they get unmasked when the * embedded inside the RTL8366RB, they get unmasked when the