public inbox for linux-i2c@vger.kernel.org
 help / color / mirror / Atom feed
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
To: Yinbo Zhu <zhuyinbo@loongson.cn>
Cc: Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	Wolfram Sang <wsa@kernel.org>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Jarkko Nikula <jarkko.nikula@linux.intel.com>,
	Jean Delvare <jdelvare@suse.de>,
	William Zhang <william.zhang@broadcom.com>,
	Conor Dooley <conor.dooley@microchip.com>,
	Jan Dabros <jsd@semihalf.com>,
	Tharun Kumar P <tharunkumar.pasumarthi@microchip.com>,
	Phil Edworthy <phil.edworthy@renesas.com>,
	Sam Protsenko <semen.protsenko@linaro.org>,
	Tyrone Ting <kfting@nuvoton.com>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	linux-i2c@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 1/2] i2c: loongson: add bus driver for the loongson i2c controller
Date: Mon, 28 Nov 2022 16:02:30 +0200	[thread overview]
Message-ID: <Y4S/dh9lztpOHxkD@smile.fi.intel.com> (raw)
In-Reply-To: <20221128130025.23184-1-zhuyinbo@loongson.cn>

On Mon, Nov 28, 2022 at 09:00:24PM +0800, Yinbo Zhu wrote:
> This bus driver supports the Loongson i2c hardware controller in the
> Loongson platforms and supports to use DTS and ACPI framework to
> register i2c adapter device resources.
> 
> The Loongson i2c controller supports operating frequencty is 50MHZ
> and supports the maximum transmission rate is 400kbps.

...

> +static inline u8 i2c_readb(struct loongson_i2c_dev *dev, u8 offset)
> +{
> +	return readb(dev->base + offset);
> +}
> +
> +static inline void i2c_writeb(struct loongson_i2c_dev *dev, u8 val,
> +			      u8 offset)

For this you may turn parameters to be in more intuitive order, i.e.

static inline void i2c_writeb(struct loongson_i2c_dev *dev, u8 offset, u8 val)

(Also, why not on one line? Even with strict 80 it still fits).

> +{
> +	writeb(val, dev->base + offset);
> +}

...

> +static int loongson_i2c_start(struct loongson_i2c_dev *dev, int dev_addr,
> +			      int flags)
> +{
> +	int ret;
> +	unsigned long time_left;
> +	int retry = 5;

> +	unsigned char addr = LOONGSON_I2C_ADDR_A7(dev_addr) << 1;
> +
> +	addr |= (flags & I2C_M_RD) ? 1 : 0;

Why not i2c_8bit_addr_from_msg()?

> +	do {

> +		mdelay(1);

Needs an explanation why.

> +		i2c_writeb(dev, addr, LOONGSON_I2C_TXR_REG);
> +		i2c_writeb(dev, (CR_START | CR_WRITE | CR_IACK),
> +			   LOONGSON_I2C_CR_REG);
> +		time_left = wait_for_completion_timeout(&dev->cmd_complete,
> +							dev->adapter.timeout);
> +		if (!time_left)
> +			return -ETIMEDOUT;
> +
> +		if (i2c_readb(dev, LOONGSON_I2C_SR_REG) & SR_NOACK) {
> +			ret = loongson_i2c_stop(dev);
> +			if (ret)
> +				return ret;
> +		} else
> +			break;
> +	} while (retry--);
> +
> +	return 0;
> +}

...

> +	i2c_writeb(dev, 0xa0, LOONGSON_I2C_CTR_REG);

Magic number.

...

> +	if (!dev->speed_hz) {


Why not positive conditional?

> +		prer_val = 0x12c;
> +	} else {
> +		pclk = 50000000;

50 * HZ_PER_MHZ?

> +		prer_val = pclk / (5 * dev->speed_hz) - 1;
> +	}
> +
> +	i2c_writeb(dev, i2c_readb(dev, LOONGSON_I2C_CR_REG) |
> +		   0x01, LOONGSON_I2C_CR_REG);
> +	i2c_writeb(dev, i2c_readb(dev, LOONGSON_I2C_CTR_REG) & ~0x80,
> +		   LOONGSON_I2C_CTR_REG);

> +	i2c_writeb(dev, prer_val & GENMASK(7, 0), LOONGSON_I2C_PRER_LO_REG);
> +	i2c_writeb(dev, (prer_val & GENMASK(15, 8)) >> 8,

Why do you need GENMASK() parts?

> +		   LOONGSON_I2C_PRER_HI_REG);
> +	i2c_writeb(dev, i2c_readb(dev, LOONGSON_I2C_CTR_REG) |
> +		   0xe0, LOONGSON_I2C_CTR_REG);

A lot of magic numbers...

...

> +static int loongson_i2c_read(struct loongson_i2c_dev *dev, unsigned char *buf,
> +			     int count)
> +{
> +	int i;
> +	unsigned long time_left;
> +
> +	for (i = 0; i < count; i++) {

> +		i2c_writeb(dev, (i == count - 1) ?
> +			(CR_READ | CR_IACK | CR_ACK) : (CR_READ | CR_IACK),
> +			LOONGSON_I2C_CR_REG);

With temporary variable this will look better.

	u8 val = CR_READ | CR_IACK;
	...

		i2c_writeb(dev, (i == count - 1) ? val | CR_ACK : val,
			   LOONGSON_I2C_CR_REG);


Also fix wrong indentation.

> +		time_left = wait_for_completion_timeout(&dev->cmd_complete,
> +							dev->adapter.timeout);
> +		if (!time_left)
> +			return -ETIMEDOUT;
> +
> +		buf[i] = i2c_readb(dev, LOONGSON_I2C_RXR_REG);
> +	}
> +
> +	return i;
> +}

