diff options
author | Guenter Roeck <guenter.roeck@ericsson.com> | 2011-02-06 11:10:15 -0500 |
---|---|---|
committer | Guenter Roeck <guenter.roeck@ericsson.com> | 2011-03-15 01:39:14 -0400 |
commit | 83cc8985b82dff2ef85987a8481a92aab1b33323 (patch) | |
tree | e89ac8f2ca8ec0b1df629c93ae1361bd5d5c5e3a | |
parent | e7e1ca6ef4f331c66392d3548cead7f1205f9278 (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.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; |