From 343c185b7d7383b1f5b5144e837045af28afc42b Mon Sep 17 00:00:00 2001 From: kaloz Date: Tue, 23 Jun 2009 21:04:37 +0000 Subject: use broken-out patches for the coldfire to make it easier to follow differences against the bsp git-svn-id: svn://svn.openwrt.org/openwrt/trunk@16547 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../linux/coldfire/patches/052-m547x_8x_dspi.patch | 1137 ++++++++++++++++++++ 1 file changed, 1137 insertions(+) create mode 100644 target/linux/coldfire/patches/052-m547x_8x_dspi.patch (limited to 'target/linux/coldfire/patches/052-m547x_8x_dspi.patch') diff --git a/target/linux/coldfire/patches/052-m547x_8x_dspi.patch b/target/linux/coldfire/patches/052-m547x_8x_dspi.patch new file mode 100644 index 000000000..c9277f8cb --- /dev/null +++ b/target/linux/coldfire/patches/052-m547x_8x_dspi.patch @@ -0,0 +1,1137 @@ +From acc2bc0cd419c176820d4a384eb36498a066366d Mon Sep 17 00:00:00 2001 +From: Kurt Mahan +Date: Wed, 30 Apr 2008 14:20:48 -0600 +Subject: [PATCH] DSPI support for M547x/M548x. + +LTIBName: m547x-8x-dspi +Signed-off-by: Kurt Mahan +--- + arch/m68k/coldfire/Makefile | 1 + + arch/m68k/coldfire/m547x_8x-devices.c | 150 +++++++++++++ + drivers/spi/Makefile | 3 +- + drivers/spi/spi_coldfire.c | 382 ++++++++++++++++----------------- + include/asm-m68k/m5485dspi.h | 144 +++++++++++++ + include/asm-m68k/mcfqspi.h | 1 + + include/asm-m68k/mcfsim.h | 1 + + 7 files changed, 485 insertions(+), 197 deletions(-) + create mode 100644 arch/m68k/coldfire/m547x_8x-devices.c + create mode 100644 include/asm-m68k/m5485dspi.h + +--- a/arch/m68k/coldfire/Makefile ++++ b/arch/m68k/coldfire/Makefile +@@ -10,4 +10,5 @@ endif + + obj-$(CONFIG_PCI) += pci.o mcf5445x-pci.o iomap.o + obj-$(CONFIG_M54455) += mcf5445x-devices.o ++obj-$(CONFIG_M547X_8X) += m547x_8x-devices.o + obj-$(CONFIG_MCD_DMA) += m547x_8x-dma.o +--- /dev/null ++++ b/arch/m68k/coldfire/m547x_8x-devices.c +@@ -0,0 +1,150 @@ ++/* ++ * arch/m68k/coldfire/m547x_8x-devices.c ++ * ++ * Coldfire M547x/M548x Platform Device Configuration ++ * ++ * Copyright (c) 2008 Freescale Semiconductor, Inc. ++ * Kurt Mahan ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++ ++#ifdef CONFIG_SPI ++/* ++ * ++ * DSPI ++ * ++ */ ++ ++/* number of supported SPI selects */ ++#define SPI_NUM_CHIPSELECTS 4 ++ ++void coldfire_spi_cs_control(u8 cs, u8 command) ++{ ++ /* nothing special required */ ++} ++ ++static struct spi_board_info spi_board_info[] = { ++ /* no board info */ ++}; ++ ++static int spi_irq_list[] = { ++ /* IRQ, ICR Offset, ICR Val, Mask */ ++ 64 + ISC_DSPI_OVRFW, 0, 0, 0, ++ 64 + ISC_DSPI_RFOF, 0, 0, 0, ++ 64 + ISC_DSPI_RFDF, 0, 0, 0, ++ 64 + ISC_DSPI_TFUF, 0, 0, 0, ++ 64 + ISC_DSPI_TCF, 0, 0, 0, ++ 64 + ISC_DSPI_TFFF, 0, 0, 0, ++ 64 + ISC_DSPI_EOQF, 0, 0, 0, ++ 0,0,0,0, ++}; ++ ++static struct coldfire_spi_master coldfire_master_info = { ++ .bus_num = 1, ++ .num_chipselect = SPI_NUM_CHIPSELECTS, ++ .irq_list = spi_irq_list, ++ .irq_source = 0, /* not used */ ++ .irq_vector = 0, /* not used */ ++ .irq_mask = 0, /* not used */ ++ .irq_lp = 0, /* not used */ ++ .par_val = 0, /* not used */ ++ .cs_control = coldfire_spi_cs_control, ++}; ++ ++static struct resource coldfire_spi_resources[] = { ++ [0] = { ++ .name = "spi-par", ++ .start = MCF_MBAR + 0x00000a50, /* PAR_DSPI */ ++ .end = MCF_MBAR + 0x00000a50, /* PAR_DSPI */ ++ .flags = IORESOURCE_MEM ++ }, ++ ++ [1] = { ++ .name = "spi-module", ++ .start = MCF_MBAR + 0x00008a00, /* DSPI MCR Base */ ++ .end = MCF_MBAR + 0x00008ab8, /* DSPI mem map end */ ++ .flags = IORESOURCE_MEM ++ }, ++ ++ [2] = { ++ .name = "spi-int-level", ++ .start = MCF_MBAR + 0x740, /* ICR start */ ++ .end = MCF_MBAR + 0x740 + ISC_DSPI_EOQF, /* ICR end */ ++ .flags = IORESOURCE_MEM ++ }, ++ ++ [3] = { ++ .name = "spi-int-mask", ++ .start = MCF_MBAR + 0x70c, /* IMRL */ ++ .end = MCF_MBAR + 0x70c, /* IMRL */ ++ .flags = IORESOURCE_MEM ++ } ++}; ++ ++static struct platform_device coldfire_spi = { ++ .name = "spi_coldfire", ++ .id = -1, ++ .resource = coldfire_spi_resources, ++ .num_resources = ARRAY_SIZE(coldfire_spi_resources), ++ .dev = { ++ .platform_data = &coldfire_master_info, ++ } ++}; ++ ++/** ++ * m547x_8x_spi_init - Initialize SPI ++ */ ++static int __init m547x_8x_spi_init(void) ++{ ++ int retval; ++ ++ /* initialize the DSPI PAR */ ++ MCF_GPIO_PAR_DSPI = (MCF_GPIO_PAR_DSPI_PAR_CS5 | ++ MCF_GPIO_PAR_DSPI_PAR_CS3_DSPICS | ++ MCF_GPIO_PAR_DSPI_PAR_CS2_DSPICS | ++ MCF_GPIO_PAR_DSPI_PAR_CS0_DSPICS | ++ MCF_GPIO_PAR_DSPI_PAR_SCK_SCK | ++ MCF_GPIO_PAR_DSPI_PAR_SIN_SIN | ++ MCF_GPIO_PAR_DSPI_PAR_SOUT_SOUT); ++ ++ /* register device */ ++ retval = platform_device_register(&coldfire_spi); ++ if (retval < 0) { ++ printk(KERN_ERR "SPI-m547x_8x: platform_device_register failed with code=%d\n", retval); ++ goto out; ++ } ++ ++ /* register board info */ ++ if (ARRAY_SIZE(spi_board_info)) ++ retval = spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); ++ ++out: ++ return retval; ++} ++#endif ++ ++ ++/** ++ * m547x_8x_init_devices - Initialize M547X_8X devices ++ * ++ * Returns 0 on success. ++ */ ++static int __init m547x_8x_init_devices(void) ++{ ++#ifdef CONFIG_SPI ++ m547x_8x_spi_init(); ++#endif ++ ++ return 0; ++} ++arch_initcall(m547x_8x_init_devices); +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -18,7 +18,8 @@ obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx. + obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o + obj-$(CONFIG_SPI_AU1550) += au1550_spi.o + obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o +-obj-$(CONFIG_SPI_COLDFIRE) += spi_coldfire.o spi-m5445x.o ++# obj-$(CONFIG_SPI_COLDFIRE) += spi_coldfire.o spi-m5445x.o ++obj-$(CONFIG_SPI_COLDFIRE) += spi_coldfire.o + obj-$(CONFIG_SPI_GPIO) += spi_gpio.o + obj-$(CONFIG_SPI_IMX) += spi_imx.o + obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o +--- a/drivers/spi/spi_coldfire.c ++++ b/drivers/spi/spi_coldfire.c +@@ -1,29 +1,39 @@ +-/****************************************************************************/ +- + /* +- * spi_coldfire.c - Master QSPI/DSPI controller for the ColdFire processors ++ * spi_coldfire.c - Master QSPI/DSPI controller for the ColdFire processors ++ * + * + * (C) Copyright 2005, Intec Automation, + * Mike Lavender (mike@steroidmicros) + * +- * (C) Copyright 2007, Freescale Inc, +- * Yaroslav Vinogradov (yaroslav.vinogradov@freescale.com) ++ * (C) Copyright 2007-2008, Freescale Inc, ++ * Yaroslav Vinogradov ++ * Andrey Butok ++ * Kurt Mahan + * +- +- 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. */ +-/* ------------------------------------------------------------------------- */ ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ *************************************************************************** ++ * Changes: ++ * v0.003 12 February 2008 Andrey Butok, Freescale Semiconductor ++ * Added suport of MCF5227x DSPI module. ++ * v0.002 2007 Yaroslav Vinogradov, Freescale Semiconductor ++ * Added suport of MCF5445x DSPI module. ++ * v0.001 2005 Mike Lavender, Intec Automation, ++ * Intial version. Coldfire QSPI master driver. ++ * ++ */ + + + /****************************************************************************/ +@@ -46,41 +56,52 @@ + #include + #include + #include +-#include + + #if defined(CONFIG_M54455) ++ #include ++ + #define SPI_DSPI + #if defined(CONFIG_SPI_COLDFIRE_DSPI_EDMA) + #define SPI_DSPI_EDMA + #ifdef CONFIG_MMU + #define SPI_USE_MMU + #endif ++ #include + #endif ++ ++ #include + #endif + +-#ifdef SPI_DSPI +-#include ++#if defined(CONFIG_M547X_8X) ++ #define SPI_DSPI ++ ++ #include ++ #include ++#endif + ++#ifdef CONFIG_M5227x ++ #define SPI_DSPI + ++ #if defined(CONFIG_SPI_COLDFIRE_DSPI_EDMA) ++ #define SPI_DSPI_EDMA ++ #endif + #endif + ++ + #if defined(SPI_DSPI_EDMA) + + /* edma buffer size in transfer units (32bits) */ + #define EDMA_BUFFER_SIZE (PAGE_SIZE/4) +-#define EDMA_BUFSIZE_KMALLOC (EDMA_BUFFER_SIZE*4) +- +-#define DSPI_DMA_RX_TCD 12 +-#define DSPI_DMA_TX_TCD 13 ++#define EDMA_BUFSIZE_KMALLOC (EDMA_BUFFER_SIZE*4) + ++#define DSPI_DMA_RX_TCD MCF_EDMA_CHAN_DSPI_RX ++#define DSPI_DMA_TX_TCD MCF_EDMA_CHAN_DSPI_TX + +-#include +-#include ++#include + #endif + +- + MODULE_AUTHOR("Mike Lavender"); +-MODULE_DESCRIPTION("ColdFire QSPI Contoller"); ++MODULE_DESCRIPTION("ColdFire SPI Contoller"); + MODULE_LICENSE("GPL"); + + #define DRIVER_NAME "Coldfire QSPI/DSPI" +@@ -92,7 +113,6 @@ MODULE_LICENSE("GPL"); + */ + + #define QSPI_RAM_SIZE 0x10 /* 16 word table */ +- + #define QSPI_TRANSMIT_RAM 0x00 + #define QSPI_RECEIVE_RAM 0x10 + #define QSPI_COMMAND_RAM 0x20 +@@ -296,13 +316,10 @@ struct driver_data { + u32 *dspi_rser; /* DSPI RSER register */ + u32 *dspi_sr; /* DSPI status register */ + u8 dspi_ctas; /* DSPI CTAS value*/ +- + #if defined(SPI_DSPI_EDMA) + void* edma_tx_buf; + void* edma_rx_buf; + #endif +- +- + #else + u16 *qmr; /* QSPI mode register */ + u16 *qdlyr; /* QSPI delay register */ +@@ -312,7 +329,11 @@ struct driver_data { + u16 *qdr; /* QSPI data register */ + u16 *qcr; /* QSPI command register */ + #endif ++#if defined(CONFIG_M532x) || defined(CONFIG_M537x) ++ u16 *par; /* Pin assignment register */ ++#else + u8 *par; /* Pin assignment register */ ++#endif + u8 *int_icr; /* Interrupt level and priority register */ + u32 *int_mr; /* Interrupt mask register */ + void (*cs_control)(u8 cs, u8 command); +@@ -327,8 +348,6 @@ struct driver_data { + * SPI local functions + */ + +-//#define SPI_COLDFIRE_DEBUG +- + static void *next_transfer(struct driver_data *drv_data) + { + struct spi_message *msg = drv_data->cur_msg; +@@ -387,11 +406,9 @@ static int write(struct driver_data *drv + int tx_word; + + #if defined(SPI_DSPI) +- + #if defined(SPI_DSPI_EDMA) + u32* edma_wr; + #endif +- + u16 d16; + u8 d8; + u32 dspi_pushr; +@@ -400,9 +417,9 @@ static int write(struct driver_data *drv + + tx_word = is_word_transfer(drv_data); + +- // If we are in word mode, but only have a single byte to transfer +- // then switch to byte mode temporarily. Will switch back at the +- // end of the transfer. ++ /* If we are in word mode, but only have a single byte to transfer ++ * then switch to byte mode temporarily. Will switch back at the ++ * end of the transfer. */ + if (tx_word && ((drv_data->tx_end - drv_data->tx) == 1)) { + drv_data->flags |= TRAN_STATE_WORD_ODD_NUM; + set_8bit_transfer_mode(drv_data); +@@ -411,12 +428,10 @@ static int write(struct driver_data *drv + + + #if defined(SPI_DSPI) +- + #if defined(SPI_DSPI_EDMA) + edma_wr = (u32*)(drv_data->edma_tx_buf); + #endif + +- + #if defined(SPI_DSPI_EDMA) + while ((drv_data->tx < drv_data->tx_end) && (tx_count < EDMA_BUFFER_SIZE)) { + #else +@@ -432,19 +447,16 @@ static int write(struct driver_data *drv + } + + dspi_pushr = MCF_DSPI_DTFR_TXDATA(d16) +- | DSPI_CS(drv_data->cs) +- | MCF_DSPI_DTFR_CTAS(drv_data->dspi_ctas) +- //| MCF_DSPI_DTFR_CONT +- ; +- ++ | DSPI_CS(drv_data->cs) ++ | MCF_DSPI_DTFR_CTAS(drv_data->dspi_ctas); + drv_data->tx += 2; + + #if defined(SPI_DSPI_EDMA) + if (drv_data->tx == drv_data->tx_end || tx_count==EDMA_BUFFER_SIZE-1) { +-#else ++#else + if (drv_data->tx == drv_data->tx_end || tx_count==DSPI_FIFO_SIZE-1) { +-#endif +- // last transfer in queue ++#endif ++ /* last transfer in the queue */ + dspi_pushr |= MCF_DSPI_DTFR_EOQ; + if (drv_data->cs_change) { + dspi_pushr &= ~MCF_DSPI_DTFR_CONT; +@@ -453,14 +465,13 @@ static int write(struct driver_data *drv + + if (first) { + first = 0; +- dspi_pushr |= MCF_DSPI_DTFR_CTCNT; // clear counter ++ dspi_pushr |= MCF_DSPI_DTFR_CTCNT; /* clear counter */ + } + #if defined(SPI_DSPI_EDMA) + *edma_wr = dspi_pushr; +- edma_wr++; ++ edma_wr++; + #else + *drv_data->dspi_dtfr = dspi_pushr; +- //MCF_DSPI_DTFR = dspi_pushr; + #endif + + +@@ -473,14 +484,13 @@ static int write(struct driver_data *drv + + dspi_pushr = MCF_DSPI_DTFR_TXDATA(d8) + | DSPI_CS(drv_data->cs) +- /* | MCF_DSPI_DTFR_PCS5 | */ + | MCF_DSPI_DTFR_CTAS(drv_data->dspi_ctas) + | MCF_DSPI_DTFR_CONT; + + drv_data->tx++; + + if (drv_data->tx == drv_data->tx_end || tx_count==DSPI_FIFO_SIZE-1) { +- // last transfer in queue ++ /* last transfer in the queue */ + dspi_pushr |= MCF_DSPI_DTFR_EOQ; + if (drv_data->cs_change) { + dspi_pushr &= ~MCF_DSPI_DTFR_CONT; +@@ -489,16 +499,15 @@ static int write(struct driver_data *drv + + if (first) { + first = 0; +- dspi_pushr |= MCF_DSPI_DTFR_CTCNT; // clear counter ++ dspi_pushr |= MCF_DSPI_DTFR_CTCNT; /* clear counter */ + } + + #if defined(SPI_DSPI_EDMA) + *edma_wr = dspi_pushr; +- edma_wr++; +-#else ++ edma_wr++; ++#else + *drv_data->dspi_dtfr = dspi_pushr; +- //MCF_DSPI_DTFR = dspi_pushr; +-#endif ++#endif + + } + tx_count++; +@@ -508,8 +517,8 @@ static int write(struct driver_data *drv + + if (tx_count>0) { + +- // TODO: initiate eDMA transfer +- set_edma_params(DSPI_DMA_TX_TCD, ++ /* TBD: initiate eDMA transfer */ ++ mcf_edma_set_tcd_params(DSPI_DMA_TX_TCD, + #ifdef SPI_USE_MMU + virt_to_phys(drv_data->edma_tx_buf), + #else +@@ -517,18 +526,18 @@ static int write(struct driver_data *drv + #endif + (u32)drv_data->dspi_dtfr, + MCF_EDMA_TCD_ATTR_SSIZE_32BIT | MCF_EDMA_TCD_ATTR_DSIZE_32BIT, +- 4, // soff +- 4, // nbytes +- 0, // slast +- tx_count, // citer +- tx_count, // biter +- 0, // doff +- 0, // dlastsga +- 0, // major_int +- 1 // disable_req ++ 4, /* soff */ ++ 4, /* nbytes */ ++ 0, /* slast */ ++ tx_count, /* citer */ ++ tx_count, /* biter */ ++ 0, /* doff */ ++ 0, /* dlastsga */ ++ 0, /* major_int */ ++ 1 /* disable_req */ + ); + +- set_edma_params(DSPI_DMA_RX_TCD, ++ mcf_edma_set_tcd_params(DSPI_DMA_RX_TCD, + (u32)drv_data->dspi_drfr, + #ifdef SPI_USE_MMU + virt_to_phys(drv_data->edma_rx_buf), +@@ -536,20 +545,20 @@ static int write(struct driver_data *drv + drv_data->edma_rx_buf, + #endif + MCF_EDMA_TCD_ATTR_SSIZE_32BIT | MCF_EDMA_TCD_ATTR_DSIZE_32BIT, +- 0, // soff +- 4, // nbytes +- 0, // slast +- tx_count, // citer +- tx_count, // biter +- 4, // doff +- 0, // dlastsga +- 0, // major_int +- 1 // disable_req ++ 0, /* soff */ ++ 4, /* nbytes */ ++ 0, /* slast */ ++ tx_count, /* citer */ ++ tx_count, /* biter */ ++ 4, /* doff */ ++ 0, /* dlastsga */ ++ 0, /* major_int */ ++ 1 /* disable_req */ + ); + + +- start_edma_transfer(DSPI_DMA_TX_TCD); // transmit SPI data +- start_edma_transfer(DSPI_DMA_RX_TCD); // receive SPI data ++ start_edma_transfer(DSPI_DMA_TX_TCD); /* transmit SPI data */ ++ start_edma_transfer(DSPI_DMA_RX_TCD); /* receive SPI data */ + } + #endif + +@@ -583,9 +592,9 @@ static int write(struct driver_data *drv + | QCR_CONT + | (~((0x01 << drv_data->cs) << 8) & 0x0F00); + +- if ( (cmd_count == tx_count - 1) +- && (drv_data->tx == drv_data->tx_end) +- && (drv_data->cs_change) ) { ++ if ( (cmd_count == tx_count - 1) ++ && (drv_data->tx == drv_data->tx_end) ++ && (drv_data->cs_change) ) { + qcr &= ~QCR_CONT; + } + *drv_data->qcr = qcr; +@@ -613,7 +622,6 @@ static int read(struct driver_data *drv_ + rx_word = is_word_transfer(drv_data); + + #if defined(SPI_DSPI) +- + #if defined(SPI_DSPI_EDMA) + rx_edma = (u32*) drv_data->edma_tx_buf; + while ((drv_data->rx < drv_data->rx_end) && (rx_count < EDMA_BUFFER_SIZE)) { +@@ -646,10 +654,7 @@ static int read(struct driver_data *drv_ + } + rx_count++; + } +- +- + #else +- + *drv_data->qar = QSPI_RECEIVE_RAM; + while ((drv_data->rx < drv_data->rx_end) && (rx_count < QSPI_RAM_SIZE)) { + if (rx_word) { +@@ -680,19 +685,18 @@ static inline void qspi_setup_chip(struc + + *drv_data->mcr = chip->mcr_val; + +- // TODO: remove later ++ /* TBD: remove later */ ++/* JKM -- validate */ + chip->ctar_val = 0x78560118; + + *drv_data->ctar = chip->ctar_val; + *drv_data->dspi_rser = 0 +- | MCF_DSPI_DRSER_EOQFE ++ | MCF_DSPI_DRSER_EOQFE + #if defined(SPI_DSPI_EDMA) +- | MCF_DSPI_DRSER_TFFFE +- | MCF_DSPI_DRSER_TFFFS ++ | MCF_DSPI_DRSER_TFFFE ++ | MCF_DSPI_DRSER_TFFFS + #endif +- ; +- +- ++ ; + #else + *drv_data->qmr = chip->qmr_val; + *drv_data->qdlyr = chip->qdlyr_val; +@@ -770,7 +774,6 @@ static irqreturn_t qspi_interrupt(int ir + * transfer tasklet + */ + if (drv_data->flags & TRAN_STATE_WORD_ODD_NUM) { +- //*drv_data->qmr &= ~QMR_BITS; + set_16bit_transfer_mode(drv_data); + } + +@@ -857,10 +860,8 @@ static void pump_transfers(unsigned long + if (message->state == START_STATE) { + qspi_setup_chip(drv_data); + +- if (drv_data->cs_control) { +- //printk( "m s\n" ); +- drv_data->cs_control(message->spi->chip_select, QSPI_CS_ASSERT); +- } ++ if (drv_data->cs_control) ++ drv_data->cs_control(message->spi->chip_select, QSPI_CS_ASSERT); + } + + /* Delay if requested at end of transfer*/ +@@ -902,12 +903,12 @@ static void pump_transfers(unsigned long + } + + +-static void pump_messages(struct work_struct * work) ++static void pump_messages(struct work_struct *work) + { + struct driver_data *drv_data; + unsigned long flags; + +- drv_data = container_of(work, struct driver_data, pump_messages); ++ drv_data = container_of(work, struct driver_data, pump_messages); + + /* Lock queue and check for queue work */ + spin_lock_irqsave(&drv_data->lock, flags); +@@ -1002,7 +1003,7 @@ static int setup(struct spi_device *spi) + chip->mcr.cont_scke = 0; + chip->mcr.dconf = 0; + chip->mcr.frz = 0; +- chip->mcr.mtfe = 1; ++ chip->mcr.mtfe = 0; + chip->mcr.pcsse = 0; + chip->mcr.rooe = 0; + chip->mcr.pcsis = 0xFF; +@@ -1019,7 +1020,7 @@ static int setup(struct spi_device *spi) + if ((spi->bits_per_word >= 4) && (spi->bits_per_word <= 16)) { + chip->ctar.fmsz = spi->bits_per_word-1; + } else { +- printk(KERN_ERR "coldfire-qspi: invalid wordsize\n"); ++ printk(KERN_ERR "coldfire-spi: invalid wordsize\n"); + kfree(chip); + return -ENODEV; + } +@@ -1056,9 +1057,9 @@ static int setup(struct spi_device *spi) + + #else + +- chip->qwr.csiv = 1; // Chip selects are active low +- chip->qmr.master = 1; // Must set to master mode +- chip->qmr.dohie = 1; // Data output high impediance enabled ++ chip->qwr.csiv = 1; /* Chip selects are active low */ ++ chip->qmr.master = 1; /* Must set to master mode */ ++ chip->qmr.dohie = 1; /* Data output high impediance enabled */ + chip->void_write_data = chip_info->void_write_data; + + chip->qdlyr.qcd = chip_info->del_cs_to_clk; +@@ -1075,8 +1076,8 @@ static int setup(struct spi_device *spi) + + chip->qmr.baud = baud_divisor; + +- //printk( "QSPI: spi->max_speed_hz %d\n", spi->max_speed_hz ); +- //printk( "QSPI: Baud set to %d\n", chip->qmr.baud ); ++ /*printk( "SPI: spi->max_speed_hz %d\n", spi->max_speed_hz );*/ ++ /*printk( "SPI: Baud set to %d\n", chip->qmr.baud );*/ + + if (spi->mode & SPI_CPHA) + chip->qmr.cpha = 1; +@@ -1089,7 +1090,7 @@ static int setup(struct spi_device *spi) + } else if ((spi->bits_per_word >= 8) && (spi->bits_per_word <= 15)) { + chip->qmr.bits = spi->bits_per_word; + } else { +- printk(KERN_ERR "coldfire-qspi: invalid wordsize\n"); ++ printk(KERN_ERR "coldfire-spi: invalid wordsize\n"); + kfree(chip); + return -ENODEV; + } +@@ -1112,7 +1113,7 @@ static int init_queue(struct driver_data + tasklet_init(&drv_data->pump_transfers, + pump_transfers, (unsigned long)drv_data); + +- INIT_WORK(&drv_data->pump_messages, pump_messages/*, drv_data*/); ++ INIT_WORK(&drv_data->pump_messages, pump_messages); + + drv_data->workqueue = create_singlethread_workqueue( + drv_data->master->dev.parent->bus_id); +@@ -1185,7 +1186,7 @@ static int destroy_queue(struct driver_d + } + + +-static void cleanup(const struct spi_device *spi) ++static void cleanup(struct spi_device *spi) + { + struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi); + +@@ -1213,11 +1214,7 @@ static int coldfire_spi_probe(struct pla + int status = 0; + int i; + +-#if defined(SPI_DSPI_EDMA) +- init_edma(); +-#endif +- +- platform_info = (struct coldfire_spi_master *)pdev->dev.platform_data; ++ platform_info = (struct coldfire_spi_master *)pdev->dev.platform_data; + + master = spi_alloc_master(dev, sizeof(struct driver_data)); + if (!master) +@@ -1241,7 +1238,7 @@ static int coldfire_spi_probe(struct pla + drv_data->cs_control(i, QSPI_CS_INIT | QSPI_CS_DROP); + + /* Setup register addresses */ +- memory_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi-module"); ++ memory_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spi-module"); + if (!memory_resource) { + dev_dbg(dev, "can not find platform module memory\n"); + goto out_error_master_alloc; +@@ -1259,13 +1256,13 @@ static int coldfire_spi_probe(struct pla + dev_dbg(dev, "cannot allocate eDMA RX memory\n"); + goto out_error_master_alloc; + } +-#endif ++#endif + + #if defined(SPI_DSPI) + +- drv_data->mcr = (void *)(memory_resource->start + 0x00000000); +- drv_data->ctar = (void *)(memory_resource->start + 0x0000000C); +- drv_data->dspi_sr = (void *)(memory_resource->start + 0x0000002C); ++ drv_data->mcr = (void *)(memory_resource->start + 0x00000000); ++ drv_data->ctar = (void *)(memory_resource->start + 0x0000000C); ++ drv_data->dspi_sr = (void *)(memory_resource->start + 0x0000002C); + drv_data->dspi_rser = (void *)(memory_resource->start + 0x00000030); + drv_data->dspi_dtfr = (void *)(memory_resource->start + 0x00000034); + drv_data->dspi_drfr = (void *)(memory_resource->start + 0x00000038); +@@ -1283,7 +1280,7 @@ static int coldfire_spi_probe(struct pla + #endif + + /* Setup register addresses */ +- memory_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi-par"); ++ memory_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spi-par"); + if (!memory_resource) { + dev_dbg(dev, "can not find platform par memory\n"); + goto out_error_master_alloc; +@@ -1292,7 +1289,7 @@ static int coldfire_spi_probe(struct pla + drv_data->par = (void *)memory_resource->start; + + /* Setup register addresses */ +- memory_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi-int-level"); ++ memory_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spi-int-level"); + if (!memory_resource) { + dev_dbg(dev, "can not find platform par memory\n"); + goto out_error_master_alloc; +@@ -1301,7 +1298,7 @@ static int coldfire_spi_probe(struct pla + drv_data->int_icr = (void *)memory_resource->start; + + /* Setup register addresses */ +- memory_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi-int-mask"); ++ memory_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spi-int-mask"); + if (!memory_resource) { + dev_dbg(dev, "can not find platform par memory\n"); + goto out_error_master_alloc; +@@ -1309,32 +1306,52 @@ static int coldfire_spi_probe(struct pla + + drv_data->int_mr = (void *)memory_resource->start; + +- irq = platform_info->irq_vector; ++ if (platform_info->irq_list) { ++ /* multiple IRQs */ ++ int *irqlist = platform_info->irq_list; ++ while ((irq = *irqlist++)) { ++ int off = *irqlist++; ++ int lvl = *irqlist++; ++ int msk = *irqlist++; ++ status = request_irq(irq, qspi_interrupt, IRQF_DISABLED, ++ dev->bus_id, drv_data); ++ if (status < 0) { ++ dev_err(&pdev->dev, ++ "unable to attach ColdFire DSPI interrupt\n"); ++ goto out_error_master_alloc; ++ } ++ ++ if (lvl) ++ *(drv_data->int_icr + off) = lvl; + +- status = request_irq(platform_info->irq_vector, qspi_interrupt, IRQF_DISABLED, dev->bus_id, drv_data); +- if (status < 0) { +- dev_err(&pdev->dev, "unable to attach ColdFire QSPI interrupt\n"); +- goto out_error_master_alloc; ++ if (msk) ++ *drv_data->int_mr &= ~msk; ++ } + } ++ else { ++ irq = platform_info->irq_vector; + +- /* Now that we have all the addresses etc. Let's set it up */ +- // TODO: +- //*drv_data->par = platform_info->par_val; ++ status = request_irq(platform_info->irq_vector, qspi_interrupt, ++ IRQF_DISABLED, dev->bus_id, drv_data); ++ if (status < 0) { ++ dev_err(&pdev->dev, "unable to attach ColdFire QSPI interrupt\n"); ++ goto out_error_master_alloc; ++ } + +- MCF_GPIO_PAR_DSPI = 0 +- | MCF_GPIO_PAR_DSPI_PCS5_PCS5 +- | MCF_GPIO_PAR_DSPI_PCS2_PCS2 +- | MCF_GPIO_PAR_DSPI_PCS1_PCS1 +- | MCF_GPIO_PAR_DSPI_PCS0_PCS0 +- | MCF_GPIO_PAR_DSPI_SIN_SIN +- | MCF_GPIO_PAR_DSPI_SOUT_SOUT +- | MCF_GPIO_PAR_DSPI_SCK_SCK; ++ *drv_data->int_icr = platform_info->irq_lp; ++ *drv_data->int_mr &= ~platform_info->irq_mask; ++ } ++ ++ /* Now that we have all the addresses etc. Let's set it up */ ++ if (platform_info->par_val) ++ *drv_data->par = platform_info->par_val; + +- *drv_data->int_icr = platform_info->irq_lp; +- *drv_data->int_mr &= ~platform_info->irq_mask; ++#ifdef CONFIG_M5227x ++ MCF_GPIO_PAR_IRQ = 0x04; /* Mistake in RM documentation */ ++#endif + + #ifdef SPI_DSPI +- drv_data->dspi_ctas = 0; // TODO: change later ++ drv_data->dspi_ctas = 0; /* TBD: change later */ + #endif + + /* Initial and start queue */ +@@ -1359,40 +1376,37 @@ static int coldfire_spi_probe(struct pla + } + + #if defined(SPI_DSPI_EDMA) +- if (request_edma_channel(DSPI_DMA_TX_TCD, +- edma_tx_handler, +- NULL, +- pdev, +- NULL, /* spinlock */ +- DRIVER_NAME +- )!=0) +- { ++ if (mcf_edma_request_channel(DSPI_DMA_TX_TCD, ++ edma_tx_handler, ++ NULL, ++ pdev, ++ NULL, /* spinlock */ ++ DRIVER_NAME ++ )!=0) { + dev_err(&pdev->dev, "problem requesting edma transmit channel\n"); + status = -EINVAL; +- goto out_error_queue_alloc; ++ goto out_error_queue_alloc; + } + +- if (request_edma_channel(DSPI_DMA_RX_TCD, +- edma_rx_handler, +- NULL, +- pdev, +- NULL, /* spinlock */ +- DRIVER_NAME +- )!=0) +- { ++ if (mcf_edma_request_channel(DSPI_DMA_RX_TCD, ++ edma_rx_handler, ++ NULL, ++ pdev, ++ NULL, /* spinlock */ ++ DRIVER_NAME ++ )!=0) { + dev_err(&pdev->dev, "problem requesting edma receive channel\n"); + status = -EINVAL; +- goto out_edma_transmit; ++ goto out_edma_transmit; + } + #endif + +- printk( "SPI: Coldfire master initialized\n" ); +- //dev_info(&pdev->dev, "driver initialized\n"); ++ printk(KERN_INFO "SPI: Coldfire master initialized\n" ); + return status; + + #if defined(SPI_DSPI_EDMA) + out_edma_transmit: +- free_edma_channel(DSPI_DMA_TX_TCD, pdev); ++ mcf_edma_free_channel(DSPI_DMA_TX_TCD, pdev); + #endif + + out_error_queue_alloc: +@@ -1417,8 +1431,8 @@ static int coldfire_spi_remove(struct pl + return 0; + + #if defined(SPI_DSPI_EDMA) +- free_edma_channel(DSPI_DMA_TX_TCD, pdev); +- free_edma_channel(DSPI_DMA_RX_TCD, pdev); ++ mcf_edma_free_channel(DSPI_DMA_TX_TCD, pdev); ++ mcf_edma_free_channel(DSPI_DMA_RX_TCD, pdev); + #endif + + /* Remove the queue */ +@@ -1426,27 +1440,8 @@ static int coldfire_spi_remove(struct pl + 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 */ ++/* JKM -- check for list and remove list */ + irq = platform_get_irq(pdev, 0); + if (irq >= 0) + free_irq(irq, drv_data); +@@ -1496,8 +1491,6 @@ static int coldfire_spi_suspend(struct p + 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; + } +@@ -1507,9 +1500,6 @@ static int coldfire_spi_resume(struct pl + 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/null ++++ b/include/asm-m68k/m5485dspi.h +@@ -0,0 +1,144 @@ ++/* ++ * File: mcf548x_dspi.h ++ * Purpose: Register and bit definitions for the MCF548X ++ * ++ * Notes: ++ * ++ */ ++ ++#ifndef _M5485DSPI_H_ ++#define _M5485DSPI_H_ ++ ++/* ++ * ++ * DMA Serial Peripheral Interface (DSPI) ++ * ++ */ ++ ++/* Register read/write macros */ ++#define MCF_DSPI_DMCR MCF_REG32(0x008A00) ++#define MCF_DSPI_DTCR MCF_REG32(0x008A08) ++#define MCF_DSPI_DCTAR0 MCF_REG32(0x008A0C) ++#define MCF_DSPI_DCTAR1 MCF_REG32(0x008A10) ++#define MCF_DSPI_DCTAR2 MCF_REG32(0x008A14) ++#define MCF_DSPI_DCTAR3 MCF_REG32(0x008A18) ++#define MCF_DSPI_DCTAR4 MCF_REG32(0x008A1C) ++#define MCF_DSPI_DCTAR5 MCF_REG32(0x008A20) ++#define MCF_DSPI_DCTAR6 MCF_REG32(0x008A24) ++#define MCF_DSPI_DCTAR7 MCF_REG32(0x008A28) ++#define MCF_DSPI_DCTARn(x) MCF_REG32(0x008A0C+(x*4)) ++#define MCF_DSPI_DSR MCF_REG32(0x008A2C) ++#define MCF_DSPI_DRSER MCF_REG32(0x008A30) ++#define MCF_DSPI_DTFR MCF_REG32(0x008A34) ++#define MCF_DSPI_DRFR MCF_REG32(0x008A38) ++#define MCF_DSPI_DTFDR0 MCF_REG32(0x008A3C) ++#define MCF_DSPI_DTFDR1 MCF_REG32(0x008A40) ++#define MCF_DSPI_DTFDR2 MCF_REG32(0x008A44) ++#define MCF_DSPI_DTFDR3 MCF_REG32(0x008A48) ++#define MCF_DSPI_DTFDRn(x) MCF_REG32(0x008A3C+(x*4)) ++#define MCF_DSPI_DRFDR0 MCF_REG32(0x008A7C) ++#define MCF_DSPI_DRFDR1 MCF_REG32(0x008A80) ++#define MCF_DSPI_DRFDR2 MCF_REG32(0x008A84) ++#define MCF_DSPI_DRFDR3 MCF_REG32(0x008A88) ++#define MCF_DSPI_DRFDRn(x) MCF_REG32(0x008A7C+(x*4)) ++ ++/* Bit definitions and macros for MCF_DSPI_DMCR */ ++#define MCF_DSPI_DMCR_HALT (0x00000001) ++#define MCF_DSPI_DMCR_SMPL_PT(x) (((x)&0x00000003)<<8) ++#define MCF_DSPI_DMCR_CRXF (0x00000400) ++#define MCF_DSPI_DMCR_CTXF (0x00000800) ++#define MCF_DSPI_DMCR_DRXF (0x00001000) ++#define MCF_DSPI_DMCR_DTXF (0x00002000) ++#define MCF_DSPI_DMCR_CSIS0 (0x00010000) ++#define MCF_DSPI_DMCR_CSIS2 (0x00040000) ++#define MCF_DSPI_DMCR_CSIS3 (0x00080000) ++#define MCF_DSPI_DMCR_CSIS5 (0x00200000) ++#define MCF_DSPI_DMCR_ROOE (0x01000000) ++#define MCF_DSPI_DMCR_PCSSE (0x02000000) ++#define MCF_DSPI_DMCR_MTFE (0x04000000) ++#define MCF_DSPI_DMCR_FRZ (0x08000000) ++#define MCF_DSPI_DMCR_DCONF(x) (((x)&0x00000003)<<28) ++#define MCF_DSPI_DMCR_CSCK (0x40000000) ++#define MCF_DSPI_DMCR_MSTR (0x80000000) ++ ++/* Bit definitions and macros for MCF_DSPI_DTCR */ ++#define MCF_DSPI_DTCR_SPI_TCNT(x) (((x)&0x0000FFFF)<<16) ++ ++/* Bit definitions and macros for MCF_DSPI_DCTARn */ ++#define MCF_DSPI_DCTAR_BR(x) (((x)&0x0000000F)<<0) ++#define MCF_DSPI_DCTAR_DT(x) (((x)&0x0000000F)<<4) ++#define MCF_DSPI_DCTAR_ASC(x) (((x)&0x0000000F)<<8) ++#define MCF_DSPI_DCTAR_CSSCK(x) (((x)&0x0000000F)<<12) ++#define MCF_DSPI_DCTAR_PBR(x) (((x)&0x00000003)<<16) ++#define MCF_DSPI_DCTAR_PDT(x) (((x)&0x00000003)<<18) ++#define MCF_DSPI_DCTAR_PASC(x) (((x)&0x00000003)<<20) ++#define MCF_DSPI_DCTAR_PCSSCK(x) (((x)&0x00000003)<<22) ++#define MCF_DSPI_DCTAR_LSBFE (0x01000000) ++#define MCF_DSPI_DCTAR_CPHA (0x02000000) ++#define MCF_DSPI_DCTAR_CPOL (0x04000000) ++/* #define MCF_DSPI_DCTAR_TRSZ(x) (((x)&0x0000000F)<<27) */ ++#define MCF_DSPI_DCTAR_FMSZ(x) (((x)&0x0000000F)<<27) ++#define MCF_DSPI_DCTAR_PCSSCK_1CLK (0x00000000) ++#define MCF_DSPI_DCTAR_PCSSCK_3CLK (0x00400000) ++#define MCF_DSPI_DCTAR_PCSSCK_5CLK (0x00800000) ++#define MCF_DSPI_DCTAR_PCSSCK_7CLK (0x00A00000) ++#define MCF_DSPI_DCTAR_PASC_1CLK (0x00000000) ++#define MCF_DSPI_DCTAR_PASC_3CLK (0x00100000) ++#define MCF_DSPI_DCTAR_PASC_5CLK (0x00200000) ++#define MCF_DSPI_DCTAR_PASC_7CLK (0x00300000) ++#define MCF_DSPI_DCTAR_PDT_1CLK (0x00000000) ++#define MCF_DSPI_DCTAR_PDT_3CLK (0x00040000) ++#define MCF_DSPI_DCTAR_PDT_5CLK (0x00080000) ++#define MCF_DSPI_DCTAR_PDT_7CLK (0x000A0000) ++#define MCF_DSPI_DCTAR_PBR_1CLK (0x00000000) ++#define MCF_DSPI_DCTAR_PBR_3CLK (0x00010000) ++#define MCF_DSPI_DCTAR_PBR_5CLK (0x00020000) ++#define MCF_DSPI_DCTAR_PBR_7CLK (0x00030000) ++ ++/* Bit definitions and macros for MCF_DSPI_DSR */ ++#define MCF_DSPI_DSR_RXPTR(x) (((x)&0x0000000F)<<0) ++#define MCF_DSPI_DSR_RXCTR(x) (((x)&0x0000000F)<<4) ++#define MCF_DSPI_DSR_TXPTR(x) (((x)&0x0000000F)<<8) ++#define MCF_DSPI_DSR_TXCTR(x) (((x)&0x0000000F)<<12) ++#define MCF_DSPI_DSR_RFDF (0x00020000) ++#define MCF_DSPI_DSR_RFOF (0x00080000) ++#define MCF_DSPI_DSR_TFFF (0x02000000) ++#define MCF_DSPI_DSR_TFUF (0x08000000) ++#define MCF_DSPI_DSR_EOQF (0x10000000) ++#define MCF_DSPI_DSR_TXRXS (0x40000000) ++#define MCF_DSPI_DSR_TCF (0x80000000) ++ ++/* Bit definitions and macros for MCF_DSPI_DRSER */ ++#define MCF_DSPI_DRSER_RFDFS (0x00010000) ++#define MCF_DSPI_DRSER_RFDFE (0x00020000) ++#define MCF_DSPI_DRSER_RFOFE (0x00080000) ++#define MCF_DSPI_DRSER_TFFFS (0x01000000) ++#define MCF_DSPI_DRSER_TFFFE (0x02000000) ++#define MCF_DSPI_DRSER_TFUFE (0x08000000) ++#define MCF_DSPI_DRSER_EOQFE (0x10000000) ++#define MCF_DSPI_DRSER_TCFE (0x80000000) ++ ++/* Bit definitions and macros for MCF_DSPI_DTFR */ ++#define MCF_DSPI_DTFR_TXDATA(x) (((x)&0x0000FFFF)<<0) ++#define MCF_DSPI_DTFR_CS0 (0x00010000) ++#define MCF_DSPI_DTFR_CS2 (0x00040000) ++#define MCF_DSPI_DTFR_CS3 (0x00080000) ++#define MCF_DSPI_DTFR_CS5 (0x00200000) ++#define MCF_DSPI_DTFR_CTCNT (0x04000000) ++#define MCF_DSPI_DTFR_EOQ (0x08000000) ++#define MCF_DSPI_DTFR_CTAS(x) (((x)&0x00000007)<<28) ++#define MCF_DSPI_DTFR_CONT (0x80000000) ++ ++/* Bit definitions and macros for MCF_DSPI_DRFR */ ++#define MCF_DSPI_DRFR_RXDATA(x) (((x)&0x0000FFFF)<<0) ++ ++/* Bit definitions and macros for MCF_DSPI_DTFDRn */ ++#define MCF_DSPI_DTFDRn_TXDATA(x) (((x)&0x0000FFFF)<<0) ++#define MCF_DSPI_DTFDRn_TXCMD(x) (((x)&0x0000FFFF)<<16) ++ ++/* Bit definitions and macros for MCF_DSPI_DRFDRn */ ++#define MCF_DSPI_DRFDRn_RXDATA(x) (((x)&0x0000FFFF)<<0) ++ ++/********************************************************************/ ++ ++#endif /* _M5485DSPI_H_ */ +--- a/include/asm-m68k/mcfqspi.h ++++ b/include/asm-m68k/mcfqspi.h +@@ -36,6 +36,7 @@ struct coldfire_spi_master { + u32 irq_mask; + u8 irq_lp; + u8 par_val; ++ u32 *irq_list; + void (*cs_control)(u8 cs, u8 command); + }; + +--- a/include/asm-m68k/mcfsim.h ++++ b/include/asm-m68k/mcfsim.h +@@ -25,6 +25,7 @@ + #include + #elif defined(CONFIG_M547X_8X) + #include ++#include + #endif + + /* -- cgit v1.2.3