aboutsummaryrefslogtreecommitdiffstats
path: root/driver
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-05-17 09:15:06 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2006-05-17 09:15:06 -0700
commit0dc51fce3ada84fe5d191d48489b50f5b927e687 (patch)
tree21d0697136a47460fa57a1fe0098a4020b58b1e4 /driver
parentf0e3ae84732e61fe198a11197b7d0bef9952a6c5 (diff)
downloadpatches-0dc51fce3ada84fe5d191d48489b50f5b927e687.tar.gz
refresh to 2.6.17-rc4-git4
Also move base file to version
Diffstat (limited to 'driver')
-rw-r--r--driver/spi-add-david-as-the-spi-subsystem-maintainer.patch33
-rw-r--r--driver/spi-add-pxa2xx-ssp-spi-driver.patch1773
-rw-r--r--driver/spi-busnum-0-needs-to-work.patch121
-rw-r--r--driver/spi-devices-can-require-lsb-first-encodings.patch79
-rw-r--r--driver/spi-per-transfer-overrides-for-wordsize-and-clocking.patch223
-rw-r--r--driver/spi-renamed-bitbang_transfer_setup-to-spi_bitbang_setup_transfer-and-export-it.patch72
-rw-r--r--driver/spi-spi-bounce-buffer-has-a-minimum-length.patch30
-rw-r--r--driver/spi-spi-whitespace-fixes.patch86
-rw-r--r--driver/spi-spi_bitbang-clocking-fixes.patch90
-rw-r--r--driver/spi-update-to-pxa2xx-spi-driver.patch202
-rw-r--r--driver/sysfs-crash-debugging.patch2
11 files changed, 1 insertions, 2710 deletions
diff --git a/driver/spi-add-david-as-the-spi-subsystem-maintainer.patch b/driver/spi-add-david-as-the-spi-subsystem-maintainer.patch
deleted file mode 100644
index 16cf37ca28728..0000000000000
--- a/driver/spi-add-david-as-the-spi-subsystem-maintainer.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From galak@kernel.crashing.org Sun Apr 2 14:07:08 2006
-Date: Sun, 2 Apr 2006 16:05:54 -0500 (CDT)
-From: Kumar Gala <galak@kernel.crashing.org>
-To: david-b@pacbell.net
-cc: <spi-devel-general@lists.sourceforge.net>, Greg KH <greg@kroah.com>, Andrew Morton <akpm@osdl.org>
-Subject: SPI: Add David as the SPI subsystem maintainer
-Message-ID: <Pine.LNX.4.44.0604021605160.9478-100000@gate.crashing.org>
-
-Add David as the SPI subsystem maintainer
-
-Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
-
----
- MAINTAINERS | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- gregkh-2.6.orig/MAINTAINERS
-+++ gregkh-2.6/MAINTAINERS
-@@ -2518,6 +2518,12 @@ M: perex@suse.cz
- L: alsa-devel@alsa-project.org
- S: Maintained
-
-+SPI SUBSYSTEM
-+P: David Brownell
-+M: dbrownell@users.sourceforge.net
-+L: spi-devel-general@lists.sourceforge.net
-+S: Maintained
-+
- TPM DEVICE DRIVER
- P: Kylene Hall
- M: kjhall@us.ibm.com
diff --git a/driver/spi-add-pxa2xx-ssp-spi-driver.patch b/driver/spi-add-pxa2xx-ssp-spi-driver.patch
deleted file mode 100644
index d8ebcc7d25c07..0000000000000
--- a/driver/spi-add-pxa2xx-ssp-spi-driver.patch
+++ /dev/null
@@ -1,1773 +0,0 @@
-From akpm@osdl.org Tue Mar 7 23:55:21 2006
-From: Stephen Street <stephen@streetfiresound.com>
-Message-Id: <200603080755.k287tDU7001158@shell0.pdx.osdl.net>
-Subject: SPI: add PXA2xx SSP SPI Driver
-To: greg@kroah.com
-Cc: akpm@osdl.org, stephen@streetfiresound.com
-Date: Tue, 07 Mar 2006 23:53:24 -0800
-
-
-From: Stephen Street <stephen@streetfiresound.com>
-
-This driver turns a PXA2xx synchronous serial port (SSP) into a SPI master
-controller (see Documentation/spi/spi_summary). The driver has the following
-features:
-
-- Support for any PXA2xx SSP
-- SSP PIO and SSP DMA data transfers.
-- External and Internal (SSPFRM) chip selects.
-- Per slave device (chip) configuration.
-- Full suspend, freeze, resume support.
-
-Signed-off-by: Stephen Street <stephen@streetfiresound.com>
-Signed-off-by: Andrew Morton <akpm@osdl.org>
-Cc: David Brownell <david-b@pacbell.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
----
-
-
----
- Documentation/spi/pxa2xx | 234 +++++
- drivers/spi/Kconfig | 8
- drivers/spi/Makefile | 1
- drivers/spi/pxa2xx_spi.c | 1399 ++++++++++++++++++++++++++++++++++
- include/asm-arm/arch-pxa/pxa2xx_spi.h | 68 +
- 5 files changed, 1710 insertions(+)
-
---- /dev/null
-+++ gregkh-2.6/Documentation/spi/pxa2xx
-@@ -0,0 +1,234 @@
-+PXA2xx SPI on SSP driver HOWTO
-+===================================================
-+This a mini howto on the pxa2xx_spi driver. The driver turns a PXA2xx
-+synchronous serial port into a SPI master controller
-+(see Documentation/spi/spi_summary). The driver has the following features
-+
-+- Support for any PXA2xx SSP
-+- SSP PIO and SSP DMA data transfers.
-+- External and Internal (SSPFRM) chip selects.
-+- Per slave device (chip) configuration.
-+- Full suspend, freeze, resume support.
-+
-+The driver is built around a "spi_message" fifo serviced by workqueue and a
-+tasklet. The workqueue, "pump_messages", drives message fifo and the tasklet
-+(pump_transfer) is responsible for queuing SPI transactions and setting up and
-+launching the dma/interrupt driven transfers.
-+
-+Declaring PXA2xx Master Controllers
-+-----------------------------------
-+Typically a SPI master is defined in the arch/.../mach-*/board-*.c as a
-+"platform device". The master configuration is passed to the driver via a table
-+found in include/asm-arm/arch-pxa/pxa2xx_spi.h:
-+
-+struct pxa2xx_spi_master {
-+ enum pxa_ssp_type ssp_type;
-+ u32 clock_enable;
-+ u16 num_chipselect;
-+ u8 enable_dma;
-+};
-+
-+The "pxa2xx_spi_master.ssp_type" field must have a value between 1 and 3 and
-+informs the driver which features a particular SSP supports.
-+
-+The "pxa2xx_spi_master.clock_enable" field is used to enable/disable the
-+corresponding SSP peripheral block in the "Clock Enable Register (CKEN"). See
-+the "PXA2xx Developer Manual" section "Clocks and Power Management".
-+
-+The "pxa2xx_spi_master.num_chipselect" field is used to determine the number of
-+slave device (chips) attached to this SPI master.
-+
-+The "pxa2xx_spi_master.enable_dma" field informs the driver that SSP DMA should
-+be used. This caused the driver to acquire two DMA channels: rx_channel and
-+tx_channel. The rx_channel has a higher DMA service priority the tx_channel.
-+See the "PXA2xx Developer Manual" section "DMA Controller".
-+
-+NSSP MASTER SAMPLE
-+------------------
-+Below is a sample configuration using the PXA255 NSSP.
-+
-+static struct resource pxa_spi_nssp_resources[] = {
-+ [0] = {
-+ .start = __PREG(SSCR0_P(2)), /* Start address of NSSP */
-+ .end = __PREG(SSCR0_P(2)) + 0x2c, /* Range of registers */
-+ .flags = IORESOURCE_MEM,
-+ },
-+ [1] = {
-+ .start = IRQ_NSSP, /* NSSP IRQ */
-+ .end = IRQ_NSSP,
-+ .flags = IORESOURCE_IRQ,
-+ },
-+};
-+
-+static struct pxa2xx_spi_master pxa_nssp_master_info = {
-+ .ssp_type = PXA25x_NSSP, /* Type of SSP */
-+ .clock_enable = CKEN9_NSSP, /* NSSP Peripheral clock */
-+ .num_chipselect = 1, /* Matches the number of chips attached to NSSP */
-+ .enable_dma = 1, /* Enables NSSP DMA */
-+};
-+
-+static struct platform_device pxa_spi_nssp = {
-+ .name = "pxa2xx-spi", /* MUST BE THIS VALUE, so device match driver */
-+ .id = 2, /* Bus number, MUST MATCH SSP number 1..n */
-+ .resource = pxa_spi_nssp_resources,
-+ .num_resources = ARRAY_SIZE(pxa_spi_nssp_resources),
-+ .dev = {
-+ .platform_data = &pxa_nssp_master_info, /* Passed to driver */
-+ },
-+};
-+
-+static struct platform_device *devices[] __initdata = {
-+ &pxa_spi_nssp,
-+};
-+
-+static void __init board_init(void)
-+{
-+ (void)platform_add_device(devices, ARRAY_SIZE(devices));
-+}
-+
-+Declaring Slave Devices
-+-----------------------
-+Typically each SPI slave (chip) is defined in the arch/.../mach-*/board-*.c
-+using the "spi_board_info" structure found in "linux/spi/spi.h". See
-+"Documentation/spi/spi_summary" for additional information.
-+
-+Each slave device attached to the PXA must provide slave specific configuration
-+information via the structure "pxa2xx_spi_chip" found in
-+"include/asm-arm/arch-pxa/pxa2xx_spi.h". The pxa2xx_spi master controller driver
-+will uses the configuration whenever the driver communicates with the slave
-+device.
-+
-+struct pxa2xx_spi_chip {
-+ u8 tx_threshold;
-+ u8 rx_threshold;
-+ u8 dma_burst_size;
-+ u32 timeout_microsecs;
-+ u8 enable_loopback;
-+ void (*cs_control)(u32 command);
-+};
-+
-+The "pxa2xx_spi_chip.tx_threshold" and "pxa2xx_spi_chip.rx_threshold" fields are
-+used to configure the SSP hardware fifo. These fields are critical to the
-+performance of pxa2xx_spi driver and misconfiguration will result in rx
-+fifo overruns (especially in PIO mode transfers). Good default values are
-+
-+ .tx_threshold = 12,
-+ .rx_threshold = 4,
-+
-+The "pxa2xx_spi_chip.dma_burst_size" field is used to configure PXA2xx DMA
-+engine and is related the "spi_device.bits_per_word" field. Read and understand
-+the PXA2xx "Developer Manual" sections on the DMA controller and SSP Controllers
-+to determine the correct value. An SSP configured for byte-wide transfers would
-+use a value of 8.
-+
-+The "pxa2xx_spi_chip.timeout_microsecs" fields is used to efficiently handle
-+trailing bytes in the SSP receiver fifo. The correct value for this field is
-+dependent on the SPI bus speed ("spi_board_info.max_speed_hz") and the specific
-+slave device. Please note the the PXA2xx SSP 1 does not support trailing byte
-+timeouts and must busy-wait any trailing bytes.
-+
-+The "pxa2xx_spi_chip.enable_loopback" field is used to place the SSP porting
-+into internal loopback mode. In this mode the SSP controller internally
-+connects the SSPTX pin the the SSPRX pin. This is useful for initial setup
-+testing.
-+
-+The "pxa2xx_spi_chip.cs_control" field is used to point to a board specific
-+function for asserting/deasserting a slave device chip select. If the field is
-+NULL, the pxa2xx_spi master controller driver assumes that the SSP port is
-+configured to use SSPFRM instead.
-+
-+NSSP SALVE SAMPLE
-+-----------------
-+The pxa2xx_spi_chip structure is passed to the pxa2xx_spi driver in the
-+"spi_board_info.controller_data" field. Below is a sample configuration using
-+the PXA255 NSSP.
-+
-+/* Chip Select control for the CS8415A SPI slave device */
-+static void cs8415a_cs_control(u32 command)
-+{
-+ if (command & PXA2XX_CS_ASSERT)
-+ GPCR(2) = GPIO_bit(2);
-+ else
-+ GPSR(2) = GPIO_bit(2);
-+}
-+
-+/* Chip Select control for the CS8405A SPI slave device */
-+static void cs8405a_cs_control(u32 command)
-+{
-+ if (command & PXA2XX_CS_ASSERT)
-+ GPCR(3) = GPIO_bit(3);
-+ else
-+ GPSR(3) = GPIO_bit(3);
-+}
-+
-+static struct pxa2xx_spi_chip cs8415a_chip_info = {
-+ .tx_threshold = 12, /* SSP hardward FIFO threshold */
-+ .rx_threshold = 4, /* SSP hardward FIFO threshold */
-+ .dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */
-+ .timeout_microsecs = 64, /* Wait at least 64usec to handle trailing */
-+ .cs_control = cs8415a_cs_control, /* Use external chip select */
-+};
-+
-+static struct pxa2xx_spi_chip cs8405a_chip_info = {
-+ .tx_threshold = 12, /* SSP hardward FIFO threshold */
-+ .rx_threshold = 4, /* SSP hardward FIFO threshold */
-+ .dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */
-+ .timeout_microsecs = 64, /* Wait at least 64usec to handle trailing */
-+ .cs_control = cs8405a_cs_control, /* Use external chip select */
-+};
-+
-+static struct spi_board_info streetracer_spi_board_info[] __initdata = {
-+ {
-+ .modalias = "cs8415a", /* Name of spi_driver for this device */
-+ .max_speed_hz = 3686400, /* Run SSP as fast a possbile */
-+ .bus_num = 2, /* Framework bus number */
-+ .chip_select = 0, /* Framework chip select */
-+ .platform_data = NULL; /* No spi_driver specific config */
-+ .controller_data = &cs8415a_chip_info, /* Master chip config */
-+ .irq = STREETRACER_APCI_IRQ, /* Slave device interrupt */
-+ },
-+ {
-+ .modalias = "cs8405a", /* Name of spi_driver for this device */
-+ .max_speed_hz = 3686400, /* Run SSP as fast a possbile */
-+ .bus_num = 2, /* Framework bus number */
-+ .chip_select = 1, /* Framework chip select */
-+ .controller_data = &cs8405a_chip_info, /* Master chip config */
-+ .irq = STREETRACER_APCI_IRQ, /* Slave device interrupt */
-+ },
-+};
-+
-+static void __init streetracer_init(void)
-+{
-+ spi_register_board_info(streetracer_spi_board_info,
-+ ARRAY_SIZE(streetracer_spi_board_info));
-+}
-+
-+
-+DMA and PIO I/O Support
-+-----------------------
-+The pxa2xx_spi driver support both DMA and interrupt driven PIO message
-+transfers. The driver defaults to PIO mode and DMA transfers must enabled by
-+setting the "enable_dma" flag in the "pxa2xx_spi_master" structure and and
-+ensuring that the "pxa2xx_spi_chip.dma_burst_size" field is non-zero. The DMA
-+mode support both coherent and stream based DMA mappings.
-+
-+The following logic is used to determine the type of I/O to be used on
-+a per "spi_transfer" basis:
-+
-+if !enable_dma or dma_burst_size == 0 then
-+ always use PIO transfers
-+
-+if spi_message.is_dma_mapped and rx_dma_buf != 0 and tx_dma_buf != 0 then
-+ use coherent DMA mode
-+
-+if rx_buf and tx_buf are aligned on 8 byte boundary then
-+ use streaming DMA mode
-+
-+otherwise
-+ use PIO transfer
-+
-+THANKS TO
-+---------
-+
-+David Brownell and others for mentoring the development of this driver.
-+
---- gregkh-2.6.orig/drivers/spi/Kconfig
-+++ gregkh-2.6/drivers/spi/Kconfig
-@@ -75,6 +75,14 @@ config SPI_BUTTERFLY
- inexpensive battery powered microcontroller evaluation board.
- This same cable can be used to flash new firmware.
-
-+config SPI_PXA2XX
-+ tristate "PXA2xx SSP SPI master"
-+ depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL
-+ help
-+ This enables using a PXA2xx SSP port as a SPI master controller.
-+ The driver can be configured to use any SSP port and additional
-+ documentation can be found a Documentation/spi/pxa2xx.
-+
- #
- # Add new SPI master controllers in alphabetical order above this line
- #
---- gregkh-2.6.orig/drivers/spi/Makefile
-+++ gregkh-2.6/drivers/spi/Makefile
-@@ -13,6 +13,7 @@ obj-$(CONFIG_SPI_MASTER) += spi.o
- # SPI master controller drivers (bus)
- obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
- obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
-+obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
- # ... add above this line ...
-
- # SPI protocol drivers (device/link on bus)
---- /dev/null
-+++ gregkh-2.6/drivers/spi/pxa2xx_spi.c
-@@ -0,0 +1,1399 @@
-+/*
-+ * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs
-+ *
-+ * 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.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/device.h>
-+#include <linux/ioport.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+#include <linux/platform_device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/spi/spi.h>
-+#include <linux/workqueue.h>
-+#include <linux/errno.h>
-+#include <linux/delay.h>
-+
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+#include <asm/delay.h>
-+#include <asm/dma.h>
-+
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/pxa-regs.h>
-+#include <asm/arch/pxa2xx_spi.h>
-+
-+MODULE_AUTHOR("Stephen Street");
-+MODULE_DESCRIPTION("PXA2xx SSP SPI Contoller");
-+MODULE_LICENSE("GPL");
-+
-+#define MAX_BUSES 3
-+
-+#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
-+#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
-+#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
-+
-+#define DEFINE_SSP_REG(reg, off) \
-+static inline u32 read_##reg(void *p) { return __raw_readl(p + (off)); } \
-+static inline void write_##reg(u32 v, void *p) { __raw_writel(v, p + (off)); }
-+
-+DEFINE_SSP_REG(SSCR0, 0x00)
-+DEFINE_SSP_REG(SSCR1, 0x04)
-+DEFINE_SSP_REG(SSSR, 0x08)
-+DEFINE_SSP_REG(SSITR, 0x0c)
-+DEFINE_SSP_REG(SSDR, 0x10)
-+DEFINE_SSP_REG(SSTO, 0x28)
-+DEFINE_SSP_REG(SSPSP, 0x2c)
-+
-+#define START_STATE ((void*)0)
-+#define RUNNING_STATE ((void*)1)
-+#define DONE_STATE ((void*)2)
-+#define ERROR_STATE ((void*)-1)
-+
-+#define QUEUE_RUNNING 0
-+#define QUEUE_STOPPED 1
-+
-+struct driver_data {
-+ /* Driver model hookup */
-+ struct platform_device *pdev;
-+
-+ /* SPI framework hookup */
-+ enum pxa_ssp_type ssp_type;
-+ struct spi_master *master;
-+
-+ /* PXA hookup */
-+ struct pxa2xx_spi_master *master_info;
-+
-+ /* DMA setup stuff */
-+ int rx_channel;
-+ int tx_channel;
-+ u32 *null_dma_buf;
-+
-+ /* SSP register addresses */
-+ void *ioaddr;
-+ u32 ssdr_physical;
-+
-+ /* SSP masks*/
-+ u32 dma_cr1;
-+ u32 int_cr1;
-+ u32 clear_sr;
-+ u32 mask_sr;
-+
-+ /* Driver message queue */
-+ struct workqueue_struct *workqueue;
-+ struct work_struct pump_messages;
-+ spinlock_t lock;
-+ struct list_head queue;
-+ int busy;
-+ int run;
-+
-+ /* Message Transfer pump */
-+ struct tasklet_struct pump_transfers;
-+
-+ /* Current message transfer state info */
-+ struct spi_message* cur_msg;
-+ struct spi_transfer* cur_transfer;
-+ struct chip_data *cur_chip;
-+ size_t len;
-+ void *tx;
-+ void *tx_end;
-+ void *rx;
-+ void *rx_end;
-+ int dma_mapped;
-+ dma_addr_t rx_dma;
-+ dma_addr_t tx_dma;
-+ size_t rx_map_len;
-+ size_t tx_map_len;
-+ int cs_change;
-+ void (*write)(struct driver_data *drv_data);
-+ void (*read)(struct driver_data *drv_data);
-+ irqreturn_t (*transfer_handler)(struct driver_data *drv_data);
-+ void (*cs_control)(u32 command);
-+};
-+
-+struct chip_data {
-+ u32 cr0;
-+ u32 cr1;
-+ u32 to;
-+ u32 psp;
-+ u32 timeout;
-+ u8 n_bytes;
-+ u32 dma_width;
-+ u32 dma_burst_size;
-+ u32 threshold;
-+ u32 dma_threshold;
-+ u8 enable_dma;
-+ void (*write)(struct driver_data *drv_data);
-+ void (*read)(struct driver_data *drv_data);
-+ void (*cs_control)(u32 command);
-+};
-+
-+static void pump_messages(void *data);
-+
-+static int flush(struct driver_data *drv_data)
-+{
-+ unsigned long limit = loops_per_jiffy << 1;
-+
-+ void *reg = drv_data->ioaddr;
-+
-+ do {
-+ while (read_SSSR(reg) & SSSR_RNE) {
-+ read_SSDR(reg);
-+ }
-+ } while ((read_SSSR(reg) & SSSR_BSY) && limit--);
-+ write_SSSR(SSSR_ROR, reg);
-+
-+ return limit;
-+}
-+
-+static void restore_state(struct driver_data *drv_data)
-+{
-+ void *reg = drv_data->ioaddr;
-+
-+ /* Clear status and disable clock */
-+ write_SSSR(drv_data->clear_sr, reg);
-+ write_SSCR0(drv_data->cur_chip->cr0 & ~SSCR0_SSE, reg);
-+
-+ /* Load the registers */
-+ write_SSCR1(drv_data->cur_chip->cr1, reg);
-+ write_SSCR0(drv_data->cur_chip->cr0, reg);
-+ if (drv_data->ssp_type != PXA25x_SSP) {
-+ write_SSTO(0, reg);
-+ write_SSPSP(drv_data->cur_chip->psp, reg);
-+ }
-+}
-+
-+static void null_cs_control(u32 command)
-+{
-+}
-+
-+static void null_writer(struct driver_data *drv_data)
-+{
-+ void *reg = drv_data->ioaddr;
-+ u8 n_bytes = drv_data->cur_chip->n_bytes;
-+
-+ while ((read_SSSR(reg) & SSSR_TNF)
-+ && (drv_data->tx < drv_data->tx_end)) {
-+ write_SSDR(0, reg);
-+ drv_data->tx += n_bytes;
-+ }
-+}
-+
-+static void null_reader(struct driver_data *drv_data)
-+{
-+ void *reg = drv_data->ioaddr;
-+ u8 n_bytes = drv_data->cur_chip->n_bytes;
-+
-+ while ((read_SSSR(reg) & SSSR_RNE)
-+ && (drv_data->rx < drv_data->rx_end)) {
-+ read_SSDR(reg);
-+ drv_data->rx += n_bytes;
-+ }
-+}
-+
-+static void u8_writer(struct driver_data *drv_data)
-+{
-+ void *reg = drv_data->ioaddr;
-+
-+ while ((read_SSSR(reg) & SSSR_TNF)
-+ && (drv_data->tx < drv_data->tx_end)) {
-+ write_SSDR(*(u8 *)(drv_data->tx), reg);
-+ ++drv_data->tx;
-+ }
-+}
-+
-+static void u8_reader(struct driver_data *drv_data)
-+{
-+ void *reg = drv_data->ioaddr;
-+
-+ while ((read_SSSR(reg) & SSSR_RNE)
-+ && (drv_data->rx < drv_data->rx_end)) {
-+ *(u8 *)(drv_data->rx) = read_SSDR(reg);
-+ ++drv_data->rx;
-+ }
-+}
-+
-+static void u16_writer(struct driver_data *drv_data)
-+{
-+ void *reg = drv_data->ioaddr;
-+
-+ while ((read_SSSR(reg) & SSSR_TNF)
-+ && (drv_data->tx < drv_data->tx_end)) {
-+ write_SSDR(*(u16 *)(drv_data->tx), reg);
-+ drv_data->tx += 2;
-+ }
-+}
-+
-+static void u16_reader(struct driver_data *drv_data)
-+{
-+ void *reg = drv_data->ioaddr;
-+
-+ while ((read_SSSR(reg) & SSSR_RNE)
-+ && (drv_data->rx < drv_data->rx_end)) {
-+ *(u16 *)(drv_data->rx) = read_SSDR(reg);
-+ drv_data->rx += 2;
-+ }
-+}
-+static void u32_writer(struct driver_data *drv_data)
-+{
-+ void *reg = drv_data->ioaddr;
-+
-+ while ((read_SSSR(reg) & SSSR_TNF)
-+ && (drv_data->tx < drv_data->tx_end)) {
-+ write_SSDR(*(u16 *)(drv_data->tx), reg);
-+ drv_data->tx += 4;
-+ }
-+}
-+
-+static void u32_reader(struct driver_data *drv_data)
-+{
-+ void *reg = drv_data->ioaddr;
-+
-+ while ((read_SSSR(reg) & SSSR_RNE)
-+ && (drv_data->rx < drv_data->rx_end)) {
-+ *(u32 *)(drv_data->rx) = read_SSDR(reg);
-+ drv_data->rx += 4;
-+ }
-+}
-+
-+static void *next_transfer(struct driver_data *drv_data)
-+{
-+ struct spi_message *msg = drv_data->cur_msg;
-+ struct spi_transfer *trans = drv_data->cur_transfer;
-+
-+ /* Move to next transfer */
-+ if (trans->transfer_list.next != &msg->transfers) {
-+ drv_data->cur_transfer =
-+ list_entry(trans->transfer_list.next,
-+ struct spi_transfer,
-+ transfer_list);
-+ return RUNNING_STATE;
-+ } else
-+ return DONE_STATE;
-+}
-+
-+static int map_dma_buffers(struct driver_data *drv_data)
-+{
-+ struct spi_message *msg = drv_data->cur_msg;
-+ struct device *dev = &msg->spi->dev;
-+
-+ if (!drv_data->cur_chip->enable_dma)
-+ return 0;
-+
-+ if (msg->is_dma_mapped)
-+ return drv_data->rx_dma && drv_data->tx_dma;
-+
-+ if (!IS_DMA_ALIGNED(drv_data->rx) || !IS_DMA_ALIGNED(drv_data->tx))
-+ return 0;
-+
-+ /* Modify setup if rx buffer is null */
-+ if (drv_data->rx == NULL) {
-+ *drv_data->null_dma_buf = 0;
-+ drv_data->rx = drv_data->null_dma_buf;
-+ drv_data->rx_map_len = 4;
-+ } else
-+ drv_data->rx_map_len = drv_data->len;
-+
-+
-+ /* Modify setup if tx buffer is null */
-+ if (drv_data->tx == NULL) {
-+ *drv_data->null_dma_buf = 0;
-+ drv_data->tx = drv_data->null_dma_buf;
-+ drv_data->tx_map_len = 4;
-+ } else
-+ drv_data->tx_map_len = drv_data->len;
-+
-+ /* Stream map the rx buffer */
-+ drv_data->rx_dma = dma_map_single(dev, drv_data->rx,
-+ drv_data->rx_map_len,
-+ DMA_FROM_DEVICE);
-+ if (dma_mapping_error(drv_data->rx_dma))
-+ return 0;
-+
-+ /* Stream map the tx buffer */
-+ drv_data->tx_dma = dma_map_single(dev, drv_data->tx,
-+ drv_data->tx_map_len,
-+ DMA_TO_DEVICE);
-+
-+ if (dma_mapping_error(drv_data->tx_dma)) {
-+ dma_unmap_single(dev, drv_data->rx_dma,
-+ drv_data->rx_map_len, DMA_FROM_DEVICE);
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+static void unmap_dma_buffers(struct driver_data *drv_data)
-+{
-+ struct device *dev;
-+
-+ if (!drv_data->dma_mapped)
-+ return;
-+
-+ if (!drv_data->cur_msg->is_dma_mapped) {
-+ dev = &drv_data->cur_msg->spi->dev;
-+ dma_unmap_single(dev, drv_data->rx_dma,
-+ drv_data->rx_map_len, DMA_FROM_DEVICE);
-+ dma_unmap_single(dev, drv_data->tx_dma,
-+ drv_data->tx_map_len, DMA_TO_DEVICE);
-+ }
-+
-+ drv_data->dma_mapped = 0;
-+}
-+
-+/* caller already set message->status; dma and pio irqs are blocked */
-+static void giveback(struct spi_message *message, struct driver_data *drv_data)
-+{
-+ struct spi_transfer* last_transfer;
-+
-+ last_transfer = list_entry(message->transfers.prev,
-+ struct spi_transfer,
-+ transfer_list);
-+
-+ if (!last_transfer->cs_change)
-+ drv_data->cs_control(PXA2XX_CS_DEASSERT);
-+
-+ message->state = NULL;
-+ if (message->complete)
-+ message->complete(message->context);
-+
-+ drv_data->cur_msg = NULL;
-+ drv_data->cur_transfer = NULL;
-+ drv_data->cur_chip = NULL;
-+ queue_work(drv_data->workqueue, &drv_data->pump_messages);
-+}
-+
-+static int wait_ssp_rx_stall(void *ioaddr)
-+{
-+ unsigned long limit = loops_per_jiffy << 1;
-+
-+ while ((read_SSSR(ioaddr) & SSSR_BSY) && limit--)
-+ cpu_relax();
-+
-+ return limit;
-+}
-+
-+static int wait_dma_channel_stop(int channel)
-+{
-+ unsigned long limit = loops_per_jiffy << 1;
-+
-+ while (!(DCSR(channel) & DCSR_STOPSTATE) && limit--)
-+ cpu_relax();
-+
-+ return limit;
-+}
-+
-+static void dma_handler(int channel, void *data, struct pt_regs *regs)
-+{
-+ struct driver_data *drv_data = data;
-+ struct spi_message *msg = drv_data->cur_msg;
-+ void *reg = drv_data->ioaddr;
-+ u32 irq_status = DCSR(channel) & DMA_INT_MASK;
-+ u32 trailing_sssr = 0;
-+
-+ if (irq_status & DCSR_BUSERR) {
-+
-+ /* Disable interrupts, clear status and reset DMA */
-+ if (drv_data->ssp_type != PXA25x_SSP)
-+ write_SSTO(0, reg);
-+ write_SSSR(drv_data->clear_sr, reg);
-+ write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
-+ DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
-+ DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
-+
-+ if (flush(drv_data) == 0)
-+ dev_err(&drv_data->pdev->dev,
-+ "dma_handler: flush fail\n");
-+
-+ unmap_dma_buffers(drv_data);
-+
-+ if (channel == drv_data->tx_channel)
-+ dev_err(&drv_data->pdev->dev,
-+ "dma_handler: bad bus address on "
-+ "tx channel %d, source %x target = %x\n",
-+ channel, DSADR(channel), DTADR(channel));
-+ else
-+ dev_err(&drv_data->pdev->dev,
-+ "dma_handler: bad bus address on "
-+ "rx channel %d, source %x target = %x\n",
-+ channel, DSADR(channel), DTADR(channel));
-+
-+ msg->state = ERROR_STATE;
-+ tasklet_schedule(&drv_data->pump_transfers);
-+ }
-+
-+ /* PXA255x_SSP has no timeout interrupt, wait for tailing bytes */
-+ if ((drv_data->ssp_type == PXA25x_SSP)
-+ && (channel == drv_data->tx_channel)
-+ && (irq_status & DCSR_ENDINTR)) {
-+
-+ /* Wait for rx to stall */
-+ if (wait_ssp_rx_stall(drv_data->ioaddr) == 0)
-+ dev_err(&drv_data->pdev->dev,
-+ "dma_handler: ssp rx stall failed\n");
-+
-+ /* Clear and disable interrupts on SSP and DMA channels*/
-+ write_SSSR(drv_data->clear_sr, reg);
-+ write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
-+ DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
-+ DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
-+ if (wait_dma_channel_stop(drv_data->rx_channel) == 0)
-+ dev_err(&drv_data->pdev->dev,
-+ "dma_handler: dma rx channel stop failed\n");
-+
-+ unmap_dma_buffers(drv_data);
-+
-+ /* Read trailing bytes */
-+ /* Calculate number of trailing bytes, read them */
-+ trailing_sssr = read_SSSR(reg);
-+ if ((trailing_sssr & 0xf008) != 0xf000) {
-+ drv_data->rx = drv_data->rx_end -
-+ (((trailing_sssr >> 12) & 0x0f) + 1);
-+ drv_data->read(drv_data);
-+ }
-+ msg->actual_length += drv_data->len;
-+
-+ /* Release chip select if requested, transfer delays are
-+ * handled in pump_transfers */
-+ if (drv_data->cs_change)
-+ drv_data->cs_control(PXA2XX_CS_DEASSERT);
-+
-+ /* Move to next transfer */
-+ msg->state = next_transfer(drv_data);
-+
-+ /* Schedule transfer tasklet */
-+ tasklet_schedule(&drv_data->pump_transfers);
-+ }
-+}
-+
-+static irqreturn_t dma_transfer(struct driver_data *drv_data)
-+{
-+ u32 irq_status;
-+ u32 trailing_sssr = 0;
-+ struct spi_message *msg = drv_data->cur_msg;
-+ void *reg = drv_data->ioaddr;
-+
-+ irq_status = read_SSSR(reg) & drv_data->mask_sr;
-+ if (irq_status & SSSR_ROR) {
-+ /* Clear and disable interrupts on SSP and DMA channels*/
-+ if (drv_data->ssp_type != PXA25x_SSP)
-+ write_SSTO(0, reg);
-+ write_SSSR(drv_data->clear_sr, reg);
-+ write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
-+ DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
-+ DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
-+ unmap_dma_buffers(drv_data);
-+
-+ if (flush(drv_data) == 0)
-+ dev_err(&drv_data->pdev->dev,
-+ "dma_transfer: flush fail\n");
-+
-+ dev_warn(&drv_data->pdev->dev, "dma_transfer: fifo overun\n");
-+
-+ drv_data->cur_msg->state = ERROR_STATE;
-+ tasklet_schedule(&drv_data->pump_transfers);
-+
-+ return IRQ_HANDLED;
-+ }
-+
-+ /* Check for false positive timeout */
-+ if ((irq_status & SSSR_TINT) && DCSR(drv_data->tx_channel) & DCSR_RUN) {
-+ write_SSSR(SSSR_TINT, reg);
-+ return IRQ_HANDLED;
-+ }
-+
-+ if (irq_status & SSSR_TINT || drv_data->rx == drv_data->rx_end) {
-+
-+ /* Clear and disable interrupts on SSP and DMA channels*/
-+ if (drv_data->ssp_type != PXA25x_SSP)
-+ write_SSTO(0, reg);
-+ write_SSSR(drv_data->clear_sr, reg);
-+ write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
-+ DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
-+ DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
-+
-+ if (wait_dma_channel_stop(drv_data->rx_channel) == 0)
-+ dev_err(&drv_data->pdev->dev,
-+ "dma_transfer: dma rx channel stop failed\n");
-+
-+ if (wait_ssp_rx_stall(drv_data->ioaddr) == 0)
-+ dev_err(&drv_data->pdev->dev,
-+ "dma_transfer: ssp rx stall failed\n");
-+
-+ unmap_dma_buffers(drv_data);
-+
-+ /* Calculate number of trailing bytes, read them */
-+ trailing_sssr = read_SSSR(reg);
-+ if ((trailing_sssr & 0xf008) != 0xf000) {
-+ drv_data->rx = drv_data->rx_end -
-+ (((trailing_sssr >> 12) & 0x0f) + 1);
-+ drv_data->read(drv_data);
-+ }
-+ msg->actual_length += drv_data->len;
-+
-+ /* Release chip select if requested, transfer delays are
-+ * handled in pump_transfers */
-+ if (drv_data->cs_change)
-+ drv_data->cs_control(PXA2XX_CS_DEASSERT);
-+
-+ /* Move to next transfer */
-+ msg->state = next_transfer(drv_data);
-+
-+ /* Schedule transfer tasklet */
-+ tasklet_schedule(&drv_data->pump_transfers);
-+
-+ return IRQ_HANDLED;
-+ }
-+
-+ /* Opps problem detected */
-+ return IRQ_NONE;
-+}
-+
-+static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
-+{
-+ u32 irq_status;
-+ struct spi_message *msg = drv_data->cur_msg;
-+ void *reg = drv_data->ioaddr;
-+ irqreturn_t handled = IRQ_NONE;
-+ unsigned long limit = loops_per_jiffy << 1;
-+
-+ while ((irq_status = (read_SSSR(reg) & drv_data->mask_sr))) {
-+
-+ if (irq_status & SSSR_ROR) {
-+
-+ /* Clear and disable interrupts */
-+ if (drv_data->ssp_type != PXA25x_SSP)
-+ write_SSTO(0, reg);
-+ write_SSSR(drv_data->clear_sr, reg);
-+ write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
-+
-+ if (flush(drv_data) == 0)
-+ dev_err(&drv_data->pdev->dev,
-+ "interrupt_transfer: flush fail\n");
-+
-+ dev_warn(&drv_data->pdev->dev,
-+ "interrupt_transfer: fifo overun\n");
-+
-+ msg->state = ERROR_STATE;
-+ tasklet_schedule(&drv_data->pump_transfers);
-+
-+ return IRQ_HANDLED;
-+ }
-+
-+ /* Look for false positive timeout */
-+ if ((irq_status & SSSR_TINT)
-+ && (drv_data->rx < drv_data->rx_end))
-+ write_SSSR(SSSR_TINT, reg);
-+
-+ /* Pump data */
-+ drv_data->read(drv_data);
-+ drv_data->write(drv_data);
-+
-+ if (drv_data->tx == drv_data->tx_end) {
-+ /* Disable tx interrupt */
-+ write_SSCR1(read_SSCR1(reg) & ~SSCR1_TIE, reg);
-+
-+ /* PXA25x_SSP has no timeout, read trailing bytes */
-+ if (drv_data->ssp_type == PXA25x_SSP) {
-+ while ((read_SSSR(reg) & SSSR_BSY) && limit--)
-+ drv_data->read(drv_data);
-+
-+ if (limit == 0)
-+ dev_err(&drv_data->pdev->dev,
-+ "interrupt_transfer: "
-+ "trailing byte read failed\n");
-+ }
-+ }
-+
-+ if ((irq_status & SSSR_TINT)
-+ || (drv_data->rx == drv_data->rx_end)) {
-+
-+ /* Clear timeout */
-+ if (drv_data->ssp_type != PXA25x_SSP)
-+ write_SSTO(0, reg);
-+ write_SSSR(drv_data->clear_sr, reg);
-+ write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
-+
-+ /* Update total byte transfered */
-+ msg->actual_length += drv_data->len;
-+
-+ /* Release chip select if requested, transfer delays are
-+ * handled in pump_transfers */
-+ if (drv_data->cs_change)
-+ drv_data->cs_control(PXA2XX_CS_DEASSERT);
-+
-+ /* Move to next transfer */
-+ msg->state = next_transfer(drv_data);
-+
-+ /* Schedule transfer tasklet */
-+ tasklet_schedule(&drv_data->pump_transfers);
-+
-+ return IRQ_HANDLED;
-+ }
-+
-+ /* We did something */
-+ handled = IRQ_HANDLED;
-+ }
-+
-+ return handled;
-+}
-+
-+static irqreturn_t ssp_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct driver_data *drv_data = (struct driver_data *)dev_id;
-+
-+ if (!drv_data->cur_msg) {
-+ dev_err(&drv_data->pdev->dev, "bad message state "
-+ "in interrupt handler\n");
-+ /* Never fail */
-+ return IRQ_HANDLED;
-+ }
-+
-+ return drv_data->transfer_handler(drv_data);
-+}
-+
-+static void pump_transfers(unsigned long data)
-+{
-+ struct driver_data *drv_data = (struct driver_data *)data;
-+ struct spi_message *message = NULL;
-+ struct spi_transfer *transfer = NULL;
-+ struct spi_transfer *previous = NULL;
-+ struct chip_data *chip = NULL;
-+ void *reg = drv_data->ioaddr;
-+
-+ /* Get current state information */
-+ message = drv_data->cur_msg;
-+ transfer = drv_data->cur_transfer;
-+ chip = drv_data->cur_chip;
-+
-+ /* Handle for abort */
-+ if (message->state == ERROR_STATE) {
-+ message->status = -EIO;
-+ giveback(message, drv_data);
-+ return;
-+ }
-+
-+ /* Handle end of message */
-+ if (message->state == DONE_STATE) {
-+ message->status = 0;
-+ giveback(message, drv_data);
-+ return;
-+ }
-+
-+ /* Delay if requested at end of transfer*/
-+ if (message->state == RUNNING_STATE) {
-+ previous = list_entry(transfer->transfer_list.prev,
-+ struct spi_transfer,
-+ transfer_list);
-+ if (previous->delay_usecs)
-+ udelay(previous->delay_usecs);
-+ }
-+
-+ /* Setup the transfer state based on the type of transfer */
-+ if (flush(drv_data) == 0) {
-+ dev_err(&drv_data->pdev->dev, "pump_transfers: flush failed\n");
-+ message->status = -EIO;
-+ giveback(message, drv_data);
-+ return;
-+ }
-+ drv_data->cs_control = chip->cs_control;
-+ drv_data->tx = (void *)transfer->tx_buf;
-+ drv_data->tx_end = drv_data->tx + transfer->len;
-+ drv_data->rx = transfer->rx_buf;
-+ drv_data->rx_end = drv_data->rx + transfer->len;
-+ drv_data->rx_dma = transfer->rx_dma;
-+ drv_data->tx_dma = transfer->tx_dma;
-+ drv_data->len = transfer->len;
-+ drv_data->write = drv_data->tx ? chip->write : null_writer;
-+ drv_data->read = drv_data->rx ? chip->read : null_reader;
-+ drv_data->cs_change = transfer->cs_change;
-+ message->state = RUNNING_STATE;
-+
-+ /* Try to map dma buffer and do a dma transfer if successful */
-+ if ((drv_data->dma_mapped = map_dma_buffers(drv_data))) {
-+
-+ /* Ensure we have the correct interrupt handler */
-+ drv_data->transfer_handler = dma_transfer;
-+
-+ /* Setup rx DMA Channel */
-+ DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
-+ DSADR(drv_data->rx_channel) = drv_data->ssdr_physical;
-+ DTADR(drv_data->rx_channel) = drv_data->rx_dma;
-+ if (drv_data->rx == drv_data->null_dma_buf)
-+ /* No target address increment */
-+ DCMD(drv_data->rx_channel) = DCMD_FLOWSRC
-+ | chip->dma_width
-+ | chip->dma_burst_size
-+ | drv_data->len;
-+ else
-+ DCMD(drv_data->rx_channel) = DCMD_INCTRGADDR
-+ | DCMD_FLOWSRC
-+ | chip->dma_width
-+ | chip->dma_burst_size
-+ | drv_data->len;
-+
-+ /* Setup tx DMA Channel */
-+ DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
-+ DSADR(drv_data->tx_channel) = drv_data->tx_dma;
-+ DTADR(drv_data->tx_channel) = drv_data->ssdr_physical;
-+ if (drv_data->tx == drv_data->null_dma_buf)
-+ /* No source address increment */
-+ DCMD(drv_data->tx_channel) = DCMD_FLOWTRG
-+ | chip->dma_width
-+ | chip->dma_burst_size
-+ | drv_data->len;
-+ else
-+ DCMD(drv_data->tx_channel) = DCMD_INCSRCADDR
-+ | DCMD_FLOWTRG
-+ | chip->dma_width
-+ | chip->dma_burst_size
-+ | drv_data->len;
-+
-+ /* Enable dma end irqs on SSP to detect end of transfer */
-+ if (drv_data->ssp_type == PXA25x_SSP)
-+ DCMD(drv_data->tx_channel) |= DCMD_ENDIRQEN;
-+
-+ /* Fix me, need to handle cs polarity */
-+ drv_data->cs_control(PXA2XX_CS_ASSERT);
-+
-+ /* Go baby, go */
-+ write_SSSR(drv_data->clear_sr, reg);
-+ DCSR(drv_data->rx_channel) |= DCSR_RUN;
-+ DCSR(drv_data->tx_channel) |= DCSR_RUN;
-+ if (drv_data->ssp_type != PXA25x_SSP)
-+ write_SSTO(chip->timeout, reg);
-+ write_SSCR1(chip->cr1
-+ | chip->dma_threshold
-+ | drv_data->dma_cr1,
-+ reg);
-+ } else {
-+ /* Ensure we have the correct interrupt handler */
-+ drv_data->transfer_handler = interrupt_transfer;
-+
-+ /* Fix me, need to handle cs polarity */
-+ drv_data->cs_control(PXA2XX_CS_ASSERT);
-+
-+ /* Go baby, go */
-+ write_SSSR(drv_data->clear_sr, reg);
-+ if (drv_data->ssp_type != PXA25x_SSP)
-+ write_SSTO(chip->timeout, reg);
-+ write_SSCR1(chip->cr1
-+ | chip->threshold
-+ | drv_data->int_cr1,
-+ reg);
-+ }
-+}
-+
-+static void pump_messages(void *data)
-+{
-+ struct driver_data *drv_data = data;
-+ unsigned long flags;
-+
-+ /* Lock queue and check for queue work */
-+ spin_lock_irqsave(&drv_data->lock, flags);
-+ if (list_empty(&drv_data->queue) || drv_data->run == QUEUE_STOPPED) {
-+ drv_data->busy = 0;
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+ return;
-+ }
-+
-+ /* Make sure we are not already running a message */
-+ if (drv_data->cur_msg) {
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+ return;
-+ }
-+
-+ /* Extract head of queue */
-+ drv_data->cur_msg = list_entry(drv_data->queue.next,
-+ struct spi_message, queue);
-+ list_del_init(&drv_data->cur_msg->queue);
-+ drv_data->busy = 1;
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+
-+ /* Initial message state*/
-+ drv_data->cur_msg->state = START_STATE;
-+ drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
-+ struct spi_transfer,
-+ transfer_list);
-+
-+ /* Setup the SSP using the per chip configuration */
-+ drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
-+ restore_state(drv_data);
-+
-+ /* Mark as busy and launch transfers */
-+ tasklet_schedule(&drv_data->pump_transfers);
-+}
-+
-+static int transfer(struct spi_device *spi, struct spi_message *msg)
-+{
-+ struct driver_data *drv_data = spi_master_get_devdata(spi->master);
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&drv_data->lock, flags);
-+
-+ if (drv_data->run == QUEUE_STOPPED) {
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+ return -ESHUTDOWN;
-+ }
-+
-+ msg->actual_length = 0;
-+ msg->status = -EINPROGRESS;
-+ msg->state = START_STATE;
-+
-+ list_add_tail(&msg->queue, &drv_data->queue);
-+
-+ if (drv_data->run == QUEUE_RUNNING && !drv_data->busy)
-+ queue_work(drv_data->workqueue, &drv_data->pump_messages);
-+
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+
-+ return 0;
-+}
-+
-+static int setup(struct spi_device *spi)
-+{
-+ struct pxa2xx_spi_chip *chip_info = NULL;
-+ struct chip_data *chip;
-+ struct driver_data *drv_data = spi_master_get_devdata(spi->master);
-+ unsigned int clk_div;
-+
-+ if (!spi->bits_per_word)
-+ spi->bits_per_word = 8;
-+
-+ if (drv_data->ssp_type != PXA25x_SSP
-+ && (spi->bits_per_word < 4 || spi->bits_per_word > 32))
-+ return -EINVAL;
-+ else if (spi->bits_per_word < 4 || spi->bits_per_word > 16)
-+ return -EINVAL;
-+
-+ /* Only alloc (or use chip_info) on first setup */
-+ chip = spi_get_ctldata(spi);
-+ if (chip == NULL) {
-+ chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
-+ if (!chip)
-+ return -ENOMEM;
-+
-+ chip->cs_control = null_cs_control;
-+ chip->enable_dma = 0;
-+ chip->timeout = 5;
-+ chip->threshold = SSCR1_RxTresh(1) | SSCR1_TxTresh(1);
-+ chip->dma_burst_size = drv_data->master_info->enable_dma ?
-+ DCMD_BURST8 : 0;
-+
-+ chip_info = spi->controller_data;
-+ }
-+
-+ /* chip_info isn't always needed */
-+ if (chip_info) {
-+ if (chip_info->cs_control)
-+ chip->cs_control = chip_info->cs_control;
-+
-+ chip->timeout = (chip_info->timeout_microsecs * 10000) / 2712;
-+
-+ chip->threshold = SSCR1_RxTresh(chip_info->rx_threshold)
-+ | SSCR1_TxTresh(chip_info->tx_threshold);
-+
-+ chip->enable_dma = chip_info->dma_burst_size != 0
-+ && drv_data->master_info->enable_dma;
-+ chip->dma_threshold = 0;
-+
-+ if (chip->enable_dma) {
-+ if (chip_info->dma_burst_size <= 8) {
-+ chip->dma_threshold = SSCR1_RxTresh(8)
-+ | SSCR1_TxTresh(8);
-+ chip->dma_burst_size = DCMD_BURST8;
-+ } else if (chip_info->dma_burst_size <= 16) {
-+ chip->dma_threshold = SSCR1_RxTresh(16)
-+ | SSCR1_TxTresh(16);
-+ chip->dma_burst_size = DCMD_BURST16;
-+ } else {
-+ chip->dma_threshold = SSCR1_RxTresh(32)
-+ | SSCR1_TxTresh(32);
-+ chip->dma_burst_size = DCMD_BURST32;
-+ }
-+ }
-+
-+
-+ if (chip_info->enable_loopback)
-+ chip->cr1 = SSCR1_LBM;
-+ }
-+
-+ if (drv_data->ioaddr == SSP1_VIRT)
-+ clk_div = SSP1_SerClkDiv(spi->max_speed_hz);
-+ else if (drv_data->ioaddr == SSP2_VIRT)
-+ clk_div = SSP2_SerClkDiv(spi->max_speed_hz);
-+ else if (drv_data->ioaddr == SSP3_VIRT)
-+ clk_div = SSP3_SerClkDiv(spi->max_speed_hz);
-+ else
-+ return -ENODEV;
-+
-+ chip->cr0 = clk_div
-+ | SSCR0_Motorola
-+ | SSCR0_DataSize(spi->bits_per_word & 0x0f)
-+ | SSCR0_SSE
-+ | (spi->bits_per_word > 16 ? SSCR0_EDSS : 0);
-+ chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) << 4)
-+ | (((spi->mode & SPI_CPOL) != 0) << 3);
-+
-+ /* NOTE: PXA25x_SSP _could_ use external clocking ... */
-+ if (drv_data->ssp_type != PXA25x_SSP)
-+ dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n",
-+ spi->bits_per_word,
-+ (CLOCK_SPEED_HZ)
-+ / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
-+ spi->mode & 0x3);
-+ else
-+ dev_dbg(&spi->dev, "%d bits/word, %d Hz, mode %d\n",
-+ spi->bits_per_word,
-+ (CLOCK_SPEED_HZ/2)
-+ / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
-+ spi->mode & 0x3);
-+
-+ if (spi->bits_per_word <= 8) {
-+ chip->n_bytes = 1;
-+ chip->dma_width = DCMD_WIDTH1;
-+ chip->read = u8_reader;
-+ chip->write = u8_writer;
-+ } else if (spi->bits_per_word <= 16) {
-+ chip->n_bytes = 2;
-+ chip->dma_width = DCMD_WIDTH2;
-+ chip->read = u16_reader;
-+ chip->write = u16_writer;
-+ } else if (spi->bits_per_word <= 32) {
-+ chip->cr0 |= SSCR0_EDSS;
-+ chip->n_bytes = 4;
-+ chip->dma_width = DCMD_WIDTH4;
-+ chip->read = u32_reader;
-+ chip->write = u32_writer;
-+ } else {
-+ dev_err(&spi->dev, "invalid wordsize\n");
-+ kfree(chip);
-+ return -ENODEV;
-+ }
-+
-+ spi_set_ctldata(spi, chip);
-+
-+ return 0;
-+}
-+
-+static void cleanup(const struct spi_device *spi)
-+{
-+ struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
-+
-+ kfree(chip);
-+}
-+
-+static int init_queue(struct driver_data *drv_data)
-+{
-+ INIT_LIST_HEAD(&drv_data->queue);
-+ spin_lock_init(&drv_data->lock);
-+
-+ drv_data->run = QUEUE_STOPPED;
-+ drv_data->busy = 0;
-+
-+ tasklet_init(&drv_data->pump_transfers,
-+ pump_transfers, (unsigned long)drv_data);
-+
-+ INIT_WORK(&drv_data->pump_messages, pump_messages, drv_data);
-+ drv_data->workqueue = create_singlethread_workqueue(
-+ drv_data->master->cdev.dev->bus_id);
-+ if (drv_data->workqueue == NULL)
-+ return -EBUSY;
-+
-+ return 0;
-+}
-+
-+static int start_queue(struct driver_data *drv_data)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&drv_data->lock, flags);
-+
-+ if (drv_data->run == QUEUE_RUNNING || drv_data->busy) {
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+ return -EBUSY;
-+ }
-+
-+ drv_data->run = QUEUE_RUNNING;
-+ drv_data->cur_msg = NULL;
-+ drv_data->cur_transfer = NULL;
-+ drv_data->cur_chip = NULL;
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+
-+ queue_work(drv_data->workqueue, &drv_data->pump_messages);
-+
-+ return 0;
-+}
-+
-+static int stop_queue(struct driver_data *drv_data)
-+{
-+ unsigned long flags;
-+ unsigned limit = 500;
-+ int status = 0;
-+
-+ spin_lock_irqsave(&drv_data->lock, flags);
-+
-+ /* This is a bit lame, but is optimized for the common execution path.
-+ * A wait_queue on the drv_data->busy could be used, but then the common
-+ * execution path (pump_messages) would be required to call wake_up or
-+ * friends on every SPI message. Do this instead */
-+ drv_data->run = QUEUE_STOPPED;
-+ while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+ msleep(10);
-+ spin_lock_irqsave(&drv_data->lock, flags);
-+ }
-+
-+ if (!list_empty(&drv_data->queue) || drv_data->busy)
-+ status = -EBUSY;
-+
-+ spin_unlock_irqrestore(&drv_data->lock, flags);
-+
-+ return status;
-+}
-+
-+static int destroy_queue(struct driver_data *drv_data)
-+{
-+ int status;
-+
-+ status = stop_queue(drv_data);
-+ if (status != 0)
-+ return status;
-+
-+ destroy_workqueue(drv_data->workqueue);
-+
-+ return 0;
-+}
-+
-+static int pxa2xx_spi_probe(struct platform_device *pdev)
-+{
-+ struct device *dev = &pdev->dev;
-+ struct pxa2xx_spi_master *platform_info;
-+ struct spi_master *master;
-+ struct driver_data *drv_data = 0;
-+ struct resource *memory_resource;
-+ int irq;
-+ int status = 0;
-+
-+ platform_info = dev->platform_data;
-+
-+ if (platform_info->ssp_type == SSP_UNDEFINED) {
-+ dev_err(&pdev->dev, "undefined SSP\n");
-+ return -ENODEV;
-+ }
-+
-+ /* Allocate master with space for drv_data and null dma buffer */
-+ master = spi_alloc_master(dev, sizeof(struct driver_data) + 16);
-+ if (!master) {
-+ dev_err(&pdev->dev, "can not alloc spi_master\n");
-+ return -ENOMEM;
-+ }
-+ drv_data = spi_master_get_devdata(master);
-+ drv_data->master = master;
-+ drv_data->master_info = platform_info;
-+ drv_data->pdev = pdev;
-+
-+ master->bus_num = pdev->id;
-+ master->num_chipselect = platform_info->num_chipselect;
-+ master->cleanup = cleanup;
-+ master->setup = setup;
-+ master->transfer = transfer;
-+
-+ drv_data->ssp_type = platform_info->ssp_type;
-+ drv_data->null_dma_buf = (u32 *)ALIGN((u32)(drv_data +
-+ sizeof(struct driver_data)), 8);
-+
-+ /* Setup register addresses */
-+ memory_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ if (!memory_resource) {
-+ dev_err(&pdev->dev, "memory resources not defined\n");
-+ status = -ENODEV;
-+ goto out_error_master_alloc;
-+ }
-+
-+ drv_data->ioaddr = (void *)io_p2v(memory_resource->start);
-+ drv_data->ssdr_physical = memory_resource->start + 0x00000010;
-+ if (platform_info->ssp_type == PXA25x_SSP) {
-+ drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE;
-+ drv_data->dma_cr1 = 0;
-+ drv_data->clear_sr = SSSR_ROR;
-+ drv_data->mask_sr = SSSR_RFS | SSSR_TFS | SSSR_ROR;
-+ } else {
-+ drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE | SSCR1_TINTE;
-+ drv_data->dma_cr1 = SSCR1_TSRE | SSCR1_RSRE | SSCR1_TINTE;
-+ drv_data->clear_sr = SSSR_ROR | SSSR_TINT;
-+ drv_data->mask_sr = SSSR_TINT | SSSR_RFS | SSSR_TFS | SSSR_ROR;
-+ }
-+
-+ /* Attach to IRQ */
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq < 0) {
-+ dev_err(&pdev->dev, "irq resource not defined\n");
-+ status = -ENODEV;
-+ goto out_error_master_alloc;
-+ }
-+
-+ status = request_irq(irq, ssp_int, SA_INTERRUPT, dev->bus_id, drv_data);
-+ if (status < 0) {
-+ dev_err(&pdev->dev, "can not get IRQ\n");
-+ goto out_error_master_alloc;
-+ }
-+
-+ /* Setup DMA if requested */
-+ drv_data->tx_channel = -1;
-+ drv_data->rx_channel = -1;
-+ if (platform_info->enable_dma) {
-+
-+ /* Get two DMA channels (rx and tx) */
-+ drv_data->rx_channel = pxa_request_dma("pxa2xx_spi_ssp_rx",
-+ DMA_PRIO_HIGH,
-+ dma_handler,
-+ drv_data);
-+ if (drv_data->rx_channel < 0) {
-+ dev_err(dev, "problem (%d) requesting rx channel\n",
-+ drv_data->rx_channel);
-+ status = -ENODEV;
-+ goto out_error_irq_alloc;
-+ }
-+ drv_data->tx_channel = pxa_request_dma("pxa2xx_spi_ssp_tx",
-+ DMA_PRIO_MEDIUM,
-+ dma_handler,
-+ drv_data);
-+ if (drv_data->tx_channel < 0) {
-+ dev_err(dev, "problem (%d) requesting tx channel\n",
-+ drv_data->tx_channel);
-+ status = -ENODEV;
-+ goto out_error_dma_alloc;
-+ }
-+
-+ if (drv_data->ioaddr == SSP1_VIRT) {
-+ DRCMRRXSSDR = DRCMR_MAPVLD
-+ | drv_data->rx_channel;
-+ DRCMRTXSSDR = DRCMR_MAPVLD
-+ | drv_data->tx_channel;
-+ } else if (drv_data->ioaddr == SSP2_VIRT) {
-+ DRCMRRXSS2DR = DRCMR_MAPVLD
-+ | drv_data->rx_channel;
-+ DRCMRTXSS2DR = DRCMR_MAPVLD
-+ | drv_data->tx_channel;
-+ } else if (drv_data->ioaddr == SSP3_VIRT) {
-+ DRCMRRXSS3DR = DRCMR_MAPVLD
-+ | drv_data->rx_channel;
-+ DRCMRTXSS3DR = DRCMR_MAPVLD
-+ | drv_data->tx_channel;
-+ } else {
-+ dev_err(dev, "bad SSP type\n");
-+ goto out_error_dma_alloc;
-+ }
-+ }
-+
-+ /* Enable SOC clock */
-+ pxa_set_cken(platform_info->clock_enable, 1);
-+
-+ /* Load default SSP configuration */
-+ write_SSCR0(0, drv_data->ioaddr);
-+ write_SSCR1(SSCR1_RxTresh(4) | SSCR1_TxTresh(12), drv_data->ioaddr);
-+ write_SSCR0(SSCR0_SerClkDiv(2)
-+ | SSCR0_Motorola
-+ | SSCR0_DataSize(8),
-+ drv_data->ioaddr);
-+ if (drv_data->ssp_type != PXA25x_SSP)
-+ write_SSTO(0, drv_data->ioaddr);
-+ write_SSPSP(0, drv_data->ioaddr);
-+
-+ /* Initial and start queue */
-+ status = init_queue(drv_data);
-+ if (status != 0) {
-+ dev_err(&pdev->dev, "problem initializing queue\n");
-+ goto out_error_clock_enabled;
-+ }
-+ status = start_queue(drv_data);
-+ if (status != 0) {
-+ dev_err(&pdev->dev, "problem starting queue\n");
-+ goto out_error_clock_enabled;
-+ }
-+
-+ /* Register with the SPI framework */
-+ platform_set_drvdata(pdev, drv_data);
-+ status = spi_register_master(master);
-+ if (status != 0) {
-+ dev_err(&pdev->dev, "problem registering spi master\n");
-+ goto out_error_queue_alloc;
-+ }
-+
-+ return status;
-+
-+out_error_queue_alloc:
-+ destroy_queue(drv_data);
-+
-+out_error_clock_enabled:
-+ pxa_set_cken(platform_info->clock_enable, 0);
-+
-+out_error_dma_alloc:
-+ if (drv_data->tx_channel != -1)
-+ pxa_free_dma(drv_data->tx_channel);
-+ if (drv_data->rx_channel != -1)
-+ pxa_free_dma(drv_data->rx_channel);
-+
-+out_error_irq_alloc:
-+ free_irq(irq, drv_data);
-+
-+out_error_master_alloc:
-+ spi_master_put(master);
-+ return status;
-+}
-+
-+static int pxa2xx_spi_remove(struct platform_device *pdev)
-+{
-+ struct driver_data *drv_data = platform_get_drvdata(pdev);
-+ int irq;
-+ int status = 0;
-+
-+ if (!drv_data)
-+ return 0;
-+
-+ /* Remove the queue */
-+ status = destroy_queue(drv_data);
-+ if (status != 0)
-+ return status;
-+
-+ /* Disable the SSP at the peripheral and SOC level */
-+ write_SSCR0(0, drv_data->ioaddr);
-+ pxa_set_cken(drv_data->master_info->clock_enable, 0);
-+
-+ /* Release DMA */
-+ if (drv_data->master_info->enable_dma) {
-+ if (drv_data->ioaddr == SSP1_VIRT) {
-+ DRCMRRXSSDR = 0;
-+ DRCMRTXSSDR = 0;
-+ } else if (drv_data->ioaddr == SSP2_VIRT) {
-+ DRCMRRXSS2DR = 0;
-+ DRCMRTXSS2DR = 0;
-+ } else if (drv_data->ioaddr == SSP3_VIRT) {
-+ DRCMRRXSS3DR = 0;
-+ DRCMRTXSS3DR = 0;
-+ }
-+ pxa_free_dma(drv_data->tx_channel);
-+ pxa_free_dma(drv_data->rx_channel);
-+ }
-+
-+ /* Release IRQ */
-+ irq = platform_get_irq(pdev, 0);
-+ if (irq >= 0)
-+ free_irq(irq, drv_data);
-+
-+ /* Disconnect from the SPI framework */
-+ spi_unregister_master(drv_data->master);
-+
-+ /* Prevent double remove */
-+ platform_set_drvdata(pdev, NULL);
-+
-+ return 0;
-+}
-+
-+static void pxa2xx_spi_shutdown(struct platform_device *pdev)
-+{
-+ int status = 0;
-+
-+ if ((status = pxa2xx_spi_remove(pdev)) != 0)
-+ dev_err(&pdev->dev, "shutdown failed with %d\n", status);
-+}
-+
-+#ifdef CONFIG_PM
-+static int suspend_devices(struct device *dev, void *pm_message)
-+{
-+ pm_message_t *state = pm_message;
-+
-+ if (dev->power.power_state.event != state->event) {
-+ dev_warn(dev, "pm state does not match request\n");
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
-+{
-+ struct driver_data *drv_data = platform_get_drvdata(pdev);
-+ int status = 0;
-+
-+ /* Check all childern for current power state */
-+ if (device_for_each_child(&pdev->dev, &state, suspend_devices) != 0) {
-+ dev_warn(&pdev->dev, "suspend aborted\n");
-+ return -1;
-+ }
-+
-+ status = stop_queue(drv_data);
-+ if (status != 0)
-+ return status;
-+ write_SSCR0(0, drv_data->ioaddr);
-+ pxa_set_cken(drv_data->master_info->clock_enable, 0);
-+
-+ return 0;
-+}
-+
-+static int pxa2xx_spi_resume(struct platform_device *pdev)
-+{
-+ struct driver_data *drv_data = platform_get_drvdata(pdev);
-+ int status = 0;
-+
-+ /* Enable the SSP clock */
-+ pxa_set_cken(drv_data->master_info->clock_enable, 1);
-+
-+ /* Start the queue running */
-+ status = start_queue(drv_data);
-+ if (status != 0) {
-+ dev_err(&pdev->dev, "problem starting queue (%d)\n", status);
-+ return status;
-+ }
-+
-+ return 0;
-+}
-+#else
-+#define pxa2xx_spi_suspend NULL
-+#define pxa2xx_spi_resume NULL
-+#endif /* CONFIG_PM */
-+
-+static struct platform_driver driver = {
-+ .driver = {
-+ .name = "pxa2xx-spi",
-+ .bus = &platform_bus_type,
-+ .owner = THIS_MODULE,
-+ },
-+ .probe = pxa2xx_spi_probe,
-+ .remove = __devexit_p(pxa2xx_spi_remove),
-+ .shutdown = pxa2xx_spi_shutdown,
-+ .suspend = pxa2xx_spi_suspend,
-+ .resume = pxa2xx_spi_resume,
-+};
-+
-+static int __init pxa2xx_spi_init(void)
-+{
-+ platform_driver_register(&driver);
-+
-+ return 0;
-+}
-+module_init(pxa2xx_spi_init);
-+
-+static void __exit pxa2xx_spi_exit(void)
-+{
-+ platform_driver_unregister(&driver);
-+}
-+module_exit(pxa2xx_spi_exit);
---- /dev/null
-+++ gregkh-2.6/include/asm-arm/arch-pxa/pxa2xx_spi.h
-@@ -0,0 +1,68 @@
-+/*
-+ * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs
-+ *
-+ * 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.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#ifndef PXA2XX_SPI_H_
-+#define PXA2XX_SPI_H_
-+
-+#define PXA2XX_CS_ASSERT (0x01)
-+#define PXA2XX_CS_DEASSERT (0x02)
-+
-+#if defined(CONFIG_PXA25x)
-+#define CLOCK_SPEED_HZ 3686400
-+#define SSP1_SerClkDiv(x) (((CLOCK_SPEED_HZ/2/(x+1))<<8)&0x0000ff00)
-+#define SSP2_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
-+#define SSP3_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
-+#elif defined(CONFIG_PXA27x)
-+#define CLOCK_SPEED_HZ 13000000
-+#define SSP1_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
-+#define SSP2_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
-+#define SSP3_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
-+#endif
-+
-+#define SSP1_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(1)))))
-+#define SSP2_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(2)))))
-+#define SSP3_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(3)))))
-+
-+enum pxa_ssp_type {
-+ SSP_UNDEFINED = 0,
-+ PXA25x_SSP, /* pxa 210, 250, 255, 26x */
-+ PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */
-+ PXA27x_SSP,
-+};
-+
-+/* device.platform_data for SSP controller devices */
-+struct pxa2xx_spi_master {
-+ enum pxa_ssp_type ssp_type;
-+ u32 clock_enable;
-+ u16 num_chipselect;
-+ u8 enable_dma;
-+};
-+
-+/* spi_board_info.controller_data for SPI slave devices,
-+ * copied to spi_device.platform_data ... mostly for dma tuning
-+ */
-+struct pxa2xx_spi_chip {
-+ u8 tx_threshold;
-+ u8 rx_threshold;
-+ u8 dma_burst_size;
-+ u32 timeout_microsecs;
-+ u8 enable_loopback;
-+ void (*cs_control)(u32 command);
-+};
-+
-+#endif /*PXA2XX_SPI_H_*/
diff --git a/driver/spi-busnum-0-needs-to-work.patch b/driver/spi-busnum-0-needs-to-work.patch
deleted file mode 100644
index 27e6c1d775336..0000000000000
--- a/driver/spi-busnum-0-needs-to-work.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-From david-b@pacbell.net Mon Apr 3 15:55:59 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: SPI: busnum == 0 needs to work
-Date: Mon, 3 Apr 2006 15:49:04 -0700
-Message-Id: <200604031549.04064.david-b@pacbell.net>
-
-We need to be able to have a "SPI bus 0" matching chip numbering; but
-that number was wrongly used to flag dynamic allocation of a bus number.
-
-This patch resolves that issue; now negative numbers trigger dynamic alloc.
-
-It also updates the how-to-write-a-controller-driver overview to mention
-this stuff.
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
-
----
- Documentation/spi/spi-summary | 34 +++++++++++++++++++++++++++++++++-
- drivers/spi/spi.c | 4 ++--
- include/linux/spi/spi.h | 6 +++---
- 3 files changed, 38 insertions(+), 6 deletions(-)
-
---- gregkh-2.6.orig/Documentation/spi/spi-summary
-+++ gregkh-2.6/Documentation/spi/spi-summary
-@@ -414,7 +414,33 @@ to get the driver-private data allocated
- The driver will initialize the fields of that spi_master, including the
- bus number (maybe the same as the platform device ID) and three methods
- used to interact with the SPI core and SPI protocol drivers. It will
--also initialize its own internal state.
-+also initialize its own internal state. (See below about bus numbering
-+and those methods.)
-+
-+After you initialize the spi_master, then use spi_register_master() to
-+publish it to the rest of the system. At that time, device nodes for
-+the controller and any predeclared spi devices will be made available,
-+and the driver model core will take care of binding them to drivers.
-+
-+If you need to remove your SPI controller driver, spi_unregister_master()
-+will reverse the effect of spi_register_master().
-+
-+
-+BUS NUMBERING
-+
-+Bus numbering is important, since that's how Linux identifies a given
-+SPI bus (shared SCK, MOSI, MISO). Valid bus numbers start at zero. On
-+SOC systems, the bus numbers should match the numbers defined by the chip
-+manufacturer. For example, hardware controller SPI2 would be bus number 2,
-+and spi_board_info for devices connected to it would use that number.
-+
-+If you don't have such hardware-assigned bus number, and for some reason
-+you can't just assign them, then provide a negative bus number. That will
-+then be replaced by a dynamically assigned number. You'd then need to treat
-+this as a non-static configuration (see above).
-+
-+
-+SPI MASTER METHODS
-
- master->setup(struct spi_device *spi)
- This sets up the device clock rate, SPI mode, and word sizes.
-@@ -431,6 +457,9 @@ also initialize its own internal state.
- state it dynamically associates with that device. If you do that,
- be sure to provide the cleanup() method to free that state.
-
-+
-+SPI MESSAGE QUEUE
-+
- The bulk of the driver will be managing the I/O queue fed by transfer().
-
- That queue could be purely conceptual. For example, a driver used only
-@@ -440,6 +469,9 @@ But the queue will probably be very real
- often DMA (especially if the root filesystem is in SPI flash), and
- execution contexts like IRQ handlers, tasklets, or workqueues (such
- as keventd). Your driver can be as fancy, or as simple, as you need.
-+Such a transfer() method would normally just add the message to a
-+queue, and then start some asynchronous transfer engine (unless it's
-+already running).
-
-
- THANKS TO
---- gregkh-2.6.orig/drivers/spi/spi.c
-+++ gregkh-2.6/drivers/spi/spi.c
-@@ -395,7 +395,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master);
- int __init_or_module
- spi_register_master(struct spi_master *master)
- {
-- static atomic_t dyn_bus_id = ATOMIC_INIT(0);
-+ static atomic_t dyn_bus_id = ATOMIC_INIT((1<<16) - 1);
- struct device *dev = master->cdev.dev;
- int status = -ENODEV;
- int dynamic = 0;
-@@ -404,7 +404,7 @@ spi_register_master(struct spi_master *m
- return -ENODEV;
-
- /* convention: dynamically assigned bus IDs count down from the max */
-- if (master->bus_num == 0) {
-+ if (master->bus_num < 0) {
- master->bus_num = atomic_dec_return(&dyn_bus_id);
- dynamic = 1;
- }
---- gregkh-2.6.orig/include/linux/spi/spi.h
-+++ gregkh-2.6/include/linux/spi/spi.h
-@@ -172,13 +172,13 @@ static inline void spi_unregister_driver
- struct spi_master {
- struct class_device cdev;
-
-- /* other than zero (== assign one dynamically), bus_num is fully
-+ /* other than negative (== assign one dynamically), bus_num is fully
- * board-specific. usually that simplifies to being SOC-specific.
-- * example: one SOC has three SPI controllers, numbered 1..3,
-+ * example: one SOC has three SPI controllers, numbered 0..2,
- * and one board's schematics might show it using SPI-2. software
- * would normally use bus_num=2 for that controller.
- */
-- u16 bus_num;
-+ s16 bus_num;
-
- /* chipselects will be integral to many controllers; some others
- * might use board-specific GPIOs.
diff --git a/driver/spi-devices-can-require-lsb-first-encodings.patch b/driver/spi-devices-can-require-lsb-first-encodings.patch
deleted file mode 100644
index 55554af2869eb..0000000000000
--- a/driver/spi-devices-can-require-lsb-first-encodings.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From david-b@pacbell.net Mon Apr 3 15:55:59 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: SPI: devices can require LSB-first encodings
-Date: Mon, 3 Apr 2006 15:46:22 -0700
-Message-Id: <200604031546.22777.david-b@pacbell.net>
-
-Add spi_device hook for LSB-first word encoding, and update all the
-(in-tree) controller drivers to reject such devices. Eventually,
-some controller drivers will be updated to support lsb-first encodings
-on the wire; no current drivers need this.
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/spi/spi_bitbang.c | 11 ++++++++++-
- include/linux/spi/spi.h | 7 +++++--
- 2 files changed, 15 insertions(+), 3 deletions(-)
-
---- gregkh-2.6.orig/drivers/spi/spi_bitbang.c
-+++ gregkh-2.6/drivers/spi/spi_bitbang.c
-@@ -187,13 +187,22 @@ int spi_bitbang_setup(struct spi_device
- if (!spi->max_speed_hz)
- return -EINVAL;
-
-+ bitbang = spi_master_get_devdata(spi->master);
-+
-+ /* REVISIT: some systems will want to support devices using lsb-first
-+ * bit encodings on the wire. In pure software that would be trivial,
-+ * just bitbang_txrx_le_cphaX() routines shifting the other way, and
-+ * some hardware controllers also have this support.
-+ */
-+ if ((spi->mode & SPI_LSB_FIRST) != 0)
-+ return -EINVAL;
-+
- if (!cs) {
- cs = kzalloc(sizeof *cs, SLAB_KERNEL);
- if (!cs)
- return -ENOMEM;
- spi->controller_state = cs;
- }
-- bitbang = spi_master_get_devdata(spi->master);
-
- if (!spi->bits_per_word)
- spi->bits_per_word = 8;
---- gregkh-2.6.orig/include/linux/spi/spi.h
-+++ gregkh-2.6/include/linux/spi/spi.h
-@@ -35,10 +35,13 @@ extern struct bus_type spi_bus_type;
- * @chip-select: Chipselect, distinguishing chips handled by "master".
- * @mode: The spi mode defines how data is clocked out and in.
- * This may be changed by the device's driver.
-+ * The "active low" default for chipselect mode can be overridden,
-+ * as can the "MSB first" default for each word in a transfer.
- * @bits_per_word: Data transfers involve one or more words; word sizes
- * like eight or 12 bits are common. In-memory wordsizes are
- * powers of two bytes (e.g. 20 bit samples use 32 bits).
-- * This may be changed by the device's driver.
-+ * This may be changed by the device's driver, or left at the
-+ * default (0) indicating protocol words are eight bit bytes.
- * The spi_transfer.bits_per_word can override this for each transfer.
- * @irq: Negative, or the number passed to request_irq() to receive
- * interrupts from this device.
-@@ -67,6 +70,7 @@ struct spi_device {
- #define SPI_MODE_2 (SPI_CPOL|0)
- #define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)
- #define SPI_CS_HIGH 0x04 /* chipselect active high? */
-+#define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */
- u8 bits_per_word;
- int irq;
- void *controller_state;
-@@ -75,7 +79,6 @@ struct spi_device {
-
- // likely need more hooks for more protocol options affecting how
- // the controller talks to each chip, like:
-- // - bit order (default is wordwise msb-first)
- // - memory packing (12 bit samples into low bits, others zeroed)
- // - priority
- // - drop chipselect after each word
diff --git a/driver/spi-per-transfer-overrides-for-wordsize-and-clocking.patch b/driver/spi-per-transfer-overrides-for-wordsize-and-clocking.patch
deleted file mode 100644
index cda64caab046f..0000000000000
--- a/driver/spi-per-transfer-overrides-for-wordsize-and-clocking.patch
+++ /dev/null
@@ -1,223 +0,0 @@
-From david-b@pacbell.net Fri Feb 17 10:02:22 2006
-From: Imre Deak <imre.deak@nokia.com>
-To: Andrew Morton <akpm@osdl.org>, Greg KH <greg@kroah.com>
-Subject: SPI: per-transfer overrides for wordsize and clocking
-Date: Fri, 17 Feb 2006 10:02:18 -0800
-Cc: imre.deak@nokia.com
-Message-Id: <200602171002.18568.david-b@pacbell.net>
-
-From: Imre Deak <imre.deak@nokia.com>
-
-Some protocols (like one for some bitmap displays) require different clock
-speed or word size settings for each transfer in an SPI message. This adds
-those parameters to struct spi_transfer. They are to be used when they are
-nonzero; otherwise the defaults from spi_device are to be used.
-
-The patch also adds a setup_transfer callback to spi_bitbang, uses it for
-messages that use those overrides, and implements it so that the pure
-bitbanging code can help resolve any questions about how it should work.
-
-Signed-off-by: Imre Deak <imre.deak@nokia.com>
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/spi/spi_bitbang.c | 77 ++++++++++++++++++++++++++++++++--------
- include/linux/spi/spi.h | 8 ++++
- include/linux/spi/spi_bitbang.h | 6 +++
- 3 files changed, 77 insertions(+), 14 deletions(-)
-
---- gregkh-2.6.orig/drivers/spi/spi_bitbang.c
-+++ gregkh-2.6/drivers/spi/spi_bitbang.c
-@@ -138,6 +138,43 @@ static unsigned bitbang_txrx_32(
- return t->len - count;
- }
-
-+static int
-+bitbang_transfer_setup(struct spi_device *spi, struct spi_transfer *t)
-+{
-+ struct spi_bitbang_cs *cs = spi->controller_state;
-+ u8 bits_per_word;
-+ u32 hz;
-+
-+ 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;
-+ if (bits_per_word <= 8)
-+ cs->txrx_bufs = bitbang_txrx_8;
-+ else if (bits_per_word <= 16)
-+ cs->txrx_bufs = bitbang_txrx_16;
-+ else if (bits_per_word <= 32)
-+ cs->txrx_bufs = bitbang_txrx_32;
-+ else
-+ return -EINVAL;
-+
-+ /* nsecs = (clock period)/2 */
-+ if (!hz)
-+ hz = spi->max_speed_hz;
-+ cs->nsecs = (1000000000/2) / hz;
-+ if (cs->nsecs > MAX_UDELAY_MS * 1000)
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
- /**
- * spi_bitbang_setup - default setup for per-word I/O loops
- */
-@@ -145,6 +182,7 @@ int spi_bitbang_setup(struct spi_device
- {
- struct spi_bitbang_cs *cs = spi->controller_state;
- struct spi_bitbang *bitbang;
-+ int retval;
-
- if (!spi->max_speed_hz)
- return -EINVAL;
-@@ -160,25 +198,14 @@ int spi_bitbang_setup(struct spi_device
- if (!spi->bits_per_word)
- spi->bits_per_word = 8;
-
-- /* spi_transfer level calls that work per-word */
-- if (spi->bits_per_word <= 8)
-- cs->txrx_bufs = bitbang_txrx_8;
-- else if (spi->bits_per_word <= 16)
-- cs->txrx_bufs = bitbang_txrx_16;
-- else if (spi->bits_per_word <= 32)
-- cs->txrx_bufs = bitbang_txrx_32;
-- else
-- return -EINVAL;
--
- /* per-word shift register access, in hardware or bitbanging */
- cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)];
- if (!cs->txrx_word)
- return -EINVAL;
-
-- /* nsecs = (clock period)/2 */
-- cs->nsecs = (1000000000/2) / (spi->max_speed_hz);
-- if (cs->nsecs > MAX_UDELAY_MS * 1000)
-- return -EINVAL;
-+ retval = bitbang_transfer_setup(spi, NULL);
-+ if (retval < 0)
-+ return retval;
-
- dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n",
- __FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA),
-@@ -246,6 +273,8 @@ static void bitbang_work(void *_bitbang)
- unsigned tmp;
- unsigned cs_change;
- int status;
-+ int (*setup_transfer)(struct spi_device *,
-+ struct spi_transfer *);
-
- m = container_of(bitbang->queue.next, struct spi_message,
- queue);
-@@ -262,6 +291,7 @@ static void bitbang_work(void *_bitbang)
- tmp = 0;
- cs_change = 1;
- status = 0;
-+ setup_transfer = NULL;
-
- list_for_each_entry (t, &m->transfers, transfer_list) {
- if (bitbang->shutdown) {
-@@ -269,6 +299,20 @@ static void bitbang_work(void *_bitbang)
- break;
- }
-
-+ /* override or restore speed and wordsize */
-+ if (t->speed_hz || t->bits_per_word) {
-+ setup_transfer = bitbang->setup_transfer;
-+ if (!setup_transfer) {
-+ status = -ENOPROTOOPT;
-+ break;
-+ }
-+ }
-+ if (setup_transfer) {
-+ status = setup_transfer(spi, t);
-+ if (status < 0)
-+ break;
-+ }
-+
- /* set up default clock polarity, and activate chip;
- * this implicitly updates clock and spi modes as
- * previously recorded for this device via setup().
-@@ -325,6 +369,10 @@ static void bitbang_work(void *_bitbang)
- m->status = status;
- m->complete(m->context);
-
-+ /* restore speed and wordsize */
-+ if (setup_transfer)
-+ setup_transfer(spi, NULL);
-+
- /* normally deactivate chipselect ... unless no error and
- * cs_change has hinted that the next message will probably
- * be for this chip too.
-@@ -406,6 +454,7 @@ int spi_bitbang_start(struct spi_bitbang
- bitbang->use_dma = 0;
- bitbang->txrx_bufs = spi_bitbang_bufs;
- if (!bitbang->master->setup) {
-+ bitbang->setup_transfer = bitbang_transfer_setup;
- bitbang->master->setup = spi_bitbang_setup;
- bitbang->master->cleanup = spi_bitbang_cleanup;
- }
---- gregkh-2.6.orig/include/linux/spi/spi.h
-+++ gregkh-2.6/include/linux/spi/spi.h
-@@ -31,6 +31,7 @@ extern struct bus_type spi_bus_type;
- * @master: SPI controller used with the device.
- * @max_speed_hz: Maximum clock rate to be used with this chip
- * (on this board); may be changed by the device's driver.
-+ * The spi_transfer.speed_hz can override this for each transfer.
- * @chip-select: Chipselect, distinguishing chips handled by "master".
- * @mode: The spi mode defines how data is clocked out and in.
- * This may be changed by the device's driver.
-@@ -38,6 +39,7 @@ extern struct bus_type spi_bus_type;
- * like eight or 12 bits are common. In-memory wordsizes are
- * powers of two bytes (e.g. 20 bit samples use 32 bits).
- * This may be changed by the device's driver.
-+ * The spi_transfer.bits_per_word can override this for each transfer.
- * @irq: Negative, or the number passed to request_irq() to receive
- * interrupts from this device.
- * @controller_state: Controller's runtime state
-@@ -268,6 +270,10 @@ extern struct spi_master *spi_busnum_to_
- * @tx_dma: DMA address of tx_buf, if spi_message.is_dma_mapped
- * @rx_dma: DMA address of rx_buf, if spi_message.is_dma_mapped
- * @len: size of rx and tx buffers (in bytes)
-+ * @speed_hz: Select a speed other then the device default for this
-+ * transfer. If 0 the default (from spi_device) is used.
-+ * @bits_per_word: select a bits_per_word other then the device default
-+ * for this transfer. If 0 the default (from spi_device) is used.
- * @cs_change: affects chipselect after this transfer completes
- * @delay_usecs: microseconds to delay after this transfer before
- * (optionally) changing the chipselect status, then starting
-@@ -322,7 +328,9 @@ struct spi_transfer {
- dma_addr_t rx_dma;
-
- unsigned cs_change:1;
-+ u8 bits_per_word;
- u16 delay_usecs;
-+ u32 speed_hz;
-
- struct list_head transfer_list;
- };
---- gregkh-2.6.orig/include/linux/spi/spi_bitbang.h
-+++ gregkh-2.6/include/linux/spi/spi_bitbang.h
-@@ -30,6 +30,12 @@ struct spi_bitbang {
-
- struct spi_master *master;
-
-+ /* setup_transfer() changes clock and/or wordsize to match settings
-+ * for this transfer; zeroes restore defaults from spi_device.
-+ */
-+ int (*setup_transfer)(struct spi_device *spi,
-+ struct spi_transfer *t);
-+
- void (*chipselect)(struct spi_device *spi, int is_on);
- #define BITBANG_CS_ACTIVE 1 /* normally nCS, active low */
- #define BITBANG_CS_INACTIVE 0
diff --git a/driver/spi-renamed-bitbang_transfer_setup-to-spi_bitbang_setup_transfer-and-export-it.patch b/driver/spi-renamed-bitbang_transfer_setup-to-spi_bitbang_setup_transfer-and-export-it.patch
deleted file mode 100644
index b81b0adda8e48..0000000000000
--- a/driver/spi-renamed-bitbang_transfer_setup-to-spi_bitbang_setup_transfer-and-export-it.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From galak@kernel.crashing.org Sun Apr 2 14:07:51 2006
-Date: Sun, 2 Apr 2006 16:06:35 -0500 (CDT)
-From: Kumar Gala <galak@kernel.crashing.org>
-To: david-b@pacbell.net
-cc: <spi-devel-general@lists.sourceforge.net>, Greg KH <greg@kroah.com>, Andrew Morton <akpm@osdl.org>
-Subject: SPI: Renamed bitbang_transfer_setup to spi_bitbang_setup_transfer and export it
-Message-ID: <Pine.LNX.4.44.0604021605560.9478-100000@gate.crashing.org>
-
-Renamed bitbang_transfer_setup to follow convention of other exported symbols
-from spi-bitbang. Exported spi_bitbang_setup_transfer to allow users of
-spi-bitbang to use the function in their own setup_transfer.
-
-Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-Cc: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/spi/spi_bitbang.c | 10 ++++++----
- include/linux/spi/spi_bitbang.h | 2 ++
- 2 files changed, 8 insertions(+), 4 deletions(-)
-
---- gregkh-2.6.orig/drivers/spi/spi_bitbang.c
-+++ gregkh-2.6/drivers/spi/spi_bitbang.c
-@@ -138,8 +138,7 @@ static unsigned bitbang_txrx_32(
- return t->len - count;
- }
-
--static int
--bitbang_transfer_setup(struct spi_device *spi, struct spi_transfer *t)
-+int spi_bitbang_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
- {
- struct spi_bitbang_cs *cs = spi->controller_state;
- u8 bits_per_word;
-@@ -174,6 +173,7 @@ bitbang_transfer_setup(struct spi_device
-
- return 0;
- }
-+EXPORT_SYMBOL_GPL(spi_bitbang_setup_transfer);
-
- /**
- * spi_bitbang_setup - default setup for per-word I/O loops
-@@ -203,7 +203,7 @@ int spi_bitbang_setup(struct spi_device
- if (!cs->txrx_word)
- return -EINVAL;
-
-- retval = bitbang_transfer_setup(spi, NULL);
-+ retval = spi_bitbang_setup_transfer(spi, NULL);
- if (retval < 0)
- return retval;
-
-@@ -454,7 +454,9 @@ int spi_bitbang_start(struct spi_bitbang
- bitbang->use_dma = 0;
- bitbang->txrx_bufs = spi_bitbang_bufs;
- if (!bitbang->master->setup) {
-- bitbang->setup_transfer = bitbang_transfer_setup;
-+ if (!bitbang->setup_transfer)
-+ bitbang->setup_transfer =
-+ spi_bitbang_setup_transfer;
- bitbang->master->setup = spi_bitbang_setup;
- bitbang->master->cleanup = spi_bitbang_cleanup;
- }
---- gregkh-2.6.orig/include/linux/spi/spi_bitbang.h
-+++ gregkh-2.6/include/linux/spi/spi_bitbang.h
-@@ -57,6 +57,8 @@ struct spi_bitbang {
- extern int spi_bitbang_setup(struct spi_device *spi);
- extern void spi_bitbang_cleanup(const struct spi_device *spi);
- extern int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m);
-+extern int spi_bitbang_setup_transfer(struct spi_device *spi,
-+ struct spi_transfer *t);
-
- /* start or stop queue processing */
- extern int spi_bitbang_start(struct spi_bitbang *spi);
diff --git a/driver/spi-spi-bounce-buffer-has-a-minimum-length.patch b/driver/spi-spi-bounce-buffer-has-a-minimum-length.patch
deleted file mode 100644
index c7acd0c539756..0000000000000
--- a/driver/spi-spi-bounce-buffer-has-a-minimum-length.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From david-b@pacbell.net Sun Apr 2 11:38:22 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: SPI: spi bounce buffer has a minimum length
-Date: Sun, 2 Apr 2006 10:37:40 -0800
-Cc: Andrew Morton <akpm@osdl.org>
-Message-Id: <200604021137.40719.david-b@pacbell.net>
-
-Make sure that spi_write_then_read() can always handle at least 32 bytes
-of transfer (total, both directions), minimizing one portability issue.
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/spi/spi.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- gregkh-2.6.orig/drivers/spi/spi.c
-+++ gregkh-2.6/drivers/spi/spi.c
-@@ -522,7 +522,8 @@ int spi_sync(struct spi_device *spi, str
- }
- EXPORT_SYMBOL_GPL(spi_sync);
-
--#define SPI_BUFSIZ (SMP_CACHE_BYTES)
-+/* portable code must never pass more than 32 bytes */
-+#define SPI_BUFSIZ max(32,SMP_CACHE_BYTES)
-
- static u8 *buf;
-
diff --git a/driver/spi-spi-whitespace-fixes.patch b/driver/spi-spi-whitespace-fixes.patch
deleted file mode 100644
index f39df4354da85..0000000000000
--- a/driver/spi-spi-whitespace-fixes.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From david-b@pacbell.net Sun Apr 2 11:38:22 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: SPI: spi whitespace fixes
-Date: Sun, 2 Apr 2006 10:33:37 -0800
-Cc: Andrew Morton <akpm@osdl.org>
-Message-Id: <200604021133.38140.david-b@pacbell.net>
-
-This removes superfluous whitespace in the <linux/spi/spi.h> header.
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- include/linux/spi/spi.h | 24 ++++++++++++------------
- 1 file changed, 12 insertions(+), 12 deletions(-)
-
---- gregkh-2.6.orig/include/linux/spi/spi.h
-+++ gregkh-2.6/include/linux/spi/spi.h
-@@ -36,15 +36,15 @@ extern struct bus_type spi_bus_type;
- * @mode: The spi mode defines how data is clocked out and in.
- * This may be changed by the device's driver.
- * @bits_per_word: Data transfers involve one or more words; word sizes
-- * like eight or 12 bits are common. In-memory wordsizes are
-+ * like eight or 12 bits are common. In-memory wordsizes are
- * powers of two bytes (e.g. 20 bit samples use 32 bits).
- * This may be changed by the device's driver.
- * The spi_transfer.bits_per_word can override this for each transfer.
- * @irq: Negative, or the number passed to request_irq() to receive
-- * interrupts from this device.
-+ * interrupts from this device.
- * @controller_state: Controller's runtime state
- * @controller_data: Board-specific definitions for controller, such as
-- * FIFO initialization parameters; from board_info.controller_data
-+ * FIFO initialization parameters; from board_info.controller_data
- *
- * An spi_device is used to interchange data between an SPI slave
- * (usually a discrete chip) and CPU memory.
-@@ -145,13 +145,13 @@ static inline void spi_unregister_driver
- * struct spi_master - interface to SPI master controller
- * @cdev: class interface to this driver
- * @bus_num: board-specific (and often SOC-specific) identifier for a
-- * given SPI controller.
-+ * given SPI controller.
- * @num_chipselect: chipselects are used to distinguish individual
-- * SPI slaves, and are numbered from zero to num_chipselects.
-- * each slave has a chipselect signal, but it's common that not
-- * every chipselect is connected to a slave.
-+ * SPI slaves, and are numbered from zero to num_chipselects.
-+ * each slave has a chipselect signal, but it's common that not
-+ * every chipselect is connected to a slave.
- * @setup: updates the device mode and clocking records used by a
-- * device's SPI controller; protocol code may call this.
-+ * device's SPI controller; protocol code may call this.
- * @transfer: adds a message to the controller's transfer queue.
- * @cleanup: frees controller-specific state
- *
-@@ -276,8 +276,8 @@ extern struct spi_master *spi_busnum_to_
- * for this transfer. If 0 the default (from spi_device) is used.
- * @cs_change: affects chipselect after this transfer completes
- * @delay_usecs: microseconds to delay after this transfer before
-- * (optionally) changing the chipselect status, then starting
-- * the next transfer or completing this spi_message.
-+ * (optionally) changing the chipselect status, then starting
-+ * the next transfer or completing this spi_message.
- * @transfer_list: transfers are sequenced through spi_message.transfers
- *
- * SPI transfers always write the same number of bytes as they read.
-@@ -364,7 +364,7 @@ struct spi_transfer {
- * and its transfers, ignore them until its completion callback.
- */
- struct spi_message {
-- struct list_head transfers;
-+ struct list_head transfers;
-
- struct spi_device *spi;
-
-@@ -382,7 +382,7 @@ struct spi_message {
- */
-
- /* completion is reported through a callback */
-- void (*complete)(void *context);
-+ void (*complete)(void *context);
- void *context;
- unsigned actual_length;
- int status;
diff --git a/driver/spi-spi_bitbang-clocking-fixes.patch b/driver/spi-spi_bitbang-clocking-fixes.patch
deleted file mode 100644
index 082ed054111f5..0000000000000
--- a/driver/spi-spi_bitbang-clocking-fixes.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From david-b@pacbell.net Thu Apr 6 23:03:36 2006
-From: David Brownell <david-b@pacbell.net>
-To: Greg KH <greg@kroah.com>
-Subject: SPI: spi_bitbang: clocking fixes
-Date: Thu, 6 Apr 2006 22:25:56 -0700
-Message-Id: <200604062225.56448.david-b@pacbell.net>
-
-This fixes two problems triggered by the MMC stack updating clocks:
-
- - SPI masters driver should accept a max clock speed of zero; that's one
- convention for marking idle devices. (Presumably that helps controllers
- that don't autogate clocks to "off" when not in use.)
-
- - There are more than 1000 nanoseconds per millisecond; setting the clock
- down to 125 KHz now works properly.
-
-Showing once again that Zero (http://en.wikipedia.org/wiki/Zero) is still
-an inexhaustible number of bugs.
-
-Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
-
----
- drivers/spi/spi_bitbang.c | 24 ++++++++++++++----------
- 1 file changed, 14 insertions(+), 10 deletions(-)
-
---- gregkh-2.6.orig/drivers/spi/spi_bitbang.c
-+++ gregkh-2.6/drivers/spi/spi_bitbang.c
-@@ -167,9 +167,11 @@ int spi_bitbang_setup_transfer(struct sp
- /* nsecs = (clock period)/2 */
- if (!hz)
- hz = spi->max_speed_hz;
-- cs->nsecs = (1000000000/2) / hz;
-- if (cs->nsecs > MAX_UDELAY_MS * 1000)
-- return -EINVAL;
-+ if (hz) {
-+ cs->nsecs = (1000000000/2) / hz;
-+ if (cs->nsecs > (MAX_UDELAY_MS * 1000 * 1000))
-+ return -EINVAL;
-+ }
-
- return 0;
- }
-@@ -184,9 +186,6 @@ int spi_bitbang_setup(struct spi_device
- struct spi_bitbang *bitbang;
- int retval;
-
-- if (!spi->max_speed_hz)
-- return -EINVAL;
--
- bitbang = spi_master_get_devdata(spi->master);
-
- /* REVISIT: some systems will want to support devices using lsb-first
-@@ -216,7 +215,7 @@ int spi_bitbang_setup(struct spi_device
- if (retval < 0)
- return retval;
-
-- dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n",
-+ dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n",
- __FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA),
- spi->bits_per_word, 2 * cs->nsecs);
-
-@@ -405,6 +404,7 @@ int spi_bitbang_transfer(struct spi_devi
- {
- struct spi_bitbang *bitbang;
- unsigned long flags;
-+ int status = 0;
-
- m->actual_length = 0;
- m->status = -EINPROGRESS;
-@@ -414,11 +414,15 @@ int spi_bitbang_transfer(struct spi_devi
- return -ESHUTDOWN;
-
- spin_lock_irqsave(&bitbang->lock, flags);
-- list_add_tail(&m->queue, &bitbang->queue);
-- queue_work(bitbang->workqueue, &bitbang->work);
-+ if (!spi->max_speed_hz)
-+ status = -ENETDOWN;
-+ else {
-+ list_add_tail(&m->queue, &bitbang->queue);
-+ queue_work(bitbang->workqueue, &bitbang->work);
-+ }
- spin_unlock_irqrestore(&bitbang->lock, flags);
-
-- return 0;
-+ return status;
- }
- EXPORT_SYMBOL_GPL(spi_bitbang_transfer);
-
diff --git a/driver/spi-update-to-pxa2xx-spi-driver.patch b/driver/spi-update-to-pxa2xx-spi-driver.patch
deleted file mode 100644
index 5603325cd8b2b..0000000000000
--- a/driver/spi-update-to-pxa2xx-spi-driver.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-From akpm@osdl.org Tue Mar 28 14:05:35 2006
-Message-Id: <200603282205.k2SM5UpW027797@shell0.pdx.osdl.net>
-Subject: spi: Update to PXA2xx SPI Driver
-To: greg@kroah.com
-Cc: akpm@osdl.org, stephen@streetfiresound.com
-From: Stephen Street <stephen@streetfiresound.com>
-Date: Tue, 28 Mar 2006 14:05:23 -0800
-
-From: Stephen Street <stephen@streetfiresound.com>
-
-Fix two outstanding issues with the pxa2xx_spi driver:
-
-1) Bad cast in the function u32_writer. Thanks to Henrik Bechmann
-2) Adds support for per transfer changes to speed and bits per word
-
-Signed-off-by: Stephen Street <stephen@streetfiresound.com>
-Cc: David Brownell <dbrownell@users.sourceforge.net>
-Signed-off-by: Andrew Morton <akpm@osdl.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-
----
- drivers/spi/pxa2xx_spi.c | 82 ++++++++++++++++++++++++++++++++++++++++++-----
- 1 file changed, 75 insertions(+), 7 deletions(-)
-
---- gregkh-2.6.orig/drivers/spi/pxa2xx_spi.c
-+++ gregkh-2.6/drivers/spi/pxa2xx_spi.c
-@@ -120,6 +120,8 @@ struct driver_data {
- dma_addr_t tx_dma;
- size_t rx_map_len;
- size_t tx_map_len;
-+ u8 n_bytes;
-+ u32 dma_width;
- int cs_change;
- void (*write)(struct driver_data *drv_data);
- void (*read)(struct driver_data *drv_data);
-@@ -139,6 +141,8 @@ struct chip_data {
- u32 threshold;
- u32 dma_threshold;
- u8 enable_dma;
-+ u8 bits_per_word;
-+ u32 speed_hz;
- void (*write)(struct driver_data *drv_data);
- void (*read)(struct driver_data *drv_data);
- void (*cs_control)(u32 command);
-@@ -186,7 +190,7 @@ static void null_cs_control(u32 command)
- static void null_writer(struct driver_data *drv_data)
- {
- void *reg = drv_data->ioaddr;
-- u8 n_bytes = drv_data->cur_chip->n_bytes;
-+ u8 n_bytes = drv_data->n_bytes;
-
- while ((read_SSSR(reg) & SSSR_TNF)
- && (drv_data->tx < drv_data->tx_end)) {
-@@ -198,7 +202,7 @@ static void null_writer(struct driver_da
- static void null_reader(struct driver_data *drv_data)
- {
- void *reg = drv_data->ioaddr;
-- u8 n_bytes = drv_data->cur_chip->n_bytes;
-+ u8 n_bytes = drv_data->n_bytes;
-
- while ((read_SSSR(reg) & SSSR_RNE)
- && (drv_data->rx < drv_data->rx_end)) {
-@@ -256,7 +260,7 @@ static void u32_writer(struct driver_dat
-
- while ((read_SSSR(reg) & SSSR_TNF)
- && (drv_data->tx < drv_data->tx_end)) {
-- write_SSDR(*(u16 *)(drv_data->tx), reg);
-+ write_SSDR(*(u32 *)(drv_data->tx), reg);
- drv_data->tx += 4;
- }
- }
-@@ -677,6 +681,10 @@ static void pump_transfers(unsigned long
- struct spi_transfer *previous = NULL;
- struct chip_data *chip = NULL;
- void *reg = drv_data->ioaddr;
-+ u32 clk_div = 0;
-+ u8 bits = 0;
-+ u32 speed = 0;
-+ u32 cr0;
-
- /* Get current state information */
- message = drv_data->cur_msg;
-@@ -713,6 +721,8 @@ static void pump_transfers(unsigned long
- giveback(message, drv_data);
- return;
- }
-+ drv_data->n_bytes = chip->n_bytes;
-+ drv_data->dma_width = chip->dma_width;
- drv_data->cs_control = chip->cs_control;
- drv_data->tx = (void *)transfer->tx_buf;
- drv_data->tx_end = drv_data->tx + transfer->len;
-@@ -724,6 +734,62 @@ static void pump_transfers(unsigned long
- drv_data->write = drv_data->tx ? chip->write : null_writer;
- drv_data->read = drv_data->rx ? chip->read : null_reader;
- drv_data->cs_change = transfer->cs_change;
-+
-+ /* Change speed and bit per word on a per transfer */
-+ if (transfer->speed_hz || transfer->bits_per_word) {
-+
-+ /* Disable clock */
-+ write_SSCR0(chip->cr0 & ~SSCR0_SSE, reg);
-+ cr0 = chip->cr0;
-+ bits = chip->bits_per_word;
-+ speed = chip->speed_hz;
-+
-+ if (transfer->speed_hz)
-+ speed = transfer->speed_hz;
-+
-+ if (transfer->bits_per_word)
-+ bits = transfer->bits_per_word;
-+
-+ if (reg == SSP1_VIRT)
-+ clk_div = SSP1_SerClkDiv(speed);
-+ else if (reg == SSP2_VIRT)
-+ clk_div = SSP2_SerClkDiv(speed);
-+ else if (reg == SSP3_VIRT)
-+ clk_div = SSP3_SerClkDiv(speed);
-+
-+ if (bits <= 8) {
-+ drv_data->n_bytes = 1;
-+ drv_data->dma_width = DCMD_WIDTH1;
-+ drv_data->read = drv_data->read != null_reader ?
-+ u8_reader : null_reader;
-+ drv_data->write = drv_data->write != null_writer ?
-+ u8_writer : null_writer;
-+ } else if (bits <= 16) {
-+ drv_data->n_bytes = 2;
-+ drv_data->dma_width = DCMD_WIDTH2;
-+ drv_data->read = drv_data->read != null_reader ?
-+ u16_reader : null_reader;
-+ drv_data->write = drv_data->write != null_writer ?
-+ u16_writer : null_writer;
-+ } else if (bits <= 32) {
-+ drv_data->n_bytes = 4;
-+ drv_data->dma_width = DCMD_WIDTH4;
-+ drv_data->read = drv_data->read != null_reader ?
-+ u32_reader : null_reader;
-+ drv_data->write = drv_data->write != null_writer ?
-+ u32_writer : null_writer;
-+ }
-+
-+ cr0 = clk_div
-+ | SSCR0_Motorola
-+ | SSCR0_DataSize(bits & 0x0f)
-+ | SSCR0_SSE
-+ | (bits > 16 ? SSCR0_EDSS : 0);
-+
-+ /* Start it back up */
-+ write_SSCR0(cr0, reg);
-+ }
-+
- message->state = RUNNING_STATE;
-
- /* Try to map dma buffer and do a dma transfer if successful */
-@@ -739,13 +805,13 @@ static void pump_transfers(unsigned long
- if (drv_data->rx == drv_data->null_dma_buf)
- /* No target address increment */
- DCMD(drv_data->rx_channel) = DCMD_FLOWSRC
-- | chip->dma_width
-+ | drv_data->dma_width
- | chip->dma_burst_size
- | drv_data->len;
- else
- DCMD(drv_data->rx_channel) = DCMD_INCTRGADDR
- | DCMD_FLOWSRC
-- | chip->dma_width
-+ | drv_data->dma_width
- | chip->dma_burst_size
- | drv_data->len;
-
-@@ -756,13 +822,13 @@ static void pump_transfers(unsigned long
- if (drv_data->tx == drv_data->null_dma_buf)
- /* No source address increment */
- DCMD(drv_data->tx_channel) = DCMD_FLOWTRG
-- | chip->dma_width
-+ | drv_data->dma_width
- | chip->dma_burst_size
- | drv_data->len;
- else
- DCMD(drv_data->tx_channel) = DCMD_INCSRCADDR
- | DCMD_FLOWTRG
-- | chip->dma_width
-+ | drv_data->dma_width
- | chip->dma_burst_size
- | drv_data->len;
-
-@@ -943,6 +1009,7 @@ static int setup(struct spi_device *spi)
- clk_div = SSP3_SerClkDiv(spi->max_speed_hz);
- else
- return -ENODEV;
-+ chip->speed_hz = spi->max_speed_hz;
-
- chip->cr0 = clk_div
- | SSCR0_Motorola
-@@ -987,6 +1054,7 @@ static int setup(struct spi_device *spi)
- kfree(chip);
- return -ENODEV;
- }
-+ chip->bits_per_word = spi->bits_per_word;
-
- spi_set_ctldata(spi, chip);
-
diff --git a/driver/sysfs-crash-debugging.patch b/driver/sysfs-crash-debugging.patch
index 7cb020e65747c..2ab142db9c54c 100644
--- a/driver/sysfs-crash-debugging.patch
+++ b/driver/sysfs-crash-debugging.patch
@@ -35,7 +35,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
NOTIFY_STOP) {
--- gregkh-2.6.orig/arch/x86_64/kernel/traps.c
+++ gregkh-2.6/arch/x86_64/kernel/traps.c
-@@ -436,6 +436,7 @@ void __kprobes __die(const char * str, s
+@@ -438,6 +438,7 @@ void __kprobes __die(const char * str, s
printk("DEBUG_PAGEALLOC");
#endif
printk("\n");