diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2010-12-02 08:46:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-03 12:08:03 -0500 |
commit | 71839f7d162f973f5931d30d1376a2dc5c0bed5a (patch) | |
tree | 0187d9996d6a2d4945acf1eaafa0f062935e4621 | |
parent | 4484cd7dedecf59aee0775c6658f95bdee65f277 (diff) |
sfc: Distinguish critical and non-critical over-temperature conditions
Set both the 'maximum' and critical temperature limits for LM87
hardware monitors on Falcon boards. Do not shut down a port until the
critical temperature is reached, but warn as soon as the 'maximum'
temperature is reached.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/sfc/falcon_boards.c | 109 |
1 files changed, 80 insertions, 29 deletions
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c index cfc29d767588..86180ee02ec0 100644 --- a/drivers/net/sfc/falcon_boards.c +++ b/drivers/net/sfc/falcon_boards.c | |||
@@ -30,17 +30,28 @@ | |||
30 | #define FALCON_BOARD_SFN4112F 0x52 | 30 | #define FALCON_BOARD_SFN4112F 0x52 |
31 | 31 | ||
32 | /* Board temperature is about 15°C above ambient when air flow is | 32 | /* Board temperature is about 15°C above ambient when air flow is |
33 | * limited. */ | 33 | * limited. The maximum acceptable ambient temperature varies |
34 | * depending on the PHY specifications but the critical temperature | ||
35 | * above which we should shut down to avoid damage is 80°C. */ | ||
34 | #define FALCON_BOARD_TEMP_BIAS 15 | 36 | #define FALCON_BOARD_TEMP_BIAS 15 |
37 | #define FALCON_BOARD_TEMP_CRIT (80 + FALCON_BOARD_TEMP_BIAS) | ||
35 | 38 | ||
36 | /* SFC4000 datasheet says: 'The maximum permitted junction temperature | 39 | /* SFC4000 datasheet says: 'The maximum permitted junction temperature |
37 | * is 125°C; the thermal design of the environment for the SFC4000 | 40 | * is 125°C; the thermal design of the environment for the SFC4000 |
38 | * should aim to keep this well below 100°C.' */ | 41 | * should aim to keep this well below 100°C.' */ |
42 | #define FALCON_JUNC_TEMP_MIN 0 | ||
39 | #define FALCON_JUNC_TEMP_MAX 90 | 43 | #define FALCON_JUNC_TEMP_MAX 90 |
44 | #define FALCON_JUNC_TEMP_CRIT 125 | ||
40 | 45 | ||
41 | /***************************************************************************** | 46 | /***************************************************************************** |
42 | * Support for LM87 sensor chip used on several boards | 47 | * Support for LM87 sensor chip used on several boards |
43 | */ | 48 | */ |
49 | #define LM87_REG_TEMP_HW_INT_LOCK 0x13 | ||
50 | #define LM87_REG_TEMP_HW_EXT_LOCK 0x14 | ||
51 | #define LM87_REG_TEMP_HW_INT 0x17 | ||
52 | #define LM87_REG_TEMP_HW_EXT 0x18 | ||
53 | #define LM87_REG_TEMP_EXT1 0x26 | ||
54 | #define LM87_REG_TEMP_INT 0x27 | ||
44 | #define LM87_REG_ALARMS1 0x41 | 55 | #define LM87_REG_ALARMS1 0x41 |
45 | #define LM87_REG_ALARMS2 0x42 | 56 | #define LM87_REG_ALARMS2 0x42 |
46 | #define LM87_IN_LIMITS(nr, _min, _max) \ | 57 | #define LM87_IN_LIMITS(nr, _min, _max) \ |
@@ -57,6 +68,27 @@ | |||
57 | 68 | ||
58 | #if defined(CONFIG_SENSORS_LM87) || defined(CONFIG_SENSORS_LM87_MODULE) | 69 | #if defined(CONFIG_SENSORS_LM87) || defined(CONFIG_SENSORS_LM87_MODULE) |
59 | 70 | ||
71 | static int efx_poke_lm87(struct i2c_client *client, const u8 *reg_values) | ||
72 | { | ||
73 | while (*reg_values) { | ||
74 | u8 reg = *reg_values++; | ||
75 | u8 value = *reg_values++; | ||
76 | int rc = i2c_smbus_write_byte_data(client, reg, value); | ||
77 | if (rc) | ||
78 | return rc; | ||
79 | } | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static const u8 falcon_lm87_common_regs[] = { | ||
84 | LM87_REG_TEMP_HW_INT_LOCK, FALCON_BOARD_TEMP_CRIT, | ||
85 | LM87_REG_TEMP_HW_INT, FALCON_BOARD_TEMP_CRIT, | ||
86 | LM87_TEMP_EXT1_LIMITS(FALCON_JUNC_TEMP_MIN, FALCON_JUNC_TEMP_MAX), | ||
87 | LM87_REG_TEMP_HW_EXT_LOCK, FALCON_JUNC_TEMP_CRIT, | ||
88 | LM87_REG_TEMP_HW_EXT, FALCON_JUNC_TEMP_CRIT, | ||
89 | 0 | ||
90 | }; | ||
91 | |||
60 | static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, | 92 | static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, |
61 | const u8 *reg_values) | 93 | const u8 *reg_values) |
62 | { | 94 | { |
@@ -67,13 +99,12 @@ static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, | |||
67 | if (!client) | 99 | if (!client) |
68 | return -EIO; | 100 | return -EIO; |
69 | 101 | ||
70 | while (*reg_values) { | 102 | rc = efx_poke_lm87(client, reg_values); |
71 | u8 reg = *reg_values++; | 103 | if (rc) |
72 | u8 value = *reg_values++; | 104 | goto err; |
73 | rc = i2c_smbus_write_byte_data(client, reg, value); | 105 | rc = efx_poke_lm87(client, falcon_lm87_common_regs); |
74 | if (rc) | 106 | if (rc) |
75 | goto err; | 107 | goto err; |
76 | } | ||
77 | 108 | ||
78 | board->hwmon_client = client; | 109 | board->hwmon_client = client; |
79 | return 0; | 110 | return 0; |
@@ -91,36 +122,56 @@ static void efx_fini_lm87(struct efx_nic *efx) | |||
91 | static int efx_check_lm87(struct efx_nic *efx, unsigned mask) | 122 | static int efx_check_lm87(struct efx_nic *efx, unsigned mask) |
92 | { | 123 | { |
93 | struct i2c_client *client = falcon_board(efx)->hwmon_client; | 124 | struct i2c_client *client = falcon_board(efx)->hwmon_client; |
94 | s32 alarms1, alarms2; | 125 | bool temp_crit, elec_fault, is_failure; |
126 | u16 alarms; | ||
127 | s32 reg; | ||
95 | 128 | ||
96 | /* If link is up then do not monitor temperature */ | 129 | /* If link is up then do not monitor temperature */ |
97 | if (EFX_WORKAROUND_7884(efx) && efx->link_state.up) | 130 | if (EFX_WORKAROUND_7884(efx) && efx->link_state.up) |
98 | return 0; | 131 | return 0; |
99 | 132 | ||
100 | alarms1 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1); | 133 | reg = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1); |
101 | alarms2 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2); | 134 | if (reg < 0) |
102 | if (alarms1 < 0) | 135 | return reg; |
103 | return alarms1; | 136 | alarms = reg; |
104 | if (alarms2 < 0) | 137 | reg = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2); |
105 | return alarms2; | 138 | if (reg < 0) |
106 | alarms1 &= mask; | 139 | return reg; |
107 | alarms2 &= mask >> 8; | 140 | alarms |= reg << 8; |
108 | if (alarms1 || alarms2) { | 141 | alarms &= mask; |
142 | |||
143 | temp_crit = false; | ||
144 | if (alarms & LM87_ALARM_TEMP_INT) { | ||
145 | reg = i2c_smbus_read_byte_data(client, LM87_REG_TEMP_INT); | ||
146 | if (reg < 0) | ||
147 | return reg; | ||
148 | if (reg > FALCON_BOARD_TEMP_CRIT) | ||
149 | temp_crit = true; | ||
150 | } | ||
151 | if (alarms & LM87_ALARM_TEMP_EXT1) { | ||
152 | reg = i2c_smbus_read_byte_data(client, LM87_REG_TEMP_EXT1); | ||
153 | if (reg < 0) | ||
154 | return reg; | ||
155 | if (reg > FALCON_JUNC_TEMP_CRIT) | ||
156 | temp_crit = true; | ||
157 | } | ||
158 | elec_fault = alarms & ~(LM87_ALARM_TEMP_INT | LM87_ALARM_TEMP_EXT1); | ||
159 | is_failure = temp_crit || elec_fault; | ||
160 | |||
161 | if (alarms) | ||
109 | netif_err(efx, hw, efx->net_dev, | 162 | netif_err(efx, hw, efx->net_dev, |
110 | "LM87 detected a hardware failure (status %02x:%02x)" | 163 | "LM87 detected a hardware %s (status %02x:%02x)" |
111 | "%s%s%s\n", | 164 | "%s%s%s%s\n", |
112 | alarms1, alarms2, | 165 | is_failure ? "failure" : "problem", |
113 | (alarms1 & LM87_ALARM_TEMP_INT) ? | 166 | alarms & 0xff, alarms >> 8, |
167 | (alarms & LM87_ALARM_TEMP_INT) ? | ||
114 | "; board is overheating" : "", | 168 | "; board is overheating" : "", |
115 | (alarms1 & LM87_ALARM_TEMP_EXT1) ? | 169 | (alarms & LM87_ALARM_TEMP_EXT1) ? |
116 | "; controller is overheating" : "", | 170 | "; controller is overheating" : "", |
117 | (alarms1 & ~(LM87_ALARM_TEMP_INT | LM87_ALARM_TEMP_EXT1) | 171 | temp_crit ? "; reached critical temperature" : "", |
118 | || alarms2) ? | 172 | elec_fault ? "; electrical fault" : ""); |
119 | "; electrical fault" : ""); | ||
120 | return -ERANGE; | ||
121 | } | ||
122 | 173 | ||
123 | return 0; | 174 | return is_failure ? -ERANGE : 0; |
124 | } | 175 | } |
125 | 176 | ||
126 | #else /* !CONFIG_SENSORS_LM87 */ | 177 | #else /* !CONFIG_SENSORS_LM87 */ |