LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 6/9] spi_mpc83xx: Split mpc83xx_spi_work() into two routines
From: Anton Vorontsov @ 2009-04-30 23:48 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev, Andrew Morton, David Brownell, linux-kernel,
	spi-devel-general
In-Reply-To: <20090430234739.GA27709@oksana.dev.rtsoft.ru>

mpc83xx_spi_work() is quite large, with up to five indentation
levels and is quite difficult to read.

So, split the function in two parts:
1. mpc83xx_spi_work() now only traverse queued spi messages;
2. mpc83xx_spi_do_one_msg() only manages single messages.

There should be no functional changes.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 drivers/spi/spi_mpc83xx.c |  115 +++++++++++++++++++++++---------------------
 1 files changed, 60 insertions(+), 55 deletions(-)

diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 40f7448..50112a5 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -350,71 +350,76 @@ static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	return mpc83xx_spi->count;
 }
 
-static void mpc83xx_spi_work(struct work_struct *work)
+static void mpc83xx_spi_do_one_msg(struct spi_message *m)
 {
-	struct mpc83xx_spi *mpc83xx_spi =
-		container_of(work, struct mpc83xx_spi, work);
-
-	spin_lock_irq(&mpc83xx_spi->lock);
-	mpc83xx_spi->busy = 1;
-	while (!list_empty(&mpc83xx_spi->queue)) {
-		struct spi_message *m;
-		struct spi_device *spi;
-		struct spi_transfer *t = NULL;
-		unsigned cs_change;
-		int status, nsecs = 50;
-
-		m = container_of(mpc83xx_spi->queue.next,
-				struct spi_message, queue);
-		list_del_init(&m->queue);
-		spin_unlock_irq(&mpc83xx_spi->lock);
-
-		spi = m->spi;
-		cs_change = 1;
-		status = 0;
-		list_for_each_entry(t, &m->transfers, transfer_list) {
-			if (t->bits_per_word || t->speed_hz) {
-				/* Don't allow changes if CS is active */
-				status = -EINVAL;
-
-				if (cs_change)
-					status = mpc83xx_spi_setup_transfer(spi, t);
-				if (status < 0)
-					break;
-			}
-
-			if (cs_change) {
-				mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE);
-				ndelay(nsecs);
-			}
-			cs_change = t->cs_change;
-			if (t->len)
-				status = mpc83xx_spi_bufs(spi, t);
-			if (status) {
-				status = -EMSGSIZE;
+	struct spi_device *spi = m->spi;
+	struct spi_transfer *t;
+	unsigned int cs_change;
+	const int nsecs = 50;
+	int status;
+
+	cs_change = 1;
+	status = 0;
+	list_for_each_entry(t, &m->transfers, transfer_list) {
+		if (t->bits_per_word || t->speed_hz) {
+			/* Don't allow changes if CS is active */
+			status = -EINVAL;
+
+			if (cs_change)
+				status = mpc83xx_spi_setup_transfer(spi, t);
+			if (status < 0)
 				break;
-			}
-			m->actual_length += t->len;
-
-			if (t->delay_usecs)
-				udelay(t->delay_usecs);
+		}
 
-			if (cs_change) {
-				ndelay(nsecs);
-				mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
-				ndelay(nsecs);
-			}
+		if (cs_change) {
+			mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE);
+			ndelay(nsecs);
+		}
+		cs_change = t->cs_change;
+		if (t->len)
+			status = mpc83xx_spi_bufs(spi, t);
+		if (status) {
+			status = -EMSGSIZE;
+			break;
 		}
+		m->actual_length += t->len;
 
-		m->status = status;
-		m->complete(m->context);
+		if (t->delay_usecs)
+			udelay(t->delay_usecs);
 
-		if (status || !cs_change) {
+		if (cs_change) {
 			ndelay(nsecs);
 			mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+			ndelay(nsecs);
 		}
+	}
+
+	m->status = status;
+	m->complete(m->context);
+
+	if (status || !cs_change) {
+		ndelay(nsecs);
+		mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+	}
+
+	mpc83xx_spi_setup_transfer(spi, NULL);
+}
+
+static void mpc83xx_spi_work(struct work_struct *work)
+{
+	struct mpc83xx_spi *mpc83xx_spi = container_of(work, struct mpc83xx_spi,
+						       work);
+
+	spin_lock_irq(&mpc83xx_spi->lock);
+	mpc83xx_spi->busy = 1;
+	while (!list_empty(&mpc83xx_spi->queue)) {
+		struct spi_message *m = container_of(mpc83xx_spi->queue.next,
+						   struct spi_message, queue);
+
+		list_del_init(&m->queue);
+		spin_unlock_irq(&mpc83xx_spi->lock);
 
-		mpc83xx_spi_setup_transfer(spi, NULL);
+		mpc83xx_spi_do_one_msg(m);
 
 		spin_lock_irq(&mpc83xx_spi->lock);
 	}
-- 
1.6.2.2

^ permalink raw reply related

* [PATCH 7/9] spi_mpc83xx: Remove dead code
From: Anton Vorontsov @ 2009-04-30 23:48 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev, Andrew Morton, David Brownell, linux-kernel,
	spi-devel-general
In-Reply-To: <20090430234739.GA27709@oksana.dev.rtsoft.ru>

This patch removes #if 0'ed code, and spi_mpc83xx->busy variable that
is used by that dead snippet only.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 drivers/spi/spi_mpc83xx.c |   16 ----------------
 1 files changed, 0 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 50112a5..4192ce4 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -98,8 +98,6 @@ struct mpc83xx_spi {
 
 	bool qe_mode;
 
-	u8 busy;
-
 	struct workqueue_struct *workqueue;
 	struct work_struct work;
 
@@ -411,7 +409,6 @@ static void mpc83xx_spi_work(struct work_struct *work)
 						       work);
 
 	spin_lock_irq(&mpc83xx_spi->lock);
-	mpc83xx_spi->busy = 1;
 	while (!list_empty(&mpc83xx_spi->queue)) {
 		struct spi_message *m = container_of(mpc83xx_spi->queue.next,
 						   struct spi_message, queue);
@@ -423,7 +420,6 @@ static void mpc83xx_spi_work(struct work_struct *work)
 
 		spin_lock_irq(&mpc83xx_spi->lock);
 	}
-	mpc83xx_spi->busy = 0;
 	spin_unlock_irq(&mpc83xx_spi->lock);
 }
 
@@ -482,18 +478,6 @@ static int mpc83xx_spi_setup(struct spi_device *spi)
 	dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u Hz\n",
 		__func__, spi->mode & (SPI_CPOL | SPI_CPHA),
 		spi->bits_per_word, spi->max_speed_hz);
-#if 0 /* Don't think this is needed */
-	/* NOTE we _need_ to call chipselect() early, ideally with adapter
-	 * setup, unless the hardware defaults cooperate to avoid confusion
-	 * between normal (active low) and inverted chipselects.
-	 */
-
-	/* deselect chip (low or high) */
-	spin_lock(&mpc83xx_spi->lock);
-	if (!mpc83xx_spi->busy)
-		mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
-	spin_unlock(&mpc83xx_spi->lock);
-#endif
 	return 0;
 }
 
-- 
1.6.2.2

^ permalink raw reply related

* [PATCH 8/9] spi_mpc83xx: Rename spi_83xx.c to spi_8xxx.c
From: Anton Vorontsov @ 2009-04-30 23:48 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev, Andrew Morton, David Brownell, linux-kernel,
	spi-devel-general
In-Reply-To: <20090430234739.GA27709@oksana.dev.rtsoft.ru>

The driver handles MPC83xx, MPC85xx and MPC86xx SPI controllers,
so rename the file for clarity.

Suggested-by: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 drivers/spi/Makefile      |    2 +-
 drivers/spi/spi_mpc83xx.c |  958 ---------------------------------------------
 drivers/spi/spi_mpc8xxx.c |  958 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 959 insertions(+), 959 deletions(-)
 delete mode 100644 drivers/spi/spi_mpc83xx.c
 create mode 100644 drivers/spi/spi_mpc8xxx.c

diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 5d04519..fdc7aa0 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -24,7 +24,7 @@ obj-$(CONFIG_SPI_OMAP_UWIRE)		+= omap_uwire.o
 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_MPC83xx)		+= spi_mpc8xxx.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_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
