diff options
author | Johan Hovold <johan@kernel.org> | 2014-11-19 12:59:15 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-21 14:08:56 -0500 |
commit | e6a423a81da0eb3da755428f4d2df5a9ba13030f (patch) | |
tree | ae09e944694fc97a589220c85781a36a65d3c25c /drivers/net | |
parent | 860f6e9eb780443381a76e3766a9698afbc5e2e5 (diff) | |
download | linux-e6a423a81da0eb3da755428f4d2df5a9ba13030f.tar.bz2 |
net: phy: micrel: add device-type abstraction
Add structured device-type information and support for generic led-mode
setup to the generic config_init callback.
This is a first step in ultimately getting rid of device-type specific
callbacks.
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/phy/micrel.c | 83 |
1 files changed, 70 insertions, 13 deletions
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 30e894d6ffbd..1b528137afd9 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -73,6 +73,30 @@ #define PS_TO_REG 200 +struct kszphy_type { + u32 led_mode_reg; +}; + +struct kszphy_priv { + const struct kszphy_type *type; +}; + +static const struct kszphy_type ksz8021_type = { + .led_mode_reg = MII_KSZPHY_CTRL_2, +}; + +static const struct kszphy_type ksz8041_type = { + .led_mode_reg = MII_KSZPHY_CTRL_1, +}; + +static const struct kszphy_type ksz8051_type = { + .led_mode_reg = MII_KSZPHY_CTRL_2, +}; + +static const struct kszphy_type ksz8081_type = { + .led_mode_reg = MII_KSZPHY_CTRL_2, +}; + static int ksz_config_flags(struct phy_device *phydev) { int regval; @@ -229,19 +253,25 @@ out: static int kszphy_config_init(struct phy_device *phydev) { - return 0; -} + struct kszphy_priv *priv = phydev->priv; + const struct kszphy_type *type; -static int kszphy_config_init_led8041(struct phy_device *phydev) -{ - return kszphy_setup_led(phydev, MII_KSZPHY_CTRL_1); + if (!priv) + return 0; + + type = priv->type; + + if (type->led_mode_reg) + kszphy_setup_led(phydev, type->led_mode_reg); + + return 0; } static int ksz8021_config_init(struct phy_device *phydev) { int rc; - kszphy_setup_led(phydev, MII_KSZPHY_CTRL_2); + kszphy_config_init(phydev); rc = ksz_config_flags(phydev); if (rc < 0) @@ -256,7 +286,7 @@ static int ks8051_config_init(struct phy_device *phydev) { int rc; - kszphy_setup_led(phydev, MII_KSZPHY_CTRL_2); + kszphy_config_init(phydev); rc = ksz_config_flags(phydev); return rc < 0 ? rc : 0; @@ -265,9 +295,8 @@ static int ks8051_config_init(struct phy_device *phydev) static int ksz8081_config_init(struct phy_device *phydev) { kszphy_broadcast_disable(phydev); - kszphy_setup_led(phydev, MII_KSZPHY_CTRL_2); - return 0; + return kszphy_config_init(phydev); } static int ksz9021_load_values_from_of(struct phy_device *phydev, @@ -499,6 +528,22 @@ ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum, { } +static int kszphy_probe(struct phy_device *phydev) +{ + const struct kszphy_type *type = phydev->drv->driver_data; + struct kszphy_priv *priv; + + priv = devm_kzalloc(&phydev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + phydev->priv = priv; + + priv->type = type; + + return 0; +} + static int ksz8021_probe(struct phy_device *phydev) { struct clk *clk; @@ -517,7 +562,7 @@ static int ksz8021_probe(struct phy_device *phydev) } } - return 0; + return kszphy_probe(phydev); } static struct phy_driver ksphy_driver[] = { @@ -542,6 +587,7 @@ static struct phy_driver ksphy_driver[] = { .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .driver_data = &ksz8021_type, .probe = ksz8021_probe, .config_init = ksz8021_config_init, .config_aneg = genphy_config_aneg, @@ -558,6 +604,7 @@ static struct phy_driver ksphy_driver[] = { .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .driver_data = &ksz8021_type, .probe = ksz8021_probe, .config_init = ksz8021_config_init, .config_aneg = genphy_config_aneg, @@ -574,7 +621,9 @@ static struct phy_driver ksphy_driver[] = { .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = kszphy_config_init_led8041, + .driver_data = &ksz8041_type, + .probe = kszphy_probe, + .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, @@ -589,7 +638,9 @@ static struct phy_driver ksphy_driver[] = { .features = PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause, .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = kszphy_config_init_led8041, + .driver_data = &ksz8041_type, + .probe = kszphy_probe, + .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, @@ -604,6 +655,8 @@ static struct phy_driver ksphy_driver[] = { .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .driver_data = &ksz8051_type, + .probe = kszphy_probe, .config_init = ks8051_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, @@ -618,7 +671,9 @@ static struct phy_driver ksphy_driver[] = { .phy_id_mask = 0x00ffffff, .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, - .config_init = kszphy_config_init_led8041, + .driver_data = &ksz8041_type, + .probe = kszphy_probe, + .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, @@ -632,6 +687,8 @@ static struct phy_driver ksphy_driver[] = { .phy_id_mask = 0x00fffff0, .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, + .driver_data = &ksz8081_type, + .probe = kszphy_probe, .config_init = ksz8081_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, |