diff options
Diffstat (limited to 'drivers/hwmon/applesmc.c')
-rw-r--r-- | drivers/hwmon/applesmc.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index b401975bc0da..d5bd0cadbf31 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -191,6 +191,26 @@ static int __wait_status(u8 val) | |||
191 | } | 191 | } |
192 | 192 | ||
193 | /* | 193 | /* |
194 | * special treatment of command port - on newer macbooks, it seems necessary | ||
195 | * to resend the command byte before polling the status again. Callers must | ||
196 | * hold applesmc_lock. | ||
197 | */ | ||
198 | static int send_command(u8 cmd) | ||
199 | { | ||
200 | int i; | ||
201 | for (i = 0; i < 1000; i++) { | ||
202 | outb(cmd, APPLESMC_CMD_PORT); | ||
203 | udelay(5); | ||
204 | if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c) | ||
205 | return 0; | ||
206 | udelay(5); | ||
207 | } | ||
208 | printk(KERN_WARNING "applesmc: command failed: %x -> %x\n", | ||
209 | cmd, inb(APPLESMC_CMD_PORT)); | ||
210 | return -EIO; | ||
211 | } | ||
212 | |||
213 | /* | ||
194 | * applesmc_read_key - reads len bytes from a given key, and put them in buffer. | 214 | * applesmc_read_key - reads len bytes from a given key, and put them in buffer. |
195 | * Returns zero on success or a negative error on failure. Callers must | 215 | * Returns zero on success or a negative error on failure. Callers must |
196 | * hold applesmc_lock. | 216 | * hold applesmc_lock. |
@@ -205,8 +225,7 @@ static int applesmc_read_key(const char* key, u8* buffer, u8 len) | |||
205 | return -EINVAL; | 225 | return -EINVAL; |
206 | } | 226 | } |
207 | 227 | ||
208 | outb(APPLESMC_READ_CMD, APPLESMC_CMD_PORT); | 228 | if (send_command(APPLESMC_READ_CMD)) |
209 | if (__wait_status(0x0c)) | ||
210 | return -EIO; | 229 | return -EIO; |
211 | 230 | ||
212 | for (i = 0; i < 4; i++) { | 231 | for (i = 0; i < 4; i++) { |
@@ -249,8 +268,7 @@ static int applesmc_write_key(const char* key, u8* buffer, u8 len) | |||
249 | return -EINVAL; | 268 | return -EINVAL; |
250 | } | 269 | } |
251 | 270 | ||
252 | outb(APPLESMC_WRITE_CMD, APPLESMC_CMD_PORT); | 271 | if (send_command(APPLESMC_WRITE_CMD)) |
253 | if (__wait_status(0x0c)) | ||
254 | return -EIO; | 272 | return -EIO; |
255 | 273 | ||
256 | for (i = 0; i < 4; i++) { | 274 | for (i = 0; i < 4; i++) { |
@@ -284,8 +302,7 @@ static int applesmc_get_key_at_index(int index, char* key) | |||
284 | readkey[2] = index >> 8; | 302 | readkey[2] = index >> 8; |
285 | readkey[3] = index; | 303 | readkey[3] = index; |
286 | 304 | ||
287 | outb(APPLESMC_GET_KEY_BY_INDEX_CMD, APPLESMC_CMD_PORT); | 305 | if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD)) |
288 | if (__wait_status(0x0c)) | ||
289 | return -EIO; | 306 | return -EIO; |
290 | 307 | ||
291 | for (i = 0; i < 4; i++) { | 308 | for (i = 0; i < 4; i++) { |
@@ -315,8 +332,7 @@ static int applesmc_get_key_type(char* key, char* type) | |||
315 | { | 332 | { |
316 | int i; | 333 | int i; |
317 | 334 | ||
318 | outb(APPLESMC_GET_KEY_TYPE_CMD, APPLESMC_CMD_PORT); | 335 | if (send_command(APPLESMC_GET_KEY_TYPE_CMD)) |
319 | if (__wait_status(0x0c)) | ||
320 | return -EIO; | 336 | return -EIO; |
321 | 337 | ||
322 | for (i = 0; i < 4; i++) { | 338 | for (i = 0; i < 4; i++) { |