deleted file mode 100644
index 4192ce4..0000000
--- a/drivers/spi/spi_mpc83xx.c
+++ /dev/null
@@ -1,958 +0,0 @@
-/*
- * MPC83xx SPI controller driver.
- *
- * Maintainer: Kumar Gala
- *
- * Copyright (C) 2006 Polycom, Inc.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/bug.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/completion.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/device.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_bitbang.h>
-#include <linux/platform_device.h>
-#include <linux/fsl_devices.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/gpio.h>
-#include <linux/of_gpio.h>
-#include <linux/of_spi.h>
-
-#include <sysdev/fsl_soc.h>
-#include <asm/irq.h>
-
-/* SPI Controller registers */
-struct mpc83xx_spi_reg {
-	u8 res1[0x20];
-	__be32 mode;
-	__be32 event;
-	__be32 mask;
-	__be32 command;
-	__be32 transmit;
-	__be32 receive;
-};
-
-/* SPI Controller mode register definitions */
-#define	SPMODE_LOOP		(1 << 30)
-#define	SPMODE_CI_INACTIVEHIGH	(1 << 29)
-#define	SPMODE_CP_BEGIN_EDGECLK	(1 << 28)
-#define	SPMODE_DIV16		(1 << 27)
-#define	SPMODE_REV		(1 << 26)
-#define	SPMODE_MS		(1 << 25)
-#define	SPMODE_ENABLE		(1 << 24)
-#define	SPMODE_LEN(x)		((x) << 20)
-#define	SPMODE_PM(x)		((x) << 16)
-#define	SPMODE_OP		(1 << 14)
-#define	SPMODE_CG(x)		((x) << 7)
-
-/*
- * Default for SPI Mode:
- * 	SPI MODE 0 (inactive low, phase middle, MSB, 8-bit length, slow clk
- */
-#define	SPMODE_INIT_VAL (SPMODE_CI_INACTIVEHIGH | SPMODE_DIV16 | SPMODE_REV | \
-			 SPMODE_MS | SPMODE_LEN(7) | SPMODE_PM(0xf))
-
-/* SPIE register values */
-#define	SPIE_NE		0x00000200	/* Not empty */
-#define	SPIE_NF		0x00000100	/* Not full */
-
-/* SPIM register values */
-#define	SPIM_NE		0x00000200	/* Not empty */
-#define	SPIM_NF		0x00000100	/* Not full */
-
-/* SPI Controller driver's private data. */
-struct mpc83xx_spi {
-	struct mpc83xx_spi_reg __iomem *base;
-
-	/* rx & tx bufs from the spi_transfer */
-	const void *tx;
-	void *rx;
-
-	/* functions to deal with different sized buffers */
-	void (*get_rx) (u32 rx_data, struct mpc83xx_spi *);
-	u32(*get_tx) (struct mpc83xx_spi *);
-
-	unsigned int count;
-	unsigned int irq;
-
-	unsigned nsecs;		/* (clock cycle time)/2 */
-
-	u32 spibrg;		/* SPIBRG input clock */
-	u32 rx_shift;		/* RX data reg shift when in qe mode */
-	u32 tx_shift;		/* TX data reg shift when in qe mode */
-
-	bool qe_mode;
-
-	struct workqueue_struct *workqueue;
-	struct work_struct work;
-
-	struct list_head queue;
-	spinlock_t lock;
-
-	struct completion done;
-};
-
-struct spi_mpc83xx_cs {
-	/* functions to deal with different sized buffers */
-	void (*get_rx) (u32 rx_data, struct mpc83xx_spi *);
-	u32 (*get_tx) (struct mpc83xx_spi *);
-	u32 rx_shift;		/* RX data reg shift when in qe mode */
-	u32 tx_shift;		/* TX data reg shift when in qe mode */
-	u32 hw_mode;		/* Holds HW mode register settings */
-};
-
-static inline void mpc83xx_spi_write_reg(__be32 __iomem *reg, u32 val)
-{
-	out_be32(reg, val);
-}
-
-static inline u32 mpc83xx_spi_read_reg(__be32 __iomem *reg)
-{
-	return in_be32(reg);
-}
-
-#define MPC83XX_SPI_RX_BUF(type) 					  \
-static									  \
-void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \
-{									  \
-	type *rx = mpc83xx_spi->rx;					  \
-	*rx++ = (type)(data >> mpc83xx_spi->rx_shift);			  \
-	mpc83xx_spi->rx = rx;						  \
-}
-
-#define MPC83XX_SPI_TX_BUF(type)				\
-static								\
-u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi)	\
-{								\
-	u32 data;						\
-	const type *tx = mpc83xx_spi->tx;			\
-	if (!tx)						\
-		return 0;					\
-	data = *tx++ << mpc83xx_spi->tx_shift;			\
-	mpc83xx_spi->tx = tx;					\
-	return data;						\
-}
-
-MPC83XX_SPI_RX_BUF(u8)
-MPC83XX_SPI_RX_BUF(u16)
-MPC83XX_SPI_RX_BUF(u32)
-MPC83XX_SPI_TX_BUF(u8)
-MPC83XX_SPI_TX_BUF(u16)
-MPC83XX_SPI_TX_BUF(u32)
-
-static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
-{
-	struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master);
-	struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data;
-	bool pol = spi->mode & SPI_CS_HIGH;
-	struct spi_mpc83xx_cs	*cs = spi->controller_state;
-
-	if (value == BITBANG_CS_INACTIVE) {
-		if (pdata->cs_control)
-			pdata->cs_control(spi, !pol);
-	}
-
-	if (value == BITBANG_CS_ACTIVE) {
-		u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
-
-		mpc83xx_spi->rx_shift = cs->rx_shift;
-		mpc83xx_spi->tx_shift = cs->tx_shift;
-		mpc83xx_spi->get_rx = cs->get_rx;
-		mpc83xx_spi->get_tx = cs->get_tx;
-
-		if (cs->hw_mode != regval) {
-			unsigned long flags;
-			__be32 __iomem *mode = &mpc83xx_spi->base->mode;
-
-			regval = cs->hw_mode;
-			/* Turn off IRQs locally to minimize time that
-			 * SPI is disabled
-			 */
-			local_irq_save(flags);
-			/* Turn off SPI unit prior changing mode */
-			mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE);
-			mpc83xx_spi_write_reg(mode, regval);
-			local_irq_restore(flags);
-		}
-		if (pdata->cs_control)
-			pdata->cs_control(spi, pol);
-	}
-}
-
-static
-int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
-{
-	struct mpc83xx_spi *mpc83xx_spi;
-	u32 regval;
-	u8 bits_per_word, pm;
-	u32 hz;
-	struct spi_mpc83xx_cs	*cs = spi->controller_state;
-
-	mpc83xx_spi = spi_master_get_devdata(spi->master);
-
-	if (t) {
-		bits_per_word = t->bits_per_word;
-		hz = t->speed_hz;
-	} else {
-		bits_per_word = 0;
-		hz = 0;
-	}
-
-	/* spi_transfer level calls that work per-word */
-	if (!bits_per_word)
-		bits_per_word = spi->bits_per_word;
-
-	/* Make sure its a bit width we support [4..16, 32] */
-	if ((bits_per_word < 4)
-	    || ((bits_per_word > 16) && (bits_per_word != 32)))
-		return -EINVAL;
-
-	if (!hz)
-		hz = spi->max_speed_hz;
-
-	cs->rx_shift = 0;
-	cs->tx_shift = 0;
-	if (bits_per_word <= 8) {
-		cs->get_rx = mpc83xx_spi_rx_buf_u8;
-		cs->get_tx = mpc83xx_spi_tx_buf_u8;
-		if (mpc83xx_spi->qe_mode) {
-			cs->rx_shift = 16;
-			cs->tx_shift = 24;
-		}
-	} else if (bits_per_word <= 16) {
-		cs->get_rx = mpc83xx_spi_rx_buf_u16;
-		cs->get_tx = mpc83xx_spi_tx_buf_u16;
-		if (mpc83xx_spi->qe_mode) {
-			cs->rx_shift = 16;
-			cs->tx_shift = 16;
-		}
-	} else if (bits_per_word <= 32) {
-		cs->get_rx = mpc83xx_spi_rx_buf_u32;
-		cs->get_tx = mpc83xx_spi_tx_buf_u32;
-	} else
-		return -EINVAL;
-
-	if (mpc83xx_spi->qe_mode && spi->mode & SPI_LSB_FIRST) {
-		cs->tx_shift = 0;
-		if (bits_per_word <= 8)
-			cs->rx_shift = 8;
-		else
-			cs->rx_shift = 0;
-	}
-
-	mpc83xx_spi->rx_shift = cs->rx_shift;
-	mpc83xx_spi->tx_shift = cs->tx_shift;
-	mpc83xx_spi->get_rx = cs->get_rx;
-	mpc83xx_spi->get_tx = cs->get_tx;
-
-	if (bits_per_word == 32)
-		bits_per_word = 0;
-	else
-		bits_per_word = bits_per_word - 1;
-
-	/* mask out bits we are going to set */
-	cs->hw_mode &= ~(SPMODE_LEN(0xF) | SPMODE_DIV16
-				  | SPMODE_PM(0xF));
-
-	cs->hw_mode |= SPMODE_LEN(bits_per_word);
-
-	if ((mpc83xx_spi->spibrg / hz) > 64) {
-		cs->hw_mode |= SPMODE_DIV16;
-		pm = mpc83xx_spi->spibrg / (hz * 64);
-
-		WARN_ONCE(pm > 16, "%s: Requested speed is too low: %d Hz. "
-			  "Will use %d Hz instead.\n", dev_name(&spi->dev),
-			  hz, mpc83xx_spi->spibrg / 1024);
-		if (pm > 16)
-			pm = 16;
-	} else
-		pm = mpc83xx_spi->spibrg / (hz * 4);
-	if (pm)
-		pm--;
-
-	cs->hw_mode |= SPMODE_PM(pm);
-	regval =  mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
-	if (cs->hw_mode != regval) {
-		unsigned long flags;
-		__be32 __iomem *mode = &mpc83xx_spi->base->mode;
-
-		regval = cs->hw_mode;
-		/* Turn off IRQs locally to minimize time
-		 * that SPI is disabled
-		 */
-		local_irq_save(flags);
-		/* Turn off SPI unit prior changing mode */
-		mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE);
-		mpc83xx_spi_write_reg(mode, regval);
-		local_irq_restore(flags);
-	}
-	return 0;
-}
-
-static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
-{
-	struct mpc83xx_spi *mpc83xx_spi;
-	u32 word, len, bits_per_word;
-
-	mpc83xx_spi = spi_master_get_devdata(spi->master);
-
-	mpc83xx_spi->tx = t->tx_buf;
-	mpc83xx_spi->rx = t->rx_buf;
-	bits_per_word = spi->bits_per_word;
-	if (t->bits_per_word)
-		bits_per_word = t->bits_per_word;
-	len = t->len;
-	if (bits_per_word > 8) {
-		/* invalid length? */
-		if (len & 1)
-			return -EINVAL;
-		len /= 2;
-	}
-	if (bits_per_word > 16) {
-		/* invalid length? */
-		if (len & 1)
-			return -EINVAL;
-		len /= 2;
-	}
-	mpc83xx_spi->count = len;
-
-	INIT_COMPLETION(mpc83xx_spi->done);
-
-	/* enable rx ints */
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE);
-
-	/* transmit word */
-	word = mpc83xx_spi->get_tx(mpc83xx_spi);
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
-
-	wait_for_completion(&mpc83xx_spi->done);
-
-	/* disable rx ints */
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
-
-	return mpc83xx_spi->count;
-}
-
-static void mpc83xx_spi_do_one_msg(struct spi_message *m)
-{
-	struct spi_device *spi = m->spi;
-	struct spi_transfer *t;
-	unsigned int cs_change;
-	const int nsecs = 50;
-	int status;
-
-	cs_change = 1;
-	status = 0;
-	list_for_each_entry(t, &m->transfers, transfer_list) {
-		if (t->bits_per_word || t->speed_hz) {
-			/* Don't allow changes if CS is active */
-			status = -EINVAL;
-
-			if (cs_change)
-				status = mpc83xx_spi_setup_transfer(spi, t);
-			if (status < 0)
-				break;
-		}
-
-		if (cs_change) {
-			mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE);
-			ndelay(nsecs);
-		}
-		cs_change = t->cs_change;
-		if (t->len)
-			status = mpc83xx_spi_bufs(spi, t);
-		if (status) {
-			status = -EMSGSIZE;
-			break;
-		}
-		m->actual_length += t->len;
-
-		if (t->delay_usecs)
-			udelay(t->delay_usecs);
-
-		if (cs_change) {
-			ndelay(nsecs);
-			mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
-			ndelay(nsecs);
-		}
-	}
-
-	m->status = status;
-	m->complete(m->context);
-
-	if (status || !cs_change) {
-		ndelay(nsecs);
-		mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
-	}
-
-	mpc83xx_spi_setup_transfer(spi, NULL);
-}
-
-static void mpc83xx_spi_work(struct work_struct *work)
-{
-	struct mpc83xx_spi *mpc83xx_spi = container_of(work, struct mpc83xx_spi,
-						       work);
-
-	spin_lock_irq(&mpc83xx_spi->lock);
-	while (!list_empty(&mpc83xx_spi->queue)) {
-		struct spi_message *m = container_of(mpc83xx_spi->queue.next,
-						   struct spi_message, queue);
-
-		list_del_init(&m->queue);
-		spin_unlock_irq(&mpc83xx_spi->lock);
-
-		mpc83xx_spi_do_one_msg(m);
-
-		spin_lock_irq(&mpc83xx_spi->lock);
-	}
-	spin_unlock_irq(&mpc83xx_spi->lock);
-}
-
-/* the spi->mode bits understood by this driver: */
-#define MODEBITS	(SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
-			| SPI_LSB_FIRST | SPI_LOOP)
-
-static int mpc83xx_spi_setup(struct spi_device *spi)
-{
-	struct mpc83xx_spi *mpc83xx_spi;
-	int retval;
-	u32 hw_mode;
-	struct spi_mpc83xx_cs	*cs = spi->controller_state;
-
-	if (spi->mode & ~MODEBITS) {
-		dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
-			spi->mode & ~MODEBITS);
-		return -EINVAL;
-	}
-
-	if (!spi->max_speed_hz)
-		return -EINVAL;
-
-	if (!cs) {
-		cs = kzalloc(sizeof *cs, GFP_KERNEL);
-		if (!cs)
-			return -ENOMEM;
-		spi->controller_state = cs;
-	}
-	mpc83xx_spi = spi_master_get_devdata(spi->master);
-
-	if (!spi->bits_per_word)
-		spi->bits_per_word = 8;
-
-	hw_mode = cs->hw_mode; /* Save orginal settings */
-	cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
-	/* mask out bits we are going to set */
-	cs->hw_mode &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH
-			 | SPMODE_REV | SPMODE_LOOP);
-
-	if (spi->mode & SPI_CPHA)
-		cs->hw_mode |= SPMODE_CP_BEGIN_EDGECLK;
-	if (spi->mode & SPI_CPOL)
-		cs->hw_mode |= SPMODE_CI_INACTIVEHIGH;
-	if (!(spi->mode & SPI_LSB_FIRST))
-		cs->hw_mode |= SPMODE_REV;
-	if (spi->mode & SPI_LOOP)
-		cs->hw_mode |= SPMODE_LOOP;
-
-	retval = mpc83xx_spi_setup_transfer(spi, NULL);
-	if (retval < 0) {
-		cs->hw_mode = hw_mode; /* Restore settings */
-		return retval;
-	}
-
-	dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u Hz\n",
-		__func__, spi->mode & (SPI_CPOL | SPI_CPHA),
-		spi->bits_per_word, spi->max_speed_hz);
-	return 0;
-}
-
-static irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
-{
-	struct mpc83xx_spi *mpc83xx_spi = context_data;
-	u32 event;
-	irqreturn_t ret = IRQ_NONE;
-
-	/* Get interrupt events(tx/rx) */
-	event = mpc83xx_spi_read_reg(&mpc83xx_spi->base->event);
-
-	/* We need handle RX first */
-	if (event & SPIE_NE) {
-		u32 rx_data = mpc83xx_spi_read_reg(&mpc83xx_spi->base->receive);
-
-		if (mpc83xx_spi->rx)
-			mpc83xx_spi->get_rx(rx_data, mpc83xx_spi);
-
-		ret = IRQ_HANDLED;
-	}
-
-	if ((event & SPIE_NF) == 0)
-		/* spin until TX is done */
-		while (((event =
-			 mpc83xx_spi_read_reg(&mpc83xx_spi->base->event)) &
-						SPIE_NF) == 0)
-			cpu_relax();
-
-	mpc83xx_spi->count -= 1;
-	if (mpc83xx_spi->count) {
-		u32 word = mpc83xx_spi->get_tx(mpc83xx_spi);
-		mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
-	} else {
-		complete(&mpc83xx_spi->done);
-	}
-
-	/* Clear the events */
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, event);
-
-	return ret;
-}
-static int mpc83xx_spi_transfer(struct spi_device *spi,
-				struct spi_message *m)
-{
-	struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master);
-	unsigned long flags;
-
-	m->actual_length = 0;
-	m->status = -EINPROGRESS;
-
-	spin_lock_irqsave(&mpc83xx_spi->lock, flags);
-	list_add_tail(&m->queue, &mpc83xx_spi->queue);
-	queue_work(mpc83xx_spi->workqueue, &mpc83xx_spi->work);
-	spin_unlock_irqrestore(&mpc83xx_spi->lock, flags);
-
-	return 0;
-}
-
-
-static void mpc83xx_spi_cleanup(struct spi_device *spi)
-{
-	kfree(spi->controller_state);
-}
-
-static struct spi_master * __devinit
-mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq)
-{
-	struct fsl_spi_platform_data *pdata = dev->platform_data;
-	struct spi_master *master;
-	struct mpc83xx_spi *mpc83xx_spi;
-	u32 regval;
-	int ret = 0;
-
-	master = spi_alloc_master(dev, sizeof(struct mpc83xx_spi));
-	if (master == NULL) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	dev_set_drvdata(dev, master);
-
-	master->setup = mpc83xx_spi_setup;
-	master->transfer = mpc83xx_spi_transfer;
-	master->cleanup = mpc83xx_spi_cleanup;
-
-	mpc83xx_spi = spi_master_get_devdata(master);
-	mpc83xx_spi->qe_mode = pdata->qe_mode;
-	mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
-	mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
-	mpc83xx_spi->spibrg = pdata->sysclk;
-
-	mpc83xx_spi->rx_shift = 0;
-	mpc83xx_spi->tx_shift = 0;
-	if (mpc83xx_spi->qe_mode) {
-		mpc83xx_spi->rx_shift = 16;
-		mpc83xx_spi->tx_shift = 24;
-	}
-
-	init_completion(&mpc83xx_spi->done);
-
-	mpc83xx_spi->base = ioremap(mem->start, mem->end - mem->start + 1);
-	if (mpc83xx_spi->base == NULL) {
-		ret = -ENOMEM;
-		goto put_master;
-	}
-
-	mpc83xx_spi->irq = irq;
-
-	/* Register for SPI Interrupt */
-	ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq,
-			  0, "mpc83xx_spi", mpc83xx_spi);
-
-	if (ret != 0)
-		goto unmap_io;
-
-	master->bus_num = pdata->bus_num;
-	master->num_chipselect = pdata->max_chipselect;
-
-	/* SPI controller initializations */
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->command, 0);
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, 0xffffffff);
-
-	/* Enable SPI interface */
-	regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE;
-	if (pdata->qe_mode)
-		regval |= SPMODE_OP;
-
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
-	spin_lock_init(&mpc83xx_spi->lock);
-	init_completion(&mpc83xx_spi->done);
-	INIT_WORK(&mpc83xx_spi->work, mpc83xx_spi_work);
-	INIT_LIST_HEAD(&mpc83xx_spi->queue);
-
-	mpc83xx_spi->workqueue = create_singlethread_workqueue(
-		dev_name(master->dev.parent));
-	if (mpc83xx_spi->workqueue == NULL) {
-		ret = -EBUSY;
-		goto free_irq;
-	}
-
-	ret = spi_register_master(master);
-	if (ret < 0)
-		goto unreg_master;
-
-	printk(KERN_INFO
-	       "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
-	       dev_name(dev), mpc83xx_spi->base, mpc83xx_spi->irq);
-
-	return master;
-
-unreg_master:
-	destroy_workqueue(mpc83xx_spi->workqueue);
-free_irq:
-	free_irq(mpc83xx_spi->irq, mpc83xx_spi);
-unmap_io:
-	iounmap(mpc83xx_spi->base);
-put_master:
-	spi_master_put(master);
-err:
-	return ERR_PTR(ret);
-}
-
-static int __devexit mpc83xx_spi_remove(struct device *dev)
-{
-	struct mpc83xx_spi *mpc83xx_spi;
-	struct spi_master *master;
-
-	master = dev_get_drvdata(dev);
-	mpc83xx_spi = spi_master_get_devdata(master);
-
-	flush_workqueue(mpc83xx_spi->workqueue);
-	destroy_workqueue(mpc83xx_spi->workqueue);
-	spi_unregister_master(master);
-
-	free_irq(mpc83xx_spi->irq, mpc83xx_spi);
-	iounmap(mpc83xx_spi->base);
-
-	return 0;
-}
-
-struct mpc83xx_spi_probe_info {
-	struct fsl_spi_platform_data pdata;
-	int *gpios;
-	bool *alow_flags;
-};
-
-static struct mpc83xx_spi_probe_info *
-to_of_pinfo(struct fsl_spi_platform_data *pdata)
-{
-	return container_of(pdata, struct mpc83xx_spi_probe_info, pdata);
-}
-
-static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on)
-{
-	struct device *dev = spi->dev.parent;
-	struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data);
-	u16 cs = spi->chip_select;
-	int gpio = pinfo->gpios[cs];
-	bool alow = pinfo->alow_flags[cs];
-
-	gpio_set_value(gpio, on ^ alow);
-}
-
-static int of_mpc83xx_spi_get_chipselects(struct device *dev)
-{
-	struct device_node *np = dev_archdata_get_node(&dev->archdata);
-	struct fsl_spi_platform_data *pdata = dev->platform_data;
-	struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata);
-	unsigned int ngpios;
-	int i = 0;
-	int ret;
-
-	ngpios = of_gpio_count(np);
-	if (!ngpios) {
-		/*
-		 * SPI w/o chip-select line. One SPI device is still permitted
-		 * though.
-		 */
-		pdata->max_chipselect = 1;
-		return 0;
-	}
-
-	pinfo->gpios = kmalloc(ngpios * sizeof(pinfo->gpios), GFP_KERNEL);
-	if (!pinfo->gpios)
-		return -ENOMEM;
-	memset(pinfo->gpios, -1, ngpios * sizeof(pinfo->gpios));
-
-	pinfo->alow_flags = kzalloc(ngpios * sizeof(pinfo->alow_flags),
-				    GFP_KERNEL);
-	if (!pinfo->alow_flags) {
-		ret = -ENOMEM;
-		goto err_alloc_flags;
-	}
-
-	for (; i < ngpios; i++) {
-		int gpio;
-		enum of_gpio_flags flags;
-
-		gpio = of_get_gpio_flags(np, i, &flags);
-		if (!gpio_is_valid(gpio)) {
-			dev_err(dev, "invalid gpio #%d: %d\n", i, gpio);
-			goto err_loop;
-		}
-
-		ret = gpio_request(gpio, dev_name(dev));
-		if (ret) {
-			dev_err(dev, "can't request gpio #%d: %d\n", i, ret);
-			goto err_loop;
-		}
-
-		pinfo->gpios[i] = gpio;
-		pinfo->alow_flags[i] = flags & OF_GPIO_ACTIVE_LOW;
-
-		ret = gpio_direction_output(pinfo->gpios[i],
-					    pinfo->alow_flags[i]);
-		if (ret) {
-			dev_err(dev, "can't set output direction for gpio "
-				"#%d: %d\n", i, ret);
-			goto err_loop;
-		}
-	}
-
-	pdata->max_chipselect = ngpios;
-	pdata->cs_control = mpc83xx_spi_cs_control;
-
-	return 0;
-
-err_loop:
-	while (i >= 0) {
-		if (gpio_is_valid(pinfo->gpios[i]))
-			gpio_free(pinfo->gpios[i]);
-		i--;
-	}
-
-	kfree(pinfo->alow_flags);
-	pinfo->alow_flags = NULL;
-err_alloc_flags:
-	kfree(pinfo->gpios);
-	pinfo->gpios = NULL;
-	return ret;
-}
-
-static int of_mpc83xx_spi_free_chipselects(struct device *dev)
-{
-	struct fsl_spi_platform_data *pdata = dev->platform_data;
-	struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata);
-	int i;
-
-	if (!pinfo->gpios)
-		return 0;
-
-	for (i = 0; i < pdata->max_chipselect; i++) {
-		if (gpio_is_valid(pinfo->gpios[i]))
-			gpio_free(pinfo->gpios[i]);
-	}
-
-	kfree(pinfo->gpios);
-	kfree(pinfo->alow_flags);
-	return 0;
-}
-
-static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev,
-					  const struct of_device_id *ofid)
-{
-	struct device *dev = &ofdev->dev;
-	struct device_node *np = ofdev->node;
-	struct mpc83xx_spi_probe_info *pinfo;
-	struct fsl_spi_platform_data *pdata;
-	struct spi_master *master;
-	struct resource mem;
-	struct resource irq;
-	const void *prop;
-	int ret = -ENOMEM;
-
-	pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL);
-	if (!pinfo)
-		return -ENOMEM;
-
-	pdata = &pinfo->pdata;
-	dev->platform_data = pdata;
-
-	/* Allocate bus num dynamically. */
-	pdata->bus_num = -1;
-
-	/* SPI controller is either clocked from QE or SoC clock. */
-	pdata->sysclk = get_brgfreq();
-	if (pdata->sysclk == -1) {
-		pdata->sysclk = fsl_get_sys_freq();
-		if (pdata->sysclk == -1) {
-			ret = -ENODEV;
-			goto err_clk;
-		}
-	}
-
-	prop = of_get_property(np, "mode", NULL);
-	if (prop && !strcmp(prop, "cpu-qe"))
-		pdata->qe_mode = 1;
-
-	ret = of_mpc83xx_spi_get_chipselects(dev);
-	if (ret)
-		goto err;
-
-	ret = of_address_to_resource(np, 0, &mem);
-	if (ret)
-		goto err;
-
-	ret = of_irq_to_resource(np, 0, &irq);
-	if (!ret) {
-		ret = -EINVAL;
-		goto err;
-	}
-
-	master = mpc83xx_spi_probe(dev, &mem, irq.start);
-	if (IS_ERR(master)) {
-		ret = PTR_ERR(master);
-		goto err;
-	}
-
-	of_register_spi_devices(master, np);
-
-	return 0;
-
-err:
-	of_mpc83xx_spi_free_chipselects(dev);
-err_clk:
-	kfree(pinfo);
-	return ret;
-}
-
-static int __devexit of_mpc83xx_spi_remove(struct of_device *ofdev)
-{
-	int ret;
-
-	ret = mpc83xx_spi_remove(&ofdev->dev);
-	if (ret)
-		return ret;
-	of_mpc83xx_spi_free_chipselects(&ofdev->dev);
-	return 0;
-}
-
-static const struct of_device_id of_mpc83xx_spi_match[] = {
-	{ .compatible = "fsl,spi" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, of_mpc83xx_spi_match);
-
-static struct of_platform_driver of_mpc83xx_spi_driver = {
-	.name		= "mpc83xx_spi",
-	.match_table	= of_mpc83xx_spi_match,
-	.probe		= of_mpc83xx_spi_probe,
-	.remove		= __devexit_p(of_mpc83xx_spi_remove),
-};
-
-#ifdef CONFIG_MPC832x_RDB
-/*
- * 				XXX XXX XXX
- * This is "legacy" platform driver, was used by the MPC8323E-RDB boards
- * only. The driver should go away soon, since newer MPC8323E-RDB's device
- * tree can work with OpenFirmware driver. But for now we support old trees
- * as well.
- */
-static int __devinit plat_mpc83xx_spi_probe(struct platform_device *pdev)
-{
-	struct resource *mem;
-	unsigned int irq;
-	struct spi_master *master;
-
-	if (!pdev->dev.platform_data)
-		return -EINVAL;
-
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!mem)
-		return -EINVAL;
-
-	irq = platform_get_irq(pdev, 0);
-	if (!irq)
-		return -EINVAL;
-
-	master = mpc83xx_spi_probe(&pdev->dev, mem, irq);
-	if (IS_ERR(master))
-		return PTR_ERR(master);
-	return 0;
-}
-
-static int __devexit plat_mpc83xx_spi_remove(struct platform_device *pdev)
-{
-	return mpc83xx_spi_remove(&pdev->dev);
-}
-
-MODULE_ALIAS("platform:mpc83xx_spi");
-static struct platform_driver mpc83xx_spi_driver = {
-	.probe = plat_mpc83xx_spi_probe,
-	.remove = __exit_p(plat_mpc83xx_spi_remove),
-	.driver = {
-		.name = "mpc83xx_spi",
-		.owner = THIS_MODULE,
-	},
-};
-
-static bool legacy_driver_failed;
-
-static void __init legacy_driver_register(void)
-{
-	legacy_driver_failed = platform_driver_register(&mpc83xx_spi_driver);
-}
-
-static void __exit legacy_driver_unregister(void)
-{
-	if (legacy_driver_failed)
-		return;
-	platform_driver_unregister(&mpc83xx_spi_driver);
-}
-#else
-static void __init legacy_driver_register(void) {}
-static void __exit legacy_driver_unregister(void) {}
-#endif /* CONFIG_MPC832x_RDB */
-
-static int __init mpc83xx_spi_init(void)
-{
-	legacy_driver_register();
-	return of_register_platform_driver(&of_mpc83xx_spi_driver);
-}
-
-static void __exit mpc83xx_spi_exit(void)
-{
-	of_unregister_platform_driver(&of_mpc83xx_spi_driver);
-	legacy_driver_unregister();
-}
-
-module_init(mpc83xx_spi_init);
-module_exit(mpc83xx_spi_exit);
-
-MODULE_AUTHOR("Kumar Gala");
-MODULE_DESCRIPTION("Simple MPC83xx SPI Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c
new file mode 100644
index 0000000..4192ce4
--- /dev/null
+++ b/drivers/spi/spi_mpc8xxx.c
@@ -0,0 +1,958 @@
+/*
+ * MPC83xx SPI controller driver.
+ *
+ * Maintainer: Kumar Gala
+ *
+ * Copyright (C) 2006 Polycom, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_spi.h>
+
+#include <sysdev/fsl_soc.h>
+#include <asm/irq.h>
+
+/* SPI Controller registers */
+struct mpc83xx_spi_reg {
+	u8 res1[0x20];
+	__be32 mode;
+	__be32 event;
+	__be32 mask;
+	__be32 command;
+	__be32 transmit;
+	__be32 receive;
+};
+
+/* SPI Controller mode register definitions */
+#define	SPMODE_LOOP		(1 << 30)
+#define	SPMODE_CI_INACTIVEHIGH	(1 << 29)
+#define	SPMODE_CP_BEGIN_EDGECLK	(1 << 28)
+#define	SPMODE_DIV16		(1 << 27)
+#define	SPMODE_REV		(1 << 26)
+#define	SPMODE_MS		(1 << 25)
+#define	SPMODE_ENABLE		(1 << 24)
+#define	SPMODE_LEN(x)		((x) << 20)
+#define	SPMODE_PM(x)		((x) << 16)
+#define	SPMODE_OP		(1 << 14)
+#define	SPMODE_CG(x)		((x) << 7)
+
+/*
+ * Default for SPI Mode:
+ * 	SPI MODE 0 (inactive low, phase middle, MSB, 8-bit length, slow clk
+ */
+#define	SPMODE_INIT_VAL (SPMODE_CI_INACTIVEHIGH | SPMODE_DIV16 | SPMODE_REV | \
+			 SPMODE_MS | SPMODE_LEN(7) | SPMODE_PM(0xf))
+
+/* SPIE register values */
+#define	SPIE_NE		0x00000200	/* Not empty */
+#define	SPIE_NF		0x00000100	/* Not full */
+
+/* SPIM register values */
+#define	SPIM_NE		0x00000200	/* Not empty */
+#define	SPIM_NF		0x00000100	/* Not full */
+
+/* SPI Controller driver's private data. */
+struct mpc83xx_spi {
+	struct mpc83xx_spi_reg __iomem *base;
+
+	/* rx & tx bufs from the spi_transfer */
+	const void *tx;
+	void *rx;
+
+	/* functions to deal with different sized buffers */
+	void (*get_rx) (u32 rx_data, struct mpc83xx_spi *);
+	u32(*get_tx) (struct mpc83xx_spi *);
+
+	unsigned int count;
+	unsigned int irq;
+
+	unsigned nsecs;		/* (clock cycle time)/2 */
+
+	u32 spibrg;		/* SPIBRG input clock */
+	u32 rx_shift;		/* RX data reg shift when in qe mode */
+	u32 tx_shift;		/* TX data reg shift when in qe mode */
+
+	bool qe_mode;
+
+	struct workqueue_struct *workqueue;
+	struct work_struct work;
+
+	struct list_head queue;
+	spinlock_t lock;
+
+	struct completion done;
+};
+
+struct spi_mpc83xx_cs {
+	/* functions to deal with different sized buffers */
+	void (*get_rx) (u32 rx_data, struct mpc83xx_spi *);
+	u32 (*get_tx) (struct mpc83xx_spi *);
+	u32 rx_shift;		/* RX data reg shift when in qe mode */
+	u32 tx_shift;		/* TX data reg shift when in qe mode */
+	u32 hw_mode;		/* Holds HW mode register settings */
+};
+
+static inline void mpc83xx_spi_write_reg(__be32 __iomem *reg, u32 val)
+{
+	out_be32(reg, val);
+}
+
+static inline u32 mpc83xx_spi_read_reg(__be32 __iomem *reg)
+{
+	return in_be32(reg);
+}
+
+#define MPC83XX_SPI_RX_BUF(type) 					  \
+static									  \
+void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \
+{									  \
+	type *rx = mpc83xx_spi->rx;					  \
+	*rx++ = (type)(data >> mpc83xx_spi->rx_shift);			  \
+	mpc83xx_spi->rx = rx;						  \
+}
+
+#define MPC83XX_SPI_TX_BUF(type)				\
+static								\
+u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi)	\
+{								\
+	u32 data;						\
+	const type *tx = mpc83xx_spi->tx;			\
+	if (!tx)						\
+		return 0;					\
+	data = *tx++ << mpc83xx_spi->tx_shift;			\
+	mpc83xx_spi->tx = tx;					\
+	return data;						\
+}
+
+MPC83XX_SPI_RX_BUF(u8)
+MPC83XX_SPI_RX_BUF(u16)
+MPC83XX_SPI_RX_BUF(u32)
+MPC83XX_SPI_TX_BUF(u8)
+MPC83XX_SPI_TX_BUF(u16)
+MPC83XX_SPI_TX_BUF(u32)
+
+static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
+{
+	struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master);
+	struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data;
+	bool pol = spi->mode & SPI_CS_HIGH;
+	struct spi_mpc83xx_cs	*cs = spi->controller_state;
+
+	if (value == BITBANG_CS_INACTIVE) {
+		if (pdata->cs_control)
+			pdata->cs_control(spi, !pol);
+	}
+
+	if (value == BITBANG_CS_ACTIVE) {
+		u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+
+		mpc83xx_spi->rx_shift = cs->rx_shift;
+		mpc83xx_spi->tx_shift = cs->tx_shift;
+		mpc83xx_spi->get_rx = cs->get_rx;
+		mpc83xx_spi->get_tx = cs->get_tx;
+
+		if (cs->hw_mode != regval) {
+			unsigned long flags;
+			__be32 __iomem *mode = &mpc83xx_spi->base->mode;
+
+			regval = cs->hw_mode;
+			/* Turn off IRQs locally to minimize time that
+			 * SPI is disabled
+			 */
+			local_irq_save(flags);
+			/* Turn off SPI unit prior changing mode */
+			mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE);
+			mpc83xx_spi_write_reg(mode, regval);
+			local_irq_restore(flags);
+		}
+		if (pdata->cs_control)
+			pdata->cs_control(spi, pol);
+	}
+}
+
+static
+int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
+{
+	struct mpc83xx_spi *mpc83xx_spi;
+	u32 regval;
+	u8 bits_per_word, pm;
+	u32 hz;
+	struct spi_mpc83xx_cs	*cs = spi->controller_state;
+
+	mpc83xx_spi = spi_master_get_devdata(spi->master);
+
+	if (t) {
+		bits_per_word = t->bits_per_word;
+		hz = t->speed_hz;
+	} else {
+		bits_per_word = 0;
+		hz = 0;
+	}
+
+	/* spi_transfer level calls that work per-word */
+	if (!bits_per_word)
+		bits_per_word = spi->bits_per_word;
+
+	/* Make sure its a bit width we support [4..16, 32] */
+	if ((bits_per_word < 4)
+	    || ((bits_per_word > 16) && (bits_per_word != 32)))
+		return -EINVAL;
+
+	if (!hz)
+		hz = spi->max_speed_hz;
+
+	cs->rx_shift = 0;
+	cs->tx_shift = 0;
+	if (bits_per_word <= 8) {
+		cs->get_rx = mpc83xx_spi_rx_buf_u8;
+		cs->get_tx = mpc83xx_spi_tx_buf_u8;
+		if (mpc83xx_spi->qe_mode) {
+			cs->rx_shift = 16;
+			cs->tx_shift = 24;
+		}
+	} else if (bits_per_word <= 16) {
+		cs->get_rx = mpc83xx_spi_rx_buf_u16;
+		cs->get_tx = mpc83xx_spi_tx_buf_u16;
+		if (mpc83xx_spi->qe_mode) {
+			cs->rx_shift = 16;
+			cs->tx_shift = 16;
+		}
+	} else if (bits_per_word <= 32) {
+		cs->get_rx = mpc83xx_spi_rx_buf_u32;
+		cs->get_tx = mpc83xx_spi_tx_buf_u32;
+	} else
+		return -EINVAL;
+
+	if (mpc83xx_spi->qe_mode && spi->mode & SPI_LSB_FIRST) {
+		cs->tx_shift = 0;
+		if (bits_per_word <= 8)
+			cs->rx_shift = 8;
+		else
+			cs->rx_shift = 0;
+	}
+
+	mpc83xx_spi->rx_shift = cs->rx_shift;
+	mpc83xx_spi->tx_shift = cs->tx_shift;
+	mpc83xx_spi->get_rx = cs->get_rx;
+	mpc83xx_spi->get_tx = cs->get_tx;
+
+	if (bits_per_word == 32)
+		bits_per_word = 0;
+	else
+		bits_per_word = bits_per_word - 1;
+
+	/* mask out bits we are going to set */
+	cs->hw_mode &= ~(SPMODE_LEN(0xF) | SPMODE_DIV16
+				  | SPMODE_PM(0xF));
+
+	cs->hw_mode |= SPMODE_LEN(bits_per_word);
+
+	if ((mpc83xx_spi->spibrg / hz) > 64) {
+		cs->hw_mode |= SPMODE_DIV16;
+		pm = mpc83xx_spi->spibrg / (hz * 64);
+
+		WARN_ONCE(pm > 16, "%s: Requested speed is too low: %d Hz. "
+			  "Will use %d Hz instead.\n", dev_name(&spi->dev),
+			  hz, mpc83xx_spi->spibrg / 1024);
+		if (pm > 16)
+			pm = 16;
+	} else
+		pm = mpc83xx_spi->spibrg / (hz * 4);
+	if (pm)
+		pm--;
+
+	cs->hw_mode |= SPMODE_PM(pm);
+	regval =  mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+	if (cs->hw_mode != regval) {
+		unsigned long flags;
+		__be32 __iomem *mode = &mpc83xx_spi->base->mode;
+
+		regval = cs->hw_mode;
+		/* Turn off IRQs locally to minimize time
+		 * that SPI is disabled
+		 */
+		local_irq_save(flags);
+		/* Turn off SPI unit prior changing mode */
+		mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE);
+		mpc83xx_spi_write_reg(mode, regval);
+		local_irq_restore(flags);
+	}
+	return 0;
+}
+
+static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
+{
+	struct mpc83xx_spi *mpc83xx_spi;
+	u32 word, len, bits_per_word;
+
+	mpc83xx_spi = spi_master_get_devdata(spi->master);
+
+	mpc83xx_spi->tx = t->tx_buf;
+	mpc83xx_spi->rx = t->rx_buf;
+	bits_per_word = spi->bits_per_word;
+	if (t->bits_per_word)
+		bits_per_word = t->bits_per_word;
+	len = t->len;
+	if (bits_per_word > 8) {
+		/* invalid length? */
+		if (len & 1)
+			return -EINVAL;
+		len /= 2;
+	}
+	if (bits_per_word > 16) {
+		/* invalid length? */
+		if (len & 1)
+			return -EINVAL;
+		len /= 2;
+	}
+	mpc83xx_spi->count = len;
+
+	INIT_COMPLETION(mpc83xx_spi->done);
+
+	/* enable rx ints */
+	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE);
+
+	/* transmit word */
+	word = mpc83xx_spi->get_tx(mpc83xx_spi);
+	mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
+
+	wait_for_completion(&mpc83xx_spi->done);
+
+	/* disable rx ints */
+	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
+
+	return mpc83xx_spi->count;
+}
+
+static void mpc83xx_spi_do_one_msg(struct spi_message *m)
+{
+	struct spi_device *spi = m->spi;
+	struct spi_transfer *t;
+	unsigned int cs_change;
+	const int nsecs = 50;
+	int status;
+
+	cs_change = 1;
+	status = 0;
+	list_for_each_entry(t, &m->transfers, transfer_list) {
+		if (t->bits_per_word || t->speed_hz) {
+			/* Don't allow changes if CS is active */
+			status = -EINVAL;
+
+			if (cs_change)
+				status = mpc83xx_spi_setup_transfer(spi, t);
+			if (status < 0)
+				break;
+		}
+
+		if (cs_change) {
+			mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE);
+			ndelay(nsecs);
+		}
+		cs_change = t->cs_change;
+		if (t->len)
+			status = mpc83xx_spi_bufs(spi, t);
+		if (status) {
+			status = -EMSGSIZE;
+			break;
+		}
+		m->actual_length += t->len;
+
+		if (t->delay_usecs)
+			udelay(t->delay_usecs);
+
+		if (cs_change) {
+			ndelay(nsecs);
+			mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+			ndelay(nsecs);
+		}
+	}
+
+	m->status = status;
+	m->complete(m->context);
+
+	if (status || !cs_change) {
+		ndelay(nsecs);
+		mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+	}
+
+	mpc83xx_spi_setup_transfer(spi, NULL);
+}
+
+static void mpc83xx_spi_work(struct work_struct *work)
+{
+	struct mpc83xx_spi *mpc83xx_spi = container_of(work, struct mpc83xx_spi,
+						       work);
+
+	spin_lock_irq(&mpc83xx_spi->lock);
+	while (!list_empty(&mpc83xx_spi->queue)) {
+		struct spi_message *m = container_of(mpc83xx_spi->queue.next,
+						   struct spi_message, queue);
+
+		list_del_init(&m->queue);
+		spin_unlock_irq(&mpc83xx_spi->lock);
+
+		mpc83xx_spi_do_one_msg(m);
+
+		spin_lock_irq(&mpc83xx_spi->lock);
+	}
+	spin_unlock_irq(&mpc83xx_spi->lock);
+}
+
+/* the spi->mode bits understood by this driver: */
+#define MODEBITS	(SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
+			| SPI_LSB_FIRST | SPI_LOOP)
+
+static int mpc83xx_spi_setup(struct spi_device *spi)
+{
+	struct mpc83xx_spi *mpc83xx_spi;
+	int retval;
+	u32 hw_mode;
+	struct spi_mpc83xx_cs	*cs = spi->controller_state;
+
+	if (spi->mode & ~MODEBITS) {
+		dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
+			spi->mode & ~MODEBITS);
+		return -EINVAL;
+	}
+
+	if (!spi->max_speed_hz)
+		return -EINVAL;
+
+	if (!cs) {
+		cs = kzalloc(sizeof *cs, GFP_KERNEL);
+		if (!cs)
+			return -ENOMEM;
+		spi->controller_state = cs;
+	}
+	mpc83xx_spi = spi_master_get_devdata(spi->master);
+
+	if (!spi->bits_per_word)
+		spi->bits_per_word = 8;
+
+	hw_mode = cs->hw_mode; /* Save orginal settings */
+	cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+	/* mask out bits we are going to set */
+	cs->hw_mode &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH
+			 | SPMODE_REV | SPMODE_LOOP);
+
+	if (spi->mode & SPI_CPHA)
+		cs->hw_mode |= SPMODE_CP_BEGIN_EDGECLK;
+	if (spi->mode & SPI_CPOL)
+		cs->hw_mode |= SPMODE_CI_INACTIVEHIGH;
+	if (!(spi->mode & SPI_LSB_FIRST))
+		cs->hw_mode |= SPMODE_REV;
+	if (spi->mode & SPI_LOOP)
+		cs->hw_mode |= SPMODE_LOOP;
+
+	retval = mpc83xx_spi_setup_transfer(spi, NULL);
+	if (retval < 0) {
+		cs->hw_mode = hw_mode; /* Restore settings */
+		return retval;
+	}
+
+	dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u Hz\n",
+		__func__, spi->mode & (SPI_CPOL | SPI_CPHA),
+		spi->bits_per_word, spi->max_speed_hz);
+	return 0;
+}
+
+static irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
+{
+	struct mpc83xx_spi *mpc83xx_spi = context_data;
+	u32 event;
+	irqreturn_t ret = IRQ_NONE;
+
+	/* Get interrupt events(tx/rx) */
+	event = mpc83xx_spi_read_reg(&mpc83xx_spi->base->event);
+
+	/* We need handle RX first */
+	if (event & SPIE_NE) {
+		u32 rx_data = mpc83xx_spi_read_reg(&mpc83xx_spi->base->receive);
+
+		if (mpc83xx_spi->rx)
+			mpc83xx_spi->get_rx(rx_data, mpc83xx_spi);
+
+		ret = IRQ_HANDLED;
+	}
+
+	if ((event & SPIE_NF) == 0)
+		/* spin until TX is done */
+		while (((event =
+			 mpc83xx_spi_read_reg(&mpc83xx_spi->base->event)) &
+						SPIE_NF) == 0)
+			cpu_relax();
+
+	mpc83xx_spi->count -= 1;
+	if (mpc83xx_spi->count) {
+		u32 word = mpc83xx_spi->get_tx(mpc83xx_spi);
+		mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
+	} else {
+		complete(&mpc83xx_spi->done);
+	}
+
+	/* Clear the events */
+	mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, event);
+
+	return ret;
+}
+static int mpc83xx_spi_transfer(struct spi_device *spi,
+				struct spi_message *m)
+{
+	struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master);
+	unsigned long flags;
+
+	m->actual_length = 0;
+	m->status = -EINPROGRESS;
+
+	spin_lock_irqsave(&mpc83xx_spi->lock, flags);
+	list_add_tail(&m->queue, &mpc83xx_spi->queue);
+	queue_work(mpc83xx_spi->workqueue, &mpc83xx_spi->work);
+	spin_unlock_irqrestore(&mpc83xx_spi->lock, flags);
+
+	return 0;
+}
+
+
+static void mpc83xx_spi_cleanup(struct spi_device *spi)
+{
+	kfree(spi->controller_state);
+}
+
+static struct spi_master * __devinit
+mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq)
+{
+	struct fsl_spi_platform_data *pdata = dev->platform_data;
+	struct spi_master *master;
+	struct mpc83xx_spi *mpc83xx_spi;
+	u32 regval;
+	int ret = 0;
+
+	master = spi_alloc_master(dev, sizeof(struct mpc83xx_spi));
+	if (master == NULL) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	dev_set_drvdata(dev, master);
+
+	master->setup = mpc83xx_spi_setup;
+	master->transfer = mpc83xx_spi_transfer;
+	master->cleanup = mpc83xx_spi_cleanup;
+
+	mpc83xx_spi = spi_master_get_devdata(master);
+	mpc83xx_spi->qe_mode = pdata->qe_mode;
+	mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
+	mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
+	mpc83xx_spi->spibrg = pdata->sysclk;
+
+	mpc83xx_spi->rx_shift = 0;
+	mpc83xx_spi->tx_shift = 0;
+	if (mpc83xx_spi->qe_mode) {
+		mpc83xx_spi->rx_shift = 16;
+		mpc83xx_spi->tx_shift = 24;
+	}
+
+	init_completion(&mpc83xx_spi->done);
+
+	mpc83xx_spi->base = ioremap(mem->start, mem->end - mem->start + 1);
+	if (mpc83xx_spi->base == NULL) {
+		ret = -ENOMEM;
+		goto put_master;
+	}
+
+	mpc83xx_spi->irq = irq;
+
+	/* Register for SPI Interrupt */
+	ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq,
+			  0, "mpc83xx_spi", mpc83xx_spi);
+
+	if (ret != 0)
+		goto unmap_io;
+
+	master->bus_num = pdata->bus_num;
+	master->num_chipselect = pdata->max_chipselect;
+
+	/* SPI controller initializations */
+	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
+	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
+	mpc83xx_spi_write_reg(&mpc83xx_spi->base->command, 0);
+	mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, 0xffffffff);
+
+	/* Enable SPI interface */
+	regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE;
+	if (pdata->qe_mode)
+		regval |= SPMODE_OP;
+
+	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
+	spin_lock_init(&mpc83xx_spi->lock);
+	init_completion(&mpc83xx_spi->done);
+	INIT_WORK(&mpc83xx_spi->work, mpc83xx_spi_work);
+	INIT_LIST_HEAD(&mpc83xx_spi->queue);
+
+	mpc83xx_spi->workqueue = create_singlethread_workqueue(
+		dev_name(master->dev.parent));
+	if (mpc83xx_spi->workqueue == NULL) {
+		ret = -EBUSY;
+		goto free_irq;
+	}
+
+	ret = spi_register_master(master);
+	if (ret < 0)
+		goto unreg_master;
+
+	printk(KERN_INFO
+	       "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
+	       dev_name(dev), mpc83xx_spi->base, mpc83xx_spi->irq);
+
+	return master;
+
+unreg_master:
+	destroy_workqueue(mpc83xx_spi->workqueue);
+free_irq:
+	free_irq(mpc83xx_spi->irq, mpc83xx_spi);
+unmap_io:
+	iounmap(mpc83xx_spi->base);
+put_master:
+	spi_master_put(master);
+err:
+	return ERR_PTR(ret);
+}
+
+static int __devexit mpc83xx_spi_remove(struct device *dev)
+{
+	struct mpc83xx_spi *mpc83xx_spi;
+	struct spi_master *master;
+
+	master = dev_get_drvdata(dev);
+	mpc83xx_spi = spi_master_get_devdata(master);
+
+	flush_workqueue(mpc83xx_spi->workqueue);
+	destroy_workqueue(mpc83xx_spi->workqueue);
+	spi_unregister_master(master);
+
+	free_irq(mpc83xx_spi->irq, mpc83xx_spi);
+	iounmap(mpc83xx_spi->base);
+
+	return 0;
+}
+
+struct mpc83xx_spi_probe_info {
+	struct fsl_spi_platform_data pdata;
+	int *gpios;
+	bool *alow_flags;
+};
+
+static struct mpc83xx_spi_probe_info *
+to_of_pinfo(struct fsl_spi_platform_data *pdata)
+{
+	return container_of(pdata, struct mpc83xx_spi_probe_info, pdata);
+}
+
+static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on)
+{
+	struct device *dev = spi->dev.parent;
+	struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data);
+	u16 cs = spi->chip_select;
+	int gpio = pinfo->gpios[cs];
+	bool alow = pinfo->alow_flags[cs];
+
+	gpio_set_value(gpio, on ^ alow);
+}
+
+static int of_mpc83xx_spi_get_chipselects(struct device *dev)
+{
+	struct device_node *np = dev_archdata_get_node(&dev->archdata);
+	struct fsl_spi_platform_data *pdata = dev->platform_data;
+	struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata);
+	unsigned int ngpios;
+	int i = 0;
+	int ret;
+
+	ngpios = of_gpio_count(np);
+	if (!ngpios) {
+		/*
+		 * SPI w/o chip-select line. One SPI device is still permitted
+		 * though.
+		 */
+		pdata->max_chipselect = 1;
+		return 0;
+	}
+
+	pinfo->gpios = kmalloc(ngpios * sizeof(pinfo->gpios), GFP_KERNEL);
+	if (!pinfo->gpios)
+		return -ENOMEM;
+	memset(pinfo->gpios, -1, ngpios * sizeof(pinfo->gpios));
+
+	pinfo->alow_flags = kzalloc(ngpios * sizeof(pinfo->alow_flags),
+				    GFP_KERNEL);
+	if (!pinfo->alow_flags) {
+		ret = -ENOMEM;
+		goto err_alloc_flags;
+	}
+
+	for (; i < ngpios; i++) {
+		int gpio;
+		enum of_gpio_flags flags;
+
+		gpio = of_get_gpio_flags(np, i, &flags);
+		if (!gpio_is_valid(gpio)) {
+			dev_err(dev, "invalid gpio #%d: %d\n", i, gpio);
+			goto err_loop;
+		}
+
+		ret = gpio_request(gpio, dev_name(dev));
+		if (ret) {
+			dev_err(dev, "can't request gpio #%d: %d\n", i, ret);
+			goto err_loop;
+		}
+
+		pinfo->gpios[i] = gpio;
+		pinfo->alow_flags[i] = flags & OF_GPIO_ACTIVE_LOW;
+
+		ret = gpio_direction_output(pinfo->gpios[i],
+					    pinfo->alow_flags[i]);
+		if (ret) {
+			dev_err(dev, "can't set output direction for gpio "
+				"#%d: %d\n", i, ret);
+			goto err_loop;
+		}
+	}
+
+	pdata->max_chipselect = ngpios;
+	pdata->cs_control = mpc83xx_spi_cs_control;
+
+	return 0;
+
+err_loop:
+	while (i >= 0) {
+		if (gpio_is_valid(pinfo->gpios[i]))
+			gpio_free(pinfo->gpios[i]);
+		i--;
+	}
+
+	kfree(pinfo->alow_flags);
+	pinfo->alow_flags = NULL;
+err_alloc_flags:
+	kfree(pinfo->gpios);
+	pinfo->gpios = NULL;
+	return ret;
+}
+
+static int of_mpc83xx_spi_free_chipselects(struct device *dev)
+{
+	struct fsl_spi_platform_data *pdata = dev->platform_data;
+	struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata);
+	int i;
+
+	if (!pinfo->gpios)
+		return 0;
+
+	for (i = 0; i < pdata->max_chipselect; i++) {
+		if (gpio_is_valid(pinfo->gpios[i]))
+			gpio_free(pinfo->gpios[i]);
+	}
+
+	kfree(pinfo->gpios);
+	kfree(pinfo->alow_flags);
+	return 0;
+}
+
+static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev,
+					  const struct of_device_id *ofid)
+{
+	struct device *dev = &ofdev->dev;
+	struct device_node *np = ofdev->node;
+	struct mpc83xx_spi_probe_info *pinfo;
+	struct fsl_spi_platform_data *pdata;
+	struct spi_master *master;
+	struct resource mem;
+	struct resource irq;
+	const void *prop;
+	int ret = -ENOMEM;
+
+	pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL);
+	if (!pinfo)
+		return -ENOMEM;
+
+	pdata = &pinfo->pdata;
+	dev->platform_data = pdata;
+
+	/* Allocate bus num dynamically. */
+	pdata->bus_num = -1;
+
+	/* SPI controller is either clocked from QE or SoC clock. */
+	pdata->sysclk = get_brgfreq();
+	if (pdata->sysclk == -1) {
+		pdata->sysclk = fsl_get_sys_freq();
+		if (pdata->sysclk == -1) {
+			ret = -ENODEV;
+			goto err_clk;
+		}
+	}
+
+	prop = of_get_property(np, "mode", NULL);
+	if (prop && !strcmp(prop, "cpu-qe"))
+		pdata->qe_mode = 1;
+
+	ret = of_mpc83xx_spi_get_chipselects(dev);
+	if (ret)
+		goto err;
+
+	ret = of_address_to_resource(np, 0, &mem);
+	if (ret)
+		goto err;
+
+	ret = of_irq_to_resource(np, 0, &irq);
+	if (!ret) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	master = mpc83xx_spi_probe(dev, &mem, irq.start);
+	if (IS_ERR(master)) {
+		ret = PTR_ERR(master);
+		goto err;
+	}
+
+	of_register_spi_devices(master, np);
+
+	return 0;
+
+err:
+	of_mpc83xx_spi_free_chipselects(dev);
+err_clk:
+	kfree(pinfo);
+	return ret;
+}
+
+static int __devexit of_mpc83xx_spi_remove(struct of_device *ofdev)
+{
+	int ret;
+
+	ret = mpc83xx_spi_remove(&ofdev->dev);
+	if (ret)
+		return ret;
+	of_mpc83xx_spi_free_chipselects(&ofdev->dev);
+	return 0;
+}
+
+static const struct of_device_id of_mpc83xx_spi_match[] = {
+	{ .compatible = "fsl,spi" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, of_mpc83xx_spi_match);
+
+static struct of_platform_driver of_mpc83xx_spi_driver = {
+	.name		= "mpc83xx_spi",
+	.match_table	= of_mpc83xx_spi_match,
+	.probe		= of_mpc83xx_spi_probe,
+	.remove		= __devexit_p(of_mpc83xx_spi_remove),
+};
+
+#ifdef CONFIG_MPC832x_RDB
+/*
+ * 				XXX XXX XXX
+ * This is "legacy" platform driver, was used by the MPC8323E-RDB boards
+ * only. The driver should go away soon, since newer MPC8323E-RDB's device
+ * tree can work with OpenFirmware driver. But for now we support old trees
+ * as well.
+ */
+static int __devinit plat_mpc83xx_spi_probe(struct platform_device *pdev)
+{
+	struct resource *mem;
+	unsigned int irq;
+	struct spi_master *master;
+
+	if (!pdev->dev.platform_data)
+		return -EINVAL;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem)
+		return -EINVAL;
+
+	irq = platform_get_irq(pdev, 0);
+	if (!irq)
+		return -EINVAL;
+
+	master = mpc83xx_spi_probe(&pdev->dev, mem, irq);
+	if (IS_ERR(master))
+		return PTR_ERR(master);
+	return 0;
+}
+
+static int __devexit plat_mpc83xx_spi_remove(struct platform_device *pdev)
+{
+	return mpc83xx_spi_remove(&pdev->dev);
+}
+
+MODULE_ALIAS("platform:mpc83xx_spi");
+static struct platform_driver mpc83xx_spi_driver = {
+	.probe = plat_mpc83xx_spi_probe,
+	.remove = __exit_p(plat_mpc83xx_spi_remove),
+	.driver = {
+		.name = "mpc83xx_spi",
+		.owner = THIS_MODULE,
+	},
+};
+
+static bool legacy_driver_failed;
+
+static void __init legacy_driver_register(void)
+{
+	legacy_driver_failed = platform_driver_register(&mpc83xx_spi_driver);
+}
+
+static void __exit legacy_driver_unregister(void)
+{
+	if (legacy_driver_failed)
+		return;
+	platform_driver_unregister(&mpc83xx_spi_driver);
+}
+#else
+static void __init legacy_driver_register(void) {}
+static void __exit legacy_driver_unregister(void) {}
+#endif /* CONFIG_MPC832x_RDB */
+
+static int __init mpc83xx_spi_init(void)
+{
+	legacy_driver_register();
+	return of_register_platform_driver(&of_mpc83xx_spi_driver);
+}
+
+static void __exit mpc83xx_spi_exit(void)
+{
+	of_unregister_platform_driver(&of_mpc83xx_spi_driver);
+	legacy_driver_unregister();
+}
+
+module_init(mpc83xx_spi_init);
+module_exit(mpc83xx_spi_exit);
+
+MODULE_AUTHOR("Kumar Gala");
+MODULE_DESCRIPTION("Simple MPC83xx SPI Driver");
+MODULE_LICENSE("GPL");
-- 
1.6.2.2

