generic: net: phy: realtek: add interrupt support for RTL8221B
This commit introduces interrupt support for RTL8221B. Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com> (cherry picked from commit 1db949a632607aa1df2987b7701da0be3e473260)
This commit is contained in:
		 Jianhui Zhao
					Jianhui Zhao
				
			
				
					committed by
					
						 Rafał Miłecki
						Rafał Miłecki
					
				
			
			
				
	
			
			
			 Rafał Miłecki
						Rafał Miłecki
					
				
			
						parent
						
							6143b730fc
						
					
				
				
					commit
					cc285dc2b6
				
			| @@ -0,0 +1,63 @@ | |||||||
|  | --- a/drivers/net/phy/realtek.c | ||||||
|  | +++ b/drivers/net/phy/realtek.c | ||||||
|  | @@ -971,6 +971,51 @@ static int rtl8221b_config_init(struct p | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static int rtl8221b_ack_interrupt(struct phy_device *phydev) | ||||||
|  | +{ | ||||||
|  | +	int err; | ||||||
|  | + | ||||||
|  | +	err = phy_read_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d4); | ||||||
|  | + | ||||||
|  | +	return (err < 0) ? err : 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int rtl8221b_config_intr(struct phy_device *phydev) | ||||||
|  | +{ | ||||||
|  | +	int err; | ||||||
|  | + | ||||||
|  | +	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { | ||||||
|  | +		err = rtl8221b_ack_interrupt(phydev); | ||||||
|  | +		if (err) | ||||||
|  | +			return err; | ||||||
|  | + | ||||||
|  | +		err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x7ff); | ||||||
|  | +	} else { | ||||||
|  | +		err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x0); | ||||||
|  | +		if (err) | ||||||
|  | +			return err; | ||||||
|  | + | ||||||
|  | +		err = rtl8221b_ack_interrupt(phydev); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return err; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev) | ||||||
|  | +{ | ||||||
|  | +	int err; | ||||||
|  | + | ||||||
|  | +	err = rtl8221b_ack_interrupt(phydev); | ||||||
|  | +	if (err) { | ||||||
|  | +		phy_error(phydev); | ||||||
|  | +		return IRQ_NONE; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	phy_trigger_machine(phydev); | ||||||
|  | + | ||||||
|  | +	return IRQ_HANDLED; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static struct phy_driver realtek_drvs[] = { | ||||||
|  |  	{ | ||||||
|  |  		PHY_ID_MATCH_EXACT(0x00008201), | ||||||
|  | @@ -1119,6 +1164,8 @@ static struct phy_driver realtek_drvs[] | ||||||
|  |  		.get_features   = rtl822x_get_features, | ||||||
|  |  		.config_init    = rtl8221b_config_init, | ||||||
|  |  		.config_aneg    = rtl822x_config_aneg, | ||||||
|  | +		.config_intr	= rtl8221b_config_intr, | ||||||
|  | +		.handle_interrupt = rtl8221b_handle_interrupt, | ||||||
|  |  		.probe          = rtl822x_probe, | ||||||
|  |  		.read_status    = rtl822x_read_status, | ||||||
|  |  		.suspend        = genphy_suspend, | ||||||
| @@ -0,0 +1,63 @@ | |||||||
|  | --- a/drivers/net/phy/realtek.c | ||||||
|  | +++ b/drivers/net/phy/realtek.c | ||||||
|  | @@ -979,6 +979,51 @@ static int rtl8221b_config_init(struct p | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static int rtl8221b_ack_interrupt(struct phy_device *phydev) | ||||||
|  | +{ | ||||||
|  | +	int err; | ||||||
|  | + | ||||||
|  | +	err = phy_read_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d4); | ||||||
|  | + | ||||||
|  | +	return (err < 0) ? err : 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int rtl8221b_config_intr(struct phy_device *phydev) | ||||||
|  | +{ | ||||||
|  | +	int err; | ||||||
|  | + | ||||||
|  | +	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { | ||||||
|  | +		err = rtl8221b_ack_interrupt(phydev); | ||||||
|  | +		if (err) | ||||||
|  | +			return err; | ||||||
|  | + | ||||||
|  | +		err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x7ff); | ||||||
|  | +	} else { | ||||||
|  | +		err = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, 0xa4d2, 0x0); | ||||||
|  | +		if (err) | ||||||
|  | +			return err; | ||||||
|  | + | ||||||
|  | +		err = rtl8221b_ack_interrupt(phydev); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return err; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static irqreturn_t rtl8221b_handle_interrupt(struct phy_device *phydev) | ||||||
|  | +{ | ||||||
|  | +	int err; | ||||||
|  | + | ||||||
|  | +	err = rtl8221b_ack_interrupt(phydev); | ||||||
|  | +	if (err) { | ||||||
|  | +		phy_error(phydev); | ||||||
|  | +		return IRQ_NONE; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	phy_trigger_machine(phydev); | ||||||
|  | + | ||||||
|  | +	return IRQ_HANDLED; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static struct phy_driver realtek_drvs[] = { | ||||||
|  |  	{ | ||||||
|  |  		PHY_ID_MATCH_EXACT(0x00008201), | ||||||
|  | @@ -1139,6 +1184,8 @@ static struct phy_driver realtek_drvs[] | ||||||
|  |  		.get_features   = rtl822x_get_features, | ||||||
|  |  		.config_init    = rtl8221b_config_init, | ||||||
|  |  		.config_aneg    = rtl822x_config_aneg, | ||||||
|  | +		.config_intr	= rtl8221b_config_intr, | ||||||
|  | +		.handle_interrupt = rtl8221b_handle_interrupt, | ||||||
|  |  		.probe          = rtl822x_probe, | ||||||
|  |  		.read_status    = rtl822x_read_status, | ||||||
|  |  		.suspend        = genphy_suspend, | ||||||
		Reference in New Issue
	
	Block a user