Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/phy: Add interrupt support for dp83640 phy.

Added functions for ack_interrupt and config_intr. Tested on an mpc5200b
powerpc board.

Signed-off-by: Stephan Gatzka <stephan.gatzka@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Stephan Gatzka and committed by
David S. Miller
1642182e 59e955ed

+77 -1
+77 -1
drivers/net/phy/dp83640.c
··· 48 48 #define CAL_TRIGGER 7 49 49 #define PER_TRIGGER 6 50 50 51 + #define MII_DP83640_MICR 0x11 52 + #define MII_DP83640_MISR 0x12 53 + 54 + #define MII_DP83640_MICR_OE 0x1 55 + #define MII_DP83640_MICR_IE 0x2 56 + 57 + #define MII_DP83640_MISR_RHF_INT_EN 0x01 58 + #define MII_DP83640_MISR_FHF_INT_EN 0x02 59 + #define MII_DP83640_MISR_ANC_INT_EN 0x04 60 + #define MII_DP83640_MISR_DUP_INT_EN 0x08 61 + #define MII_DP83640_MISR_SPD_INT_EN 0x10 62 + #define MII_DP83640_MISR_LINK_INT_EN 0x20 63 + #define MII_DP83640_MISR_ED_INT_EN 0x40 64 + #define MII_DP83640_MISR_LQ_INT_EN 0x80 65 + 51 66 /* phyter seems to miss the mark by 16 ns */ 52 67 #define ADJTIME_FIX 16 53 68 ··· 1058 1043 kfree(dp83640); 1059 1044 } 1060 1045 1046 + static int dp83640_ack_interrupt(struct phy_device *phydev) 1047 + { 1048 + int err = phy_read(phydev, MII_DP83640_MISR); 1049 + 1050 + if (err < 0) 1051 + return err; 1052 + 1053 + return 0; 1054 + } 1055 + 1056 + static int dp83640_config_intr(struct phy_device *phydev) 1057 + { 1058 + int micr; 1059 + int misr; 1060 + int err; 1061 + 1062 + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { 1063 + misr = phy_read(phydev, MII_DP83640_MISR); 1064 + if (misr < 0) 1065 + return misr; 1066 + misr |= 1067 + (MII_DP83640_MISR_ANC_INT_EN | 1068 + MII_DP83640_MISR_DUP_INT_EN | 1069 + MII_DP83640_MISR_SPD_INT_EN | 1070 + MII_DP83640_MISR_LINK_INT_EN); 1071 + err = phy_write(phydev, MII_DP83640_MISR, misr); 1072 + if (err < 0) 1073 + return err; 1074 + 1075 + micr = phy_read(phydev, MII_DP83640_MICR); 1076 + if (micr < 0) 1077 + return micr; 1078 + micr |= 1079 + (MII_DP83640_MICR_OE | 1080 + MII_DP83640_MICR_IE); 1081 + return phy_write(phydev, MII_DP83640_MICR, micr); 1082 + } else { 1083 + micr = phy_read(phydev, MII_DP83640_MICR); 1084 + if (micr < 0) 1085 + return micr; 1086 + micr &= 1087 + ~(MII_DP83640_MICR_OE | 1088 + MII_DP83640_MICR_IE); 1089 + err = phy_write(phydev, MII_DP83640_MICR, micr); 1090 + if (err < 0) 1091 + return err; 1092 + 1093 + misr = phy_read(phydev, MII_DP83640_MISR); 1094 + if (misr < 0) 1095 + return misr; 1096 + misr &= 1097 + ~(MII_DP83640_MISR_ANC_INT_EN | 1098 + MII_DP83640_MISR_DUP_INT_EN | 1099 + MII_DP83640_MISR_SPD_INT_EN | 1100 + MII_DP83640_MISR_LINK_INT_EN); 1101 + return phy_write(phydev, MII_DP83640_MISR, misr); 1102 + } 1103 + } 1104 + 1061 1105 static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) 1062 1106 { 1063 1107 struct dp83640_private *dp83640 = phydev->priv; ··· 1327 1253 .phy_id_mask = 0xfffffff0, 1328 1254 .name = "NatSemi DP83640", 1329 1255 .features = PHY_BASIC_FEATURES, 1330 - .flags = 0, 1256 + .flags = PHY_HAS_INTERRUPT, 1331 1257 .probe = dp83640_probe, 1332 1258 .remove = dp83640_remove, 1333 1259 .config_aneg = genphy_config_aneg, 1334 1260 .read_status = genphy_read_status, 1261 + .ack_interrupt = dp83640_ack_interrupt, 1262 + .config_intr = dp83640_config_intr, 1335 1263 .ts_info = dp83640_ts_info, 1336 1264 .hwtstamp = dp83640_hwtstamp, 1337 1265 .rxtstamp = dp83640_rxtstamp,