^ permalink raw reply related

* [PATCH 9/9] spi_mpc8xxx: s/83xx/8xxx/g
From: Anton Vorontsov @ 2009-04-30 23:48 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linuxppc-dev, Andrew Morton, David Brownell, linux-kernel,
	spi-devel-general
In-Reply-To: <20090430234739.GA27709@oksana.dev.rtsoft.ru>

Since we renamed the file, we might want to rename the file
internals too.

Though we don't bother with changing platform driver name and
platform module alias. The stuff is legacy and hopefully we'll
remove it soon.

Suggested-by: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 drivers/spi/Kconfig       |    2 +-
 drivers/spi/Makefile      |    2 +-
 drivers/spi/spi_mpc8xxx.c |  396 ++++++++++++++++++++++----------------------
 3 files changed, 200 insertions(+), 200 deletions(-)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 3c1845c..9e77bf1 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -139,7 +139,7 @@ config SPI_MPC52xx_PSC
 	  This enables using the Freescale MPC52xx Programmable Serial
 	  Controller in master SPI mode.
 
-config SPI_MPC83xx
+config SPI_MPC8xxx
 	tristate "Freescale MPC8xxx SPI controller"
 	depends on FSL_SOC
 	help
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index fdc7aa0..18ba6b4 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -24,7 +24,7 @@ obj-$(CONFIG_SPI_OMAP_UWIRE)		+= omap_uwire.o
 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_mpc8xxx.o
