diff options
author | Heiner Kallweit <hkallweit1@gmail.com> | 2018-11-11 21:49:12 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-11-15 09:30:00 -0800 |
commit | ba2f55b06826fb51f15e3cb04b4457be5f66e0ef (patch) | |
tree | 7affa25cde1839f873613a3147c1e2abd7638976 | |
parent | 6d5db6c37929cb0a84e64ba0590a74593e5ce3b8 (diff) |
net: phy: icplus: add config_intr callback
Move IRQ configuration for IP101A/G from config_init to config_intr
callback. Reasons:
1. This allows phylib to disable interrupts if needed.
2. Icplus was the only driver supporting interrupts w/o defining a
config_intr callback. Now we can add a phylib plausibility check
disabling interrupt mode if one of the two irq-related callbacks
isn't defined.
I don't own hardware with this PHY, and the change is based on the
datasheet for IP101A LF (which is supposed to be register-compatible
with IP101A/G). Change is compile-tested only.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/phy/icplus.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index 21ce68964204..ad87bd3280d7 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -42,8 +42,8 @@ MODULE_LICENSE("GPL"); #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ #define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ #define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */ -#define IP101A_G_IRQ_PIN_USED (1<<15) /* INTR pin used */ -#define IP101A_G_IRQ_DEFAULT IP101A_G_IRQ_PIN_USED +#define IP101A_G_IRQ_PIN_USED BIT(15) /* INTR pin used */ +#define IP101A_G_NO_IRQ BIT(11) /* IRQ's inactive */ static int ip175c_config_init(struct phy_device *phydev) { @@ -170,11 +170,6 @@ static int ip101a_g_config_init(struct phy_device *phydev) if (c < 0) return c; - /* INTR pin used: speed/link/duplex will cause an interrupt */ - c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT); - if (c < 0) - return c; - /* Enable Auto Power Saving mode */ c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); c |= IP101A_G_APS_ON; @@ -201,6 +196,19 @@ static int ip175c_config_aneg(struct phy_device *phydev) return 0; } +static int ip101a_g_config_intr(struct phy_device *phydev) +{ + u16 val; + + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) + /* INTR pin used: Speed/link/duplex will cause an interrupt */ + val = IP101A_G_IRQ_PIN_USED; + else + val = IP101A_G_NO_IRQ; + + return phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, val); +} + static int ip101a_g_ack_interrupt(struct phy_device *phydev) { int err = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS); @@ -234,6 +242,7 @@ static struct phy_driver icplus_driver[] = { .name = "ICPlus IP101A/G", .phy_id_mask = 0x0ffffff0, .features = PHY_BASIC_FEATURES, + .config_intr = ip101a_g_config_intr, .ack_interrupt = ip101a_g_ack_interrupt, .config_init = &ip101a_g_config_init, .suspend = genphy_suspend, |