net: phy: enable interrupts when PHY is attached already
This patch is a step towards allowing PHY drivers to handle more interrupt sources than just link change. E.g. several PHY's have built-in temperature monitoring and can raise an interrupt if a temperature threshold is exceeded. We may be interested in such interrupts also if the phylib state machine isn't started. Therefore move enabling interrupts to phy_request_interrupt(). v2: - patch added to series Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8e2ea3ea96
commit
07b0928918
@ -799,10 +799,10 @@ static int phy_enable_interrupts(struct phy_device *phydev)
|
||||
}
|
||||
|
||||
/**
|
||||
* phy_request_interrupt - request interrupt for a PHY device
|
||||
* phy_request_interrupt - request and enable interrupt for a PHY device
|
||||
* @phydev: target phy_device struct
|
||||
*
|
||||
* Description: Request the interrupt for the given PHY.
|
||||
* Description: Request and enable the interrupt for the given PHY.
|
||||
* If this fails, then we set irq to PHY_POLL.
|
||||
* This should only be called with a valid IRQ number.
|
||||
*/
|
||||
@ -817,10 +817,30 @@ void phy_request_interrupt(struct phy_device *phydev)
|
||||
phydev_warn(phydev, "Error %d requesting IRQ %d, falling back to polling\n",
|
||||
err, phydev->irq);
|
||||
phydev->irq = PHY_POLL;
|
||||
} else {
|
||||
if (phy_enable_interrupts(phydev)) {
|
||||
phydev_warn(phydev, "Can't enable interrupt, falling back to polling\n");
|
||||
phy_free_interrupt(phydev);
|
||||
phydev->irq = PHY_POLL;
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(phy_request_interrupt);
|
||||
|
||||
/**
|
||||
* phy_free_interrupt - disable and free interrupt for a PHY device
|
||||
* @phydev: target phy_device struct
|
||||
*
|
||||
* Description: Disable and free the interrupt for the given PHY.
|
||||
* This should only be called with a valid IRQ number.
|
||||
*/
|
||||
void phy_free_interrupt(struct phy_device *phydev)
|
||||
{
|
||||
phy_disable_interrupts(phydev);
|
||||
free_irq(phydev->irq, phydev);
|
||||
}
|
||||
EXPORT_SYMBOL(phy_free_interrupt);
|
||||
|
||||
/**
|
||||
* phy_stop - Bring down the PHY link, and stop checking the status
|
||||
* @phydev: target phy_device struct
|
||||
@ -835,9 +855,6 @@ void phy_stop(struct phy_device *phydev)
|
||||
|
||||
mutex_lock(&phydev->lock);
|
||||
|
||||
if (phy_interrupt_is_valid(phydev))
|
||||
phy_disable_interrupts(phydev);
|
||||
|
||||
phydev->state = PHY_HALTED;
|
||||
|
||||
mutex_unlock(&phydev->lock);
|
||||
@ -864,8 +881,6 @@ EXPORT_SYMBOL(phy_stop);
|
||||
*/
|
||||
void phy_start(struct phy_device *phydev)
|
||||
{
|
||||
int err;
|
||||
|
||||
mutex_lock(&phydev->lock);
|
||||
|
||||
if (phydev->state != PHY_READY && phydev->state != PHY_HALTED) {
|
||||
@ -877,13 +892,6 @@ void phy_start(struct phy_device *phydev)
|
||||
/* if phy was suspended, bring the physical link up again */
|
||||
__phy_resume(phydev);
|
||||
|
||||
/* make sure interrupts are enabled for the PHY */
|
||||
if (phy_interrupt_is_valid(phydev)) {
|
||||
err = phy_enable_interrupts(phydev);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
phydev->state = PHY_UP;
|
||||
|
||||
phy_start_machine(phydev);
|
||||
|
@ -1016,7 +1016,7 @@ void phy_disconnect(struct phy_device *phydev)
|
||||
phy_stop(phydev);
|
||||
|
||||
if (phy_interrupt_is_valid(phydev))
|
||||
free_irq(phydev->irq, phydev);
|
||||
phy_free_interrupt(phydev);
|
||||
|
||||
phydev->adjust_link = NULL;
|
||||
|
||||
|
@ -1147,6 +1147,7 @@ int phy_ethtool_ksettings_set(struct phy_device *phydev,
|
||||
const struct ethtool_link_ksettings *cmd);
|
||||
int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd);
|
||||
void phy_request_interrupt(struct phy_device *phydev);
|
||||
void phy_free_interrupt(struct phy_device *phydev);
|
||||
void phy_print_status(struct phy_device *phydev);
|
||||
int phy_set_max_speed(struct phy_device *phydev, u32 max_speed);
|
||||
void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode);
|
||||
|
Loading…
Reference in New Issue
Block a user