[PATCH v12 2/2] i2c: aspeed: support ast2600 i2c new register mode driver

Ryan Chen ryan_chen at aspeedtech.com
Thu Oct 5 17:21:35 AEDT 2023


Hello Andy,
	appreciate your review and comments.

> -----Original Message-----
> From: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> Sent: Tuesday, September 5, 2023 7:55 PM
> To: Ryan Chen <ryan_chen at aspeedtech.com>
> Cc: jk at codeconstruct.com.au; Brendan Higgins <brendan.higgins at linux.dev>;
> Benjamin Herrenschmidt <benh at kernel.crashing.org>; Joel Stanley
> <joel at jms.id.au>; Rob Herring <robh+dt at kernel.org>; Krzysztof Kozlowski
> <krzysztof.kozlowski+dt at linaro.org>; Andrew Jeffery <andrew at aj.id.au>;
> Philipp Zabel <p.zabel at pengutronix.de>; Wolfram Sang <wsa at kernel.org>;
> linux-i2c at vger.kernel.org; Florian Fainelli <f.fainelli at gmail.com>; Jean
> Delvare <jdelvare at suse.de>; William Zhang <william.zhang at broadcom.com>;
> Tyrone Ting <kfting at nuvoton.com>; Tharun Kumar P
> <tharunkumar.pasumarthi at microchip.com>; Conor Dooley
> <conor.dooley at microchip.com>; Phil Edworthy <phil.edworthy at renesas.com>;
> openbmc at lists.ozlabs.org; devicetree at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linux-aspeed at lists.ozlabs.org;
> =linux-kernel at vger.kernel.org; Andi Shyti <andi.shyti at kernel.org>
> Subject: Re: [PATCH v12 2/2] i2c: aspeed: support ast2600 i2c new register
> mode driver
> 
> On Tue, Sep 05, 2023 at 06:52:37AM +0000, Ryan Chen wrote:
> > > From: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> > > Sent: Friday, July 14, 2023 4:55 PM
> > > On Fri, Jul 14, 2023 at 03:45:22PM +0800, Ryan Chen wrote:
> 
> ...
> 
> > > > +#define AST2600_I2CC_GET_RX_BUFF(x)			(((x) >> 8) &
> > > GENMASK(7, 0))
> > >
> > > > +#define AST2600_I2CC_GET_RX_BUF_LEN(x)		(((x) >> 24) &
> > > GENMASK(5, 0))
> > >
> > > > +#define AST2600_I2CC_GET_TX_BUF_LEN(x)		((((x) >> 8) &
> > > GENMASK(4, 0)) + 1)
> > >
> > > With right shifts it's better to have GENMASK to be applied first,
> > > it will show exact MSB of the bitfield.
> > >
> > > (Ditto for other cases similar to these)
> 
> > It will update next version.
> > #define AST2600_I2CC_GET_RX_BUF_LEN(x)      (((x) & GENMASK(29, 24))
> >> 24)
> > #define AST2600_I2CC_GET_TX_BUF_LEN(x)      ((((x) & GENMASK(12, 8))
> >> 8) + 1)
> 
> Note, these were just an example, check _all_ of the similar cases.
> 
> In general any reviewer's comment should be considered for the entire code
> where it makes sense.
> 

Sure, will check entire code.

> ...
> 
> > 			divisor = DIV_ROUND_UP(base_clk[3],
> i2c_bus->timing_info.bus_freq_hz);
> > 			for_each_set_bit(divisor, &divisor, 32) {
> 
> This is wrong.
> 
> > 				if ((divisor + 1) <= 32)
> > 					break;
> 
> > 				divisor >>= 1;
> 
> And this.
> 
> > 				baseclk_idx++;
> 
> > 			}
> 
> for_each_set_bit() should use two different variables.

Will update by following.

for_each_set_bit(bit, &divisor, 32) {
    divisor >>= 1;
    baseclk_idx++;
}

