Lines 170-175
Link Here
|
170 |
else |
170 |
else |
171 |
dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n"); |
171 |
dev_dbg(&dev->dev, "I801 using PCI Interrupt for SMBus.\n"); |
172 |
|
172 |
|
|
|
173 |
/* Check for stuck SMBus semaphore */ |
174 |
temp = inb_p(SMBHSTSTS); |
175 |
if (temp & 0x40) |
176 |
dev_warn(&dev->dev, "SMBus semaphore reset (bad BIOS?)\n"); |
177 |
outb_p(0x40, SMBHSTSTS); |
178 |
|
173 |
pci_read_config_byte(I801_dev, SMBREV, &temp); |
179 |
pci_read_config_byte(I801_dev, SMBREV, &temp); |
174 |
dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp); |
180 |
dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp); |
175 |
dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba); |
181 |
dev_dbg(&dev->dev, "I801_smba = 0x%X\n", i801_smba); |
Lines 235-241
Link Here
|
235 |
} |
241 |
} |
236 |
|
242 |
|
237 |
if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00) |
243 |
if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00) |
238 |
outb_p(inb(SMBHSTSTS), SMBHSTSTS); |
244 |
outb_p(inb(SMBHSTSTS) & 0x1f, SMBHSTSTS); |
239 |
|
245 |
|
240 |
if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { |
246 |
if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { |
241 |
dev_dbg(&I801_dev->dev, "Failed reset at end of transaction " |
247 |
dev_dbg(&I801_dev->dev, "Failed reset at end of transaction " |
Lines 314-320
Link Here
|
314 |
if (temp & errmask) { |
320 |
if (temp & errmask) { |
315 |
dev_dbg(&I801_dev->dev, "SMBus busy (%02x). " |
321 |
dev_dbg(&I801_dev->dev, "SMBus busy (%02x). " |
316 |
"Resetting...\n", temp); |
322 |
"Resetting...\n", temp); |
317 |
outb_p(temp, SMBHSTSTS); |
323 |
outb_p(temp & errmask, SMBHSTSTS); |
318 |
if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) { |
324 |
if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) { |
319 |
dev_err(&I801_dev->dev, |
325 |
dev_err(&I801_dev->dev, |
320 |
"Reset failed! (%02x)\n", temp); |
326 |
"Reset failed! (%02x)\n", temp); |
Lines 373-379
Link Here
|
373 |
if (read_write == I2C_SMBUS_WRITE && i+1 <= len) |
379 |
if (read_write == I2C_SMBUS_WRITE && i+1 <= len) |
374 |
outb_p(data->block[i+1], SMBBLKDAT); |
380 |
outb_p(data->block[i+1], SMBBLKDAT); |
375 |
if ((temp & 0x9e) != 0x00) |
381 |
if ((temp & 0x9e) != 0x00) |
376 |
outb_p(temp, SMBHSTSTS); /* signals SMBBLKDAT ready */ |
382 |
outb_p(temp & 0x9e, SMBHSTSTS); /* signals SMBBLKDAT ready */ |
377 |
|
383 |
|
378 |
if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) { |
384 |
if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) { |
379 |
dev_dbg(&I801_dev->dev, |
385 |
dev_dbg(&I801_dev->dev, |
Lines 401-407
Link Here
|
401 |
if (timeout >= MAX_TIMEOUT) { |
407 |
if (timeout >= MAX_TIMEOUT) { |
402 |
dev_dbg(&I801_dev->dev, "PEC Timeout!\n"); |
408 |
dev_dbg(&I801_dev->dev, "PEC Timeout!\n"); |
403 |
} |
409 |
} |
404 |
outb_p(temp, SMBHSTSTS); |
410 |
outb_p(temp & ~0x40, SMBHSTSTS); |
405 |
} |
411 |
} |
406 |
result = 0; |
412 |
result = 0; |
407 |
END: |
413 |
END: |
Lines 420-430
Link Here
|
420 |
int hwpec; |
426 |
int hwpec; |
421 |
int block = 0; |
427 |
int block = 0; |
422 |
int ret, xact = 0; |
428 |
int ret, xact = 0; |
|
|
429 |
int timeout; |
423 |
|
430 |
|
424 |
hwpec = isich4 && (flags & I2C_CLIENT_PEC) |
431 |
hwpec = isich4 && (flags & I2C_CLIENT_PEC) |
425 |
&& size != I2C_SMBUS_QUICK |
432 |
&& size != I2C_SMBUS_QUICK |
426 |
&& size != I2C_SMBUS_I2C_BLOCK_DATA; |
433 |
&& size != I2C_SMBUS_I2C_BLOCK_DATA; |
427 |
|
434 |
|
|
|
435 |
/* Grab the hardware semaphore |
436 |
This may help prevent concurrent accesses with ACPI EC or BIOS, |
437 |
but will only work if they play fair too. */ |
438 |
timeout = 0; |
439 |
while (((ret = inb_p(SMBHSTSTS)) & 0x40) && timeout < MAX_TIMEOUT) { |
440 |
msleep(2); |
441 |
timeout++; |
442 |
} |
443 |
if (timeout >= MAX_TIMEOUT) { |
444 |
dev_err(&I801_dev->dev, |
445 |
"SMBus semaphore is held by someone else!\n"); |
446 |
return -1; |
447 |
} else if (timeout) { |
448 |
dev_warn(&I801_dev->dev, "Had to wait %d ms for SMBus " |
449 |
"semaphore\n", 2 * timeout); |
450 |
} |
451 |
|
428 |
switch (size) { |
452 |
switch (size) { |
429 |
case I2C_SMBUS_QUICK: |
453 |
case I2C_SMBUS_QUICK: |
430 |
outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), |
454 |
outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), |
Lines 466-472
Link Here
|
466 |
case I2C_SMBUS_PROC_CALL: |
490 |
case I2C_SMBUS_PROC_CALL: |
467 |
default: |
491 |
default: |
468 |
dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size); |
492 |
dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size); |
469 |
return -1; |
493 |
ret = -1; |
|
|
494 |
goto exit_sema; |
470 |
} |
495 |
} |
471 |
|
496 |
|
472 |
outb_p(hwpec, SMBAUXCTL); /* enable/disable hardware PEC */ |
497 |
outb_p(hwpec, SMBAUXCTL); /* enable/disable hardware PEC */ |
Lines 483-494
Link Here
|
483 |
if (hwpec) |
508 |
if (hwpec) |
484 |
outb_p(0, SMBAUXCTL); |
509 |
outb_p(0, SMBAUXCTL); |
485 |
|
510 |
|
486 |
if(block) |
511 |
if (block || ret || read_write == I2C_SMBUS_WRITE |
487 |
return ret; |
512 |
|| xact == I801_QUICK) |
488 |
if(ret) |
513 |
goto exit_sema; |
489 |
return -1; |
|
|
490 |
if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK)) |
491 |
return 0; |
492 |
|
514 |
|
493 |
switch (xact & 0x7f) { |
515 |
switch (xact & 0x7f) { |
494 |
case I801_BYTE: /* Result put in SMBHSTDAT0 */ |
516 |
case I801_BYTE: /* Result put in SMBHSTDAT0 */ |
Lines 499-505
Link Here
|
499 |
data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); |
521 |
data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); |
500 |
break; |
522 |
break; |
501 |
} |
523 |
} |
502 |
return 0; |
524 |
|
|
|
525 |
exit_sema: |
526 |
/* Release the hardware semaphore for other users (ACPI EC) */ |
527 |
outb_p(0x40, SMBHSTSTS); |
528 |
return ret; |
503 |
} |
529 |
} |
504 |
|
530 |
|
505 |
|
531 |
|