linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: David Brownell <david-b@pacbell.net>
To: Stefan Roese <sr@denx.de>
Cc: linuxppc-dev@ozlabs.org, spi-devel-general@lists.sourceforge.net
Subject: Re: [PATCH v5] spi: Add PPC4xx SPI driver
Date: Sat, 27 Dec 2008 11:30:12 -0800	[thread overview]
Message-ID: <200812271130.12513.david-b@pacbell.net> (raw)
In-Reply-To: <1227628088-10849-1-git-send-email-sr@denx.de>

On Tuesday 25 November 2008, Stefan Roese wrote:
> Changes in v5:
> - Don't call setupxfer() from setup() so that the baudrate etc
>   won't get changed while another transfer is active, as suggested
>   by David Brownell.

Better, but this still doesn't seem quite right:


> +static int spi_ppc4xx_setupxfer(struct spi_device *spi, struct spi_transfer *t)
> +{
> +	struct ppc4xx_spi *hw = spi_master_get_devdata(spi->master);
> +	struct spi_ppc4xx_cs *cs = spi->controller_state;
> +	unsigned char cdm = 0;
> +	int scr;
> +	u8 bpw;
> +
> +	/* Write new configration */
> +	out_8(&hw->regs->mode, cs->mode);
> +
> +	/*
> +	 * Allow platform reduce the interrupt load on the CPU during SPI
> +	 * transfers. We do not target maximum performance, but rather allow
> +	 * platform to limit SPI bus frequency and interrupt rate.

That comment doesn't seem even vaguely related to the
code it allegedly refers to ... nothing in this routine
affects the IRQ load.


> +	 */
> +	bpw = t ? t->bits_per_word : spi->bits_per_word;
> +	cs->speed_hz = t ? min(t->speed_hz, spi->max_speed_hz) :
> +		spi->max_speed_hz;
> +
> +	if (bpw != 8) {
> +		dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw);
> +		return -EINVAL;
> +	}
> +
> +	if (cs->speed_hz == 0) {
> +		dev_err(&spi->dev, "invalid speed_hz (must be non-zero)\n");
> +		return -EINVAL;
> +	}
> +
> +	/* set the clock */
> +	/* opb_freq was already divided by 4 */
> +	scr = (hw->opb_freq / cs->speed_hz) - 1;
> +
> +	if (scr > 0)
> +		cdm = min(scr, 0xff);
> +
> +	dev_dbg(&spi->dev, "setting pre-scaler to %d (hz %d)\n", cdm,
> +		cs->speed_hz);
> +
> +	if (in_8(&hw->regs->cdm) != cdm)
> +		out_8(&hw->regs->cdm, cdm);
> +
> +	spin_lock(&hw->bitbang.lock);
> +	if (!hw->bitbang.busy) {
> +		hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);
> +		/* need to ndelay here? */
> +	}
> +	spin_unlock(&hw->bitbang.lock);
> +
> +	return 0;
> +}
> +
> +static int spi_ppc4xx_setup(struct spi_device *spi)
> +{
> +	int ret;
> +	struct spi_ppc4xx_cs *cs = spi->controller_state;
> +	int init = 0;
> +
> +	if (!spi->bits_per_word)
> +		spi->bits_per_word = 8;

Given the above restrictions, it'd be better to

	if (spi->bits_per_word != 8)
		return -EINVAL;

On the general policy of reporting such errors as near as
practical to the place they appear ... otherwise it gets
hard to track them down, since the faults get reported a
long time later, well after the point drivers expect to see
such reports.  Likewise with spi->max_speed_hz.


> +
> +	if (spi->mode & ~MODEBITS) {
> +		dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
> +			spi->mode & ~MODEBITS);
> +		return -EINVAL;
> +	}
> +
> +	if (cs == NULL) {
> +		cs = kzalloc(sizeof *cs, GFP_KERNEL);
> +		if (!cs)
> +			return -ENOMEM;
> +		spi->controller_state = cs;
> +
> +		/*
> +		 * First time called, so let's init the SPI controller
> +		 * at the end of this function
> +		 */
> +		init = 1;
> +	}
> +
> +	/*
> +	 * We set all bits of the SPI0_MODE register, so,
> +	 * no need to read-modify-write
> +	 */
> +	cs->mode = SPI_PPC4XX_MODE_SPE;
> +
> +	switch (spi->mode & (SPI_CPHA | SPI_CPOL)) {
> +	case SPI_MODE_0:
> +		cs->mode |= SPI_CLK_MODE0;
> +		break;
> +	case SPI_MODE_1:
> +		cs->mode |= SPI_CLK_MODE1;
> +		break;
> +	case SPI_MODE_2:
> +		cs->mode |= SPI_CLK_MODE2;
> +		break;
> +	case SPI_MODE_3:
> +		cs->mode |= SPI_CLK_MODE3;
> +		break;
> +	}
> +
> +	if (spi->mode & SPI_LSB_FIRST) {
> +		/* this assumes that bit 7 is the LSb! */
> +		cs->mode |= SPI_PPC4XX_MODE_RD;

The Linux bit numbering convention is that BIT(0) is the LSB,
so that comment is nonsensical.  BIT(7) will always bee the
MSB of an 8-bit byte.

If the issue is a PPC convention that BIT(0) is the MSB,
then please adjust comments accordingly.  Or better, just
strike the comment ... bit numbering is irrelevant here,
the only requirement is that LSB_FIRST causes the LSB
to be sent first, instead of the MSB.


> +	}
> +
> +	/*
> +	 * New configuration (mode, speed etc) will be written to the
> +	 * controller in spi_ppc4xx_setupxfer(). Only call
> +	 * spi_ppc4xx_setupxfer() directly upon first initialization.
> +	 */
> +	if (init) {
> +		ret = spi_ppc4xx_setupxfer(spi, NULL);

Here it is, calling setupxfer()... despite one of the goals
of the v5 patch being to *not* do that from spi_setup()!

I suspect what you must intend here is to just force the
slave to be deselected.  If so, then just call your

   hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);

directly, instead of letting setupxfer() trash register
state that may be controlling some active transfer.


> +		if (ret < 0) {
> +			dev_err(&spi->dev, "setupxfer returned %d\n", ret);
> +			return ret;
> +		}
> +	}
> +
> +	dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n",
> +		__func__, spi->mode, spi->bits_per_word,
> +		spi->max_speed_hz);
> +
> +	return 0;
> +}

  parent reply	other threads:[~2008-12-27 19:30 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-25 15:48 [PATCH v5] spi: Add PPC4xx SPI driver Stefan Roese
2008-12-09 21:48 ` Steven A. Falco
2008-12-09 22:14   ` Steven A. Falco
2008-12-27 19:30 ` David Brownell [this message]
2009-01-05 18:12   ` Stefan Roese
2009-01-05 19:31     ` Wolfgang Denk
2009-01-06  8:26       ` Stefan Roese
2008-12-27 19:32 ` David Brownell
2008-12-27 21:36   ` Stephen Rothwell
2009-01-06  2:06 ` [spi-devel-general] " Anton Vorontsov
2009-01-06  8:14   ` Stefan Roese

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=200812271130.12513.david-b@pacbell.net \
    --to=david-b@pacbell.net \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=spi-devel-general@lists.sourceforge.net \
    --cc=sr@denx.de \
    /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;
as well as URLs for NNTP newsgroup(s).