diff options
-rw-r--r-- | drivers/i2c/busses/i2c-octeon.c | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c index 4fc471ce173e..cb418140cbbe 100644 --- a/drivers/i2c/busses/i2c-octeon.c +++ b/drivers/i2c/busses/i2c-octeon.c | |||
@@ -109,6 +109,8 @@ | |||
109 | #define TWSI_INT_SDA BIT_ULL(10) | 109 | #define TWSI_INT_SDA BIT_ULL(10) |
110 | #define TWSI_INT_SCL BIT_ULL(11) | 110 | #define TWSI_INT_SCL BIT_ULL(11) |
111 | 111 | ||
112 | #define I2C_OCTEON_EVENT_WAIT 80 /* microseconds */ | ||
113 | |||
112 | struct octeon_i2c { | 114 | struct octeon_i2c { |
113 | wait_queue_head_t queue; | 115 | wait_queue_head_t queue; |
114 | struct i2c_adapter adap; | 116 | struct i2c_adapter adap; |
@@ -339,11 +341,29 @@ static irqreturn_t octeon_i2c_hlc_isr78(int irq, void *dev_id) | |||
339 | return IRQ_HANDLED; | 341 | return IRQ_HANDLED; |
340 | } | 342 | } |
341 | 343 | ||
342 | static int octeon_i2c_test_iflg(struct octeon_i2c *i2c) | 344 | static bool octeon_i2c_test_iflg(struct octeon_i2c *i2c) |
343 | { | 345 | { |
344 | return (octeon_i2c_ctl_read(i2c) & TWSI_CTL_IFLG); | 346 | return (octeon_i2c_ctl_read(i2c) & TWSI_CTL_IFLG); |
345 | } | 347 | } |
346 | 348 | ||
349 | static bool octeon_i2c_test_ready(struct octeon_i2c *i2c, bool *first) | ||
350 | { | ||
351 | if (octeon_i2c_test_iflg(i2c)) | ||
352 | return true; | ||
353 | |||
354 | if (*first) { | ||
355 | *first = false; | ||
356 | return false; | ||
357 | } | ||
358 | |||
359 | /* | ||
360 | * IRQ has signaled an event but IFLG hasn't changed. | ||
361 | * Sleep and retry once. | ||
362 | */ | ||
363 | usleep_range(I2C_OCTEON_EVENT_WAIT, 2 * I2C_OCTEON_EVENT_WAIT); | ||
364 | return octeon_i2c_test_iflg(i2c); | ||
365 | } | ||
366 | |||
347 | /** | 367 | /** |
348 | * octeon_i2c_wait - wait for the IFLG to be set | 368 | * octeon_i2c_wait - wait for the IFLG to be set |
349 | * @i2c: The struct octeon_i2c | 369 | * @i2c: The struct octeon_i2c |
@@ -353,15 +373,14 @@ static int octeon_i2c_test_iflg(struct octeon_i2c *i2c) | |||
353 | static int octeon_i2c_wait(struct octeon_i2c *i2c) | 373 | static int octeon_i2c_wait(struct octeon_i2c *i2c) |
354 | { | 374 | { |
355 | long time_left; | 375 | long time_left; |
376 | bool first = 1; | ||
356 | 377 | ||
357 | i2c->int_enable(i2c); | 378 | i2c->int_enable(i2c); |
358 | time_left = wait_event_timeout(i2c->queue, octeon_i2c_test_iflg(i2c), | 379 | time_left = wait_event_timeout(i2c->queue, octeon_i2c_test_ready(i2c, &first), |
359 | i2c->adap.timeout); | 380 | i2c->adap.timeout); |
360 | i2c->int_disable(i2c); | 381 | i2c->int_disable(i2c); |
361 | if (!time_left) { | 382 | if (!time_left) |
362 | dev_dbg(i2c->dev, "%s: timeout\n", __func__); | ||
363 | return -ETIMEDOUT; | 383 | return -ETIMEDOUT; |
364 | } | ||
365 | 384 | ||
366 | return 0; | 385 | return 0; |
367 | } | 386 | } |
@@ -427,11 +446,28 @@ static int octeon_i2c_check_status(struct octeon_i2c *i2c, int final_read) | |||
427 | } | 446 | } |
428 | } | 447 | } |
429 | 448 | ||
430 | static bool octeon_i2c_hlc_test_ready(struct octeon_i2c *i2c) | 449 | static bool octeon_i2c_hlc_test_valid(struct octeon_i2c *i2c) |
450 | { | ||
451 | return (__raw_readq(i2c->twsi_base + SW_TWSI) & SW_TWSI_V) == 0; | ||
452 | } | ||
453 | |||
454 | static bool octeon_i2c_hlc_test_ready(struct octeon_i2c *i2c, bool *first) | ||
431 | { | 455 | { |
432 | u64 val = __raw_readq(i2c->twsi_base + SW_TWSI); | 456 | /* check if valid bit is cleared */ |
457 | if (octeon_i2c_hlc_test_valid(i2c)) | ||
458 | return true; | ||
433 | 459 | ||
434 | return (val & SW_TWSI_V) == 0; | 460 | if (*first) { |
461 | *first = false; | ||
462 | return false; | ||
463 | } | ||
464 | |||
465 | /* | ||
466 | * IRQ has signaled an event but valid bit isn't cleared. | ||
467 | * Sleep and retry once. | ||
468 | */ | ||
469 | usleep_range(I2C_OCTEON_EVENT_WAIT, 2 * I2C_OCTEON_EVENT_WAIT); | ||
470 | return octeon_i2c_hlc_test_valid(i2c); | ||
435 | } | 471 | } |
436 | 472 | ||
437 | static void octeon_i2c_hlc_int_enable(struct octeon_i2c *i2c) | 473 | static void octeon_i2c_hlc_int_enable(struct octeon_i2c *i2c) |
@@ -453,11 +489,12 @@ static void octeon_i2c_hlc_int_clear(struct octeon_i2c *i2c) | |||
453 | */ | 489 | */ |
454 | static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c) | 490 | static int octeon_i2c_hlc_wait(struct octeon_i2c *i2c) |
455 | { | 491 | { |
492 | bool first = 1; | ||
456 | int time_left; | 493 | int time_left; |
457 | 494 | ||
458 | i2c->hlc_int_enable(i2c); | 495 | i2c->hlc_int_enable(i2c); |
459 | time_left = wait_event_timeout(i2c->queue, | 496 | time_left = wait_event_timeout(i2c->queue, |
460 | octeon_i2c_hlc_test_ready(i2c), | 497 | octeon_i2c_hlc_test_ready(i2c, &first), |
461 | i2c->adap.timeout); | 498 | i2c->adap.timeout); |
462 | i2c->hlc_int_disable(i2c); | 499 | i2c->hlc_int_disable(i2c); |
463 | if (!time_left) { | 500 | if (!time_left) { |