diff options
-rw-r--r-- | drivers/i2c/busses/i2c-piix4.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index c2268cdf38e8..e34d82e79b98 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c | |||
@@ -585,10 +585,29 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, | |||
585 | u8 command, int size, union i2c_smbus_data *data) | 585 | u8 command, int size, union i2c_smbus_data *data) |
586 | { | 586 | { |
587 | struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap); | 587 | struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap); |
588 | unsigned short piix4_smba = adapdata->smba; | ||
589 | int retries = MAX_TIMEOUT; | ||
590 | int smbslvcnt; | ||
588 | u8 smba_en_lo; | 591 | u8 smba_en_lo; |
589 | u8 port; | 592 | u8 port; |
590 | int retval; | 593 | int retval; |
591 | 594 | ||
595 | /* Request the SMBUS semaphore, avoid conflicts with the IMC */ | ||
596 | smbslvcnt = inb_p(SMBSLVCNT); | ||
597 | do { | ||
598 | outb_p(smbslvcnt | 0x10, SMBSLVCNT); | ||
599 | |||
600 | /* Check the semaphore status */ | ||
601 | smbslvcnt = inb_p(SMBSLVCNT); | ||
602 | if (smbslvcnt & 0x10) | ||
603 | break; | ||
604 | |||
605 | usleep_range(1000, 2000); | ||
606 | } while (--retries); | ||
607 | /* SMBus is still owned by the IMC, we give up */ | ||
608 | if (!retries) | ||
609 | return -EBUSY; | ||
610 | |||
592 | mutex_lock(&piix4_mutex_sb800); | 611 | mutex_lock(&piix4_mutex_sb800); |
593 | 612 | ||
594 | outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX); | 613 | outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX); |
@@ -606,6 +625,9 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr, | |||
606 | 625 | ||
607 | mutex_unlock(&piix4_mutex_sb800); | 626 | mutex_unlock(&piix4_mutex_sb800); |
608 | 627 | ||
628 | /* Release the semaphore */ | ||
629 | outb_p(smbslvcnt | 0x20, SMBSLVCNT); | ||
630 | |||
609 | return retval; | 631 | return retval; |
610 | } | 632 | } |
611 | 633 | ||