> 
> > 		} else {
> > 			baseclk_idx = i + 1;
> > 			divisor = DIV_ROUND_UP(base_clk[i],
> i2c_bus->timing_info.bus_freq_hz);
> > 		}
> > 	}
> 
> ...
> 
> > 	divisor = min_t(unsigned long, divisor, 32);
> 
> Can't you use min()? min_t is a beast with some subtle corner cases.
> 
Will update to 
divisor = min(divisor, (unsigned long)32);

> ...
> 
> > Sorry I don't catch this split slave out to separate change?
> > Do you mean go for another file name example ast2600_i2c_slave.c ?
> 
> No, I mean
> 
>  patch 1: Introduce the driver with only master support  patch 2: Add slave
> capability (all what is under ifdeffery for I2C_SLAVE)
> 
Got your point, will be separate patch. master -> slave added.
> ...
> 
> > static int ast2600_i2c_do_start(struct ast2600_i2c_bus *i2c_bus) {
> > 	struct i2c_msg *msg = &i2c_bus->msgs[i2c_bus->msgs_index];
> 
> > 	int ret;
> 
> This is not needed, you may return directly.
> 
> > 	/* send start */
> > 	dev_dbg(i2c_bus->dev, "[%d] %sing %d byte%s %s 0x%02x\n",
> > 		i2c_bus->msgs_index, str_read_write(msg->flags & I2C_M_RD),
> > 		msg->len, msg->len > 1 ? "s" : "",
> > 		msg->flags & I2C_M_RD ? "from" : "to", msg->addr);
> >
> > 	i2c_bus->master_xfer_cnt = 0;
> > 	i2c_bus->buf_index = 0;
> 
> > 	if (msg->flags & I2C_M_RD) {
> > 		if (i2c_bus->mode == DMA_MODE)
> > 			ret = ast2600_i2c_setup_dma_rx(i2c_bus);
> 
> 			return ...;
> 		if ...
> 
> 
> > 		else if (i2c_bus->mode == BUFF_MODE)
> > 			ret = ast2600_i2c_setup_buff_rx(i2c_bus);
> > 		else
> > 			ret = ast2600_i2c_setup_byte_rx(i2c_bus);
> 
> > 	} else {
> > 		if (i2c_bus->mode == DMA_MODE)
> > 			ret = ast2600_i2c_setup_dma_tx(AST2600_I2CM_START_CMD,
> i2c_bus);
> > 		else if (i2c_bus->mode == BUFF_MODE)
> > 			ret = ast2600_i2c_setup_buff_tx(AST2600_I2CM_START_CMD,
> i2c_bus);
> > 		else
> > 			ret = ast2600_i2c_setup_byte_tx(AST2600_I2CM_START_CMD,
> i2c_bus);
> 
> Same way.
> 
Yes, will update it.

> > 	}
> >
> > 	return ret;
> > }
> 
> ...
> 
> > > Wrong memory accessors. You should use something from
> > > asm/byteorder.h which includes linux/byteorder/generic.h.
> >
> > Sorry, about these parts. I quit no idea.
> > This is chip register limited, it only support dword write, not support byte
> write.
> > So the only way I have is use get_unaligned_le32 function get the byte buffer
> to align dword write.
> > Or I may need your help point me a good way.
> 
> >  	for (i = 0; i < xfer_len; i++) {
> >  		wbuf[i % 4] = msg->buf[i2c_bus->master_xfer_cnt + i];
> >  		if (i % 4 == 3) {
> >  			wbuf_dword = get_unaligned_le32(wbuf);
> >  			writel(wbuf_dword, i2c_bus->buf_base + i - 3);
> >  		}
> >  	}
> >
> >  	if (--i % 4 != 3) {
> >  		wbuf_dword = get_unaligned_le32(wbuf);
> >  		writel(wbuf_dword, i2c_bus->buf_base + i - (i % 4));
> >  	}
> 
> Something like that. The most problematic part in your original code is
> dereferencing byte memory as 32-bit memory with all possible problems
> behind.
> With this code it's gone. The code itself might be improved even more, you can
> think about it, you still have time (we are now in v6.7 cycle).
> 
Got it, let me find a better way, and also readable. 

> --
> With Best Regards,
> Andy Shevchenko
> 



More information about the openbmc mailing list