diff options
| author | Stephan Gatzka <stephan.gatzka@gmail.com> | 2012-12-04 05:21:38 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2012-12-05 16:01:28 -0500 |
| commit | 1642182ea0eedecc5d6f330c43cef8639327f0e5 (patch) | |
| tree | 357dced259176e94507954d95a68b2247e1b1ab2 /drivers | |
| parent | 59e955edb763375f8211c009c628ca37f1bc46c0 (diff) | |
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>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/phy/dp83640.c | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 24e05c43bff8..7490b6c866e6 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c | |||
| @@ -48,6 +48,21 @@ | |||
| 48 | #define CAL_TRIGGER 7 | 48 | #define CAL_TRIGGER 7 |
| 49 | #define PER_TRIGGER 6 | 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 | /* phyter seems to miss the mark by 16 ns */ | 66 | /* phyter seems to miss the mark by 16 ns */ |
| 52 | #define ADJTIME_FIX 16 | 67 | #define ADJTIME_FIX 16 |
| 53 | 68 | ||
| @@ -1043,6 +1058,65 @@ static void dp83640_remove(struct phy_device *phydev) | |||
| 1043 | kfree(dp83640); | 1058 | kfree(dp83640); |
| 1044 | } | 1059 | } |
| 1045 | 1060 | ||
| 1061 | static int dp83640_ack_interrupt(struct phy_device *phydev) | ||
| 1062 | { | ||
| 1063 | int err = phy_read(phydev, MII_DP83640_MISR); | ||
| 1064 | |||
| 1065 | if (err < 0) | ||
| 1066 | return err; | ||
| 1067 | |||
| 1068 | return 0; | ||
| 1069 | } | ||
| 1070 | |||
| 1071 | static int dp83640_config_intr(struct phy_device *phydev) | ||
| 1072 | { | ||
| 1073 | int micr; | ||
| 1074 | int misr; | ||
| 1075 | int err; | ||
| 1076 | |||
| 1077 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { | ||
| 1078 | misr = phy_read(phydev, MII_DP83640_MISR); | ||
| 1079 | if (misr < 0) | ||
| 1080 | return misr; | ||
| 1081 | misr |= | ||
| 1082 | (MII_DP83640_MISR_ANC_INT_EN | | ||
| 1083 | MII_DP83640_MISR_DUP_INT_EN | | ||
| 1084 | MII_DP83640_MISR_SPD_INT_EN | | ||
| 1085 | MII_DP83640_MISR_LINK_INT_EN); | ||
| 1086 | err = phy_write(phydev, MII_DP83640_MISR, misr); | ||
| 1087 | if (err < 0) | ||
| 1088 | return err; | ||
| 1089 | |||
| 1090 | micr = phy_read(phydev, MII_DP83640_MICR); | ||
| 1091 | if (micr < 0) | ||
| 1092 | return micr; | ||
| 1093 | micr |= | ||
| 1094 | (MII_DP83640_MICR_OE | | ||
| 1095 | MII_DP83640_MICR_IE); | ||
| 1096 | return phy_write(phydev, MII_DP83640_MICR, micr); | ||
| 1097 | } else { | ||
| 1098 | micr = phy_read(phydev, MII_DP83640_MICR); | ||
| 1099 | if (micr < 0) | ||
| 1100 | return micr; | ||
| 1101 | micr &= | ||
| 1102 | ~(MII_DP83640_MICR_OE | | ||
| 1103 | MII_DP83640_MICR_IE); | ||
| 1104 | err = phy_write(phydev, MII_DP83640_MICR, micr); | ||
| 1105 | if (err < 0) | ||
| 1106 | return err; | ||
| 1107 | |||
| 1108 | misr = phy_read(phydev, MII_DP83640_MISR); | ||
| 1109 | if (misr < 0) | ||
| 1110 | return misr; | ||
| 1111 | misr &= | ||
| 1112 | ~(MII_DP83640_MISR_ANC_INT_EN | | ||
| 1113 | MII_DP83640_MISR_DUP_INT_EN | | ||
| 1114 | MII_DP83640_MISR_SPD_INT_EN | | ||
| 1115 | MII_DP83640_MISR_LINK_INT_EN); | ||
| 1116 | return phy_write(phydev, MII_DP83640_MISR, misr); | ||
| 1117 | } | ||
| 1118 | } | ||
| 1119 | |||
| 1046 | static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) | 1120 | static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) |
| 1047 | { | 1121 | { |
| 1048 | struct dp83640_private *dp83640 = phydev->priv; | 1122 | struct dp83640_private *dp83640 = phydev->priv; |
| @@ -1253,11 +1327,13 @@ static struct phy_driver dp83640_driver = { | |||
| 1253 | .phy_id_mask = 0xfffffff0, | 1327 | .phy_id_mask = 0xfffffff0, |
| 1254 | .name = "NatSemi DP83640", | 1328 | .name = "NatSemi DP83640", |
| 1255 | .features = PHY_BASIC_FEATURES, | 1329 | .features = PHY_BASIC_FEATURES, |
| 1256 | .flags = 0, | 1330 | .flags = PHY_HAS_INTERRUPT, |
| 1257 | .probe = dp83640_probe, | 1331 | .probe = dp83640_probe, |
| 1258 | .remove = dp83640_remove, | 1332 | .remove = dp83640_remove, |
| 1259 | .config_aneg = genphy_config_aneg, | 1333 | .config_aneg = genphy_config_aneg, |
| 1260 | .read_status = genphy_read_status, | 1334 | .read_status = genphy_read_status, |
| 1335 | .ack_interrupt = dp83640_ack_interrupt, | ||
| 1336 | .config_intr = dp83640_config_intr, | ||
| 1261 | .ts_info = dp83640_ts_info, | 1337 | .ts_info = dp83640_ts_info, |
| 1262 | .hwtstamp = dp83640_hwtstamp, | 1338 | .hwtstamp = dp83640_hwtstamp, |
| 1263 | .rxtstamp = dp83640_rxtstamp, | 1339 | .rxtstamp = dp83640_rxtstamp, |
