All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Roese <sr@denx.de>
To: David Brownell <david-b@pacbell.net>
Cc: linuxppc-dev@ozlabs.org, spi-devel-general@lists.sourceforge.net
Subject: Re: [PATCH v5] spi: Add PPC4xx SPI driver
Date: Mon, 5 Jan 2009 19:12:25 +0100	[thread overview]
Message-ID: <200901051912.25874.sr@denx.de> (raw)
In-Reply-To: <200812271130.12513.david-b@pacbell.net>

On Saturday 27 December 2008, David Brownell wrote:
> 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:

David, thanks for the review. Please find some comments below.

> > +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.

IIRC (I didn't write the original version of this driver) then this comments 
simply refers to the fact that the platform can select a maximum SPI 
frequency via spi->max_speed_hz which is pretty obvious. So I'll just remove 
this comment in the next version.

> > +	 */
> > +	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.

OK, point gotten. Will change in next version.

> Likewise with spi->max_speed_hz. 

OK.

> > +
> > +	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.

OK, comment removed.

> > +	}
> > +
> > +	/*
> > +	 * 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()!

It's only called upon first driver initialization (as the comment above 
explains).

> 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,

No, this doesn't work. I just tried it in my next driver version. Somehow the 
communication doesn't start up when setupxfer is not called at least once 
upon initialization. Sorry, but I worked on this driver quite some time ago 
and don't remember the details now.

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

As this call is done only upon first driver initialization, no active transfer 
can be interrupted. Or did I miss something here?

Please let me know if this approach is acceptable for now, or if I need to dig 
into this deeper. The problem is that I don't have the time for this now so 
further patch versions would come (much) later.

Otherwise I will send a new patch version with the fixes/changes mentioned 
above tomorrow.

Thanks.

Best regards,
Stefan

  parent reply	other threads:[~2009-01-05 18:12 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-25 15:48 [PATCH v5] spi: Add PPC4xx SPI driver Stefan Roese
2008-11-25 15:48 ` Stefan Roese
2008-12-09 21:48 ` Steven A. Falco
2008-12-09 22:14   ` Steven A. Falco
     [not found] ` <1227628088-10849-1-git-send-email-sr-ynQEQJNshbs@public.gmane.org>
2008-12-27 19:30   ` David Brownell
2008-12-27 19:30     ` David Brownell
     [not found]     ` <200812271130.12513.david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
2009-01-05 18:12       ` Stefan Roese
2009-01-05 18:12     ` Stefan Roese
2009-01-05 18:12     ` Stefan Roese [this message]
     [not found]       ` <200901051912.25874.sr-ynQEQJNshbs@public.gmane.org>
2009-01-05 19:31         ` Wolfgang Denk
2009-01-05 19:31           ` Wolfgang Denk
2009-01-06  8:26           ` Stefan Roese
     [not found]           ` <20090105193117.E5AD98387CDB-C2Gvrrd9BC/j/ljBK/0BTg@public.gmane.org>
2009-01-06  8:26             ` Stefan Roese
2009-01-06  8:26           ` Stefan Roese
2008-12-27 19:32   ` David Brownell
2008-12-27 19:32     ` David Brownell
2008-12-27 21:36     ` Stephen Rothwell
2008-12-27 21:36       ` Stephen Rothwell
2009-01-06  2:06   ` Anton Vorontsov
2009-01-06  2:06     ` [spi-devel-general] " Anton Vorontsov
     [not found]     ` <20090106020603.GA14074-wnGakbxT3iijyJ0x5qLZdcN33GVbZNy3@public.gmane.org>
2009-01-06  8:14       ` Stefan Roese
2009-01-06  8:14         ` [spi-devel-general] " 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=200901051912.25874.sr@denx.de \
    --to=sr@denx.de \
    --cc=david-b@pacbell.net \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=spi-devel-general@lists.sourceforge.net \
    /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.