+obj-$(CONFIG_SPI_MPC8xxx)		+= spi_mpc8xxx.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_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c
index 4192ce4..15d9527 100644
--- a/drivers/spi/spi_mpc8xxx.c
+++ b/drivers/spi/spi_mpc8xxx.c
@@ -1,5 +1,5 @@
 /*
- * MPC83xx SPI controller driver.
+ * MPC8xxx SPI controller driver.
  *
  * Maintainer: Kumar Gala
  *
@@ -37,7 +37,7 @@
 #include <asm/irq.h>
 
 /* SPI Controller registers */
-struct mpc83xx_spi_reg {
+struct mpc8xxx_spi_reg {
 	u8 res1[0x20];
 	__be32 mode;
 	__be32 event;
@@ -76,16 +76,16 @@ struct mpc83xx_spi_reg {
 #define	SPIM_NF		0x00000100	/* Not full */
 
 /* SPI Controller driver's private data. */
-struct mpc83xx_spi {
-	struct mpc83xx_spi_reg __iomem *base;
+struct mpc8xxx_spi {
+	struct mpc8xxx_spi_reg __iomem *base;
 
 	/* rx & tx bufs from the spi_transfer */
 	const void *tx;
 	void *rx;
 
 	/* functions to deal with different sized buffers */
-	void (*get_rx) (u32 rx_data, struct mpc83xx_spi *);
-	u32(*get_tx) (struct mpc83xx_spi *);
+	void (*get_rx) (u32 rx_data, struct mpc8xxx_spi *);
+	u32(*get_tx) (struct mpc8xxx_spi *);
 
 	unsigned int count;
 	unsigned int irq;
@@ -107,44 +107,44 @@ struct mpc83xx_spi {
 	struct completion done;
 };
 
-struct spi_mpc83xx_cs {
+struct spi_mpc8xxx_cs {
 	/* functions to deal with different sized buffers */
-	void (*get_rx) (u32 rx_data, struct mpc83xx_spi *);
-	u32 (*get_tx) (struct mpc83xx_spi *);
+	void (*get_rx) (u32 rx_data, struct mpc8xxx_spi *);
+	u32 (*get_tx) (struct mpc8xxx_spi *);
 	u32 rx_shift;		/* RX data reg shift when in qe mode */
 	u32 tx_shift;		/* TX data reg shift when in qe mode */
 	u32 hw_mode;		/* Holds HW mode register settings */
 };
 
-static inline void mpc83xx_spi_write_reg(__be32 __iomem *reg, u32 val)
+static inline void mpc8xxx_spi_write_reg(__be32 __iomem *reg, u32 val)
 {
 	out_be32(reg, val);
 }
 
-static inline u32 mpc83xx_spi_read_reg(__be32 __iomem *reg)
+static inline u32 mpc8xxx_spi_read_reg(__be32 __iomem *reg)
 {
 	return in_be32(reg);
 }
 
 #define MPC83XX_SPI_RX_BUF(type) 					  \
 static									  \
-void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \
+void mpc8xxx_spi_rx_buf_##type(u32 data, struct mpc8xxx_spi *mpc8xxx_spi) \
 {									  \
-	type *rx = mpc83xx_spi->rx;					  \
-	*rx++ = (type)(data >> mpc83xx_spi->rx_shift);			  \
-	mpc83xx_spi->rx = rx;						  \
+	type *rx = mpc8xxx_spi->rx;					  \
+	*rx++ = (type)(data >> mpc8xxx_spi->rx_shift);			  \
+	mpc8xxx_spi->rx = rx;						  \
 }
 
 #define MPC83XX_SPI_TX_BUF(type)				\
 static								\
-u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi)	\
+u32 mpc8xxx_spi_tx_buf_##type(struct mpc8xxx_spi *mpc8xxx_spi)	\
 {								\
 	u32 data;						\
-	const type *tx = mpc83xx_spi->tx;			\
+	const type *tx = mpc8xxx_spi->tx;			\
 	if (!tx)						\
 		return 0;					\
-	data = *tx++ << mpc83xx_spi->tx_shift;			\
-	mpc83xx_spi->tx = tx;					\
+	data = *tx++ << mpc8xxx_spi->tx_shift;			\
+	mpc8xxx_spi->tx = tx;					\
 	return data;						\
 }
 
@@ -155,12 +155,12 @@ MPC83XX_SPI_TX_BUF(u8)
 MPC83XX_SPI_TX_BUF(u16)
 MPC83XX_SPI_TX_BUF(u32)
 
-static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
+static void mpc8xxx_spi_chipselect(struct spi_device *spi, int value)
 {
-	struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master);
+	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
 	struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data;
 	bool pol = spi->mode & SPI_CS_HIGH;
-	struct spi_mpc83xx_cs	*cs = spi->controller_state;
+	struct spi_mpc8xxx_cs	*cs = spi->controller_state;
 
 	if (value == BITBANG_CS_INACTIVE) {
 		if (pdata->cs_control)
@@ -168,16 +168,16 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
 	}
 
 	if (value == BITBANG_CS_ACTIVE) {
-		u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+		u32 regval = mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->mode);
 
-		mpc83xx_spi->rx_shift = cs->rx_shift;
-		mpc83xx_spi->tx_shift = cs->tx_shift;
-		mpc83xx_spi->get_rx = cs->get_rx;
-		mpc83xx_spi->get_tx = cs->get_tx;
+		mpc8xxx_spi->rx_shift = cs->rx_shift;
+		mpc8xxx_spi->tx_shift = cs->tx_shift;
+		mpc8xxx_spi->get_rx = cs->get_rx;
+		mpc8xxx_spi->get_tx = cs->get_tx;
 
 		if (cs->hw_mode != regval) {
 			unsigned long flags;
-			__be32 __iomem *mode = &mpc83xx_spi->base->mode;
+			__be32 __iomem *mode = &mpc8xxx_spi->base->mode;
 
 			regval = cs->hw_mode;
 			/* Turn off IRQs locally to minimize time that
@@ -185,8 +185,8 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
 			 */
 			local_irq_save(flags);
 			/* Turn off SPI unit prior changing mode */
-			mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE);
-			mpc83xx_spi_write_reg(mode, regval);
+			mpc8xxx_spi_write_reg(mode, regval & ~SPMODE_ENABLE);
+			mpc8xxx_spi_write_reg(mode, regval);
 			local_irq_restore(flags);
 		}
 		if (pdata->cs_control)
@@ -195,15 +195,15 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
 }
 
 static
-int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
+int mpc8xxx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 {
-	struct mpc83xx_spi *mpc83xx_spi;
+	struct mpc8xxx_spi *mpc8xxx_spi;
 	u32 regval;
 	u8 bits_per_word, pm;
 	u32 hz;
-	struct spi_mpc83xx_cs	*cs = spi->controller_state;
+	struct spi_mpc8xxx_cs	*cs = spi->controller_state;
 
-	mpc83xx_spi = spi_master_get_devdata(spi->master);
+	mpc8xxx_spi = spi_master_get_devdata(spi->master);
 
 	if (t) {
 		bits_per_word = t->bits_per_word;
@@ -228,26 +228,26 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 	cs->rx_shift = 0;
 	cs->tx_shift = 0;
 	if (bits_per_word <= 8) {
-		cs->get_rx = mpc83xx_spi_rx_buf_u8;
-		cs->get_tx = mpc83xx_spi_tx_buf_u8;
-		if (mpc83xx_spi->qe_mode) {
+		cs->get_rx = mpc8xxx_spi_rx_buf_u8;
+		cs->get_tx = mpc8xxx_spi_tx_buf_u8;
+		if (mpc8xxx_spi->qe_mode) {
 			cs->rx_shift = 16;
 			cs->tx_shift = 24;
 		}
 	} else if (bits_per_word <= 16) {
-		cs->get_rx = mpc83xx_spi_rx_buf_u16;
-		cs->get_tx = mpc83xx_spi_tx_buf_u16;
-		if (mpc83xx_spi->qe_mode) {
+		cs->get_rx = mpc8xxx_spi_rx_buf_u16;
+		cs->get_tx = mpc8xxx_spi_tx_buf_u16;
+		if (mpc8xxx_spi->qe_mode) {
 			cs->rx_shift = 16;
 			cs->tx_shift = 16;
 		}
 	} else if (bits_per_word <= 32) {
-		cs->get_rx = mpc83xx_spi_rx_buf_u32;
-		cs->get_tx = mpc83xx_spi_tx_buf_u32;
+		cs->get_rx = mpc8xxx_spi_rx_buf_u32;
+		cs->get_tx = mpc8xxx_spi_tx_buf_u32;
 	} else
 		return -EINVAL;
 
-	if (mpc83xx_spi->qe_mode && spi->mode & SPI_LSB_FIRST) {
+	if (mpc8xxx_spi->qe_mode && spi->mode & SPI_LSB_FIRST) {
 		cs->tx_shift = 0;
 		if (bits_per_word <= 8)
 			cs->rx_shift = 8;
@@ -255,10 +255,10 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 			cs->rx_shift = 0;
 	}
 
-	mpc83xx_spi->rx_shift = cs->rx_shift;
-	mpc83xx_spi->tx_shift = cs->tx_shift;
-	mpc83xx_spi->get_rx = cs->get_rx;
-	mpc83xx_spi->get_tx = cs->get_tx;
+	mpc8xxx_spi->rx_shift = cs->rx_shift;
+	mpc8xxx_spi->tx_shift = cs->tx_shift;
+	mpc8xxx_spi->get_rx = cs->get_rx;
+	mpc8xxx_spi->get_tx = cs->get_tx;
 
 	if (bits_per_word == 32)
 		bits_per_word = 0;
@@ -271,25 +271,25 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 
 	cs->hw_mode |= SPMODE_LEN(bits_per_word);
 
-	if ((mpc83xx_spi->spibrg / hz) > 64) {
+	if ((mpc8xxx_spi->spibrg / hz) > 64) {
 		cs->hw_mode |= SPMODE_DIV16;
-		pm = mpc83xx_spi->spibrg / (hz * 64);
+		pm = mpc8xxx_spi->spibrg / (hz * 64);
 
 		WARN_ONCE(pm > 16, "%s: Requested speed is too low: %d Hz. "
 			  "Will use %d Hz instead.\n", dev_name(&spi->dev),
-			  hz, mpc83xx_spi->spibrg / 1024);
+			  hz, mpc8xxx_spi->spibrg / 1024);
 		if (pm > 16)
 			pm = 16;
 	} else
-		pm = mpc83xx_spi->spibrg / (hz * 4);
+		pm = mpc8xxx_spi->spibrg / (hz * 4);
 	if (pm)
 		pm--;
 
 	cs->hw_mode |= SPMODE_PM(pm);
-	regval =  mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+	regval =  mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->mode);
 	if (cs->hw_mode != regval) {
 		unsigned long flags;
-		__be32 __iomem *mode = &mpc83xx_spi->base->mode;
+		__be32 __iomem *mode = &mpc8xxx_spi->base->mode;
 
 		regval = cs->hw_mode;
 		/* Turn off IRQs locally to minimize time
@@ -297,22 +297,22 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 		 */
 		local_irq_save(flags);
 		/* Turn off SPI unit prior changing mode */
-		mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE);
-		mpc83xx_spi_write_reg(mode, regval);
+		mpc8xxx_spi_write_reg(mode, regval & ~SPMODE_ENABLE);
+		mpc8xxx_spi_write_reg(mode, regval);
 		local_irq_restore(flags);
 	}
 	return 0;
 }
 
-static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
+static int mpc8xxx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
 {
-	struct mpc83xx_spi *mpc83xx_spi;
+	struct mpc8xxx_spi *mpc8xxx_spi;
 	u32 word, len, bits_per_word;
 
-	mpc83xx_spi = spi_master_get_devdata(spi->master);
+	mpc8xxx_spi = spi_master_get_devdata(spi->master);
 
-	mpc83xx_spi->tx = t->tx_buf;
-	mpc83xx_spi->rx = t->rx_buf;
+	mpc8xxx_spi->tx = t->tx_buf;
+	mpc8xxx_spi->rx = t->rx_buf;
 	bits_per_word = spi->bits_per_word;
 	if (t->bits_per_word)
 		bits_per_word = t->bits_per_word;
@@ -329,26 +329,26 @@ static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
 			return -EINVAL;
 		len /= 2;
 	}
-	mpc83xx_spi->count = len;
+	mpc8xxx_spi->count = len;
 
-	INIT_COMPLETION(mpc83xx_spi->done);
+	INIT_COMPLETION(mpc8xxx_spi->done);
 
 	/* enable rx ints */
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE);
+	mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mask, SPIM_NE);
 
 	/* transmit word */
-	word = mpc83xx_spi->get_tx(mpc83xx_spi);
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
+	word = mpc8xxx_spi->get_tx(mpc8xxx_spi);
+	mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->transmit, word);
 
-	wait_for_completion(&mpc83xx_spi->done);
+	wait_for_completion(&mpc8xxx_spi->done);
 
 	/* disable rx ints */
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
+	mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mask, 0);
 
-	return mpc83xx_spi->count;
+	return mpc8xxx_spi->count;
 }
 
