diff options
Diffstat (limited to 'drivers/hwmon/w83627ehf.c')
-rw-r--r-- | drivers/hwmon/w83627ehf.c | 26 |
1 files changed, 11 insertions, 15 deletions
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 1128eac7023b..5a627b9db3e8 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -304,6 +304,7 @@ struct w83627ehf_data { | |||
304 | unsigned long last_updated; /* In jiffies */ | 304 | unsigned long last_updated; /* In jiffies */ |
305 | 305 | ||
306 | /* Register values */ | 306 | /* Register values */ |
307 | u8 bank; /* current register bank */ | ||
307 | u8 in_num; /* number of in inputs we have */ | 308 | u8 in_num; /* number of in inputs we have */ |
308 | u8 in[10]; /* Register value */ | 309 | u8 in[10]; /* Register value */ |
309 | u8 in_max[10]; /* Register value */ | 310 | u8 in_max[10]; /* Register value */ |
@@ -347,21 +348,19 @@ struct w83627ehf_sio_data { | |||
347 | enum kinds kind; | 348 | enum kinds kind; |
348 | }; | 349 | }; |
349 | 350 | ||
350 | /* Registers 0x50-0x5f are banked */ | 351 | /* |
352 | * On older chips, only registers 0x50-0x5f are banked. | ||
353 | * On more recent chips, all registers are banked. | ||
354 | * Assume that is the case and set the bank number for each access. | ||
355 | * Cache the bank number so it only needs to be set if it changes. | ||
356 | */ | ||
351 | static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) | 357 | static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) |
352 | { | 358 | { |
353 | if ((reg & 0x00f0) == 0x50) { | 359 | u8 bank = reg >> 8; |
354 | outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); | 360 | if (data->bank != bank) { |
355 | outb_p(reg >> 8, data->addr + DATA_REG_OFFSET); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | /* Not strictly necessary, but play it safe for now */ | ||
360 | static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg) | ||
361 | { | ||
362 | if (reg & 0xff00) { | ||
363 | outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); | 361 | outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); |
364 | outb_p(0, data->addr + DATA_REG_OFFSET); | 362 | outb_p(bank, data->addr + DATA_REG_OFFSET); |
363 | data->bank = bank; | ||
365 | } | 364 | } |
366 | } | 365 | } |
367 | 366 | ||
@@ -379,10 +378,8 @@ static u16 w83627ehf_read_value(struct w83627ehf_data *data, u16 reg) | |||
379 | data->addr + ADDR_REG_OFFSET); | 378 | data->addr + ADDR_REG_OFFSET); |
380 | res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET); | 379 | res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET); |
381 | } | 380 | } |
382 | w83627ehf_reset_bank(data, reg); | ||
383 | 381 | ||
384 | mutex_unlock(&data->lock); | 382 | mutex_unlock(&data->lock); |
385 | |||
386 | return res; | 383 | return res; |
387 | } | 384 | } |
388 | 385 | ||
@@ -401,7 +398,6 @@ static int w83627ehf_write_value(struct w83627ehf_data *data, u16 reg, | |||
401 | data->addr + ADDR_REG_OFFSET); | 398 | data->addr + ADDR_REG_OFFSET); |
402 | } | 399 | } |
403 | outb_p(value & 0xff, data->addr + DATA_REG_OFFSET); | 400 | outb_p(value & 0xff, data->addr + DATA_REG_OFFSET); |
404 | w83627ehf_reset_bank(data, reg); | ||
405 | 401 | ||
406 | mutex_unlock(&data->lock); | 402 | mutex_unlock(&data->lock); |
407 | return 0; | 403 | return 0; |