Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 319397
b: refs/heads/master
c: 829917c
h: refs/heads/master
i:
  319395: 52cacaa
v: v3
  • Loading branch information
Henrik Rydberg authored and Guenter Roeck committed Jul 27, 2012
1 parent 1dd06f3 commit fab9643
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 25 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5953e2761be088f66fd930dfbf6b36a5a41d82a3
refs/heads/master: 829917cd7246204d6c5f066c40b66d2b62d0930d
70 changes: 46 additions & 24 deletions trunk/drivers/hwmon/applesmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@

/* wait up to 32 ms for a status change. */
#define APPLESMC_MIN_WAIT 0x0010
#define APPLESMC_RETRY_WAIT 0x0100
#define APPLESMC_MAX_WAIT 0x8000

#define APPLESMC_STATUS_MASK 0x0f
#define APPLESMC_READ_CMD 0x10
#define APPLESMC_WRITE_CMD 0x11
#define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12
Expand Down Expand Up @@ -162,51 +162,68 @@ static unsigned int key_at_index;
static struct workqueue_struct *applesmc_led_wq;

/*
* __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
* wait_read - Wait for a byte to appear on SMC port. Callers must
* hold applesmc_lock.
*/
static int __wait_status(u8 val)
static int wait_read(void)
{
u8 status;
int us;

val = val & APPLESMC_STATUS_MASK;

for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
udelay(us);
if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val)
status = inb(APPLESMC_CMD_PORT);
/* read: wait for smc to settle */
if (status & 0x01)
return 0;
}

pr_warn("wait_read() fail: 0x%02x\n", status);
return -EIO;
}

/*
* special treatment of command port - on newer macbooks, it seems necessary
* to resend the command byte before polling the status again. Callers must
* hold applesmc_lock.
* send_byte - Write to SMC port, retrying when necessary. Callers
* must hold applesmc_lock.
*/
static int send_command(u8 cmd)
static int send_byte(u8 cmd, u16 port)
{
u8 status;
int us;

outb(cmd, port);
for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
outb(cmd, APPLESMC_CMD_PORT);
udelay(us);
if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
status = inb(APPLESMC_CMD_PORT);
/* write: wait for smc to settle */
if (status & 0x02)
continue;
/* ready: cmd accepted, return */
if (status & 0x04)
return 0;
/* timeout: give up */
if (us << 1 == APPLESMC_MAX_WAIT)
break;
/* busy: long wait and resend */
udelay(APPLESMC_RETRY_WAIT);
outb(cmd, port);
}

pr_warn("send_byte(0x%02x, 0x%04x) fail: 0x%02x\n", cmd, port, status);
return -EIO;
}

static int send_command(u8 cmd)
{
return send_byte(cmd, APPLESMC_CMD_PORT);
}

static int send_argument(const char *key)
{
int i;

for (i = 0; i < 4; i++) {
outb(key[i], APPLESMC_DATA_PORT);
if (__wait_status(0x04))
for (i = 0; i < 4; i++)
if (send_byte(key[i], APPLESMC_DATA_PORT))
return -EIO;
}
return 0;
}

Expand All @@ -219,11 +236,14 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len)
return -EIO;
}

outb(len, APPLESMC_DATA_PORT);
if (send_byte(len, APPLESMC_DATA_PORT)) {
pr_warn("%.4s: read len fail\n", key);
return -EIO;
}

for (i = 0; i < len; i++) {
if (__wait_status(0x05)) {
pr_warn("%.4s: read data fail\n", key);
if (wait_read()) {
pr_warn("%.4s: read data[%d] fail\n", key, i);
return -EIO;
}
buffer[i] = inb(APPLESMC_DATA_PORT);
Expand All @@ -241,14 +261,16 @@ static int write_smc(u8 cmd, const char *key, const u8 *buffer, u8 len)
return -EIO;
}

outb(len, APPLESMC_DATA_PORT);
if (send_byte(len, APPLESMC_DATA_PORT)) {
pr_warn("%.4s: write len fail\n", key);
return -EIO;
}

for (i = 0; i < len; i++) {
if (__wait_status(0x04)) {
if (send_byte(buffer[i], APPLESMC_DATA_PORT)) {
pr_warn("%s: write data fail\n", key);
return -EIO;
}
outb(buffer[i], APPLESMC_DATA_PORT);
}

return 0;
Expand Down

0 comments on commit fab9643

Please sign in to comment.