aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/phy.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy/phy.c')
-rw-r--r--drivers/net/phy/phy.c68
1 files changed, 46 insertions, 22 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 7c9e6e349503..12fccb1c76dc 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -26,7 +26,6 @@
26#include <linux/netdevice.h> 26#include <linux/netdevice.h>
27#include <linux/etherdevice.h> 27#include <linux/etherdevice.h>
28#include <linux/skbuff.h> 28#include <linux/skbuff.h>
29#include <linux/spinlock.h>
30#include <linux/mm.h> 29#include <linux/mm.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/mii.h> 31#include <linux/mii.h>
@@ -72,9 +71,11 @@ int phy_read(struct phy_device *phydev, u16 regnum)
72 int retval; 71 int retval;
73 struct mii_bus *bus = phydev->bus; 72 struct mii_bus *bus = phydev->bus;
74 73
75 spin_lock_bh(&bus->mdio_lock); 74 BUG_ON(in_interrupt());
75
76 mutex_lock(&bus->mdio_lock);
76 retval = bus->read(bus, phydev->addr, regnum); 77 retval = bus->read(bus, phydev->addr, regnum);
77 spin_unlock_bh(&bus->mdio_lock); 78 mutex_unlock(&bus->mdio_lock);
78 79
79 return retval; 80 return retval;
80} 81}
@@ -95,9 +96,11 @@ int phy_write(struct phy_device *phydev, u16 regnum, u16 val)
95 int err; 96 int err;
96 struct mii_bus *bus = phydev->bus; 97 struct mii_bus *bus = phydev->bus;
97 98
98 spin_lock_bh(&bus->mdio_lock); 99 BUG_ON(in_interrupt());
100
101 mutex_lock(&bus->mdio_lock);
99 err = bus->write(bus, phydev->addr, regnum, val); 102 err = bus->write(bus, phydev->addr, regnum, val);
100 spin_unlock_bh(&bus->mdio_lock); 103 mutex_unlock(&bus->mdio_lock);
101 104
102 return err; 105 return err;
103} 106}
@@ -428,7 +431,7 @@ int phy_start_aneg(struct phy_device *phydev)
428{ 431{
429 int err; 432 int err;
430 433
431 spin_lock_bh(&phydev->lock); 434 mutex_lock(&phydev->lock);
432 435
433 if (AUTONEG_DISABLE == phydev->autoneg) 436 if (AUTONEG_DISABLE == phydev->autoneg)
434 phy_sanitize_settings(phydev); 437 phy_sanitize_settings(phydev);
@@ -449,13 +452,14 @@ int phy_start_aneg(struct phy_device *phydev)
449 } 452 }
450 453
451out_unlock: 454out_unlock:
452 spin_unlock_bh(&phydev->lock); 455 mutex_unlock(&phydev->lock);
453 return err; 456 return err;
454} 457}
455EXPORT_SYMBOL(phy_start_aneg); 458EXPORT_SYMBOL(phy_start_aneg);
456 459
457 460
458static void phy_change(struct work_struct *work); 461static void phy_change(struct work_struct *work);
462static void phy_state_machine(struct work_struct *work);
459static void phy_timer(unsigned long data); 463static void phy_timer(unsigned long data);
460 464
461/** 465/**
@@ -476,6 +480,7 @@ void phy_start_machine(struct phy_device *phydev,
476{ 480{
477 phydev->adjust_state = handler; 481 phydev->adjust_state = handler;
478 482
483 INIT_WORK(&phydev->state_queue, phy_state_machine);
479 init_timer(&phydev->phy_timer); 484 init_timer(&phydev->phy_timer);
480 phydev->phy_timer.function = &phy_timer; 485 phydev->phy_timer.function = &phy_timer;
481 phydev->phy_timer.data = (unsigned long) phydev; 486 phydev->phy_timer.data = (unsigned long) phydev;
@@ -493,11 +498,12 @@ void phy_start_machine(struct phy_device *phydev,
493void phy_stop_machine(struct phy_device *phydev) 498void phy_stop_machine(struct phy_device *phydev)
494{ 499{
495 del_timer_sync(&phydev->phy_timer); 500 del_timer_sync(&phydev->phy_timer);
501 cancel_work_sync(&phydev->state_queue);
496 502
497 spin_lock_bh(&phydev->lock); 503 mutex_lock(&phydev->lock);
498 if (phydev->state > PHY_UP) 504 if (phydev->state > PHY_UP)
499 phydev->state = PHY_UP; 505 phydev->state = PHY_UP;
500 spin_unlock_bh(&phydev->lock); 506 mutex_unlock(&phydev->lock);
501 507
502 phydev->adjust_state = NULL; 508 phydev->adjust_state = NULL;
503} 509}
@@ -541,9 +547,9 @@ static void phy_force_reduction(struct phy_device *phydev)
541 */ 547 */
542void phy_error(struct phy_device *phydev) 548void phy_error(struct phy_device *phydev)
543{ 549{
544 spin_lock_bh(&phydev->lock); 550 mutex_lock(&phydev->lock);
545 phydev->state = PHY_HALTED; 551 phydev->state = PHY_HALTED;
546 spin_unlock_bh(&phydev->lock); 552 mutex_unlock(&phydev->lock);
547} 553}
548 554
549/** 555/**
@@ -705,10 +711,10 @@ static void phy_change(struct work_struct *work)
705 if (err) 711 if (err)
706 goto phy_err; 712 goto phy_err;
707 713
708 spin_lock_bh(&phydev->lock); 714 mutex_lock(&phydev->lock);
709 if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state)) 715 if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state))
710 phydev->state = PHY_CHANGELINK; 716 phydev->state = PHY_CHANGELINK;
711 spin_unlock_bh(&phydev->lock); 717 mutex_unlock(&phydev->lock);
712 718
713 atomic_dec(&phydev->irq_disable); 719 atomic_dec(&phydev->irq_disable);
714 enable_irq(phydev->irq); 720 enable_irq(phydev->irq);
@@ -735,7 +741,7 @@ phy_err:
735 */ 741 */
736void phy_stop(struct phy_device *phydev) 742void phy_stop(struct phy_device *phydev)
737{ 743{
738 spin_lock_bh(&phydev->lock); 744 mutex_lock(&phydev->lock);
739 745
740 if (PHY_HALTED == phydev->state) 746 if (PHY_HALTED == phydev->state)
741 goto out_unlock; 747 goto out_unlock;
@@ -751,7 +757,7 @@ void phy_stop(struct phy_device *phydev)
751 phydev->state = PHY_HALTED; 757 phydev->state = PHY_HALTED;
752 758
753out_unlock: 759out_unlock:
754 spin_unlock_bh(&phydev->lock); 760 mutex_unlock(&phydev->lock);
755 761
756 /* 762 /*
757 * Cannot call flush_scheduled_work() here as desired because 763 * Cannot call flush_scheduled_work() here as desired because
@@ -773,7 +779,7 @@ out_unlock:
773 */ 779 */
774void phy_start(struct phy_device *phydev) 780void phy_start(struct phy_device *phydev)
775{ 781{
776 spin_lock_bh(&phydev->lock); 782 mutex_lock(&phydev->lock);
777 783
778 switch (phydev->state) { 784 switch (phydev->state) {
779 case PHY_STARTING: 785 case PHY_STARTING:
@@ -787,19 +793,26 @@ void phy_start(struct phy_device *phydev)
787 default: 793 default:
788 break; 794 break;
789 } 795 }
790 spin_unlock_bh(&phydev->lock); 796 mutex_unlock(&phydev->lock);
791} 797}
792EXPORT_SYMBOL(phy_stop); 798EXPORT_SYMBOL(phy_stop);
793EXPORT_SYMBOL(phy_start); 799EXPORT_SYMBOL(phy_start);
794 800
795/* PHY timer which handles the state machine */ 801/**
796static void phy_timer(unsigned long data) 802 * phy_state_machine - Handle the state machine
803 * @work: work_struct that describes the work to be done
804 *
805 * Description: Scheduled by the state_queue workqueue each time
806 * phy_timer is triggered.
807 */
808static void phy_state_machine(struct work_struct *work)
797{ 809{
798 struct phy_device *phydev = (struct phy_device *)data; 810 struct phy_device *phydev =
811 container_of(work, struct phy_device, state_queue);
799 int needs_aneg = 0; 812 int needs_aneg = 0;
800 int err = 0; 813 int err = 0;
801 814
802 spin_lock_bh(&phydev->lock); 815 mutex_lock(&phydev->lock);
803 816
804 if (phydev->adjust_state) 817 if (phydev->adjust_state)
805 phydev->adjust_state(phydev->attached_dev); 818 phydev->adjust_state(phydev->attached_dev);
@@ -965,7 +978,7 @@ static void phy_timer(unsigned long data)
965 break; 978 break;
966 } 979 }
967 980
968 spin_unlock_bh(&phydev->lock); 981 mutex_unlock(&phydev->lock);
969 982
970 if (needs_aneg) 983 if (needs_aneg)
971 err = phy_start_aneg(phydev); 984 err = phy_start_aneg(phydev);
@@ -976,3 +989,14 @@ static void phy_timer(unsigned long data)
976 mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ); 989 mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ);
977} 990}
978 991
992/* PHY timer which schedules the state machine work */
993static void phy_timer(unsigned long data)
994{
995 struct phy_device *phydev = (struct phy_device *)data;
996
997 /*
998 * PHY I/O operations can potentially sleep so we ensure that
999 * it's done from a process context
1000 */
1001 schedule_work(&phydev->state_queue);
1002}