diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-mv64xxx.c')
-rw-r--r-- | drivers/i2c/busses/i2c-mv64xxx.c | 33 |
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); |