aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/phy.c
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2013-05-19 18:53:43 -0400
committerDavid S. Miller <davem@davemloft.net>2013-05-20 17:13:08 -0400
commit5ea94e7686a3aa04cc0d01a2d8bd3d0292b3f592 (patch)
treec698dd2f66fc211a06deab14696ed7d998616b0f /drivers/net/phy/phy.c
parent2c7b49212a86f13697281a4dace2cb96aec71d6b (diff)
phy: add phy_mac_interrupt() to use with PHY_IGNORE_INTERRUPT
There is currently no way for an Ethernet MAC driver servicing PHY link interrupts to notify this to the PHY state machine without defining its own state machine. Since most drivers are not so special, introduce a helper: phy_mac_interrupt() which can be called from a link up/down interrupt routine to update the PHY state machine. To avoid code duplication some refactoring has been done to expose the workqueue and its corresponding callback internally. 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.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 3bcf0994d3ba..2d28a0ef4572 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -419,8 +419,6 @@ out_unlock:
419EXPORT_SYMBOL(phy_start_aneg); 419EXPORT_SYMBOL(phy_start_aneg);
420 420
421 421
422static void phy_change(struct work_struct *work);
423
424/** 422/**
425 * phy_start_machine - start PHY state machine tracking 423 * phy_start_machine - start PHY state machine tracking
426 * @phydev: the phy_device struct 424 * @phydev: the phy_device struct
@@ -565,8 +563,6 @@ int phy_start_interrupts(struct phy_device *phydev)
565{ 563{
566 int err = 0; 564 int err = 0;
567 565
568 INIT_WORK(&phydev->phy_queue, phy_change);
569
570 atomic_set(&phydev->irq_disable, 0); 566 atomic_set(&phydev->irq_disable, 0);
571 if (request_irq(phydev->irq, phy_interrupt, 567 if (request_irq(phydev->irq, phy_interrupt,
572 IRQF_SHARED, 568 IRQF_SHARED,
@@ -623,7 +619,7 @@ EXPORT_SYMBOL(phy_stop_interrupts);
623 * phy_change - Scheduled by the phy_interrupt/timer to handle PHY changes 619 * phy_change - Scheduled by the phy_interrupt/timer to handle PHY changes
624 * @work: work_struct that describes the work to be done 620 * @work: work_struct that describes the work to be done
625 */ 621 */
626static void phy_change(struct work_struct *work) 622void phy_change(struct work_struct *work)
627{ 623{
628 int err; 624 int err;
629 struct phy_device *phydev = 625 struct phy_device *phydev =
@@ -922,6 +918,14 @@ void phy_state_machine(struct work_struct *work)
922 schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ); 918 schedule_delayed_work(&phydev->state_queue, PHY_STATE_TIME * HZ);
923} 919}
924 920
921void phy_mac_interrupt(struct phy_device *phydev, int new_link)
922{
923 cancel_work_sync(&phydev->phy_queue);
924 phydev->link = new_link;
925 schedule_work(&phydev->phy_queue);
926}
927EXPORT_SYMBOL(phy_mac_interrupt);
928
925static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad, 929static inline void mmd_phy_indirect(struct mii_bus *bus, int prtad, int devad,
926 int addr) 930 int addr)
927{ 931{