4343#define MLXSW_I2C_PREP_SIZE (MLXSW_I2C_ADDR_WIDTH + 28)
4444#define MLXSW_I2C_MBOX_SIZE 20
4545#define MLXSW_I2C_MBOX_OUT_PARAM_OFF 12
46- #define MLXSW_I2C_MAX_BUFF_SIZE 32
4746#define MLXSW_I2C_MBOX_OFFSET_BITS 20
4847#define MLXSW_I2C_MBOX_SIZE_BITS 12
4948#define MLXSW_I2C_ADDR_BUF_SIZE 4
50- #define MLXSW_I2C_BLK_MAX 32
49+ #define MLXSW_I2C_BLK_DEF 32
5150#define MLXSW_I2C_RETRY 5
5251#define MLXSW_I2C_TIMEOUT_MSECS 5000
5352#define MLXSW_I2C_MAX_DATA_SIZE 256
6261 * @dev: I2C device;
6362 * @core: switch core pointer;
6463 * @bus_info: bus info block;
64+ * @block_size: maximum block size allowed to pass to under layer;
6565 */
6666struct mlxsw_i2c {
6767 struct {
@@ -74,6 +74,7 @@ struct mlxsw_i2c {
7474 struct device * dev ;
7575 struct mlxsw_core * core ;
7676 struct mlxsw_bus_info bus_info ;
77+ u16 block_size ;
7778};
7879
7980#define MLXSW_I2C_READ_MSG (_client , _addr_buf , _buf , _len ) { \
@@ -315,20 +316,26 @@ mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num,
315316 struct i2c_client * client = to_i2c_client (dev );
316317 struct mlxsw_i2c * mlxsw_i2c = i2c_get_clientdata (client );
317318 unsigned long timeout = msecs_to_jiffies (MLXSW_I2C_TIMEOUT_MSECS );
318- u8 tran_buf [MLXSW_I2C_MAX_BUFF_SIZE + MLXSW_I2C_ADDR_BUF_SIZE ];
319319 int off = mlxsw_i2c -> cmd .mb_off_in , chunk_size , i , j ;
320320 unsigned long end ;
321+ u8 * tran_buf ;
321322 struct i2c_msg write_tran =
322- MLXSW_I2C_WRITE_MSG (client , tran_buf , MLXSW_I2C_PUSH_CMD_SIZE );
323+ MLXSW_I2C_WRITE_MSG (client , NULL , MLXSW_I2C_PUSH_CMD_SIZE );
323324 int err ;
324325
326+ tran_buf = kmalloc (mlxsw_i2c -> block_size + MLXSW_I2C_ADDR_BUF_SIZE ,
327+ GFP_KERNEL );
328+ if (!tran_buf )
329+ return - ENOMEM ;
330+
331+ write_tran .buf = tran_buf ;
325332 for (i = 0 ; i < num ; i ++ ) {
326- chunk_size = (in_mbox_size > MLXSW_I2C_BLK_MAX ) ?
327- MLXSW_I2C_BLK_MAX : in_mbox_size ;
333+ chunk_size = (in_mbox_size > mlxsw_i2c -> block_size ) ?
334+ mlxsw_i2c -> block_size : in_mbox_size ;
328335 write_tran .len = MLXSW_I2C_ADDR_WIDTH + chunk_size ;
329336 mlxsw_i2c_set_slave_addr (tran_buf , off );
330337 memcpy (& tran_buf [MLXSW_I2C_ADDR_BUF_SIZE ], in_mbox +
331- MLXSW_I2C_BLK_MAX * i , chunk_size );
338+ mlxsw_i2c -> block_size * i , chunk_size );
332339
333340 j = 0 ;
334341 end = jiffies + timeout ;
@@ -342,9 +349,10 @@ mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num,
342349 (j ++ < MLXSW_I2C_RETRY ));
343350
344351 if (err != 1 ) {
345- if (!err )
352+ if (!err ) {
346353 err = - EIO ;
347- return err ;
354+ goto mlxsw_i2c_write_exit ;
355+ }
348356 }
349357
350358 off += chunk_size ;
@@ -355,24 +363,27 @@ mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num,
355363 err = mlxsw_i2c_write_cmd (client , mlxsw_i2c , 0 );
356364 if (err ) {
357365 dev_err (& client -> dev , "Could not start transaction" );
358- return - EIO ;
366+ err = - EIO ;
367+ goto mlxsw_i2c_write_exit ;
359368 }
360369
361370 /* Wait until go bit is cleared. */
362371 err = mlxsw_i2c_wait_go_bit (client , mlxsw_i2c , p_status );
363372 if (err ) {
364373 dev_err (& client -> dev , "HW semaphore is not released" );
365- return err ;
374+ goto mlxsw_i2c_write_exit ;
366375 }
367376
368377 /* Validate transaction completion status. */
369378 if (* p_status ) {
370379 dev_err (& client -> dev , "Bad transaction completion status %x\n" ,
371380 * p_status );
372- return - EIO ;
381+ err = - EIO ;
373382 }
374383
375- return 0 ;
384+ mlxsw_i2c_write_exit :
385+ kfree (tran_buf );
386+ return err ;
376387}
377388
378389/* Routine executes I2C command. */
@@ -395,8 +406,8 @@ mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
395406
396407 if (in_mbox ) {
397408 reg_size = mlxsw_i2c_get_reg_size (in_mbox );
398- num = reg_size / MLXSW_I2C_BLK_MAX ;
399- if (reg_size % MLXSW_I2C_BLK_MAX )
409+ num = reg_size / mlxsw_i2c -> block_size ;
410+ if (reg_size % mlxsw_i2c -> block_size )
400411 num ++ ;
401412
402413 if (mutex_lock_interruptible (& mlxsw_i2c -> cmd .lock ) < 0 ) {
@@ -416,7 +427,7 @@ mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
416427 } else {
417428 /* No input mailbox is case of initialization query command. */
418429 reg_size = MLXSW_I2C_MAX_DATA_SIZE ;
419- num = reg_size / MLXSW_I2C_BLK_MAX ;
430+ num = reg_size / mlxsw_i2c -> block_size ;
420431
421432 if (mutex_lock_interruptible (& mlxsw_i2c -> cmd .lock ) < 0 ) {
422433 dev_err (& client -> dev , "Could not acquire lock" );
@@ -432,8 +443,8 @@ mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
432443 /* Send read transaction to get output mailbox content. */
433444 read_tran [1 ].buf = out_mbox ;
434445 for (i = 0 ; i < num ; i ++ ) {
435- chunk_size = (reg_size > MLXSW_I2C_BLK_MAX ) ?
436- MLXSW_I2C_BLK_MAX : reg_size ;
446+ chunk_size = (reg_size > mlxsw_i2c -> block_size ) ?
447+ mlxsw_i2c -> block_size : reg_size ;
437448 read_tran [1 ].len = chunk_size ;
438449 mlxsw_i2c_set_slave_addr (tran_buf , off );
439450
@@ -546,6 +557,7 @@ static const struct mlxsw_bus mlxsw_i2c_bus = {
546557static int mlxsw_i2c_probe (struct i2c_client * client ,
547558 const struct i2c_device_id * id )
548559{
560+ const struct i2c_adapter_quirks * quirks = client -> adapter -> quirks ;
549561 struct mlxsw_i2c * mlxsw_i2c ;
550562 u8 status ;
551563 int err ;
@@ -554,6 +566,22 @@ static int mlxsw_i2c_probe(struct i2c_client *client,
554566 if (!mlxsw_i2c )
555567 return - ENOMEM ;
556568
569+ if (quirks ) {
570+ if ((quirks -> max_read_len &&
571+ quirks -> max_read_len < MLXSW_I2C_BLK_DEF ) ||
572+ (quirks -> max_write_len &&
573+ quirks -> max_write_len < MLXSW_I2C_BLK_DEF )) {
574+ dev_err (& client -> dev , "Insufficient transaction buffer length\n" );
575+ return - EOPNOTSUPP ;
576+ }
577+
578+ mlxsw_i2c -> block_size = max_t (u16 , MLXSW_I2C_BLK_DEF ,
579+ min_t (u16 , quirks -> max_read_len ,
580+ quirks -> max_write_len ));
581+ } else {
582+ mlxsw_i2c -> block_size = MLXSW_I2C_BLK_DEF ;
583+ }
584+
557585 i2c_set_clientdata (client , mlxsw_i2c );
558586 mutex_init (& mlxsw_i2c -> cmd .lock );
559587
0 commit comments