aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <guenter.roeck@ericsson.com>2011-02-06 11:10:15 -0500
committerGuenter Roeck <guenter.roeck@ericsson.com>2011-03-15 01:39:14 -0400
commit83cc8985b82dff2ef85987a8481a92aab1b33323 (patch)
treee89ac8f2ca8ec0b1df629c93ae1361bd5d5c5e3a
parente7e1ca6ef4f331c66392d3548cead7f1205f9278 (diff)
hwmon: (w83627ehf) Optimize multi-bank register access
Assume that each register is banked, and set the bank for each access. Cache the bank number so it only needs to be set if it changes. Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com> Acked-by: Ian Dobson <i.dobson@planet-ian.com>
-rw-r--r--drivers/hwmon/w83627ehf.c26
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 */
351static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) 357static 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 */
360static 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;