All of lore.kernel.org
 help / color / mirror / Atom feed
From: andy.shevchenko@gmail.com
To: Yinbo Zhu <zhuyinbo@loongson.cn>
Cc: Mark Brown <broonie@kernel.org>, Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	linux-spi@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, Jianmin Lv <lvjianmin@loongson.cn>,
	wanghongliang@loongson.cn, Liu Peibao <liupeibao@loongson.cn>,
	loongson-kernel@lists.loongnix.cn
Subject: Re: [PATCH v9 2/2] spi: loongson: add bus driver for the loongson spi controller
Date: Mon, 8 May 2023 18:04:06 +0300	[thread overview]
Message-ID: <ZFkPZhF8QqScXAmH@surfacebook> (raw)
In-Reply-To: <20230426071045.20753-3-zhuyinbo@loongson.cn>

Wed, Apr 26, 2023 at 03:10:45PM +0800, Yinbo Zhu kirjoitti:
> This bus driver supports the Loongson spi hardware controller in the
> Loongson platforms and supports to use DTS and PCI framework to
> register spi device resources.

SPI

...

> +config SPI_LOONGSON_CORE
> +	tristate "Loongson SPI Controller Core Driver Support"

Does it need to be visible to the user?

> +	depends on LOONGARCH || COMPILE_TEST
> +	help
> +	  This core driver supports the Loongson spi hardware controller in
> +	  the Loongson platforms.
> +	  Say Y or M here if you want to use the SPI controller on
> +	  Loongson platform.

...

> +config SPI_LOONGSON_PLATFORM
> +	tristate "Loongson SPI Controller Platform Driver Support"
> +	select SPI_LOONGSON_CORE
> +	depends on OF && (LOONGARCH || COMPILE_TEST)

Is it really dependent to OF? Why?

> +	help
> +	  This bus driver supports the Loongson spi hardware controller in
> +	  the Loongson platforms and supports to use DTS framework to
> +	  register spi device resources.
> +	  Say Y or M here if you want to use the SPI controller on
> +	  Loongson platform.

...

> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/interrupt.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/spi/spi.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>

Ordered?

...

> +	if (loongson_spi->mode & SPI_NO_CS)
> +		loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_SFCS_REG, 0);

Missing {}

> +	else {
> +		cs = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SFCS_REG)
> +					   & ~(0x11 << spi->chip_select);
> +		loongson_spi_write_reg(loongson_spi,
> +				       LOONGSON_SPI_SFCS_REG,
> +				       (val ? (0x11 << spi->chip_select) :
> +				       (0x1 << spi->chip_select)) | cs);

Too many parentheses.

> +	}

...

> +	const char rdiv[12] = {0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10, 11};

Oh, why?!

...

> +	if ((hz && loongson_spi->hz != hz) ||
> +	    ((spi->mode ^ loongson_spi->mode) & (SPI_CPOL | SPI_CPHA))) {
> +		div = DIV_ROUND_UP_ULL(loongson_spi->clk_rate, hz);

> +		if (div < 2)
> +			div = 2;
> +		if (div > 4096)
> +			div = 4096;

NIH clamp_val()

> +		bit = fls(div) - 1;
> +		if ((1<<bit) == div)
> +			bit--;
> +		div_tmp = rdiv[bit];

I believe this can be optimized.

> +		dev_dbg(&spi->dev, "clk_rate = %llu hz = %d div_tmp = %d bit = %d\n",
> +			loongson_spi->clk_rate, hz, div_tmp, bit);
> +
> +		loongson_spi->hz = hz;
> +		loongson_spi->spcr = div_tmp & 3;
> +		loongson_spi->sper = (div_tmp >> 2) & 3;
> +		val = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SPCR_REG);
> +		val &= ~0xc;

GENMASK()

> +		if (spi->mode & SPI_CPOL)
> +			val |= 8;

BIT()

> +		if (spi->mode & SPI_CPHA)
> +			val |= 4;