-static void mpc83xx_spi_do_one_msg(struct spi_message *m)
+static void mpc8xxx_spi_do_one_msg(struct spi_message *m)
 {
 	struct spi_device *spi = m->spi;
 	struct spi_transfer *t;
@@ -364,18 +364,18 @@ static void mpc83xx_spi_do_one_msg(struct spi_message *m)
 			status = -EINVAL;
 
 			if (cs_change)
-				status = mpc83xx_spi_setup_transfer(spi, t);
+				status = mpc8xxx_spi_setup_transfer(spi, t);
 			if (status < 0)
 				break;
 		}
 
 		if (cs_change) {
-			mpc83xx_spi_chipselect(spi, BITBANG_CS_ACTIVE);
+			mpc8xxx_spi_chipselect(spi, BITBANG_CS_ACTIVE);
 			ndelay(nsecs);
 		}
 		cs_change = t->cs_change;
 		if (t->len)
-			status = mpc83xx_spi_bufs(spi, t);
+			status = mpc8xxx_spi_bufs(spi, t);
 		if (status) {
 			status = -EMSGSIZE;
 			break;
@@ -387,7 +387,7 @@ static void mpc83xx_spi_do_one_msg(struct spi_message *m)
 
 		if (cs_change) {
 			ndelay(nsecs);
-			mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+			mpc8xxx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
 			ndelay(nsecs);
 		}
 	}
@@ -397,42 +397,42 @@ static void mpc83xx_spi_do_one_msg(struct spi_message *m)
 
 	if (status || !cs_change) {
 		ndelay(nsecs);
-		mpc83xx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
+		mpc8xxx_spi_chipselect(spi, BITBANG_CS_INACTIVE);
 	}
 
-	mpc83xx_spi_setup_transfer(spi, NULL);
+	mpc8xxx_spi_setup_transfer(spi, NULL);
 }
 
-static void mpc83xx_spi_work(struct work_struct *work)
+static void mpc8xxx_spi_work(struct work_struct *work)
 {
-	struct mpc83xx_spi *mpc83xx_spi = container_of(work, struct mpc83xx_spi,
+	struct mpc8xxx_spi *mpc8xxx_spi = container_of(work, struct mpc8xxx_spi,
 						       work);
 
-	spin_lock_irq(&mpc83xx_spi->lock);
-	while (!list_empty(&mpc83xx_spi->queue)) {
-		struct spi_message *m = container_of(mpc83xx_spi->queue.next,
+	spin_lock_irq(&mpc8xxx_spi->lock);
+	while (!list_empty(&mpc8xxx_spi->queue)) {
+		struct spi_message *m = container_of(mpc8xxx_spi->queue.next,
 						   struct spi_message, queue);
 
 		list_del_init(&m->queue);
-		spin_unlock_irq(&mpc83xx_spi->lock);
+		spin_unlock_irq(&mpc8xxx_spi->lock);
 
-		mpc83xx_spi_do_one_msg(m);
+		mpc8xxx_spi_do_one_msg(m);
 
-		spin_lock_irq(&mpc83xx_spi->lock);
+		spin_lock_irq(&mpc8xxx_spi->lock);
 	}
-	spin_unlock_irq(&mpc83xx_spi->lock);
+	spin_unlock_irq(&mpc8xxx_spi->lock);
 }
 
 /* the spi->mode bits understood by this driver: */
 #define MODEBITS	(SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
 			| SPI_LSB_FIRST | SPI_LOOP)
 
-static int mpc83xx_spi_setup(struct spi_device *spi)
+static int mpc8xxx_spi_setup(struct spi_device *spi)
 {
-	struct mpc83xx_spi *mpc83xx_spi;
+	struct mpc8xxx_spi *mpc8xxx_spi;
 	int retval;
 	u32 hw_mode;
-	struct spi_mpc83xx_cs	*cs = spi->controller_state;
+	struct spi_mpc8xxx_cs	*cs = spi->controller_state;
 
 	if (spi->mode & ~MODEBITS) {
 		dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n",
@@ -449,13 +449,13 @@ static int mpc83xx_spi_setup(struct spi_device *spi)
 			return -ENOMEM;
 		spi->controller_state = cs;
 	}
-	mpc83xx_spi = spi_master_get_devdata(spi->master);
+	mpc8xxx_spi = spi_master_get_devdata(spi->master);
 
 	if (!spi->bits_per_word)
 		spi->bits_per_word = 8;
 
 	hw_mode = cs->hw_mode; /* Save orginal settings */
-	cs->hw_mode = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+	cs->hw_mode = mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->mode);
 	/* mask out bits we are going to set */
 	cs->hw_mode &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH
 			 | SPMODE_REV | SPMODE_LOOP);
@@ -469,7 +469,7 @@ static int mpc83xx_spi_setup(struct spi_device *spi)
 	if (spi->mode & SPI_LOOP)
 		cs->hw_mode |= SPMODE_LOOP;
 
-	retval = mpc83xx_spi_setup_transfer(spi, NULL);
+	retval = mpc8xxx_spi_setup_transfer(spi, NULL);
 	if (retval < 0) {
 		cs->hw_mode = hw_mode; /* Restore settings */
 		return retval;
@@ -481,21 +481,21 @@ static int mpc83xx_spi_setup(struct spi_device *spi)
 	return 0;
 }
 
-static irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
+static irqreturn_t mpc8xxx_spi_irq(s32 irq, void *context_data)
 {
-	struct mpc83xx_spi *mpc83xx_spi = context_data;
+	struct mpc8xxx_spi *mpc8xxx_spi = context_data;
 	u32 event;
 	irqreturn_t ret = IRQ_NONE;
 
 	/* Get interrupt events(tx/rx) */
-	event = mpc83xx_spi_read_reg(&mpc83xx_spi->base->event);
+	event = mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->event);
 
 	/* We need handle RX first */
 	if (event & SPIE_NE) {
-		u32 rx_data = mpc83xx_spi_read_reg(&mpc83xx_spi->base->receive);
+		u32 rx_data = mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->receive);
 
-		if (mpc83xx_spi->rx)
-			mpc83xx_spi->get_rx(rx_data, mpc83xx_spi);
+		if (mpc8xxx_spi->rx)
+			mpc8xxx_spi->get_rx(rx_data, mpc8xxx_spi);
 
 		ret = IRQ_HANDLED;
 	}
@@ -503,56 +503,56 @@ static irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
 	if ((event & SPIE_NF) == 0)
 		/* spin until TX is done */
 		while (((event =
-			 mpc83xx_spi_read_reg(&mpc83xx_spi->base->event)) &
+			 mpc8xxx_spi_read_reg(&mpc8xxx_spi->base->event)) &
 						SPIE_NF) == 0)
 			cpu_relax();
 
-	mpc83xx_spi->count -= 1;
-	if (mpc83xx_spi->count) {
-		u32 word = mpc83xx_spi->get_tx(mpc83xx_spi);
-		mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
+	mpc8xxx_spi->count -= 1;
+	if (mpc8xxx_spi->count) {
+		u32 word = mpc8xxx_spi->get_tx(mpc8xxx_spi);
+		mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->transmit, word);
 	} else {
-		complete(&mpc83xx_spi->done);
+		complete(&mpc8xxx_spi->done);
 	}
 
 	/* Clear the events */
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, event);
+	mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->event, event);
 
 	return ret;
 }
-static int mpc83xx_spi_transfer(struct spi_device *spi,
+static int mpc8xxx_spi_transfer(struct spi_device *spi,
 				struct spi_message *m)
 {
-	struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master);
+	struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
 	unsigned long flags;
 
 	m->actual_length = 0;
 	m->status = -EINPROGRESS;
 
-	spin_lock_irqsave(&mpc83xx_spi->lock, flags);
-	list_add_tail(&m->queue, &mpc83xx_spi->queue);
-	queue_work(mpc83xx_spi->workqueue, &mpc83xx_spi->work);
-	spin_unlock_irqrestore(&mpc83xx_spi->lock, flags);
+	spin_lock_irqsave(&mpc8xxx_spi->lock, flags);
+	list_add_tail(&m->queue, &mpc8xxx_spi->queue);
+	queue_work(mpc8xxx_spi->workqueue, &mpc8xxx_spi->work);
+	spin_unlock_irqrestore(&mpc8xxx_spi->lock, flags);
 
 	return 0;
 }
 
 
-static void mpc83xx_spi_cleanup(struct spi_device *spi)
+static void mpc8xxx_spi_cleanup(struct spi_device *spi)
 {
 	kfree(spi->controller_state);
 }
 
 static struct spi_master * __devinit
-mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq)
+mpc8xxx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq)
 {
 	struct fsl_spi_platform_data *pdata = dev->platform_data;
 	struct spi_master *master;
-	struct mpc83xx_spi *mpc83xx_spi;
+	struct mpc8xxx_spi *mpc8xxx_spi;
 	u32 regval;
 	int ret = 0;
 
-	master = spi_alloc_master(dev, sizeof(struct mpc83xx_spi));
+	master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi));
 	if (master == NULL) {
 		ret = -ENOMEM;
 		goto err;
@@ -560,36 +560,36 @@ mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq)
 
 	dev_set_drvdata(dev, master);
 
