Skip to content

Commit

Permalink
hwmon: applesmc: lighter wait mechanism, drastic improvement
Browse files Browse the repository at this point in the history
The read fail ratio is sensitive to the delay between the first byte
written and the first byte read; apparently the sensors cannot be rushed.
Increasing the minimum wait time, without changing the total wait time,
improves the fail ratio from a 8% chance that any of the sensors fails in
one read, down to 0.4%, on a Macbook Air.  On a Macbook Pro 3,1, the
effect is even more apparent.  By reducing the number of status polls, the
ratio is further improved to below 0.1%.  Finally, increasing the total
wait time brings the fail ratio down to virtually zero.

Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Tested-by: Bob McElrath <bob@mcelrath.org>
Cc: Nicolas Boichat <nicolas@boichat.ch>
Cc: "Mark M. Hoffman" <mhoffman@lightlink.com>
Cc: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
rydberg authored and torvalds committed Oct 20, 2008
1 parent 07e8dbd commit 8c9398d
Showing 1 changed file with 12 additions and 10 deletions.
22 changes: 12 additions & 10 deletions drivers/hwmon/applesmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@

#define APPLESMC_MAX_DATA_LENGTH 32

#define APPLESMC_MIN_WAIT 0x0040
#define APPLESMC_MAX_WAIT 0x8000

#define APPLESMC_STATUS_MASK 0x0f
#define APPLESMC_READ_CMD 0x10
#define APPLESMC_WRITE_CMD 0x11
Expand Down Expand Up @@ -172,25 +175,25 @@ static unsigned int key_at_index;
static struct workqueue_struct *applesmc_led_wq;

/*
* __wait_status - Wait up to 10ms for the status port to get a certain value
* __wait_status - Wait up to 32ms for the status port to get a certain value
* (masked with 0x0f), returning zero if the value is obtained. Callers must
* hold applesmc_lock.
*/
static int __wait_status(u8 val)
{
unsigned int i;
int us;

val = val & APPLESMC_STATUS_MASK;

for (i = 0; i < 1000; i++) {
for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
udelay(us);
if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
if (debug)
printk(KERN_DEBUG
"Waited %d us for status %x\n",
i*10, val);
"Waited %d us for status %x\n",
2 * us - APPLESMC_MIN_WAIT, val);
return 0;
}
udelay(10);
}

printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
Expand All @@ -206,13 +209,12 @@ static int __wait_status(u8 val)
*/
static int send_command(u8 cmd)
{
int i;
for (i = 0; i < 1000; i++) {
int us;
for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
outb(cmd, APPLESMC_CMD_PORT);
udelay(5);
udelay(us);
if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
return 0;
udelay(5);
}
printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
cmd, inb(APPLESMC_CMD_PORT));
Expand Down

0 comments on commit 8c9398d

Please sign in to comment.