aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/phy.c
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2013-05-19 18:53:42 -0400
committerDavid S. Miller <davem@davemloft.net>2013-05-20 17:13:08 -0400
commit2c7b49212a86f13697281a4dace2cb96aec71d6b (patch)
tree315bc489f7c0ee3a9c55ae86041bc1846acc2a05 /drivers/net/phy/phy.c
parent45e983414334f217c60bd04d39d6f5ec2d8d7bb4 (diff)
phy: fix the use of PHY_IGNORE_INTERRUPT
When a PHY device is registered with the special IRQ value PHY_IGNORE_INTERRUPT (-2) it will not properly be handled by the PHY library: - it continues to poll its register, while we do not want this because such PHY link events or register changes are serviced by an Ethernet MAC - it will still try to configure PHY interrupts at the PHY level, such interrupts do not exist at the PHY but at the MAC level - the state machine only handles PHY_POLL, but should also handle PHY_IGNORE_INTERRUPT similarly This patch updates the PHY state machine and initialization paths to account for the specific PHY_IGNORE_INTERRUPT. Based on an earlier patch by Thomas Petazzoni, and reworked to add the missing bits. Add a helper phy_interrupt_is_valid() which specifically tests for a PHY interrupt not to be PHY_POLL or PHY_IGNORE_INTERRUPT and use it throughout the code. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy/phy.c')
-rw-r--r--drivers/net/phy/phy.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index c14f14741b3f..3bcf0994d3ba 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -682,7 +682,7 @@ void phy_stop(struct phy_device *phydev)
682 if (PHY_HALTED == phydev->state) 682 if (PHY_HALTED == phydev->state)
683 goto out_unlock; 683 goto out_unlock;
684 684
685 if (phydev->irq != PHY_POLL) { 685 if (phy_interrupt_is_valid(phydev)) {
686 /* Disable PHY Interrupts */ 686 /* Disable PHY Interrupts */
687 phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED); 687 phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
688 688
@@ -828,8 +828,9 @@ void phy_state_machine(struct work_struct *work)
828 break; 828 break;
829 case PHY_RUNNING: 829 case PHY_RUNNING:
830 /* Only register a CHANGE if we are 830 /* Only register a CHANGE if we are
831 * polling */ 831 * polling or ignoring interrupts
832 if (PHY_POLL == phydev->irq) 832 */
833 if (!phy_interrupt_is_valid(phydev))
833 phydev->state = PHY_CHANGELINK; 834 phydev->state = PHY_CHANGELINK;
834 break; 835 break;
835 case PHY_CHANGELINK: 836 case PHY_CHANGELINK:
@@ -848,7 +849,7 @@ void phy_state_machine(struct work_struct *work)
848 849
849 phydev->adjust_link(phydev->attached_dev); 850 phydev->adjust_link(phydev->attached_dev);
850 851
851 if (PHY_POLL != phydev->irq) 852 if (phy_interrupt_is_valid(phydev))
852 err = phy_config_interrupt(phydev, 853 err = phy_config_interrupt(phydev,
853 PHY_INTERRUPT_ENABLED); 854 PHY_INTERRUPT_ENABLED);
854 break; 855 break;