diff options
author | Florian Fainelli <f.fainelli@gmail.com> | 2013-05-19 18:53:42 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-05-20 17:13:08 -0400 |
commit | 2c7b49212a86f13697281a4dace2cb96aec71d6b (patch) | |
tree | 315bc489f7c0ee3a9c55ae86041bc1846acc2a05 /drivers/net/phy | |
parent | 45e983414334f217c60bd04d39d6f5ec2d8d7bb4 (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')
-rw-r--r-- | drivers/net/phy/phy.c | 9 | ||||
-rw-r--r-- | drivers/net/phy/phy_device.c | 7 |
2 files changed, 10 insertions, 6 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; |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 3657b4a29124..8e29d22ba113 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -1009,8 +1009,11 @@ static int phy_probe(struct device *dev) | |||
1009 | phydrv = to_phy_driver(drv); | 1009 | phydrv = to_phy_driver(drv); |
1010 | phydev->drv = phydrv; | 1010 | phydev->drv = phydrv; |
1011 | 1011 | ||
1012 | /* Disable the interrupt if the PHY doesn't support it */ | 1012 | /* Disable the interrupt if the PHY doesn't support it |
1013 | if (!(phydrv->flags & PHY_HAS_INTERRUPT)) | 1013 | * but the interrupt is still a valid one |
1014 | */ | ||
1015 | if (!(phydrv->flags & PHY_HAS_INTERRUPT) && | ||
1016 | phy_interrupt_is_valid(phydev)) | ||
1014 | phydev->irq = PHY_POLL; | 1017 | phydev->irq = PHY_POLL; |
1015 | 1018 | ||
1016 | mutex_lock(&phydev->lock); | 1019 | mutex_lock(&phydev->lock); |