> +		loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_SPCR_REG, (val & ~3) |
> +				       loongson_spi->spcr);
> +		val = loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SPER_REG);
> +		loongson_spi_write_reg(loongson_spi, LOONGSON_SPI_SPER_REG, (val & ~3) |
> +				       loongson_spi->sper);
> +		loongson_spi->mode &= SPI_NO_CS;
> +		loongson_spi->mode |= spi->mode;
> +	}

...

> +		while ((loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SPSR_REG) & 0x1) == 1 &&
> +			time_after(timeout, jiffies))
> +			cpu_relax();

iopoll.h has a suitable macro for this.

...

> +		while ((loongson_spi_read_reg(loongson_spi, LOONGSON_SPI_SPSR_REG) & 0x1) == 1 &&
> +			time_after(timeout, jiffies))
> +			cpu_relax();

Ditto.

...

> +	master = devm_spi_alloc_master(dev, sizeof(struct loongson_spi));
> +	if (master == NULL) {

> +		dev_info(dev, "master allocation failed\n");

We do not issue a message for ENOMEM

> +		return -ENOMEM;
> +	}

...

> +	master->dev.of_node = of_node_get(dev->of_node);

device_set_node()

...

> +	spi->base = devm_ioremap(dev, res->start, resource_size(res));

Why not devm_ioremap_resource()?


> +	if (spi->base == NULL) {
> +		dev_err(dev, "cannot map io\n");
> +		return -ENXIO;

	return dev_err_probe();

> +	}

...

> +	clk = devm_clk_get(dev, NULL);

Can we hav

> +	if (!IS_ERR(clk))

Use _optional variant above instead of this.
Do not forget about deferred probe.

> +		spi->clk_rate = clk_get_rate(clk);

...

> +	if (of_get_property(dev->of_node, "spi-nocs", NULL))
> +		spi->mode |= SPI_NO_CS;

Don't we have something in the SPI core to handle this in a generic way?

...


> +EXPORT_SYMBOL_GPL(loongson_spi_init_master);

Please, use _NS variant.

...

> +MODULE_DESCRIPTION("Loongson spi core driver");

SPI

...

> +	struct resource res[2];
> +	struct device *dev = &pdev->dev;
> +
> +	ret = pci_enable_device(pdev);

pcim_enable_device()

> +	if (ret < 0) {
> +		dev_err(dev, "cannot enable pci device\n");
> +		goto err_out;

	return dev_err_probe();

> +	}
> +
> +	ret = pci_request_region(pdev, 0, "loongson-spi io");
> +	if (ret < 0) {
> +		dev_err(dev, "cannot request region 0.\n");
> +		goto err_out;
> +	}
> +
> +	res[0].start = pci_resource_start(pdev, 0);
> +	res[0].end = pci_resource_end(pdev, 0);

What's wrong with pcim_iomap_regions()?

...

> +	ret = pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &v8);

What?!

What's wrong with pci_alloc_irq_vectors()?

> +
> +	if (ret == PCIBIOS_SUCCESSFUL) {
> +		res[1].start = v8;
> +		res[1].end = v8;
> +	}
> +
> +	ret = loongson_spi_init_master(dev, res);

Why not passing the remapped address and IRQ number instead?

> +	if (ret)
> +		dev_err(dev, "failed to initialize master\n");

	return dev_err_probe();

> +
> +err_out:

Completely useless. Return in-line.

> +	return ret;
> +}

...

> +static struct pci_device_id loongson_spi_devices[] = {
> +	{PCI_DEVICE(0x14, 0x7a0b)},
> +	{PCI_DEVICE(0x14, 0x7a1b)},

Can you define vendor ID in pci_ids.h?


> +	{0, 0, 0, 0, 0, 0, 0}

What is this? Why {} is not working for you?

> +};

> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (res == NULL) {

Why not using devm_platform_ioremap_resource()?

> +		dev_err(dev, "cannot get io resource memory\n");
> +		return -ENOENT;

	return dev_err_probe();

> +	}
> +
> +	ret = loongson_spi_init_master(dev, res);
> +	if (ret)
> +		dev_err(dev, "failed to initialize master\n");

