|
@@ -263,11 +263,6 @@ static void pch_i2c_init(struct i2c_algo_pch_data *adap)
|
|
|
init_waitqueue_head(&pch_event);
|
|
|
}
|
|
|
|
|
|
-static inline bool ktime_lt(const ktime_t cmp1, const ktime_t cmp2)
|
|
|
-{
|
|
|
- return cmp1.tv64 < cmp2.tv64;
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* pch_i2c_wait_for_bus_idle() - check the status of bus.
|
|
|
* @adap: Pointer to struct i2c_algo_pch_data.
|
|
@@ -316,33 +311,6 @@ static void pch_i2c_start(struct i2c_algo_pch_data *adap)
|
|
|
pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_START);
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * pch_i2c_wait_for_xfer_complete() - initiates a wait for the tx complete event
|
|
|
- * @adap: Pointer to struct i2c_algo_pch_data.
|
|
|
- */
|
|
|
-static s32 pch_i2c_wait_for_xfer_complete(struct i2c_algo_pch_data *adap)
|
|
|
-{
|
|
|
- long ret;
|
|
|
- ret = wait_event_timeout(pch_event,
|
|
|
- (adap->pch_event_flag != 0), msecs_to_jiffies(1000));
|
|
|
-
|
|
|
- if (ret == 0) {
|
|
|
- pch_err(adap, "timeout: %x\n", adap->pch_event_flag);
|
|
|
- adap->pch_event_flag = 0;
|
|
|
- return -ETIMEDOUT;
|
|
|
- }
|
|
|
-
|
|
|
- if (adap->pch_event_flag & I2C_ERROR_MASK) {
|
|
|
- pch_err(adap, "error bits set: %x\n", adap->pch_event_flag);
|
|
|
- adap->pch_event_flag = 0;
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
-
|
|
|
- adap->pch_event_flag = 0;
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* pch_i2c_getack() - to confirm ACK/NACK
|
|
|
* @adap: Pointer to struct i2c_algo_pch_data.
|
|
@@ -373,6 +341,40 @@ static void pch_i2c_stop(struct i2c_algo_pch_data *adap)
|
|
|
pch_clrbit(adap->pch_base_address, PCH_I2CCTL, PCH_START);
|
|
|
}
|
|
|
|
|
|
+static int pch_i2c_wait_for_check_xfer(struct i2c_algo_pch_data *adap)
|
|
|
+{
|
|
|
+ long ret;
|
|
|
+
|
|
|
+ ret = wait_event_timeout(pch_event,
|
|
|
+ (adap->pch_event_flag != 0), msecs_to_jiffies(1000));
|
|
|
+ if (!ret) {
|
|
|
+ pch_err(adap, "%s:wait-event timeout\n", __func__);
|
|
|
+ adap->pch_event_flag = 0;
|
|
|
+ pch_i2c_stop(adap);
|
|
|
+ pch_i2c_init(adap);
|
|
|
+ return -ETIMEDOUT;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (adap->pch_event_flag & I2C_ERROR_MASK) {
|
|
|
+ pch_err(adap, "Lost Arbitration\n");
|
|
|
+ adap->pch_event_flag = 0;
|
|
|
+ pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMAL_BIT);
|
|
|
+ pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMIF_BIT);
|
|
|
+ pch_i2c_init(adap);
|
|
|
+ return -EAGAIN;
|
|
|
+ }
|
|
|
+
|
|
|
+ adap->pch_event_flag = 0;
|
|
|
+
|
|
|
+ if (pch_i2c_getack(adap)) {
|
|
|
+ pch_dbg(adap, "Receive NACK for slave address"
|
|
|
+ "setting\n");
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* pch_i2c_repstart() - generate repeated start condition in normal mode
|
|
|
* @adap: Pointer to struct i2c_algo_pch_data.
|
|
@@ -427,27 +429,12 @@ static s32 pch_i2c_writebytes(struct i2c_adapter *i2c_adap,
|
|
|
if (first)
|
|
|
pch_i2c_start(adap);
|
|
|
|
|
|
- rtn = pch_i2c_wait_for_xfer_complete(adap);
|
|
|
- if (rtn == 0) {
|
|
|
- if (pch_i2c_getack(adap)) {
|
|
|
- pch_dbg(adap, "Receive NACK for slave address"
|
|
|
- "setting\n");
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
- addr_8_lsb = (addr & I2C_ADDR_MSK);
|
|
|
- iowrite32(addr_8_lsb, p + PCH_I2CDR);
|
|
|
- } else if (rtn == -EIO) { /* Arbitration Lost */
|
|
|
- pch_err(adap, "Lost Arbitration\n");
|
|
|
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
|
|
|
- I2CMAL_BIT);
|
|
|
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
|
|
|
- I2CMIF_BIT);
|
|
|
- pch_i2c_init(adap);
|
|
|
- return -EAGAIN;
|
|
|
- } else { /* wait-event timeout */
|
|
|
- pch_i2c_stop(adap);
|
|
|
- return -ETIME;
|
|
|
- }
|
|
|
+ rtn = pch_i2c_wait_for_check_xfer(adap);
|
|
|
+ if (rtn)
|
|
|
+ return rtn;
|
|
|
+
|
|
|
+ addr_8_lsb = (addr & I2C_ADDR_MSK);
|
|
|
+ iowrite32(addr_8_lsb, p + PCH_I2CDR);
|
|
|
} else {
|
|
|
/* set 7 bit slave address and R/W bit as 0 */
|
|
|
iowrite32(addr << 1, p + PCH_I2CDR);
|
|
@@ -455,44 +442,21 @@ static s32 pch_i2c_writebytes(struct i2c_adapter *i2c_adap,
|
|
|
pch_i2c_start(adap);
|
|
|
}
|
|
|
|
|
|
- rtn = pch_i2c_wait_for_xfer_complete(adap);
|
|
|
- if (rtn == 0) {
|
|
|
- if (pch_i2c_getack(adap)) {
|
|
|
- pch_dbg(adap, "Receive NACK for slave address"
|
|
|
- "setting\n");
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
- } else if (rtn == -EIO) { /* Arbitration Lost */
|
|
|
- pch_err(adap, "Lost Arbitration\n");
|
|
|
- pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMAL_BIT);
|
|
|
- pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMIF_BIT);
|
|
|
- pch_i2c_init(adap);
|
|
|
- return -EAGAIN;
|
|
|
- } else { /* wait-event timeout */
|
|
|
- pch_i2c_stop(adap);
|
|
|
- return -ETIME;
|
|
|
- }
|
|
|
+ rtn = pch_i2c_wait_for_check_xfer(adap);
|
|
|
+ if (rtn)
|
|
|
+ return rtn;
|
|
|
|
|
|
for (wrcount = 0; wrcount < length; ++wrcount) {
|
|
|
/* write buffer value to I2C data register */
|
|
|
iowrite32(buf[wrcount], p + PCH_I2CDR);
|
|
|
pch_dbg(adap, "writing %x to Data register\n", buf[wrcount]);
|
|
|
|
|
|
- rtn = pch_i2c_wait_for_xfer_complete(adap);
|
|
|
- if (rtn == 0) {
|
|
|
- if (pch_i2c_getack(adap)) {
|
|
|
- pch_dbg(adap, "Receive NACK for slave address"
|
|
|
- "setting\n");
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
|
|
|
- I2CMCF_BIT);
|
|
|
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
|
|
|
- I2CMIF_BIT);
|
|
|
- } else { /* wait-event timeout */
|
|
|
- pch_i2c_stop(adap);
|
|
|
- return -ETIME;
|
|
|
- }
|
|
|
+ rtn = pch_i2c_wait_for_check_xfer(adap);
|
|
|
+ if (rtn)
|
|
|
+ return rtn;
|
|
|
+
|
|
|
+ pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMCF_BIT);
|
|
|
+ pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMIF_BIT);
|
|
|
}
|
|
|
|
|
|
/* check if this is the last message */
|
|
@@ -580,50 +544,21 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
|
|
|
if (first)
|
|
|
pch_i2c_start(adap);
|
|
|
|
|
|
- rtn = pch_i2c_wait_for_xfer_complete(adap);
|
|
|
- if (rtn == 0) {
|
|
|
- if (pch_i2c_getack(adap)) {
|
|
|
- pch_dbg(adap, "Receive NACK for slave address"
|
|
|
- "setting\n");
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
- addr_8_lsb = (addr & I2C_ADDR_MSK);
|
|
|
- iowrite32(addr_8_lsb, p + PCH_I2CDR);
|
|
|
- } else if (rtn == -EIO) { /* Arbitration Lost */
|
|
|
- pch_err(adap, "Lost Arbitration\n");
|
|
|
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
|
|
|
- I2CMAL_BIT);
|
|
|
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
|
|
|
- I2CMIF_BIT);
|
|
|
- pch_i2c_init(adap);
|
|
|
- return -EAGAIN;
|
|
|
- } else { /* wait-event timeout */
|
|
|
- pch_i2c_stop(adap);
|
|
|
- return -ETIME;
|
|
|
- }
|
|
|
+ rtn = pch_i2c_wait_for_check_xfer(adap);
|
|
|
+ if (rtn)
|
|
|
+ return rtn;
|
|
|
+
|
|
|
+ addr_8_lsb = (addr & I2C_ADDR_MSK);
|
|
|
+ iowrite32(addr_8_lsb, p + PCH_I2CDR);
|
|
|
+
|
|
|
pch_i2c_restart(adap);
|
|
|
- rtn = pch_i2c_wait_for_xfer_complete(adap);
|
|
|
- if (rtn == 0) {
|
|
|
- if (pch_i2c_getack(adap)) {
|
|
|
- pch_dbg(adap, "Receive NACK for slave address"
|
|
|
- "setting\n");
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
- addr_2_msb |= I2C_RD;
|
|
|
- iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK,
|
|
|
- p + PCH_I2CDR);
|
|
|
- } else if (rtn == -EIO) { /* Arbitration Lost */
|
|
|
- pch_err(adap, "Lost Arbitration\n");
|
|
|
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
|
|
|
- I2CMAL_BIT);
|
|
|
- pch_clrbit(adap->pch_base_address, PCH_I2CSR,
|
|
|
- I2CMIF_BIT);
|
|
|
- pch_i2c_init(adap);
|
|
|
- return -EAGAIN;
|
|
|
- } else { /* wait-event timeout */
|
|
|
- pch_i2c_stop(adap);
|
|
|
- return -ETIME;
|
|
|
- }
|
|
|
+
|
|
|
+ rtn = pch_i2c_wait_for_check_xfer(adap);
|
|
|
+ if (rtn)
|
|
|
+ return rtn;
|
|
|
+
|
|
|
+ addr_2_msb |= I2C_RD;
|
|
|
+ iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK, p + PCH_I2CDR);
|
|
|
} else {
|
|
|
/* 7 address bits + R/W bit */
|
|
|
addr = (((addr) << 1) | (I2C_RD));
|
|
@@ -634,23 +569,9 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
|
|
|
if (first)
|
|
|
pch_i2c_start(adap);
|
|
|
|
|
|
- rtn = pch_i2c_wait_for_xfer_complete(adap);
|
|
|
- if (rtn == 0) {
|
|
|
- if (pch_i2c_getack(adap)) {
|
|
|
- pch_dbg(adap, "Receive NACK for slave address"
|
|
|
- "setting\n");
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
- } else if (rtn == -EIO) { /* Arbitration Lost */
|
|
|
- pch_err(adap, "Lost Arbitration\n");
|
|
|
- pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMAL_BIT);
|
|
|
- pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMIF_BIT);
|
|
|
- pch_i2c_init(adap);
|
|
|
- return -EAGAIN;
|
|
|
- } else { /* wait-event timeout */
|
|
|
- pch_i2c_stop(adap);
|
|
|
- return -ETIME;
|
|
|
- }
|
|
|
+ rtn = pch_i2c_wait_for_check_xfer(adap);
|
|
|
+ if (rtn)
|
|
|
+ return rtn;
|
|
|
|
|
|
if (length == 0) {
|
|
|
pch_i2c_stop(adap);
|
|
@@ -669,18 +590,9 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
|
|
|
if (loop != 1)
|
|
|
read_index++;
|
|
|
|
|
|
- rtn = pch_i2c_wait_for_xfer_complete(adap);
|
|
|
- if (rtn == 0) {
|
|
|
- if (pch_i2c_getack(adap)) {
|
|
|
- pch_dbg(adap, "Receive NACK for slave"
|
|
|
- "address setting\n");
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
- } else { /* wait-event timeout */
|
|
|
- pch_i2c_stop(adap);
|
|
|
- return -ETIME;
|
|
|
- }
|
|
|
-
|
|
|
+ rtn = pch_i2c_wait_for_check_xfer(adap);
|
|
|
+ if (rtn)
|
|
|
+ return rtn;
|
|
|
} /* end for */
|
|
|
|
|
|
pch_i2c_sendnack(adap);
|
|
@@ -690,17 +602,9 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
|
|
|
if (length != 1)
|
|
|
read_index++;
|
|
|
|
|
|
- rtn = pch_i2c_wait_for_xfer_complete(adap);
|
|
|
- if (rtn == 0) {
|
|
|
- if (pch_i2c_getack(adap)) {
|
|
|
- pch_dbg(adap, "Receive NACK for slave"
|
|
|
- "address setting\n");
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
- } else { /* wait-event timeout */
|
|
|
- pch_i2c_stop(adap);
|
|
|
- return -ETIME;
|
|
|
- }
|
|
|
+ rtn = pch_i2c_wait_for_check_xfer(adap);
|
|
|
+ if (rtn)
|
|
|
+ return rtn;
|
|
|
|
|
|
if (last)
|
|
|
pch_i2c_stop(adap);
|
|
@@ -790,7 +694,7 @@ static s32 pch_i2c_xfer(struct i2c_adapter *i2c_adap,
|
|
|
|
|
|
ret = mutex_lock_interruptible(&pch_mutex);
|
|
|
if (ret)
|
|
|
- return -ERESTARTSYS;
|
|
|
+ return ret;
|
|
|
|
|
|
if (adap->p_adapter_info->pch_i2c_suspended) {
|
|
|
mutex_unlock(&pch_mutex);
|
|
@@ -909,7 +813,7 @@ static int __devinit pch_i2c_probe(struct pci_dev *pdev,
|
|
|
|
|
|
pch_adap->owner = THIS_MODULE;
|
|
|
pch_adap->class = I2C_CLASS_HWMON;
|
|
|
- strcpy(pch_adap->name, KBUILD_MODNAME);
|
|
|
+ strlcpy(pch_adap->name, KBUILD_MODNAME, sizeof(pch_adap->name));
|
|
|
pch_adap->algo = &pch_algorithm;
|
|
|
pch_adap->algo_data = &adap_info->pch_data[i];
|
|
|
|
|
@@ -963,7 +867,7 @@ static void __devexit pch_i2c_remove(struct pci_dev *pdev)
|
|
|
pci_iounmap(pdev, adap_info->pch_data[0].pch_base_address);
|
|
|
|
|
|
for (i = 0; i < adap_info->ch_num; i++)
|
|
|
- adap_info->pch_data[i].pch_base_address = 0;
|
|
|
+ adap_info->pch_data[i].pch_base_address = NULL;
|
|
|
|
|
|
pci_set_drvdata(pdev, NULL);
|
|
|
|