...

> +static int loongson_i2c_write(struct loongson_i2c_dev *dev, unsigned char *buf,
> +			      int count)
> +{
> +	int i;
> +	int ret;
> +	unsigned long time_left;
> +
> +	for (i = 0; i < count; i++) {
> +		i2c_writeb(dev, buf[i], LOONGSON_I2C_TXR_REG);
> +		i2c_writeb(dev, CR_WRITE | CR_IACK, LOONGSON_I2C_CR_REG);
> +		time_left = wait_for_completion_timeout(&dev->cmd_complete,
> +							dev->adapter.timeout);
> +		if (!time_left)
> +			return -ETIMEDOUT;
> +
> +		if (i2c_readb(dev, LOONGSON_I2C_SR_REG) & SR_NOACK) {
> +			ret = loongson_i2c_stop(dev);
> +			if (ret)
> +				return ret;
> +			return 0;
> +		}
> +	}
> +
> +	return i;

Can i be not equal to count here?

> +}

...

> +static int loongson_i2c_doxfer(struct loongson_i2c_dev *dev, struct i2c_msg *msgs,
> +			       int num)
> +{
> +	int i, ret;
> +	struct i2c_msg *m = msgs;
> +
> +	for (i = 0; i < num; i++) {
> +		reinit_completion(&dev->cmd_complete);
> +		ret = loongson_i2c_start(dev, m->addr, m->flags);
> +		if (ret)
> +			return ret;
> +
> +		if (m->flags & I2C_M_RD) {
> +			ret = loongson_i2c_read(dev, m->buf, m->len);
> +			if (ret)
> +				return ret;
> +		}
> +
> +		if (!(m->flags & I2C_M_RD)) {
> +			ret = loongson_i2c_write(dev, m->buf, m->len);
> +			if (ret)
> +				return ret;
> +		}
> +
> +		++m;
> +	}
> +
> +	ret = loongson_i2c_stop(dev);
> +	if (ret)
> +		return ret;
> +
> +	return i;

Can i be not equal to num here?

> +}

...

> +static int loongson_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
> +			     int num)
> +{
> +	int ret;
> +	int retry;
> +	struct loongson_i2c_dev *dev;
> +
> +	dev = i2c_get_adapdata(adap);
> +	for (retry = 0; retry < adap->retries; retry++) {
> +		ret = loongson_i2c_doxfer(dev, msgs, num);
> +		if (ret != -EAGAIN)
> +			return ret;
> +
> +		udelay(100);
> +	}

Why udelay() and not usleep_range() ?
Why so long?

All these at least have to be explained.

> +	return -EREMOTEIO;
> +}

Why not utilizing something from iopoll.h?

...

> +	if (dev->slave_state == LOONGSON_I2C_SLAVE_START)
> +		if (stat & SR_SLAVE_RW)
> +			dev->slave_state =
> +				LOONGSON_I2C_SLAVE_READ_REQUESTED;
> +		else
> +			dev->slave_state =
> +				LOONGSON_I2C_SLAVE_WRITE_REQUESTED;

Even with strict 80 rule, these are fine to be on one line.

I suggest you to go through the code and shrink it by 20-30 LoCs. It seems
feasible taking into account this kind of indentation.

...

> +static irqreturn_t loongson_i2c_isr(int this_irq, void *dev_id)
> +{
> +	unsigned char iflag;
> +	struct loongson_i2c_dev *dev = dev_id;
> +
> +	iflag = i2c_readb(dev, LOONGSON_I2C_SR_REG);

> +	if (iflag & SR_IF) {


Why not using the usual pattern, i.e.

	if (!(...))
		return IRQ_NONE;

?

It seems you ignored some of my comments...
I stopped here, please check what was given against v1 and try again.

-- 
With Best Regards,
Andy Shevchenko



  parent reply	other threads:[~2022-11-28 14:02 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-28 13:00 [PATCH v2 1/2] i2c: loongson: add bus driver for the loongson i2c controller Yinbo Zhu
2022-11-28 13:00 ` [PATCH v2 2/2] dt-bindings: i2c: add loongson i2c Yinbo Zhu
2022-11-28 14:11   ` Krzysztof Kozlowski
2022-11-28 23:51     ` Yinbo Zhu
2022-11-29  6:56       ` Yinbo Zhu
2022-11-28 14:02 ` Andy Shevchenko [this message]
2022-11-28 14:12   ` [PATCH v2 1/2] i2c: loongson: add bus driver for the loongson i2c controller Krzysztof Kozlowski
2022-11-28 14:26     ` Andy Shevchenko
2022-11-29  7:04       ` Yinbo Zhu
2022-12-05  8:40 ` Wolfram Sang
2022-12-05  8:56   ` Yinbo Zhu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y4S/dh9lztpOHxkD@smile.fi.intel.com \
    --to=andriy.shevchenko@linux.intel.com \
    --cc=conor.dooley@microchip.com \
    --cc=devicetree@vger.kernel.org \
    --cc=f.fainelli@gmail.com \
    --cc=jarkko.nikula@linux.intel.com \
    --cc=jdelvare@suse.de \
    --cc=jsd@semihalf.com \
    --cc=kfting@nuvoton.com \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=p.zabel@pengutronix.de \
    --cc=phil.edworthy@renesas.com \
    --cc=robh+dt@kernel.org \
    --cc=semen.protsenko@linaro.org \
    --cc=tharunkumar.pasumarthi@microchip.com \
    --cc=william.zhang@broadcom.com \
    --cc=wsa@kernel.org \
    --cc=zhuyinbo@loongson.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox