Patchwork [v5] spi: Add PPC4xx SPI driver

login
register
mail settings
Submitter Stefan Roese
Date Nov. 25, 2008, 3:48 p.m.
Message ID <1227628088-10849-1-git-send-email-sr@denx.de>
Download mbox | patch
Permalink /patch/10653/
State Accepted
Delegated to: Josh Boyer
Headers show

Comments

Stefan Roese - Nov. 25, 2008, 3:48 p.m.
This adds a SPI driver for the SPI controller found in the IBM/AMCC
4xx PowerPC's.

Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Wolfgang Ocker <weo@reccoware.de>
Acked-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
---
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.
- module_{init,exit} moved directly to the functions to which they
  apply.
- Use __func__ instead of __FUNCTION__.

Changes in v4:
- Added fixes suggested by Josh Boyer
- Changed compatible property from "ibm,spi" to "ibm,ppc4xx-spi"

Changes in v3:
- When the device is removed the GPIOs are released. The memory
  for the GPIO array is freed.

Changes in v2:
- Now the gpios property is correctly decoded and the
  resulting gpio numbers are used as the devices chip
  selects.

 drivers/spi/Kconfig      |    7 +
 drivers/spi/Makefile     |    1 +
 drivers/spi/spi_ppc4xx.c |  597 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 605 insertions(+), 0 deletions(-)
 create mode 100644 drivers/spi/spi_ppc4xx.c
Steven A. Falco - Dec. 9, 2008, 9:48 p.m.
Stefan Roese wrote:
> This adds a SPI driver for the SPI controller found in the IBM/AMCC
> 4xx PowerPC's.
> 
> Signed-off-by: Stefan Roese <sr@denx.de>
> Signed-off-by: Wolfgang Ocker <weo@reccoware.de>
> Acked-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
> ---

I have a question as to how to use this driver.  of_num_gpios() starts
testing for gpio's at num = 0, and stops at the first invalid one.
However, gpio numbers are apparently allocated dynamically from 255 down,
meaning that there probably is no gpio-0.

For example, on my Sequoia board I have gpiochip176, gpiochip192,
and gpiochip224.  So, of_num_gpios() returns zero, even though there
are 72 gpio's on my board.

This gets back to an earlier discussion about setting the gpio index
of each controller, which was rejected, IIRC.  If we could set the
base gpio of each chip, we could start at zero and use consecutive
numbers.  Failing that, it seems that Stefan's SPI driver needs to
probe the entire 0-255 gpio space.

How is this intended to work?  An example .dts would be greatly
appreciated.

	Steve
Steven A. Falco - Dec. 9, 2008, 10:14 p.m.
Steven A. Falco wrote:
> Stefan Roese wrote:
>> This adds a SPI driver for the SPI controller found in the IBM/AMCC
>> 4xx PowerPC's.
>>
>> Signed-off-by: Stefan Roese <sr@denx.de>
>> Signed-off-by: Wolfgang Ocker <weo@reccoware.de>
>> Acked-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
>> ---
>
> How is this intended to work?  An example .dts would be greatly
> appreciated.

Answered my own question.  The gpios must be directly under the spi
node rather than elsewhere in the tree.  This works:

			SPI0: spi@ef600900 {
				compatible = "ibm,ppc4xx-spi";
				reg = <ef600900 7>;
				interrupts = <8 4>;
				interrupt-parent = <&UIC0>;

				gpios = <&GPIO1 14 0>;
			};
David Brownell - Dec. 27, 2008, 7:30 p.m.
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;
> +}
David Brownell - Dec. 27, 2008, 7:32 p.m.
Also:

> +static struct of_platform_driver spi_ppc4xx_of_driver = {
> +       .owner = THIS_MODULE,
> +       .name = DRIVER_NAME,

I'd hope the PPC folk eliminate this duplication soonish.
Those fields are obvious duplicates of the driver model
fields...


> +       .match_table = spi_ppc4xx_of_match,
> +       .probe = spi_ppc4xx_of_probe,
> +       .remove = __exit_p(spi_ppc4xx_of_remove),
> +       .driver = {
> +               .name = DRIVER_NAME,
> +               .owner = THIS_MODULE,
> +       },
> +};
Stephen Rothwell - Dec. 27, 2008, 9:36 p.m.
Hi David, Stefan,

On Sat, 27 Dec 2008 11:32:25 -0800 David Brownell <david-b@pacbell.net> wrote:
>
> Also:
> 
> > +static struct of_platform_driver spi_ppc4xx_of_driver = {
> > +       .owner = THIS_MODULE,
> > +       .name = DRIVER_NAME,
> 
> I'd hope the PPC folk eliminate this duplication soonish.
> Those fields are obvious duplicates of the driver model
> fields...

We are on the path (have been for some time).  Only the driver model
versions should be filled in for new drivers.  For old drivers we copy
the values into the driver model fields if they are not already set.  We
intend to remove the of_platform_drivers versions of "name" and "owner"
soon.

> > +       .match_table = spi_ppc4xx_of_match,
> > +       .probe = spi_ppc4xx_of_probe,
> > +       .remove = __exit_p(spi_ppc4xx_of_remove),
> > +       .driver = {
> > +               .name = DRIVER_NAME,
> > +               .owner = THIS_MODULE,
> > +       },
> > +};
Stefan Roese - Jan. 5, 2009, 6:12 p.m.
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
Wolfgang Denk - Jan. 5, 2009, 7:31 p.m.
Dear Stefan,

In message <200901051912.25874.sr@denx.de> you wrote:
>
> > > +	/* 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.

On PPC4xx systems we get one interrupt per transferred  byte,  i.  e.
there  is  a  direct relation between SPI bus frequency and interrupt
rate.

Since this is a PPC4xx SPI driver, the comment is actually helpful to
understand the operation of the driver especially in relation to  the
limitations of the hardware.

Instead of removing the  comment  (which  leaves  the  casual  reader
clueless)  it  would probably better to add a sentence explaining the
one byte / one interrupt situation?

Best regards,

Wolfgang Denk
Anton Vorontsov - Jan. 6, 2009, 2:06 a.m.
Hi Stefan,

On Tue, Nov 25, 2008 at 04:48:08PM +0100, Stefan Roese wrote:
> This adds a SPI driver for the SPI controller found in the IBM/AMCC
> 4xx PowerPC's.
> 
> Signed-off-by: Stefan Roese <sr@denx.de>
> Signed-off-by: Wolfgang Ocker <weo@reccoware.de>
> Acked-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
> ---
[...]
> +static unsigned int of_num_gpios(struct device_node *node)
> +{
> +	unsigned int num = 0;
> +
> +	while (gpio_is_valid(of_get_gpio(node, num)))
> +		num++;
> +	return num;
> +}

FYI, as of commit 749820928a2fd47ff536773d869d2c3f8038b7d1 ("of/gpio:
Implement of_gpio_count()") you can use of_gpio_count() from
linux/of_gpio.h.
Stefan Roese - Jan. 6, 2009, 8:14 a.m.
Hi Anton,

On Tuesday 06 January 2009, Anton Vorontsov wrote:
> > This adds a SPI driver for the SPI controller found in the IBM/AMCC
> > 4xx PowerPC's.
> >
> > Signed-off-by: Stefan Roese <sr@denx.de>
> > Signed-off-by: Wolfgang Ocker <weo@reccoware.de>
> > Acked-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
> > ---
>
> [...]
>
> > +static unsigned int of_num_gpios(struct device_node *node)
> > +{
> > +	unsigned int num = 0;
> > +
> > +	while (gpio_is_valid(of_get_gpio(node, num)))
> > +		num++;
> > +	return num;
> > +}
>
> FYI, as of commit 749820928a2fd47ff536773d869d2c3f8038b7d1 ("of/gpio:
> Implement of_gpio_count()") you can use of_gpio_count() from
> linux/of_gpio.h.

Thanks for the hint. I'll use it in the next version.

Best regards,
Stefan
Stefan Roese - Jan. 6, 2009, 8:26 a.m.
Hi Wolfgang,

On Monday 05 January 2009, Wolfgang Denk wrote:
> > 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.
>
> On PPC4xx systems we get one interrupt per transferred  byte,  i.  e.
> there  is  a  direct relation between SPI bus frequency and interrupt
> rate.
>
> Since this is a PPC4xx SPI driver, the comment is actually helpful to
> understand the operation of the driver especially in relation to  the
> limitations of the hardware.
>
> Instead of removing the  comment  (which  leaves  the  casual  reader
> clueless)  it  would probably better to add a sentence explaining the
> one byte / one interrupt situation?

OK, I'll this explanation instead.

Thanks.

Best regards,
Stefan

Patch

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index b9d0efb..69d5fee 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -155,6 +155,13 @@  config SPI_ORION
 	help
 	  This enables using the SPI master controller on the Orion chips.
 
+config SPI_PPC4xx
+	tristate "PPC4xx SPI Controller"
+	depends on 4xx && SPI_MASTER
+	select SPI_BITBANG
+	help
+	  This selects a driver for the PPC4xx SPI Controller.
+
 config SPI_PXA2XX
 	tristate "PXA2xx SSP SPI master"
 	depends on ARCH_PXA && EXPERIMENTAL
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index ccf18de..a2e5816 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -24,6 +24,7 @@  obj-$(CONFIG_SPI_OMAP24XX)		+= omap2_mcspi.o
 obj-$(CONFIG_SPI_ORION)			+= orion_spi.o
 obj-$(CONFIG_SPI_MPC52xx_PSC)		+= mpc52xx_psc_spi.o
 obj-$(CONFIG_SPI_MPC83xx)		+= spi_mpc83xx.o
+obj-$(CONFIG_SPI_PPC4xx)		+= spi_ppc4xx.o
 obj-$(CONFIG_SPI_S3C24XX_GPIO)		+= spi_s3c24xx_gpio.o
 obj-$(CONFIG_SPI_S3C24XX)		+= spi_s3c24xx.o
 obj-$(CONFIG_SPI_TXX9)			+= spi_txx9.o
diff --git a/drivers/spi/spi_ppc4xx.c b/drivers/spi/spi_ppc4xx.c
new file mode 100644
index 0000000..e46292b
--- /dev/null
+++ b/drivers/spi/spi_ppc4xx.c
@@ -0,0 +1,597 @@ 
+/*
+ * SPI_PPC4XX SPI controller driver.
+ *
+ * Copyright (C) 2007 Gary Jennejohn <garyj@denx.de>
+ * Copyright 2008 Stefan Roese <sr@denx.de>, DENX Software Engineering
+ *
+ * Based in part on drivers/spi/spi_s3c24xx.c
+ *
+ * Copyright (c) 2006 Ben Dooks
+ * Copyright (c) 2006 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/of_platform.h>
+#include <linux/of_spi.h>
+#include <linux/of_gpio.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+
+#include <asm/io.h>
+#include <asm/dcr.h>
+#include <asm/dcr-regs.h>
+
+/* bits in mode register - bit 0 ist MSb */
+/* data latched on leading edge of clock, else trailing edge */
+#define SPI_PPC4XX_MODE_SCP	(0x80 >> 3)
+/* port enabled */
+#define SPI_PPC4XX_MODE_SPE	(0x80 >> 4)
+/* MSB first, else LSB first */
+#define SPI_PPC4XX_MODE_RD	(0x80 >> 5)
+/* clock invert - idle clock = 1, active clock = 0; else reversed */
+#define SPI_PPC4XX_MODE_CI	(0x80 >> 6)
+/* loopback enable */
+#define SPI_PPC4XX_MODE_IL	(0x80 >> 7)
+/* bits in control register */
+/* starts a transfer when set */
+#define SPI_PPC4XX_CR_STR	(0x80 >> 7)
+/* bits in status register */
+/* port is busy with a transfer */
+#define SPI_PPC4XX_SR_BSY	(0x80 >> 6)
+/* RxD ready */
+#define SPI_PPC4XX_SR_RBR	(0x80 >> 7)
+
+/* the spi->mode bits understood by this driver: */
+#define MODEBITS	(SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LSB_FIRST)
+
+/* clock settings (SCP and CI) for various SPI modes */
+#define SPI_CLK_MODE0	SPI_PPC4XX_MODE_SCP
+#define SPI_CLK_MODE1	0
+#define SPI_CLK_MODE2	SPI_PPC4XX_MODE_CI
+#define SPI_CLK_MODE3	(SPI_PPC4XX_MODE_SCP | SPI_PPC4XX_MODE_CI)
+
+#define DRIVER_NAME	"spi_ppc4xx_of"
+
+struct spi_ppc4xx_regs {
+	u8 mode;
+	u8 rxd;
+	u8 txd;
+	u8 cr;
+	u8 sr;
+	u8 dummy;
+	/*
+	 * Clock divisor modulus register
+	 * This uses the follwing formula:
+	 *    SCPClkOut = OPBCLK/(4(CDM + 1))
+	 * or
+	 *    CDM = (OPBCLK/4*SCPClkOut) - 1
+	 * bit 0 is the MSb!
+	 */
+	u8 cdm;
+};
+
+/* SPI Controller driver's private data. */
+struct ppc4xx_spi {
+	/* bitbang has to be first */
+	struct spi_bitbang bitbang;
+	struct completion done;
+
+	u64 mapbase;
+	u64 mapsize;
+	int irqnum;
+	/* need this to set the SPI clock */
+	unsigned int opb_freq;
+
+	/* for transfers */
+	int len;
+	int count;
+	/* data buffers */
+	const unsigned char *tx;
+	unsigned char *rx;
+
+	int *gpios;
+	unsigned int num_gpios;
+
+	struct spi_ppc4xx_regs __iomem *regs; /* pointer to the registers */
+	struct spi_master *master;
+	struct device *dev;
+};
+
+/* need this so we can set the clock in the chipselect routine */
+struct spi_ppc4xx_cs {
+	u32 speed_hz;
+	u8 mode;
+};
+
+static int spi_ppc4xx_txrx(struct spi_device *spi, struct spi_transfer *t)
+{
+	struct ppc4xx_spi *hw;
+	u8 data;
+
+	dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
+		t->tx_buf, t->rx_buf, t->len);
+
+	hw = spi_master_get_devdata(spi->master);
+
+	hw->tx = t->tx_buf;
+	hw->rx = t->rx_buf;
+	hw->len = t->len;
+	hw->count = 0;
+
+	/* send the first byte */
+	data = hw->tx ? hw->tx[0] : 0;
+	out_8(&hw->regs->txd, data);
+	out_8(&hw->regs->cr, SPI_PPC4XX_CR_STR);
+	wait_for_completion(&hw->done);
+
+	return hw->count;
+}
+
+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.
+	 */
+	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;
+
+	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;
+	}
+
+	/*
+	 * 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);
+		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;
+}
+
+static void spi_ppc4xx_chipsel(struct spi_device *spi, int value)
+{
+	struct ppc4xx_spi *hw = spi_master_get_devdata(spi->master);
+	unsigned int cspol = spi->mode & SPI_CS_HIGH ? 1 : 0;
+	unsigned int cs = spi->chip_select;
+
+	if (!hw->num_gpios)
+		return;
+
+	if (cs >= hw->num_gpios)
+		return;
+
+	if (value != BITBANG_CS_INACTIVE && value != BITBANG_CS_ACTIVE)
+		return;
+
+	if (value == BITBANG_CS_INACTIVE)
+		cspol = !cspol;
+
+	gpio_set_value(hw->gpios[cs], cspol);
+}
+
+static irqreturn_t spi_ppc4xx_int(int irq, void *dev_id)
+{
+	struct ppc4xx_spi *hw;
+	u8 status;
+	u8 data;
+	unsigned int count;
+
+	hw = (struct ppc4xx_spi *)dev_id;
+
+	status = in_8(&hw->regs->sr);
+	if (!status)
+		return IRQ_NONE;
+
+	/* should never happen but check anyway */
+	if (status & SPI_PPC4XX_SR_BSY) {
+		u8 lstatus;
+		int cnt = 0;
+
+		dev_dbg(hw->dev, "got interrupt but spi still busy?\n");
+		do {
+			ndelay(10);
+			lstatus = in_8(&hw->regs->sr);
+		} while (++cnt < 100 && lstatus & SPI_PPC4XX_SR_BSY);
+
+		if (cnt >= 100) {
+			dev_err(hw->dev, "busywait: too many loops!\n");
+			complete(&hw->done);
+			return IRQ_HANDLED;
+		} else {
+			/* status is always 1 (RBR) here */
+			status = in_8(&hw->regs->sr);
+			dev_dbg(hw->dev, "loops %d status %x\n", cnt, status);
+		}
+	}
+
+	count = hw->count;
+	hw->count++;
+
+	if (status & SPI_PPC4XX_SR_RBR) {
+		/* Data Ready */
+		data = in_8(&hw->regs->rxd);
+		if (hw->rx)
+			hw->rx[count] = data;
+	}
+
+	count++;
+
+	if (count < hw->len) {
+		data = hw->tx ? hw->tx[count] : 0;
+		out_8(&hw->regs->txd, data);
+		out_8(&hw->regs->cr, SPI_PPC4XX_CR_STR);
+	} else {
+		complete(&hw->done);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void spi_ppc4xx_cleanup(struct spi_device *spi)
+{
+	kfree(spi->controller_state);
+}
+
+static void spi_ppc4xx_enable(struct ppc4xx_spi *hw)
+{
+	/*
+	 * On all 4xx PPC's the SPI bus is shared/multiplexed with
+	 * the 2nd I2C bus. We need to enable the the SPI bus before
+	 * using it.
+	 */
+
+	/* need to clear bit 14 to enable SPC */
+	dcri_clrset(SDR0, SDR0_PFC1, 0x80000000 >> 14, 0);
+}
+
+static unsigned int of_num_gpios(struct device_node *node)
+{
+	unsigned int num = 0;
+
+	while (gpio_is_valid(of_get_gpio(node, num)))
+		num++;
+	return num;
+}
+
+static void free_gpios(struct ppc4xx_spi *hw)
+{
+	if (hw->num_gpios) {
+		int i;
+		for (i = 0; i < hw->num_gpios; i++)
+			gpio_free(hw->gpios[i]);
+
+		kfree(hw->gpios);
+		hw->gpios = NULL;
+	}
+}
+
+/*
+ * of_device layer stuff...
+ */
+static int __init spi_ppc4xx_of_probe(struct of_device *op,
+				      const struct of_device_id *match)
+{
+	struct ppc4xx_spi *hw;
+	struct spi_master *master;
+	struct spi_bitbang *bbp;
+	struct resource resource;
+	struct device_node *np = op->node;
+	struct device *dev = &op->dev;
+	struct device_node *opbnp;
+	int ret;
+	const unsigned int *clk;
+
+	master = spi_alloc_master(dev, sizeof *hw);
+	if (master == NULL)
+		return -ENOMEM;
+	dev_set_drvdata(dev, master);
+	hw = spi_master_get_devdata(master);
+	memset(hw, 0, sizeof(struct ppc4xx_spi));
+
+	hw->master = spi_master_get(master);
+	hw->dev = dev;
+
+	init_completion(&hw->done);
+
+	hw->num_gpios = of_num_gpios(np);
+	if (hw->num_gpios) {
+		int i;
+
+		hw->gpios = kzalloc(sizeof(int) * hw->num_gpios,
+				    GFP_KERNEL);
+		if (!hw->gpios) {
+			ret = -ENOMEM;
+			goto free_master;
+		}
+
+		for (i = 0; i < hw->num_gpios; i++) {
+			int gpio = of_get_gpio(np, i);
+			if (gpio < 0) {
+				dev_err(dev, "Invalid gpio spec %d\n", i);
+				ret = gpio;
+				goto free_gpios;
+			}
+
+			ret = gpio_request(gpio, np->name);
+			if (ret < 0) {
+				dev_err(dev, "gpio %d already in use\n", i);
+				ret = gpio;
+				goto free_gpios;
+			}
+
+			gpio_direction_output(gpio, 0);
+			hw->gpios[i] = gpio;
+		}
+	}
+
+	/* Setup the state for the bitbang driver */
+	bbp = &hw->bitbang;
+	bbp->master = hw->master;
+	bbp->setup_transfer = spi_ppc4xx_setupxfer;
+	bbp->chipselect = spi_ppc4xx_chipsel;
+	bbp->txrx_bufs = spi_ppc4xx_txrx;
+	bbp->use_dma = 0;
+	bbp->master->setup = spi_ppc4xx_setup;
+	bbp->master->cleanup = spi_ppc4xx_cleanup;
+	/* only one SPI controller */
+	bbp->master->bus_num = 0;
+	if (bbp->master->num_chipselect == 0) {
+		/* this many pins in al GPIO controllers */
+		bbp->master->num_chipselect = hw->num_gpios;
+	}
+
+	/* Get the clock for the OPB */
+	opbnp = of_find_compatible_node(NULL, NULL, "ibm,opb");
+	if (opbnp == NULL) {
+		dev_err(dev, "OPB: cannot find node\n");
+		ret = -ENODEV;
+		goto free_gpios;
+	}
+	/* Get the clock (Hz) for the OPB */
+	clk = of_get_property(opbnp, "clock-frequency", NULL);
+	if (clk == NULL) {
+		dev_err(dev, "OPB: no clock-frequency property set\n");
+		of_node_put(opbnp);
+		ret = -ENODEV;
+		goto free_gpios;
+	}
+	hw->opb_freq = *clk;
+	hw->opb_freq >>= 2;
+	of_node_put(opbnp);
+
+	ret = of_address_to_resource(np, 0, &resource);
+	if (ret) {
+		dev_err(dev, "error while parsing device node resource\n");
+		goto free_gpios;
+	}
+	hw->mapbase = resource.start;
+	hw->mapsize = resource.end - resource.start + 1;
+
+	/* Sanity check */
+	if (hw->mapsize < sizeof(struct spi_ppc4xx_regs)) {
+		dev_err(dev, "too small to map registers\n");
+		ret = -EINVAL;
+		goto free_gpios;
+	}
+
+	/* Request IRQ */
+	hw->irqnum = irq_of_parse_and_map(np, 0);
+	ret = request_irq(hw->irqnum, spi_ppc4xx_int,
+			  IRQF_DISABLED, "spi_ppc4xx_of", (void *)hw);
+	if (ret) {
+		dev_err(dev, "unable to allocate interrupt\n");
+		goto free_gpios;
+	}
+
+	if (!request_mem_region(hw->mapbase, hw->mapsize, DRIVER_NAME)) {
+		dev_err(dev, "resource unavailable\n");
+		ret = -EBUSY;
+		goto request_mem_error;
+	}
+
+	hw->regs = ioremap(hw->mapbase, sizeof(struct spi_ppc4xx_regs));
+
+	if (!hw->regs) {
+		dev_err(dev, "unable to memory map registers\n");
+		ret = -ENXIO;
+		goto map_io_error;
+	}
+
+	spi_ppc4xx_enable(hw);
+
+	/* Finally register our spi controller */
+	dev->dma_mask = 0;
+	ret = spi_bitbang_start(bbp);
+	if (ret) {
+		dev_err(dev, "failed to register SPI master\n");
+		goto unmap_regs;
+	}
+
+	dev_info(dev, "driver initialized\n");
+	of_register_spi_devices(master, np);
+
+	return 0;
+
+unmap_regs:
+	iounmap(hw->regs);
+map_io_error:
+	release_mem_region(hw->mapbase, hw->mapsize);
+request_mem_error:
+	free_irq(hw->irqnum, hw);
+free_gpios:
+	free_gpios(hw);
+free_master:
+	dev_set_drvdata(dev, NULL);
+	spi_master_put(master);
+
+	dev_err(dev, "initialization failed\n");
+	return ret;
+}
+
+static int __exit spi_ppc4xx_of_remove(struct of_device *op)
+{
+	struct spi_master *master = dev_get_drvdata(&op->dev);
+	struct ppc4xx_spi *hw = spi_master_get_devdata(master);
+
+	spi_bitbang_stop(&hw->bitbang);
+	dev_set_drvdata(&op->dev, NULL);
+	release_mem_region(hw->mapbase, hw->mapsize);
+	free_irq(hw->irqnum, hw);
+	iounmap(hw->regs);
+	free_gpios(hw);
+	return 0;
+}
+
+static struct of_device_id spi_ppc4xx_of_match[] = {
+	{ .compatible = "ibm,ppc4xx-spi", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, spi_ppc4xx_of_match);
+
+static struct of_platform_driver spi_ppc4xx_of_driver = {
+	.owner = THIS_MODULE,
+	.name = DRIVER_NAME,
+	.match_table = spi_ppc4xx_of_match,
+	.probe = spi_ppc4xx_of_probe,
+	.remove = __exit_p(spi_ppc4xx_of_remove),
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init spi_ppc4xx_init(void)
+{
+	return of_register_platform_driver(&spi_ppc4xx_of_driver);
+}
+module_init(spi_ppc4xx_init);
+
+static void __exit spi_ppc4xx_exit(void)
+{
+	of_unregister_platform_driver(&spi_ppc4xx_of_driver);
+}
+module_exit(spi_ppc4xx_exit);
+
+MODULE_AUTHOR("Gary Jennejohn & Stefan Roese");
+MODULE_DESCRIPTION("Simple PPC4xx SPI Driver");
+MODULE_LICENSE("GPL");