-	master->setup = mpc83xx_spi_setup;
-	master->transfer = mpc83xx_spi_transfer;
-	master->cleanup = mpc83xx_spi_cleanup;
-
-	mpc83xx_spi = spi_master_get_devdata(master);
-	mpc83xx_spi->qe_mode = pdata->qe_mode;
-	mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
-	mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
-	mpc83xx_spi->spibrg = pdata->sysclk;
-
-	mpc83xx_spi->rx_shift = 0;
-	mpc83xx_spi->tx_shift = 0;
-	if (mpc83xx_spi->qe_mode) {
-		mpc83xx_spi->rx_shift = 16;
-		mpc83xx_spi->tx_shift = 24;
+	master->setup = mpc8xxx_spi_setup;
+	master->transfer = mpc8xxx_spi_transfer;
+	master->cleanup = mpc8xxx_spi_cleanup;
+
+	mpc8xxx_spi = spi_master_get_devdata(master);
+	mpc8xxx_spi->qe_mode = pdata->qe_mode;
+	mpc8xxx_spi->get_rx = mpc8xxx_spi_rx_buf_u8;
+	mpc8xxx_spi->get_tx = mpc8xxx_spi_tx_buf_u8;
+	mpc8xxx_spi->spibrg = pdata->sysclk;
+
+	mpc8xxx_spi->rx_shift = 0;
+	mpc8xxx_spi->tx_shift = 0;
+	if (mpc8xxx_spi->qe_mode) {
+		mpc8xxx_spi->rx_shift = 16;
+		mpc8xxx_spi->tx_shift = 24;
 	}
 
-	init_completion(&mpc83xx_spi->done);
+	init_completion(&mpc8xxx_spi->done);
 
-	mpc83xx_spi->base = ioremap(mem->start, mem->end - mem->start + 1);
-	if (mpc83xx_spi->base == NULL) {
+	mpc8xxx_spi->base = ioremap(mem->start, mem->end - mem->start + 1);
+	if (mpc8xxx_spi->base == NULL) {
 		ret = -ENOMEM;
 		goto put_master;
 	}
 
-	mpc83xx_spi->irq = irq;
+	mpc8xxx_spi->irq = irq;
 
 	/* Register for SPI Interrupt */
-	ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq,
-			  0, "mpc83xx_spi", mpc83xx_spi);
+	ret = request_irq(mpc8xxx_spi->irq, mpc8xxx_spi_irq,
+			  0, "mpc8xxx_spi", mpc8xxx_spi);
 
 	if (ret != 0)
 		goto unmap_io;
@@ -598,25 +598,25 @@ mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq)
 	master->num_chipselect = pdata->max_chipselect;
 
 	/* SPI controller initializations */
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->command, 0);
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, 0xffffffff);
+	mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mode, 0);
+	mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mask, 0);
+	mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->command, 0);
+	mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->event, 0xffffffff);
 
 	/* Enable SPI interface */
 	regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE;
 	if (pdata->qe_mode)
 		regval |= SPMODE_OP;
 
-	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
-	spin_lock_init(&mpc83xx_spi->lock);
-	init_completion(&mpc83xx_spi->done);
-	INIT_WORK(&mpc83xx_spi->work, mpc83xx_spi_work);
-	INIT_LIST_HEAD(&mpc83xx_spi->queue);
+	mpc8xxx_spi_write_reg(&mpc8xxx_spi->base->mode, regval);
+	spin_lock_init(&mpc8xxx_spi->lock);
+	init_completion(&mpc8xxx_spi->done);
+	INIT_WORK(&mpc8xxx_spi->work, mpc8xxx_spi_work);
+	INIT_LIST_HEAD(&mpc8xxx_spi->queue);
 
-	mpc83xx_spi->workqueue = create_singlethread_workqueue(
+	mpc8xxx_spi->workqueue = create_singlethread_workqueue(
 		dev_name(master->dev.parent));
-	if (mpc83xx_spi->workqueue == NULL) {
+	if (mpc8xxx_spi->workqueue == NULL) {
 		ret = -EBUSY;
 		goto free_irq;
 	}
@@ -626,57 +626,57 @@ mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq)
 		goto unreg_master;
 
 	printk(KERN_INFO
-	       "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
-	       dev_name(dev), mpc83xx_spi->base, mpc83xx_spi->irq);
+	       "%s: MPC8xxx SPI Controller driver at 0x%p (irq = %d)\n",
+	       dev_name(dev), mpc8xxx_spi->base, mpc8xxx_spi->irq);
 
 	return master;
 
 unreg_master:
-	destroy_workqueue(mpc83xx_spi->workqueue);
+	destroy_workqueue(mpc8xxx_spi->workqueue);
 free_irq:
-	free_irq(mpc83xx_spi->irq, mpc83xx_spi);
+	free_irq(mpc8xxx_spi->irq, mpc8xxx_spi);
 unmap_io:
-	iounmap(mpc83xx_spi->base);
+	iounmap(mpc8xxx_spi->base);
 put_master:
 	spi_master_put(master);
 err:
 	return ERR_PTR(ret);
 }
 
-static int __devexit mpc83xx_spi_remove(struct device *dev)
+static int __devexit mpc8xxx_spi_remove(struct device *dev)
 {
-	struct mpc83xx_spi *mpc83xx_spi;
+	struct mpc8xxx_spi *mpc8xxx_spi;
 	struct spi_master *master;
 
 	master = dev_get_drvdata(dev);
-	mpc83xx_spi = spi_master_get_devdata(master);
+	mpc8xxx_spi = spi_master_get_devdata(master);
 
-	flush_workqueue(mpc83xx_spi->workqueue);
-	destroy_workqueue(mpc83xx_spi->workqueue);
+	flush_workqueue(mpc8xxx_spi->workqueue);
+	destroy_workqueue(mpc8xxx_spi->workqueue);
 	spi_unregister_master(master);
 
-	free_irq(mpc83xx_spi->irq, mpc83xx_spi);
-	iounmap(mpc83xx_spi->base);
+	free_irq(mpc8xxx_spi->irq, mpc8xxx_spi);
+	iounmap(mpc8xxx_spi->base);
 
 	return 0;
 }
 
-struct mpc83xx_spi_probe_info {
+struct mpc8xxx_spi_probe_info {
 	struct fsl_spi_platform_data pdata;
 	int *gpios;
 	bool *alow_flags;
 };
 
-static struct mpc83xx_spi_probe_info *
+static struct mpc8xxx_spi_probe_info *
 to_of_pinfo(struct fsl_spi_platform_data *pdata)
 {
-	return container_of(pdata, struct mpc83xx_spi_probe_info, pdata);
+	return container_of(pdata, struct mpc8xxx_spi_probe_info, pdata);
 }
 
-static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on)
+static void mpc8xxx_spi_cs_control(struct spi_device *spi, bool on)
 {
 	struct device *dev = spi->dev.parent;
-	struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data);
+	struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data);
 	u16 cs = spi->chip_select;
 	int gpio = pinfo->gpios[cs];
 	bool alow = pinfo->alow_flags[cs];
@@ -684,11 +684,11 @@ static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on)
 	gpio_set_value(gpio, on ^ alow);
 }
 
-static int of_mpc83xx_spi_get_chipselects(struct device *dev)
+static int of_mpc8xxx_spi_get_chipselects(struct device *dev)
 {
 	struct device_node *np = dev_archdata_get_node(&dev->archdata);
 	struct fsl_spi_platform_data *pdata = dev->platform_data;
-	struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata);
+	struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata);
 	unsigned int ngpios;
 	int i = 0;
 	int ret;
@@ -744,7 +744,7 @@ static int of_mpc83xx_spi_get_chipselects(struct device *dev)
 	}
 
 	pdata->max_chipselect = ngpios;
-	pdata->cs_control = mpc83xx_spi_cs_control;
+	pdata->cs_control = mpc8xxx_spi_cs_control;
 
 	return 0;
 
@@ -763,10 +763,10 @@ err_alloc_flags:
 	return ret;
 }
 
-static int of_mpc83xx_spi_free_chipselects(struct device *dev)
+static int of_mpc8xxx_spi_free_chipselects(struct device *dev)
 {
 	struct fsl_spi_platform_data *pdata = dev->platform_data;
-	struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata);
+	struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata);
 	int i;
 
 	if (!pinfo->gpios)
@@ -782,12 +782,12 @@ static int of_mpc83xx_spi_free_chipselects(struct device *dev)
 	return 0;
 }
 
-static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev,
+static int __devinit of_mpc8xxx_spi_probe(struct of_device *ofdev,
 					  const struct of_device_id *ofid)
 {
 	struct device *dev = &ofdev->dev;
 	struct device_node *np = ofdev->node;
-	struct mpc83xx_spi_probe_info *pinfo;
+	struct mpc8xxx_spi_probe_info *pinfo;
 	struct fsl_spi_platform_data *pdata;
 	struct spi_master *master;
 	struct resource mem;
@@ -819,7 +819,7 @@ static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev,
 	if (prop && !strcmp(prop, "cpu-qe"))
 		pdata->qe_mode = 1;
 
-	ret = of_mpc83xx_spi_get_chipselects(dev);
+	ret = of_mpc8xxx_spi_get_chipselects(dev);
 	if (ret)
 		goto err;
 
@@ -833,7 +833,7 @@ static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev,
 		goto err;
 	}
 
-	master = mpc83xx_spi_probe(dev, &mem, irq.start);
+	master = mpc8xxx_spi_probe(dev, &mem, irq.start);
 	if (IS_ERR(master)) {
 		ret = PTR_ERR(master);
 		goto err;
@@ -844,34 +844,34 @@ static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev,
 	return 0;
 
 err:
-	of_mpc83xx_spi_free_chipselects(dev);
+	of_mpc8xxx_spi_free_chipselects(dev);
 err_clk:
 	kfree(pinfo);
 	return ret;
 }
 
-static int __devexit of_mpc83xx_spi_remove(struct of_device *ofdev)
+static int __devexit of_mpc8xxx_spi_remove(struct of_device *ofdev)
 {
 	int ret;
 
-	ret = mpc83xx_spi_remove(&ofdev->dev);
+	ret = mpc8xxx_spi_remove(&ofdev->dev);
 	if (ret)
 		return ret;
-	of_mpc83xx_spi_free_chipselects(&ofdev->dev);
+	of_mpc8xxx_spi_free_chipselects(&ofdev->dev);
 	return 0;
 }
 
