aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-mv64xxx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-mv64xxx.c')
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 81031eb51056..22781d84f79f 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * drivers/i2c/busses/i2c-mv64xxx.c
3 *
4 * Driver for the i2c controller on the Marvell line of host bridges for MIPS 2 * Driver for the i2c controller on the Marvell line of host bridges for MIPS
5 * and PPC (e.g, gt642[46]0, mv643[46]0, mv644[46]0). 3 * and PPC (e.g, gt642[46]0, mv643[46]0, mv644[46]0).
6 * 4 *
@@ -65,7 +63,6 @@ enum {
65 MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK, 63 MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK,
66 MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK, 64 MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK,
67 MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA, 65 MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA,
68 MV64XXX_I2C_STATE_ABORTING,
69}; 66};
70 67
71/* Driver actions */ 68/* Driver actions */
@@ -85,6 +82,7 @@ struct mv64xxx_i2c_data {
85 int irq; 82 int irq;
86 u32 state; 83 u32 state;
87 u32 action; 84 u32 action;
85 u32 aborting;
88 u32 cntl_bits; 86 u32 cntl_bits;
89 void __iomem *reg_base; 87 void __iomem *reg_base;
90 u32 reg_base_p; 88 u32 reg_base_p;
@@ -122,12 +120,6 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
122 return; 120 return;
123 } 121 }
124 122
125 if (drv_data->state == MV64XXX_I2C_STATE_ABORTING) {
126 drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
127 drv_data->state = MV64XXX_I2C_STATE_IDLE;
128 return;
129 }
130
131 /* The status from the ctlr [mostly] tells us what to do next */ 123 /* The status from the ctlr [mostly] tells us what to do next */
132 switch (status) { 124 switch (status) {
133 /* Start condition interrupt */ 125 /* Start condition interrupt */
@@ -148,14 +140,16 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
148 /* FALLTHRU */ 140 /* FALLTHRU */
149 case MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */ 141 case MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */
150 case MV64XXX_I2C_STATUS_MAST_WR_ACK: /* 0x28 */ 142 case MV64XXX_I2C_STATUS_MAST_WR_ACK: /* 0x28 */
151 if (drv_data->bytes_left > 0) { 143 if ((drv_data->bytes_left == 0)
144 || (drv_data->aborting
145 && (drv_data->byte_posn != 0))) {
146 drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
147 drv_data->state = MV64XXX_I2C_STATE_IDLE;
148 } else {
152 drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA; 149 drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA;
153 drv_data->state = 150 drv_data->state =
154 MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK; 151 MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK;
155 drv_data->bytes_left--; 152 drv_data->bytes_left--;
156 } else {
157 drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
158 drv_data->state = MV64XXX_I2C_STATE_IDLE;
159 } 153 }
160 break; 154 break;
161 155
@@ -184,7 +178,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
184 } 178 }
185 drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA; 179 drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA;
186 180
187 if (drv_data->bytes_left == 1) 181 if ((drv_data->bytes_left == 1) || drv_data->aborting)
188 drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_ACK; 182 drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_ACK;
189 break; 183 break;
190 184
@@ -320,6 +314,7 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
320 drv_data->msg = msg; 314 drv_data->msg = msg;
321 drv_data->byte_posn = 0; 315 drv_data->byte_posn = 0;
322 drv_data->bytes_left = msg->len; 316 drv_data->bytes_left = msg->len;
317 drv_data->aborting = 0;
323 drv_data->rc = 0; 318 drv_data->rc = 0;
324 drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK | 319 drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
325 MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN; 320 MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN;
@@ -359,17 +354,19 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
359 } 354 }
360 355
361 if (abort && drv_data->block) { 356 if (abort && drv_data->block) {
362 drv_data->state = MV64XXX_I2C_STATE_ABORTING; 357 drv_data->aborting = 1;
363 spin_unlock_irqrestore(&drv_data->lock, flags); 358 spin_unlock_irqrestore(&drv_data->lock, flags);
364 359
365 time_left = wait_event_timeout(drv_data->waitq, 360 time_left = wait_event_timeout(drv_data->waitq,
366 !drv_data->block, 361 !drv_data->block,
367 msecs_to_jiffies(drv_data->adapter.timeout)); 362 msecs_to_jiffies(drv_data->adapter.timeout));
368 363
369 if (time_left <= 0) { 364 if ((time_left <= 0) && drv_data->block) {
370 drv_data->state = MV64XXX_I2C_STATE_IDLE; 365 drv_data->state = MV64XXX_I2C_STATE_IDLE;
371 dev_err(&drv_data->adapter.dev, 366 dev_err(&drv_data->adapter.dev,
372 "mv64xxx: I2C bus locked\n"); 367 "mv64xxx: I2C bus locked, block: %d, "
368 "time_left: %d\n", drv_data->block,
369 (int)time_left);
373 } 370 }
374 } else 371 } else
375 spin_unlock_irqrestore(&drv_data->lock, flags); 372 spin_unlock_irqrestore(&drv_data->lock, flags);
@@ -510,7 +507,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
510 goto exit_kfree; 507 goto exit_kfree;
511 } 508 }
512 509
513 strncpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter", 510 strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
514 I2C_NAME_SIZE); 511 I2C_NAME_SIZE);
515 512
516 init_waitqueue_head(&drv_data->waitq); 513 init_waitqueue_head(&drv_data->waitq);