diff options
Diffstat (limited to 'drivers/net/phy/phy.c')
| -rw-r--r-- | drivers/net/phy/phy.c | 56 | 
1 files changed, 13 insertions, 43 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index ed10d1fc8f59..f3313a129531 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -493,7 +493,10 @@ static int phy_start_aneg_priv(struct phy_device *phydev, bool sync)  	/* Invalidate LP advertising flags */  	phydev->lp_advertising = 0; -	err = phydev->drv->config_aneg(phydev); +	if (phydev->drv->config_aneg) +		err = phydev->drv->config_aneg(phydev); +	else +		err = genphy_config_aneg(phydev);  	if (err < 0)  		goto out_unlock; @@ -629,9 +632,6 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)  	if (PHY_HALTED == phydev->state)  		return IRQ_NONE;		/* It can't be ours.  */ -	disable_irq_nosync(irq); -	atomic_inc(&phydev->irq_disable); -  	phy_change(phydev);  	return IRQ_HANDLED; @@ -689,7 +689,6 @@ phy_err:   */  int phy_start_interrupts(struct phy_device *phydev)  { -	atomic_set(&phydev->irq_disable, 0);  	if (request_threaded_irq(phydev->irq, NULL, phy_interrupt,  				 IRQF_ONESHOT | IRQF_SHARED,  				 phydev_name(phydev), phydev) < 0) { @@ -716,13 +715,6 @@ int phy_stop_interrupts(struct phy_device *phydev)  	free_irq(phydev->irq, phydev); -	/* If work indeed has been cancelled, disable_irq() will have -	 * been left unbalanced from phy_interrupt() and enable_irq() -	 * has to be called so that other devices on the line work. -	 */ -	while (atomic_dec_return(&phydev->irq_disable) >= 0) -		enable_irq(phydev->irq); -  	return err;  }  EXPORT_SYMBOL(phy_stop_interrupts); @@ -736,10 +728,11 @@ void phy_change(struct phy_device *phydev)  	if (phy_interrupt_is_valid(phydev)) {  		if (phydev->drv->did_interrupt &&  		    !phydev->drv->did_interrupt(phydev)) -			goto ignore; +			return; -		if (phy_disable_interrupts(phydev)) -			goto phy_err; +		if (phydev->state == PHY_HALTED) +			if (phy_disable_interrupts(phydev)) +				goto phy_err;  	}  	mutex_lock(&phydev->lock); @@ -747,28 +740,13 @@ void phy_change(struct phy_device *phydev)  		phydev->state = PHY_CHANGELINK;  	mutex_unlock(&phydev->lock); -	if (phy_interrupt_is_valid(phydev)) { -		atomic_dec(&phydev->irq_disable); -		enable_irq(phydev->irq); - -		/* Reenable interrupts */ -		if (PHY_HALTED != phydev->state && -		    phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED)) -			goto irq_enable_err; -	} -  	/* reschedule state queue work to run as soon as possible */  	phy_trigger_machine(phydev, true); -	return; -ignore: -	atomic_dec(&phydev->irq_disable); -	enable_irq(phydev->irq); +	if (phy_interrupt_is_valid(phydev) && phy_clear_interrupt(phydev)) +		goto phy_err;  	return; -irq_enable_err: -	disable_irq(phydev->irq); -	atomic_inc(&phydev->irq_disable);  phy_err:  	phy_error(phydev);  } @@ -1003,10 +981,6 @@ void phy_state_machine(struct work_struct *work)  			phydev->state = PHY_NOLINK;  			phy_link_down(phydev, true);  		} - -		if (phy_interrupt_is_valid(phydev)) -			err = phy_config_interrupt(phydev, -						   PHY_INTERRUPT_ENABLED);  		break;  	case PHY_HALTED:  		if (phydev->link) { @@ -1083,16 +1057,12 @@ void phy_state_machine(struct work_struct *work)  /**   * phy_mac_interrupt - MAC says the link has changed   * @phydev: phy_device struct with changed link - * @new_link: Link is Up/Down.   * - * Description: The MAC layer is able indicate there has been a change - *   in the PHY link status. Set the new link status, and trigger the - *   state machine, work a work queue. + * The MAC layer is able to indicate there has been a change in the PHY link + * status. Trigger the state machine and work a work queue.   */ -void phy_mac_interrupt(struct phy_device *phydev, int new_link) +void phy_mac_interrupt(struct phy_device *phydev)  { -	phydev->link = new_link; -  	/* Trigger a state machine change */  	queue_work(system_power_efficient_wq, &phydev->phy_queue);  }  |