View | Details | Raw Unified | Return to bug 6315 | Differences between
and this patch

Collapse All | Expand All

(-)linux-2.6.16.9.orig/drivers/i2c/busses/i2c-i801.c (-12 / +38 lines)
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

Return to bug 6315