Ditto.

...

> +static const struct of_device_id loongson_spi_id_table[] = {
> +	{ .compatible = "loongson,ls2k-spi", },

Inned comma is redundant.

> +	{ }
> +};

...

> +#ifndef __LINUX_SPI_LOONGSON_H
> +#define __LINUX_SPI_LOONGSON_H

Missing bits.h
Missing types.h
Missing declaration for msecs_to_jiffies()
Missing forward declarations for struct spi_master and struct device.
MIssing declaration for dev_pm_ops.


> +#define	LOONGSON_SPI_SPCR_REG	0x00
> +#define	LOONGSON_SPI_SPSR_REG	0x01
> +#define	LOONGSON_SPI_FIFO_REG	0x02
> +#define	LOONGSON_SPI_SPER_REG	0x03
> +#define	LOONGSON_SPI_PARA_REG	0x04
> +#define	LOONGSON_SPI_SFCS_REG	0x05
> +#define	LOONGSON_SPI_TIMI_REG	0x06
> +
> +/* Bits definition for Loongson SPI register */
> +#define	LOONGSON_SPI_PARA_MEM_EN	BIT(0)
> +#define	LOONGSON_SPI_SPSR_SPIF	BIT(7)
> +#define	LOONGSON_SPI_SPSR_WCOL	BIT(6)
> +#define	LOONGSON_SPI_SPCR_SPE	BIT(6)
> +
> +#define SPI_COMPLETION_TIMEOUT	msecs_to_jiffies(2000)
> +
> +struct loongson_spi {
> +	struct	spi_master	*master;
> +	void __iomem		*base;
> +	int			cs_active;
> +	unsigned int		hz;
> +	unsigned char		spcr;
> +	unsigned char		sper;
> +	unsigned char		spsr;
> +	unsigned char		para;
> +	unsigned char		sfcs;
> +	unsigned char		timi;
> +	unsigned int		mode;
> +	u64			clk_rate;
> +};
> +
> +extern int loongson_spi_init_master(struct device *dev, struct resource *res);

No extern for the function declarations.

> +extern const struct dev_pm_ops loongson_spi_dev_pm_ops;

> +#endif /* __LINUX_SPI_LOONGSON_H */

-- 
With Best Regards,
Andy Shevchenko



  parent reply	other threads:[~2023-05-08 15:05 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-26  7:10 [PATCH v9 0/2] spi: loongson: add bus driver for the loongson spi Yinbo Zhu
2023-04-26  7:10 ` [PATCH v9 1/2] dt-bindings: spi: add " Yinbo Zhu
2023-04-26  7:10 ` [PATCH v9 2/2] spi: loongson: add bus driver for the loongson spi controller Yinbo Zhu
2023-05-08 13:20   ` Mark Brown
2023-05-09  1:26     ` zhuyinbo
2023-05-08 15:04   ` andy.shevchenko [this message]
2023-05-09  4:39     ` Mark Brown
2023-05-10  7:03       ` Andy Shevchenko
2023-05-12  8:12         ` zhuyinbo
2023-05-12  9:40           ` Andy Shevchenko
2023-05-13  6:16             ` zhuyinbo
2023-05-11  7:18     ` zhuyinbo
2023-05-15  8:14       ` zhuyinbo
2023-05-15  9:15         ` andy.shevchenko
2023-05-15 12:01           ` zhuyinbo
2023-05-15 13:54             ` Andy Shevchenko
2023-05-16  0:50               ` zhuyinbo

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=ZFkPZhF8QqScXAmH@surfacebook \
    --to=andy.shevchenko@gmail.com \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=liupeibao@loongson.cn \
    --cc=loongson-kernel@lists.loongnix.cn \
    --cc=lvjianmin@loongson.cn \
    --cc=robh+dt@kernel.org \
    --cc=wanghongliang@loongson.cn \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.