-static const struct of_device_id of_mpc83xx_spi_match[] = {
+static const struct of_device_id of_mpc8xxx_spi_match[] = {
 	{ .compatible = "fsl,spi" },
 	{},
 };
-MODULE_DEVICE_TABLE(of, of_mpc83xx_spi_match);
+MODULE_DEVICE_TABLE(of, of_mpc8xxx_spi_match);
 
-static struct of_platform_driver of_mpc83xx_spi_driver = {
-	.name		= "mpc83xx_spi",
-	.match_table	= of_mpc83xx_spi_match,
-	.probe		= of_mpc83xx_spi_probe,
-	.remove		= __devexit_p(of_mpc83xx_spi_remove),
+static struct of_platform_driver of_mpc8xxx_spi_driver = {
+	.name		= "mpc8xxx_spi",
+	.match_table	= of_mpc8xxx_spi_match,
+	.probe		= of_mpc8xxx_spi_probe,
+	.remove		= __devexit_p(of_mpc8xxx_spi_remove),
 };
 
 #ifdef CONFIG_MPC832x_RDB
@@ -882,7 +882,7 @@ static struct of_platform_driver of_mpc83xx_spi_driver = {
  * tree can work with OpenFirmware driver. But for now we support old trees
  * as well.
  */
-static int __devinit plat_mpc83xx_spi_probe(struct platform_device *pdev)
+static int __devinit plat_mpc8xxx_spi_probe(struct platform_device *pdev)
 {
 	struct resource *mem;
 	unsigned int irq;
@@ -899,21 +899,21 @@ static int __devinit plat_mpc83xx_spi_probe(struct platform_device *pdev)
 	if (!irq)
 		return -EINVAL;
 
-	master = mpc83xx_spi_probe(&pdev->dev, mem, irq);
+	master = mpc8xxx_spi_probe(&pdev->dev, mem, irq);
 	if (IS_ERR(master))
 		return PTR_ERR(master);
 	return 0;
 }
 
-static int __devexit plat_mpc83xx_spi_remove(struct platform_device *pdev)
+static int __devexit plat_mpc8xxx_spi_remove(struct platform_device *pdev)
 {
-	return mpc83xx_spi_remove(&pdev->dev);
+	return mpc8xxx_spi_remove(&pdev->dev);
 }
 
 MODULE_ALIAS("platform:mpc83xx_spi");
-static struct platform_driver mpc83xx_spi_driver = {
-	.probe = plat_mpc83xx_spi_probe,
-	.remove = __exit_p(plat_mpc83xx_spi_remove),
+static struct platform_driver mpc8xxx_spi_driver = {
+	.probe = plat_mpc8xxx_spi_probe,
+	.remove = __exit_p(plat_mpc8xxx_spi_remove),
 	.driver = {
 		.name = "mpc83xx_spi",
 		.owner = THIS_MODULE,
@@ -924,35 +924,35 @@ static bool legacy_driver_failed;
 
 static void __init legacy_driver_register(void)
 {
-	legacy_driver_failed = platform_driver_register(&mpc83xx_spi_driver);
+	legacy_driver_failed = platform_driver_register(&mpc8xxx_spi_driver);
 }
 
 static void __exit legacy_driver_unregister(void)
 {
 	if (legacy_driver_failed)
 		return;
-	platform_driver_unregister(&mpc83xx_spi_driver);
+	platform_driver_unregister(&mpc8xxx_spi_driver);
 }
 #else
 static void __init legacy_driver_register(void) {}
 static void __exit legacy_driver_unregister(void) {}
 #endif /* CONFIG_MPC832x_RDB */
 
-static int __init mpc83xx_spi_init(void)
+static int __init mpc8xxx_spi_init(void)
 {
 	legacy_driver_register();
-	return of_register_platform_driver(&of_mpc83xx_spi_driver);
+	return of_register_platform_driver(&of_mpc8xxx_spi_driver);
 }
 
-static void __exit mpc83xx_spi_exit(void)
+static void __exit mpc8xxx_spi_exit(void)
 {
-	of_unregister_platform_driver(&of_mpc83xx_spi_driver);
+	of_unregister_platform_driver(&of_mpc8xxx_spi_driver);
 	legacy_driver_unregister();
 }
 
-module_init(mpc83xx_spi_init);
-module_exit(mpc83xx_spi_exit);
+module_init(mpc8xxx_spi_init);
+module_exit(mpc8xxx_spi_exit);
 
 MODULE_AUTHOR("Kumar Gala");
-MODULE_DESCRIPTION("Simple MPC83xx SPI Driver");
+MODULE_DESCRIPTION("Simple MPC8xxx SPI Driver");
 MODULE_LICENSE("GPL");
-- 
1.6.2.2

^ permalink raw reply related

* [PATCH 1/8] powerpc: Remove unused __page_aligned macro.
From: Tim Abbott @ 2009-04-30 23:56 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Denys Vlasenko, Jeff Arnold, Linux kernel mailing list,
	Anders Kaseorg, linuxppc-dev, Paul Mackerras, Tim Abbott,
	Waseem Daher
In-Reply-To: <1241135777-9462-1-git-send-email-tabbott@mit.edu>

Signed-off-by: Tim Abbott <tabbott@mit.edu>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@ozlabs.org
---
 arch/powerpc/include/asm/page_64.h |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
index 043bfdf..20f9c74 100644
--- a/arch/powerpc/include/asm/page_64.h
+++ b/arch/powerpc/include/asm/page_64.h
@@ -152,14 +152,6 @@ do {						\
 
 #endif /* !CONFIG_HUGETLB_PAGE */
 
-#ifdef MODULE
-#define __page_aligned __attribute__((__aligned__(PAGE_SIZE)))
-#else
-#define __page_aligned \
-	__attribute__((__aligned__(PAGE_SIZE), \
-		__section__(".data.page_aligned")))
-#endif
-
 #define VM_DATA_DEFAULT_FLAGS \
 	(test_thread_flag(TIF_32BIT) ? \
 	 VM_DATA_DEFAULT_FLAGS32 : VM_DATA_DEFAULT_FLAGS64)
-- 
1.6.2.1

^ permalink raw reply related

* [PATCH 2/8] powerpc: share .data output section definition between 32 and 64 bits.
From: Tim Abbott @ 2009-04-30 23:56 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Denys Vlasenko, Jeff Arnold, Linux kernel mailing list,
	Anders Kaseorg, linuxppc-dev, Paul Mackerras, Tim Abbott,
	Waseem Daher
In-Reply-To: <1241135777-9462-2-git-send-email-tabbott@mit.edu>

Since upcoming changes will add several more common pieces of code
between the 32-bit and 64-bit powerpc architectures, it seems best to
unify these two blocks.

Signed-off-by: Tim Abbott <tabbott@mit.edu>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@ozlabs.org
---
 arch/powerpc/kernel/vmlinux.lds.S |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index a047a6c..47899b0 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -220,20 +220,19 @@ SECTIONS
 	. = ALIGN(PAGE_SIZE);
 	_sdata = .;
 
-#ifdef CONFIG_PPC32
 	.data : AT(ADDR(.data) - LOAD_OFFSET) {
 		DATA_DATA
+#ifdef CONFIG_PPC32
 		*(.sdata)
 		*(.got.plt) *(.got)
-	}
 #else
-	.data : AT(ADDR(.data) - LOAD_OFFSET) {
-		DATA_DATA
 		*(.data.rel*)
 		*(.toc1)
 		*(.branch_lt)
+#endif
 	}
 
+#ifndef CONFIG_PPC32
 	.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
 		*(.opd)
 	}
-- 
1.6.2.1

^ permalink raw reply related

* [PATCH 0/8] section name cleanup for powerpc
From: Tim Abbott @ 2009-04-30 23:56 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Denys Vlasenko, Jeff Arnold, Linux kernel mailing list,
	Anders Kaseorg, linuxppc-dev, Paul Mackerras, Tim Abbott,
	Waseem Daher

This patch series cleans up the section names on the powerpc
architecture.  It requires the architecture-independent macro
definitions from this patch series:

<http://www.spinics.net/lists/mips/msg33499.html>

The long-term goal here is to add support for building the kernel with
-ffunction-sections -fdata-sections.  This requires renaming all the
magic section names in the kernel of the form .text.foo, .data.foo,
.bss.foo, and .rodata.foo to not have collisions with sections
generated for code like:

static int nosave = 0; /* -fdata-sections places in .data.nosave */
static void head(); /* -ffunction-sections places in .text.head */

Note that these patches have not been boot-tested (aside from testing
the analogous changes on x86), since I don't have access to the
appropriate hardware.

	-Tim Abbott


Tim Abbott (8):
  powerpc: Remove unused __page_aligned macro.
  powerpc: share .data output section definition between 32 and 64
    bits.
  powerpc: Use macros for .data.page_aligned section.
  powerpc: use NOSAVE_DATA macro for .data.nosave section.
  powerpc: use new macro for .data.cacheline_aligned section.
  powerpc: use new macros for .data.init_task.
  powerpc: use new macro for .data.read_mostly section.
  powerpc: convert to new generic read_mostly support.

 arch/powerpc/Kconfig                        |    3 ++
 arch/powerpc/include/asm/cache.h            |    4 --
 arch/powerpc/include/asm/page_64.h          |    8 ----
 arch/powerpc/kernel/init_task.c             |    3 +-
 arch/powerpc/kernel/machine_kexec_64.c      |    4 +-
 arch/powerpc/kernel/vdso.c                  |    3 +-
 arch/powerpc/kernel/vdso32/vdso32_wrapper.S |    3 +-
 arch/powerpc/kernel/vdso64/vdso64_wrapper.S |    3 +-
 arch/powerpc/kernel/vmlinux.lds.S           |   47 ++++++--------------------
 9 files changed, 23 insertions(+), 55 deletions(-)

^ permalink raw reply

* [PATCH 4/8] powerpc: use NOSAVE_DATA macro for .data.nosave section.
From: Tim Abbott @ 2009-04-30 23:56 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Denys Vlasenko, Jeff Arnold, Linux kernel mailing list,
	Anders Kaseorg, linuxppc-dev, Paul Mackerras, Tim Abbott,
	Waseem Daher
In-Reply-To: <1241135777-9462-4-git-send-email-tabbott@mit.edu>

.data.nosave should not need a separate output section; this change
moves it into the .data section.

Signed-off-by: Tim Abbott <tabbott@mit.edu>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@ozlabs.org
---
 arch/powerpc/kernel/vmlinux.lds.S |    9 +--------
 1 files changed, 1 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index d3dcea0..4223892 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -222,6 +222,7 @@ SECTIONS
 
 	.data : AT(ADDR(.data) - LOAD_OFFSET) {
 		PAGE_ALIGNED_DATA
+		NOSAVE_DATA
 		DATA_DATA
 #ifdef CONFIG_PPC32
 		*(.sdata)
@@ -268,14 +269,6 @@ SECTIONS
 		*(.data.read_mostly)
 	}
 
-	. = ALIGN(PAGE_SIZE);
-	.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
-		__nosave_begin = .;
-		*(.data.nosave)
-		. = ALIGN(PAGE_SIZE);
-		__nosave_end = .;
-	}
-
 /*
  * And finally the bss
  */
-- 
1.6.2.1

^ permalink raw reply related

* [PATCH 7/8] powerpc: use new macro for .data.read_mostly section.
From: Tim Abbott @ 2009-04-30 23:56 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Denys Vlasenko, Jeff Arnold, Linux kernel mailing list,
	Anders Kaseorg, linuxppc-dev, Paul Mackerras, Tim Abbott,
	Waseem Daher
In-Reply-To: <1241135777-9462-7-git-send-email-tabbott@mit.edu>

.data.read_mostly should not need a separate output section; this
change moves it into the .data section.

Signed-off-by: Tim Abbott <tabbott@mit.edu>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@ozlabs.org
---
 arch/powerpc/kernel/vmlinux.lds.S |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index f91d7c1..c982827 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -1,3 +1,4 @@
+
 #ifdef CONFIG_PPC64
 #define PROVIDE32(x)	PROVIDE(__unused__##x)
 #else
@@ -227,6 +228,7 @@ SECTIONS
 		PAGE_ALIGNED_DATA
 		NOSAVE_DATA
 		CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
+		READ_MOSTLY_DATA(L1_CACHE_BYTES)
 		DATA_DATA
 #ifdef CONFIG_PPC32
 		*(.sdata)
@@ -254,11 +256,6 @@ SECTIONS
 	_edata  =  .;
 	PROVIDE32 (edata = .);
 
-	. = ALIGN(L1_CACHE_BYTES);
-	.data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
-		*(.data.read_mostly)
-	}
-
 /*
  * And finally the bss
  */
-- 
1.6.2.1

^ permalink raw reply related

* [PATCH 8/8] powerpc: convert to new generic read_mostly support.
From: Tim Abbott @ 2009-04-30 23:56 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Denys Vlasenko, Jeff Arnold, Linux kernel mailing list,
	Anders Kaseorg, linuxppc-dev, Paul Mackerras, Tim Abbott,
	Waseem Daher
In-Reply-To: <1241135777-9462-8-git-send-email-tabbott@mit.edu>

Signed-off-by: Tim Abbott <tabbott@mit.edu>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@ozlabs.org
---
 arch/powerpc/Kconfig             |    3 +++
 arch/powerpc/include/asm/cache.h |    4 ----
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 4c78045..d29ea59 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -32,6 +32,9 @@ config GENERIC_CMOS_UPDATE
 config GENERIC_TIME
 	def_bool y
 
+config HAVE_READ_MOSTLY_DATA
+	def_bool y
+
 config GENERIC_TIME_VSYSCALL
 	def_bool y
 
diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
index 81de6eb..1843a11 100644
--- a/arch/powerpc/include/asm/cache.h
+++ b/arch/powerpc/include/asm/cache.h
@@ -37,9 +37,5 @@ struct ppc64_caches {
 extern struct ppc64_caches ppc64_caches;
 #endif /* __powerpc64__ && ! __ASSEMBLY__ */
 
-#if !defined(__ASSEMBLY__)
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
-#endif
-
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_CACHE_H */
-- 
1.6.2.1

^ permalink raw reply related

* [PATCH 5/8] powerpc: use new macro for .data.cacheline_aligned section.
From: Tim Abbott @ 2009-04-30 23:56 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Denys Vlasenko, Jeff Arnold, Linux kernel mailing list,
	Anders Kaseorg, linuxppc-dev, Paul Mackerras, Tim Abbott,
	Waseem Daher
In-Reply-To: <1241135777-9462-5-git-send-email-tabbott@mit.edu>

.data.cacheline_aligned should not need a separate output section;
this change moves it into the .data section.

Since there isn't an ALIGN() directive before the
.data.cacheline_aligned scetion in the current linker script, I'd like
an ack from one of the powerpc maintainers that L1_CACHE_BYTES is the
correct alignment here.

Signed-off-by: Tim Abbott <tabbott@mit.edu>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@ozlabs.org
---
 arch/powerpc/kernel/vmlinux.lds.S |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 4223892..e769717 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -223,6 +223,7 @@ SECTIONS
 	.data : AT(ADDR(.data) - LOAD_OFFSET) {
 		PAGE_ALIGNED_DATA
 		NOSAVE_DATA
+		CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
 		DATA_DATA
 #ifdef CONFIG_PPC32
 		*(.sdata)
@@ -260,10 +261,6 @@ SECTIONS
 		*(.data.init_task)
 	}
 
-	.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
-		*(.data.cacheline_aligned)
-	}
-
 	. = ALIGN(L1_CACHE_BYTES);
 	.data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
 		*(.data.read_mostly)
-- 
1.6.2.1

^ permalink raw reply related

* [PATCH 3/8] powerpc: Use macros for .data.page_aligned section.
From: Tim Abbott @ 2009-04-30 23:56 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Denys Vlasenko, Jeff Arnold, Linux kernel mailing list,
	Anders Kaseorg, linuxppc-dev, Paul Mackerras, Tim Abbott,
	Waseem Daher
In-Reply-To: <1241135777-9462-3-git-send-email-tabbott@mit.edu>

.data.page_aligned should not need a separate output section, so as
part of this cleanup I moved into the .data output section in the
linker scripts in order to eliminate unnecessary references to the
section name.

Note that this change moves the page-aligned data inside _edata.
Since it _is_ data, I suspect having page-aligned data outside _edata
was a bug.  Please comment if it is not.

Signed-off-by: Tim Abbott <tabbott@mit.edu>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@ozlabs.org
---
 arch/powerpc/kernel/vdso.c                  |    3 ++-
 arch/powerpc/kernel/vdso32/vdso32_wrapper.S |    3 ++-
 arch/powerpc/kernel/vdso64/vdso64_wrapper.S |    3 ++-
 arch/powerpc/kernel/vmlinux.lds.S           |    6 +-----
 4 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index ad06d5c..f075591 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -1,3 +1,4 @@
+
 /*
  *    Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
  *			 <benh@kernel.crashing.org>
@@ -74,7 +75,7 @@ static int vdso_ready;
 static union {
 	struct vdso_data	data;
 	u8			page[PAGE_SIZE];
-} vdso_data_store __attribute__((__section__(".data.page_aligned")));
+} vdso_data_store __page_aligned_data;
 struct vdso_data *vdso_data = &vdso_data_store.data;
 
 /* Format of the patch table */
diff --git a/arch/powerpc/kernel/vdso32/vdso32_wrapper.S b/arch/powerpc/kernel/vdso32/vdso32_wrapper.S
index 556f0ca..6e8f507 100644
--- a/arch/powerpc/kernel/vdso32/vdso32_wrapper.S
+++ b/arch/powerpc/kernel/vdso32/vdso32_wrapper.S
@@ -1,7 +1,8 @@
 #include <linux/init.h>
+#include <linux/linkage.h>
 #include <asm/page.h>
 
-	.section ".data.page_aligned"
+	__PAGE_ALIGNED_DATA
 
 	.globl vdso32_start, vdso32_end
 	.balign PAGE_SIZE
diff --git a/arch/powerpc/kernel/vdso64/vdso64_wrapper.S b/arch/powerpc/kernel/vdso64/vdso64_wrapper.S
index 0529cb9..b8553d6 100644
--- a/arch/powerpc/kernel/vdso64/vdso64_wrapper.S
+++ b/arch/powerpc/kernel/vdso64/vdso64_wrapper.S
@@ -1,7 +1,8 @@
 #include <linux/init.h>
+#include <linux/linkage.h>
 #include <asm/page.h>
 
-	.section ".data.page_aligned"
+	__PAGE_ALIGNED_DATA
 
 	.globl vdso64_start, vdso64_end
 	.balign PAGE_SIZE
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 47899b0..d3dcea0 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -221,6 +221,7 @@ SECTIONS
 	_sdata = .;
 
 	.data : AT(ADDR(.data) - LOAD_OFFSET) {
+		PAGE_ALIGNED_DATA
 		DATA_DATA
 #ifdef CONFIG_PPC32
 		*(.sdata)
@@ -258,11 +259,6 @@ SECTIONS
 		*(.data.init_task)
 	}
 
-	. = ALIGN(PAGE_SIZE);
-	.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
-		*(.data.page_aligned)
-	}
-
 	.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
 		*(.data.cacheline_aligned)
 	}
-- 
1.6.2.1

^ permalink raw reply related

* [PATCH 6/8] powerpc: use new macros for .data.init_task.
From: Tim Abbott @ 2009-04-30 23:56 UTC (permalink / raw)
  To: Sam Ravnborg
  Cc: Denys Vlasenko, Jeff Arnold, Linux kernel mailing list,
	Anders Kaseorg, linuxppc-dev, Paul Mackerras, Tim Abbott,
	Waseem Daher
In-Reply-To: <1241135777-9462-6-git-send-email-tabbott@mit.edu>

.data.init_task should not need a separate output section; this change
moves it into the .data section.

This patch uses THREAD_SIZE rather than 8192/16384 for the alignment.
This should have the effect of increasing the alignment to 32768 if
CONFIG_PPC_256K_PAGES is defined, but it seems that it should be that
way.  One of the powerpc maintainers should confirm that this is
correct, otherwise we can go back to the #ifdef.

Signed-off-by: Tim Abbott <tabbott@mit.edu>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@ozlabs.org
---
 arch/powerpc/kernel/init_task.c        |    3 +--
 arch/powerpc/kernel/machine_kexec_64.c |    4 ++--
 arch/powerpc/kernel/vmlinux.lds.S      |   13 +++----------
 3 files changed, 6 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/kernel/init_task.c b/arch/powerpc/kernel/init_task.c
index 688b329..a4eb25d 100644
--- a/arch/powerpc/kernel/init_task.c
+++ b/arch/powerpc/kernel/init_task.c
@@ -20,8 +20,7 @@ EXPORT_SYMBOL(init_mm);
  * way process stacks are handled. This is done by having a special
  * "init_task" linker map entry..
  */
-union thread_union init_thread_union 
-	__attribute__((__section__(".data.init_task"))) =
+union thread_union init_thread_union __init_task_data =
 		{ INIT_THREAD_INFO(init_task) };
 
 /*
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 49e705f..3761f76 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -10,6 +10,7 @@
  */
 
 
+#include <linux/init_task.h>
 #include <linux/kexec.h>
 #include <linux/smp.h>
 #include <linux/thread_info.h>
@@ -249,8 +250,7 @@ static void kexec_prepare_cpus(void)
  * We could use a smaller stack if we don't care about anything using
  * current, but that audit has not been performed.
  */
-static union thread_union kexec_stack
-	__attribute__((__section__(".data.init_task"))) = { };
+static union thread_union kexec_stack __init_task_data = { };
 
 /* Our assembly helper, in kexec_stub.S */
 extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start,
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index e769717..f91d7c1 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -6,6 +6,7 @@
 #include <asm/page.h>
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/cache.h>
+#include <asm/thread_info.h>
 
 ENTRY(_stext)
 
@@ -221,6 +222,8 @@ SECTIONS
 	_sdata = .;
 
 	.data : AT(ADDR(.data) - LOAD_OFFSET) {
+		/* The initial task and kernel stack */
+		INIT_TASK_DATA(THREAD_SIZE)
 		PAGE_ALIGNED_DATA
 		NOSAVE_DATA
 		CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
@@ -251,16 +254,6 @@ SECTIONS
 	_edata  =  .;
 	PROVIDE32 (edata = .);
 
-	/* The initial task and kernel stack */
-#ifdef CONFIG_PPC32
-	. = ALIGN(8192);
-#else
-	. = ALIGN(16384);
-#endif
-	.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
-		*(.data.init_task)
-	}
-
 	. = ALIGN(L1_CACHE_BYTES);
 	.data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
 		*(.data.read_mostly)
-- 
1.6.2.1

^ permalink raw reply related

* linux-next: galak tree build warning
From: Stephen Rothwell @ 2009-05-01  0:30 UTC (permalink / raw)
  To: Kumar Gala; +Cc: ppc-dev, linux-next

[-- Attachment #1: Type: text/plain, Size: 836 bytes --]

Hi Kumar,

Today's linux-next build (powerpc_ppc64_defconfig) produced these
warnings:

arch/powerpc/platforms/pseries/iommu.c: In function 'pci_dma_bus_setup_pSeries':
arch/powerpc/platforms/pseries/iommu.c:391: warning: format '%lx' expects type 'long unsigned int', but argument 2 has type 'resource_size_t'
arch/powerpc/platforms/pseries/iommu.c:417: warning: format '%lx' expects type 'long unsigned int', but argument 2 has type 'resource_size_t'

Caused by commit 78665c790a654cc2d509df3bf3971cdb102beac9 ("powerpc: make
dma_window_* in pci_controller struct avail on 32b").  resource_size_t
can be 32 or 64 bit depending on platform and config, so it needs to be
cast to (unsigned long long) when printed.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: [PATCH 2/8] powerpc: share .data output section definition between 32 and 64 bits.
From: Michael Ellerman @ 2009-05-01  1:46 UTC (permalink / raw)
  To: Tim Abbott
  Cc: Denys Vlasenko, Jeff Arnold, Linux kernel mailing list,
	Anders Kaseorg, linuxppc-dev, Paul Mackerras, Sam Ravnborg,
	Waseem Daher
In-Reply-To: <1241135777-9462-3-git-send-email-tabbott@mit.edu>

[-- Attachment #1: Type: text/plain, Size: 1284 bytes --]

On Thu, 2009-04-30 at 19:56 -0400, Tim Abbott wrote:
> Since upcoming changes will add several more common pieces of code
> between the 32-bit and 64-bit powerpc architectures, it seems best to
> unify these two blocks.
> 
> Signed-off-by: Tim Abbott <tabbott@mit.edu>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: linuxppc-dev@ozlabs.org
> ---
>  arch/powerpc/kernel/vmlinux.lds.S |    7 +++----
>  1 files changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
> index a047a6c..47899b0 100644
> --- a/arch/powerpc/kernel/vmlinux.lds.S
> +++ b/arch/powerpc/kernel/vmlinux.lds.S
> @@ -220,20 +220,19 @@ SECTIONS
>  	. = ALIGN(PAGE_SIZE);
>  	_sdata = .;
>  
> -#ifdef CONFIG_PPC32
>  	.data : AT(ADDR(.data) - LOAD_OFFSET) {
>  		DATA_DATA
> +#ifdef CONFIG_PPC32
>  		*(.sdata)
>  		*(.got.plt) *(.got)
> -	}
>  #else
> -	.data : AT(ADDR(.data) - LOAD_OFFSET) {
> -		DATA_DATA
>  		*(.data.rel*)
>  		*(.toc1)
>  		*(.branch_lt)
> +#endif
>  	}
>  
> +#ifndef CONFIG_PPC32
>  	.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
>  		*(.opd)
>  	}

This would be clearer in the positive, as in #ifdef CONFIG_PPC64.

cheers

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: [PATCH 2/8] powerpc: share .data output section definition between 32 and 64 bits.
From: Tim Abbott @ 2009-05-01  1:56 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: Denys Vlasenko, Jeff Arnold, Linux kernel mailing list,
	Anders Kaseorg, linuxppc-dev, Paul Mackerras, Sam Ravnborg,
	Waseem Daher
In-Reply-To: <1241142402.6928.7.camel@concordia>

On Fri, 1 May 2009, Michael Ellerman wrote:

> On Thu, 2009-04-30 at 19:56 -0400, Tim Abbott wrote:
> > +#ifndef CONFIG_PPC32
> 
> This would be clearer in the positive, as in #ifdef CONFIG_PPC64.

Good point.  New version below.

	-Tim Abbott

powerpc: share .data output section definition between 32 and 64 bits.

Since upcoming changes will add several more common pieces of code
between the 32-bit and 64-bit powerpc architectures, it seems best to
unify these two blocks.

Signed-off-by: Tim Abbott <tabbott@mit.edu>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@ozlabs.org
---
 arch/powerpc/kernel/vmlinux.lds.S |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index b9ef164..de80f89 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -219,20 +219,19 @@ SECTIONS
 	. = ALIGN(PAGE_SIZE);
 	_sdata = .;
 
-#ifdef CONFIG_PPC32
 	.data : AT(ADDR(.data) - LOAD_OFFSET) {
 		DATA_DATA
+#ifdef CONFIG_PPC32
 		*(.sdata)
 		*(.got.plt) *(.got)
-	}
 #else
-	.data : AT(ADDR(.data) - LOAD_OFFSET) {
-		DATA_DATA
 		*(.data.rel*)
 		*(.toc1)
 		*(.branch_lt)
+#endif
 	}
 
+#ifdef CONFIG_PPC64
 	.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
 		*(.opd)
 	}
-- 
1.6.2.1

^ permalink raw reply related

* Re: [v2 PATCH 1/1] Fix 64bit Maple Host Bridge 'reg' property
From: Benjamin Herrenschmidt @ 2009-05-01  5:02 UTC (permalink / raw)
  To: tiejun.china; +Cc: linuxppc-dev, akpm
In-Reply-To: <1239704021-12431-1-git-send-email-tiejun.china@gamil.com>

On Tue, 2009-04-14 at 18:13 +0800, tiejun.china@gamil.com wrote:
> In the DTB tree created by firmware on some Maple 64bit targets, such as ATCA6101, 
> the "reg" property of host bridge node is incorrectly encoded as if #address-cells 
> and #size-cells were 1. So we have to provide one fixup function to fix that.
> 
> Signed-off-by: Tiejun Chen <tiejun.china@gmail.com>

Almost there :-)

> +	/*  FIXME: This may be used for more Maple targets not only ATCA6101. */
> +	node = call_prom("finddevice", 1, 1, ADDR("/"));
> +	model = prom_getprop(node, "model", prop, sizeof(prop));

Couldn't you use _prom->root above ?

> +	if (model != PROM_ERROR && (strcmp(prop, "Motorola,ATCA-6101") == 0))
> +                fixup_device_tree_atca6101();
>  
>  	name = "/ht@0/isa@4";
>  	isa = call_prom("finddevice", 1, 1, ADDR(name));

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH 1/2] Add support for Designware SATA controller driver
From: Jeff Garzik @ 2009-05-01  7:26 UTC (permalink / raw)
  To: Feng Kan; +Cc: linuxppc-dev, linux-ide
In-Reply-To: <1241042419-19774-1-git-send-email-fkan@amcc.com>

Feng Kan wrote:
> Signed-off-by: Feng Kan <fkan@amcc.com>
> ---
>  drivers/ata/Kconfig    |   76 +-
>  drivers/ata/Makefile   |    1 +
>  drivers/ata/sata_dwc.c | 2047 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 2091 insertions(+), 33 deletions(-)
>  create mode 100644 drivers/ata/sata_dwc.c

I don't see a patch 2/2 ?

^ permalink raw reply

* Multiple NAND chips with 4xx NAND driver
From: Felix Radensky @ 2009-05-01  7:43 UTC (permalink / raw)
  To: linuxppc-dev, Sean MacLennan

Hi,

I will soon have 460EX board with twin die NAND device having
2 chip selects. A comment in ndfc driver says that several NAND
chips are not supported. What should be modified in the driver to
support such configuration ? I'd like to have a separate mtd device
per chip select, and then concatenate them into a single device, which
can later be partitioned. Do ndfc DTS bindings support that ?

Thanks a lot.

Felix.

^ permalink raw reply

* [PATCH] powerpc: fix mktree build error on Mac OS X host
From: Timur Tabi @ 2009-05-01  4:16 UTC (permalink / raw)
  To: linuxppc-dev, galak

The mktree utility defines some variables as "uint", although this is not a
standard C type, and so cross-compiling on Mac OS X fails.  Change this to
"unsigned int".

Signed-off-by: Timur Tabi <timur@freescale.com>
---
 arch/powerpc/boot/mktree.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/boot/mktree.c b/arch/powerpc/boot/mktree.c
index 45d06a8..c2baae0 100644
--- a/arch/powerpc/boot/mktree.c
+++ b/arch/powerpc/boot/mktree.c
@@ -42,7 +42,7 @@ int main(int argc, char *argv[])
 {
 	int	in_fd, out_fd;
 	int	nblks, i;
-	uint	cksum, *cp;
+	unsigned int	cksum, *cp;
 	struct	stat	st;
 	boot_block_t	bt;
 
@@ -90,7 +90,7 @@ int main(int argc, char *argv[])
 
 	cksum = 0;
 	cp = (void *)&bt;
-	for (i=0; i<sizeof(bt)/sizeof(uint); i++)
+	for (i = 0; i < sizeof(bt) / sizeof(unsigned int); i++)
 		cksum += *cp++;
 
 	/* Assume zImage is an ELF file, and skip the 64K header.
@@ -101,7 +101,7 @@ int main(int argc, char *argv[])
 		exit(4);
 	}
 
-	if ((*(uint *)tmpbuf) != htonl(0x7f454c46)) {
+	if ((*(unsigned int *)tmpbuf) != htonl(0x7f454c46)) {
 		fprintf(stderr, "%s is not an ELF image\n", argv[1]);
 		exit(4);
 	}
@@ -125,8 +125,8 @@ int main(int argc, char *argv[])
 			perror("zImage read");
 			exit(5);
 		}
-		cp = (uint *)tmpbuf;
-		for (i=0; i<sizeof(tmpbuf)/sizeof(uint); i++)
+		cp = (unsigned int *)tmpbuf;
+		for (i = 0; i < sizeof(tmpbuf) / sizeof(unsigned int); i++)
 			cksum += *cp++;
 		if (write(out_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) {
 			perror("boot-image write");
-- 
1.6.2.4

^ permalink raw reply related

* Re: [PATCH 1/2] Add support for Designware SATA controller driver
From: Benjamin Herrenschmidt @ 2009-05-01  8:49 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linuxppc-dev, Feng Kan, linux-ide
In-Reply-To: <49FAA434.9040106@garzik.org>

On Fri, 2009-05-01 at 03:26 -0400, Jeff Garzik wrote:
> Feng Kan wrote:
> > Signed-off-by: Feng Kan <fkan@amcc.com>
> > ---
> >  drivers/ata/Kconfig    |   76 +-
> >  drivers/ata/Makefile   |    1 +
> >  drivers/ata/sata_dwc.c | 2047 ++++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 2091 insertions(+), 33 deletions(-)
> >  create mode 100644 drivers/ata/sata_dwc.c
> 
> I don't see a patch 2/2 ?

Patch 2/2 is just adding the device-tree bits to the platform for
this driver to match against, so it's no big deal. However, Feng,
we already mentioned that you do a lot of unrelated changes to the
Kconfig file that shouldn't be part of this patch, just add the
entry for this chip, don't move stuff around in Kconfig, unless I
missed a good reason why this is done that way.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH v2 0/6] macros for section name cleanup
From: Sam Ravnborg @ 2009-05-01  9:04 UTC (permalink / raw)
  To: Tim Abbott
  Cc: linux-mips, linux-m68k, linux-ia64, linux-sh, Denys Vlasenko,
	Greg Ungerer, Jeff Arnold, linuxppc-dev, Paul Mackerras,
	H. Peter Anvin, sparclinux, Waseem Daher, linux-s390,
	Jesper Nilsson, Yoshinori Sato, Helge Deller, Ingo Molnar,
	Geert Uytterhoeven, microblaze-uclinux, Russell King,
	user-mode-linux-devel, Heiko Carstens, Jeff Dike, dev-etrax,
	Mikael Starvik, Cyrill Gorcunov, Michal Simek, Richard Henderson,
	Chris Zankel, Bryan Wu, Tony Luck, linux-parisc,
	Haavard Skinnemoen, Hirokazu Takata, Linux kernel mailing list,
	Ralf Baechle, Anders Kaseorg, Kyle McMartin, Paul Mundt,
	Thomas Gleixner, linux-alpha, Martin Schwidefsky,
	uclinux-dist-devel, Linus Torvalds, David S. Miller
In-Reply-To: <1241121253-32341-1-git-send-email-tabbott@mit.edu>

On Thu, Apr 30, 2009 at 03:54:07PM -0400, Tim Abbott wrote:
> (this patch series differs from v1 only in the CC list; some of the
> architecture lists I sent the previous one to are moderated against
> non-members; all replies should go to this version).
> 
> Here are the architecture-independent macro definitions needed for
> to clean up the kernel's section names.  The overall diffstat from
> this section name cleanup project is:
> 
>  96 files changed, 261 insertions(+), 503 deletions(-)
> 
> The decrease results from removing a lot of redundancy in the linker
> scripts.
> 
> The long-term goal here is to add support for building the kernel with
> -ffunction-sections -fdata-sections.  This requires renaming all the
> magic section names in the kernel of the form .text.foo, .data.foo,
> .bss.foo, and .rodata.foo to not have collisions with sections
> generated for code like:
> 
> static int nosave = 0; /* -fdata-sections places in .data.nosave */
> static void head(); /* -ffunction-sections places in .text.head */
> 
> Sam Ravnborg proposed that rather than just renaming all the sections
> outright, we should start by first getting more control over the
> section names used in the kernel so that we can later rename sections
> without touching too many files.  These patch series implement that
> cleanup.  Later, there will be another patch series to actually rename
> the sections.
> 
> I'm hoping we can get just these macro definitions into 2.6.30 so that
> the arch maintainers don't have to grab the macro definitions for
> their trees while reviewing the patches for 2.6.31.
> 
> Shortly, I'm going to send one patch series for each of the
> architectures updating those architectures to use these new macros
> (and otherwise cleaning up section names on those architectures).

Hi Tim.

We agreed to get the common stuff and one architecture done before
proceeding with the rest.
Please stick to that plan so we avoid patch-bombing lkml + maintainers.

When we have this ready it will be a simple one-patch-per-arch to cover
the rest.

I will comment on your common patches for now.

	Sam

^ permalink raw reply

* Re: [PATCH v2 1/6] Add new macros for page-aligned data and bss sections.
From: Sam Ravnborg @ 2009-05-01  9:18 UTC (permalink / raw)
  To: Tim Abbott
  Cc: linux-mips, linux-m68k, linux-ia64, linux-sh, Denys Vlasenko,
	Greg Ungerer, Jeff Arnold, linuxppc-dev, Paul Mackerras,
	H. Peter Anvin, sparclinux, Waseem Daher, linux-s390,
	Jesper Nilsson, Yoshinori Sato, Helge Deller, Ingo Molnar,
	Geert Uytterhoeven, microblaze-uclinux, Russell King,
	user-mode-linux-devel, Heiko Carstens, Jeff Dike, dev-etrax,
	Mikael Starvik, Cyrill Gorcunov, Michal Simek, Richard Henderson,
	Chris Zankel, Bryan Wu, Tony Luck, linux-parisc,
	Haavard Skinnemoen, Hirokazu Takata, Linux kernel mailing list,
	Ralf Baechle, Anders Kaseorg, Kyle McMartin, Paul Mundt,
	Thomas Gleixner, linux-alpha, Martin Schwidefsky,
	uclinux-dist-devel, Linus Torvalds, David S. Miller
In-Reply-To: <1241121253-32341-2-git-send-email-tabbott@mit.edu>

On Thu, Apr 30, 2009 at 03:54:08PM -0400, Tim Abbott wrote:
> This patch is preparation for replacing most uses of
> ".bss.page_aligned" and ".data.page_aligned" in the kernel with
> macros, so that the section name can later be changed without having
> to touch a lot of the kernel.
> 
> The long-term goal here is to be able to change the kernel's magic
> section names to those that are compatible with -ffunction-sections
> -fdata-sections.  This requires renaming all magic sections with names
> of the form ".data.foo".
> 
> Signed-off-by: Tim Abbott <tabbott@mit.edu>
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Acked-by: David Howells <dhowells@redhat.com>
> ---
>  include/asm-generic/vmlinux.lds.h |    8 ++++++++
>  include/linux/linkage.h           |    9 +++++++++
>  2 files changed, 17 insertions(+), 0 deletions(-)
> 
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index 89853bc..3d88c87 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -116,6 +116,14 @@
>  	FTRACE_EVENTS()							\
>  	TRACE_SYSCALLS()
>  
> +#define PAGE_ALIGNED_DATA						\
> +	. = ALIGN(PAGE_SIZE);						\
> +	*(.data.page_aligned)
> +
> +#define PAGE_ALIGNED_BSS						\
> +	. = ALIGN(PAGE_SIZE);						\
> +	*(.bss.page_aligned)
> +
>  #define RO_DATA(align)							\
>  	. = ALIGN((align));						\
>  	.rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {		\
> diff --git a/include/linux/linkage.h b/include/linux/linkage.h
> index fee9e59..af051fc 100644
> --- a/include/linux/linkage.h
> +++ b/include/linux/linkage.h
> @@ -22,6 +22,15 @@
>  #define __page_aligned_bss	__section(.bss.page_aligned) __aligned(PAGE_SIZE)
>  
>  /*
> + * For assembly routines.
> + *
> + * Note when using these that you must specify the appropriate
> + * alignment directives yourself
> + */
> +#define __PAGE_ALIGNED_DATA	.section ".data.page_aligned", "aw", @progbits
> +#define __PAGE_ALIGNED_BSS	.section ".bss.page_aligned", "aw", @nobits

The above will work on most architectures but fails (silently?) on arm.
arm uses %{progbits,nobits} where all other uses @{nobits,progbits}.

I know we do not use page_aligned in arm assembler code for now,
but if we do then it should work.
It is my understanding that the linker will automatically
assume nobits for section names starting with .bss and likewise
progbits for section names starting with .data - so we can leave them out?


	Sam

^ permalink raw reply

* Re: [PATCH v2 2/6] Add new NOSAVE_DATA linker script macro.
From: Sam Ravnborg @ 2009-05-01  9:21 UTC (permalink / raw)
  To: Tim Abbott
  Cc: linux-mips, linux-m68k, linux-ia64, linux-sh, Denys Vlasenko,
	Greg Ungerer, Jeff Arnold, linuxppc-dev, Paul Mackerras,
	H. Peter Anvin, sparclinux, Waseem Daher, linux-s390,
	Jesper Nilsson, Yoshinori Sato, Helge Deller, Ingo Molnar,
	Geert Uytterhoeven, microblaze-uclinux, Russell King,
	user-mode-linux-devel, Heiko Carstens, Jeff Dike, dev-etrax,
	Mikael Starvik, Cyrill Gorcunov, Michal Simek, Richard Henderson,
	Chris Zankel, Bryan Wu, Tony Luck, linux-parisc,
	Haavard Skinnemoen, Hirokazu Takata, Linux kernel mailing list,
	Ralf Baechle, Anders Kaseorg, Kyle McMartin, Paul Mundt,
	Thomas Gleixner, linux-alpha, Martin Schwidefsky,
	uclinux-dist-devel, Linus Torvalds, David S. Miller
In-Reply-To: <1241121253-32341-3-git-send-email-tabbott@mit.edu>

On Thu, Apr 30, 2009 at 03:54:09PM -0400, Tim Abbott wrote:
> This patch is preparation for replacing most ".data.nosave" in the
> kernel with macros, so that the section name can later be changed
> without having to touch a lot of the kernel.
> 
> The long-term goal here is to be able to change the kernel's magic
> section names to those that are compatible with -ffunction-sections
> -fdata-sections.  This requires renaming all magic sections with names
> of the form ".data.foo".
> 
> Signed-off-by: Tim Abbott <tabbott@mit.edu>
> Cc: Sam Ravnborg <sam@ravnborg.org>
> ---
>  include/asm-generic/vmlinux.lds.h |    7 +++++++
>  1 files changed, 7 insertions(+), 0 deletions(-)
> 
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index 3d88c87..f5ebd2b 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -124,6 +124,13 @@
>  	. = ALIGN(PAGE_SIZE);						\
>  	*(.bss.page_aligned)
>  
> +#define NOSAVE_DATA							\
> +	. = ALIGN(PAGE_SIZE);						\
> +	__nosave_begin = .;						\
> +	*(.data.nosave)							\
> +	. = ALIGN(PAGE_SIZE);						\
> +	__nosave_end = .;
> +

You need to use:
	VMLINUX_SYMBOL(__nosave_begin) = .;

Otherwise architectures such as m68k wil break as they
add a leading underscore.

See other symbols that is defined inside vmlinux.lds.h

	Sam

^ permalink raw reply

* Re: [PATCH 6/6] Add support for __read_mostly to linux/cache.h
From: Sam Ravnborg @ 2009-05-01  9:44 UTC (permalink / raw)
  To: Tim Abbott, Christoph Lameter
  Cc: linux-mips, linux-m68k, linux-ia64, linux-sh, Denys Vlasenko,
	Greg Ungerer, Jeff Arnold, linuxppc-dev, Paul Mackerras,
	H. Peter Anvin, sparclinux, Waseem Daher, linux-arm-kernel,
	linux-s390, Jesper Nilsson, linux-am33-list, Yoshinori Sato,
	Helge Deller, Ingo Molnar, Geert Uytterhoeven, microblaze-uclinux,
	Russell King, user-mode-linux-devel, Heiko Carstens, Jeff Dike,
	dev-etrax, Mikael Starvik, Tony Luck, Cyrill Gorcunov,
	Michal Simek, Richard Henderson, Chris Zankel, Bryan Wu,
	linux-m32r, linux-parisc, Haavard Skinnemoen, Hirokazu Takata,
	Ralf Baechle, Anders Kaseorg, Kyle McMartin, Paul Mundt,
	Thomas Gleixner, linux-alpha, Martin Schwidefsky,
	uclinux-dist-devel, Linus Torvalds, David S. Miller
In-Reply-To: <1241119956-31453-7-git-send-email-tabbott@mit.edu>

On Thu, Apr 30, 2009 at 03:32:36PM -0400, Tim Abbott wrote:
> Signed-off-by: Tim Abbott <tabbott@mit.edu>
> ---
>  include/linux/cache.h |    6 ++++++
>  1 files changed, 6 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/cache.h b/include/linux/cache.h
> index 97e2488..99d8a6f 100644
> --- a/include/linux/cache.h
> +++ b/include/linux/cache.h
> @@ -13,7 +13,13 @@
>  #endif
>  
>  #ifndef __read_mostly
> +#ifdef CONFIG_HAVE_READ_MOSTLY_DATA
> +#define __read_mostly __attribute__((__section__(".data.read_mostly")))
> +#define __READ_MOSTLY .section ".data.read_mostly", "aw"
> +#else
>  #define __read_mostly
> +#define __READ_MOSTLY
> +#endif /* CONFIG_HAVE_READ_MOSTLY_DATA */
>  #endif

Are there any specific reason why we do not support read_mostly on all
architectures?

read_mostly is about grouping rarely written data together
so what is needed is to introduce this section in the remaining
archtectures.

Christoph - git log says you did the inital implmentation.
Do you agree?

	Sam

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox