160
160
161
161
#define IE_S_ALL_INTERRUPT_SHIFT 21
162
162
#define IE_S_ALL_INTERRUPT_MASK 0x3f
163
+ /*
164
+ * It takes ~18us to reading 10bytes of data, hence to keep tasklet
165
+ * running for less time, max slave read per tasklet is set to 10 bytes.
166
+ */
167
+ #define MAX_SLAVE_RX_PER_INT 10
163
168
164
169
enum i2c_slave_read_status {
165
170
I2C_SLAVE_RX_FIFO_EMPTY = 0 ,
@@ -206,8 +211,18 @@ struct bcm_iproc_i2c_dev {
206
211
/* bytes that have been read */
207
212
unsigned int rx_bytes ;
208
213
unsigned int thld_bytes ;
214
+
215
+ bool slave_rx_only ;
216
+ bool rx_start_rcvd ;
217
+ bool slave_read_complete ;
218
+ u32 tx_underrun ;
219
+ u32 slave_int_mask ;
220
+ struct tasklet_struct slave_rx_tasklet ;
209
221
};
210
222
223
+ /* tasklet to process slave rx data */
224
+ static void slave_rx_tasklet_fn (unsigned long );
225
+
211
226
/*
212
227
* Can be expanded in the future if more interrupt status bits are utilized
213
228
*/
@@ -261,6 +276,7 @@ static void bcm_iproc_i2c_slave_init(
261
276
{
262
277
u32 val ;
263
278
279
+ iproc_i2c -> tx_underrun = 0 ;
264
280
if (need_reset ) {
265
281
/* put controller in reset */
266
282
val = iproc_i2c_rd_reg (iproc_i2c , CFG_OFFSET );
@@ -297,8 +313,11 @@ static void bcm_iproc_i2c_slave_init(
297
313
298
314
/* Enable interrupt register to indicate a valid byte in receive fifo */
299
315
val = BIT (IE_S_RX_EVENT_SHIFT );
316
+ /* Enable interrupt register to indicate a Master read transaction */
317
+ val |= BIT (IE_S_RD_EVENT_SHIFT );
300
318
/* Enable interrupt register for the Slave BUSY command */
301
319
val |= BIT (IE_S_START_BUSY_SHIFT );
320
+ iproc_i2c -> slave_int_mask = val ;
302
321
iproc_i2c_wr_reg (iproc_i2c , IE_OFFSET , val );
303
322
}
304
323
@@ -324,76 +343,176 @@ static void bcm_iproc_i2c_check_slave_status(
324
343
}
325
344
}
326
345
327
- static bool bcm_iproc_i2c_slave_isr (struct bcm_iproc_i2c_dev * iproc_i2c ,
328
- u32 status )
346
+ static void bcm_iproc_i2c_slave_read (struct bcm_iproc_i2c_dev * iproc_i2c )
329
347
{
348
+ u8 rx_data , rx_status ;
349
+ u32 rx_bytes = 0 ;
330
350
u32 val ;
331
- u8 value , rx_status ;
332
351
333
- /* Slave RX byte receive */
334
- if (status & BIT (IS_S_RX_EVENT_SHIFT )) {
352
+ while (rx_bytes < MAX_SLAVE_RX_PER_INT ) {
335
353
val = iproc_i2c_rd_reg (iproc_i2c , S_RX_OFFSET );
336
354
rx_status = (val >> S_RX_STATUS_SHIFT ) & S_RX_STATUS_MASK ;
337
- if (rx_status == I2C_SLAVE_RX_START ) {
338
- /* Start of SMBUS for Master write */
339
- i2c_slave_event (iproc_i2c -> slave ,
340
- I2C_SLAVE_WRITE_REQUESTED , & value );
355
+ rx_data = ((val >> S_RX_DATA_SHIFT ) & S_RX_DATA_MASK );
341
356
342
- val = iproc_i2c_rd_reg ( iproc_i2c , S_RX_OFFSET );
343
- value = ( u8 )(( val >> S_RX_DATA_SHIFT ) & S_RX_DATA_MASK );
357
+ if ( rx_status == I2C_SLAVE_RX_START ) {
358
+ /* Start of SMBUS Master write */
344
359
i2c_slave_event (iproc_i2c -> slave ,
345
- I2C_SLAVE_WRITE_RECEIVED , & value );
346
- } else if (status & BIT (IS_S_RD_EVENT_SHIFT )) {
347
- /* Start of SMBUS for Master Read */
360
+ I2C_SLAVE_WRITE_REQUESTED , & rx_data );
361
+ iproc_i2c -> rx_start_rcvd = true;
362
+ iproc_i2c -> slave_read_complete = false;
363
+ } else if (rx_status == I2C_SLAVE_RX_DATA &&
364
+ iproc_i2c -> rx_start_rcvd ) {
365
+ /* Middle of SMBUS Master write */
348
366
i2c_slave_event (iproc_i2c -> slave ,
349
- I2C_SLAVE_READ_REQUESTED , & value );
350
- iproc_i2c_wr_reg (iproc_i2c , S_TX_OFFSET , value );
367
+ I2C_SLAVE_WRITE_RECEIVED , & rx_data );
368
+ } else if (rx_status == I2C_SLAVE_RX_END &&
369
+ iproc_i2c -> rx_start_rcvd ) {
370
+ /* End of SMBUS Master write */
371
+ if (iproc_i2c -> slave_rx_only )
372
+ i2c_slave_event (iproc_i2c -> slave ,
373
+ I2C_SLAVE_WRITE_RECEIVED ,
374
+ & rx_data );
375
+
376
+ i2c_slave_event (iproc_i2c -> slave , I2C_SLAVE_STOP ,
377
+ & rx_data );
378
+ } else if (rx_status == I2C_SLAVE_RX_FIFO_EMPTY ) {
379
+ iproc_i2c -> rx_start_rcvd = false;
380
+ iproc_i2c -> slave_read_complete = true;
381
+ break ;
382
+ }
351
383
352
- val = BIT (S_CMD_START_BUSY_SHIFT );
353
- iproc_i2c_wr_reg (iproc_i2c , S_CMD_OFFSET , val );
384
+ rx_bytes ++ ;
385
+ }
386
+ }
354
387
355
- /*
356
- * Enable interrupt for TX FIFO becomes empty and
357
- * less than PKT_LENGTH bytes were output on the SMBUS
358
- */
359
- val = iproc_i2c_rd_reg (iproc_i2c , IE_OFFSET );
360
- val |= BIT (IE_S_TX_UNDERRUN_SHIFT );
361
- iproc_i2c_wr_reg (iproc_i2c , IE_OFFSET , val );
362
- } else {
363
- /* Master write other than start */
364
- value = (u8 )((val >> S_RX_DATA_SHIFT ) & S_RX_DATA_MASK );
388
+ static void slave_rx_tasklet_fn (unsigned long data )
389
+ {
390
+ struct bcm_iproc_i2c_dev * iproc_i2c = (struct bcm_iproc_i2c_dev * )data ;
391
+ u32 int_clr ;
392
+
393
+ bcm_iproc_i2c_slave_read (iproc_i2c );
394
+
395
+ /* clear pending IS_S_RX_EVENT_SHIFT interrupt */
396
+ int_clr = BIT (IS_S_RX_EVENT_SHIFT );
397
+
398
+ if (!iproc_i2c -> slave_rx_only && iproc_i2c -> slave_read_complete ) {
399
+ /*
400
+ * In case of single byte master-read request,
401
+ * IS_S_TX_UNDERRUN_SHIFT event is generated before
402
+ * IS_S_START_BUSY_SHIFT event. Hence start slave data send
403
+ * from first IS_S_TX_UNDERRUN_SHIFT event.
404
+ *
405
+ * This means don't send any data from slave when
406
+ * IS_S_RD_EVENT_SHIFT event is generated else it will increment
407
+ * eeprom or other backend slave driver read pointer twice.
408
+ */
409
+ iproc_i2c -> tx_underrun = 0 ;
410
+ iproc_i2c -> slave_int_mask |= BIT (IE_S_TX_UNDERRUN_SHIFT );
411
+
412
+ /* clear IS_S_RD_EVENT_SHIFT interrupt */
413
+ int_clr |= BIT (IS_S_RD_EVENT_SHIFT );
414
+ }
415
+
416
+ /* clear slave interrupt */
417
+ iproc_i2c_wr_reg (iproc_i2c , IS_OFFSET , int_clr );
418
+ /* enable slave interrupts */
419
+ iproc_i2c_wr_reg (iproc_i2c , IE_OFFSET , iproc_i2c -> slave_int_mask );
420
+ }
421
+
422
+ static bool bcm_iproc_i2c_slave_isr (struct bcm_iproc_i2c_dev * iproc_i2c ,
423
+ u32 status )
424
+ {
425
+ u32 val ;
426
+ u8 value ;
427
+
428
+ /*
429
+ * Slave events in case of master-write, master-write-read and,
430
+ * master-read
431
+ *
432
+ * Master-write : only IS_S_RX_EVENT_SHIFT event
433
+ * Master-write-read: both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT
434
+ * events
435
+ * Master-read : both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT
436
+ * events or only IS_S_RD_EVENT_SHIFT
437
+ */
438
+ if (status & BIT (IS_S_RX_EVENT_SHIFT ) ||
439
+ status & BIT (IS_S_RD_EVENT_SHIFT )) {
440
+ /* disable slave interrupts */
441
+ val = iproc_i2c_rd_reg (iproc_i2c , IE_OFFSET );
442
+ val &= ~iproc_i2c -> slave_int_mask ;
443
+ iproc_i2c_wr_reg (iproc_i2c , IE_OFFSET , val );
444
+
445
+ if (status & BIT (IS_S_RD_EVENT_SHIFT ))
446
+ /* Master-write-read request */
447
+ iproc_i2c -> slave_rx_only = false;
448
+ else
449
+ /* Master-write request only */
450
+ iproc_i2c -> slave_rx_only = true;
451
+
452
+ /* schedule tasklet to read data later */
453
+ tasklet_schedule (& iproc_i2c -> slave_rx_tasklet );
454
+
455
+ /* clear only IS_S_RX_EVENT_SHIFT interrupt */
456
+ iproc_i2c_wr_reg (iproc_i2c , IS_OFFSET ,
457
+ BIT (IS_S_RX_EVENT_SHIFT ));
458
+ }
459
+
460
+ if (status & BIT (IS_S_TX_UNDERRUN_SHIFT )) {
461
+ iproc_i2c -> tx_underrun ++ ;
462
+ if (iproc_i2c -> tx_underrun == 1 )
463
+ /* Start of SMBUS for Master Read */
365
464
i2c_slave_event (iproc_i2c -> slave ,
366
- I2C_SLAVE_WRITE_RECEIVED , & value );
367
- if (rx_status == I2C_SLAVE_RX_END )
368
- i2c_slave_event (iproc_i2c -> slave ,
369
- I2C_SLAVE_STOP , & value );
370
- }
371
- } else if (status & BIT (IS_S_TX_UNDERRUN_SHIFT )) {
372
- /* Master read other than start */
373
- i2c_slave_event (iproc_i2c -> slave ,
374
- I2C_SLAVE_READ_PROCESSED , & value );
465
+ I2C_SLAVE_READ_REQUESTED ,
466
+ & value );
467
+ else
468
+ /* Master read other than start */
469
+ i2c_slave_event (iproc_i2c -> slave ,
470
+ I2C_SLAVE_READ_PROCESSED ,
471
+ & value );
375
472
376
473
iproc_i2c_wr_reg (iproc_i2c , S_TX_OFFSET , value );
474
+ /* start transfer */
377
475
val = BIT (S_CMD_START_BUSY_SHIFT );
378
476
iproc_i2c_wr_reg (iproc_i2c , S_CMD_OFFSET , val );
477
+
478
+ /* clear interrupt */
479
+ iproc_i2c_wr_reg (iproc_i2c , IS_OFFSET ,
480
+ BIT (IS_S_TX_UNDERRUN_SHIFT ));
379
481
}
380
482
381
- /* Stop */
483
+ /* Stop received from master in case of master read transaction */
382
484
if (status & BIT (IS_S_START_BUSY_SHIFT )) {
383
- i2c_slave_event (iproc_i2c -> slave , I2C_SLAVE_STOP , & value );
384
485
/*
385
486
* Disable interrupt for TX FIFO becomes empty and
386
487
* less than PKT_LENGTH bytes were output on the SMBUS
387
488
*/
388
- val = iproc_i2c_rd_reg (iproc_i2c , IE_OFFSET );
389
- val &= ~BIT (IE_S_TX_UNDERRUN_SHIFT );
390
- iproc_i2c_wr_reg (iproc_i2c , IE_OFFSET , val );
489
+ iproc_i2c -> slave_int_mask &= ~BIT (IE_S_TX_UNDERRUN_SHIFT );
490
+ iproc_i2c_wr_reg (iproc_i2c , IE_OFFSET ,
491
+ iproc_i2c -> slave_int_mask );
492
+
493
+ /* End of SMBUS for Master Read */
494
+ val = BIT (S_TX_WR_STATUS_SHIFT );
495
+ iproc_i2c_wr_reg (iproc_i2c , S_TX_OFFSET , val );
496
+
497
+ val = BIT (S_CMD_START_BUSY_SHIFT );
498
+ iproc_i2c_wr_reg (iproc_i2c , S_CMD_OFFSET , val );
499
+
500
+ /* flush TX FIFOs */
501
+ val = iproc_i2c_rd_reg (iproc_i2c , S_FIFO_CTRL_OFFSET );
502
+ val |= (BIT (S_FIFO_TX_FLUSH_SHIFT ));
503
+ iproc_i2c_wr_reg (iproc_i2c , S_FIFO_CTRL_OFFSET , val );
504
+
505
+ i2c_slave_event (iproc_i2c -> slave , I2C_SLAVE_STOP , & value );
506
+
507
+ /* clear interrupt */
508
+ iproc_i2c_wr_reg (iproc_i2c , IS_OFFSET ,
509
+ BIT (IS_S_START_BUSY_SHIFT ));
391
510
}
392
511
393
- /* clear interrupt status */
394
- iproc_i2c_wr_reg (iproc_i2c , IS_OFFSET , status );
512
+ /* check slave transmit status only if slave is transmitting */
513
+ if (!iproc_i2c -> slave_rx_only )
514
+ bcm_iproc_i2c_check_slave_status (iproc_i2c );
395
515
396
- bcm_iproc_i2c_check_slave_status (iproc_i2c );
397
516
return true;
398
517
}
399
518
@@ -1074,6 +1193,10 @@ static int bcm_iproc_i2c_reg_slave(struct i2c_client *slave)
1074
1193
return - EAFNOSUPPORT ;
1075
1194
1076
1195
iproc_i2c -> slave = slave ;
1196
+
1197
+ tasklet_init (& iproc_i2c -> slave_rx_tasklet , slave_rx_tasklet_fn ,
1198
+ (unsigned long )iproc_i2c );
1199
+
1077
1200
bcm_iproc_i2c_slave_init (iproc_i2c , false);
1078
1201
return 0 ;
1079
1202
}
@@ -1094,6 +1217,8 @@ static int bcm_iproc_i2c_unreg_slave(struct i2c_client *slave)
1094
1217
IE_S_ALL_INTERRUPT_SHIFT );
1095
1218
iproc_i2c_wr_reg (iproc_i2c , IE_OFFSET , tmp );
1096
1219
1220
+ tasklet_kill (& iproc_i2c -> slave_rx_tasklet );
1221
+
1097
1222
/* Erase the slave address programmed */
1098
1223
tmp = iproc_i2c_rd_reg (iproc_i2c , S_CFG_SMBUS_ADDR_OFFSET );
1099
1224
tmp &= ~BIT (S_CFG_EN_NIC_SMB_ADDR3_SHIFT );
0 commit comments