Browse Source

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu:
  arch/m68knommu/platform/68360/commproc.c: Checkpatch cleanup
  arch/m68knommu/mm/fault.c: Checkpatch cleanup
  m68knommu: improve short help of m68knommu/Kconfig/RAMSIZE for '0' case
  m68knommu: remove un-used mcfsmc.h
  m68knommu: add smc91x support for ColdFire NETtel boards
  m68knommu: add smc91x support to ColdFire 5249 platform
  m68knommu: remove size limit on non-MMU TASK_SIZE
  m68knommu: fix broken use of BUAD_TABLE_SIZE in 68328serial driver
  m68knommu: Coldfire QSPI platform support
Linus Torvalds 15 years ago
parent
commit
c19eb8f0d1

+ 1 - 0
arch/m68k/include/asm/m520xsim.h

@@ -113,6 +113,7 @@
 
 #define MCF_GPIO_PAR_UART                   (0xA4036)
 #define MCF_GPIO_PAR_FECI2C                 (0xA4033)
+#define MCF_GPIO_PAR_QSPI                   (0xA4034)
 #define MCF_GPIO_PAR_FEC                    (0xA4038)
 
 #define MCF_GPIO_PAR_UART_PAR_URXD0         (0x0001)

+ 5 - 0
arch/m68k/include/asm/m523xsim.h

@@ -127,5 +127,10 @@
 #define MCFGPIO_IRQ_MAX			8
 #define MCFGPIO_IRQ_VECBASE		MCFINT_VECBASE
 
+/*
+ * Pin Assignment
+*/
+#define	MCFGPIO_PAR_QSPI	(MCF_IPSBAR + 0x10004A)
+#define	MCFGPIO_PAR_TIMER	(MCF_IPSBAR + 0x10004C)
 /****************************************************************************/
 #endif	/* m523xsim_h */

+ 2 - 0
arch/m68k/include/asm/m5249sim.h

@@ -69,10 +69,12 @@
 #define	MCFSIM_DMA1ICR		MCFSIM_ICR7	/* DMA 1 ICR */
 #define	MCFSIM_DMA2ICR		MCFSIM_ICR8	/* DMA 2 ICR */
 #define	MCFSIM_DMA3ICR		MCFSIM_ICR9	/* DMA 3 ICR */
+#define	MCFSIM_QSPIICR		MCFSIM_ICR10	/* QSPI ICR */
 
 /*
  *	Define system peripheral IRQ usage.
  */
+#define	MCF_IRQ_QSPI		28		/* QSPI, Level 4 */
 #define	MCF_IRQ_TIMER		30		/* Timer0, Level 6 */
 #define	MCF_IRQ_PROFILER	31		/* Timer1, Level 7 */
 

+ 7 - 0
arch/m68k/include/asm/m527xsim.h

@@ -31,6 +31,7 @@
 #define	MCFINT_UART0		13		/* Interrupt number for UART0 */
 #define	MCFINT_UART1		14		/* Interrupt number for UART1 */
 #define	MCFINT_UART2		15		/* Interrupt number for UART2 */
+#define	MCFINT_QSPI		18		/* Interrupt number for QSPI */
 #define	MCFINT_PIT1		36		/* Interrupt number for PIT1 */
 
 /*
@@ -120,6 +121,9 @@
 #define MCFGPIO_PIN_MAX			100
 #define MCFGPIO_IRQ_MAX			8
 #define MCFGPIO_IRQ_VECBASE		MCFINT_VECBASE
+
+#define MCFGPIO_PAR_QSPI	(MCF_IPSBAR + 0x10004A)
+#define MCFGPIO_PAR_TIMER	(MCF_IPSBAR + 0x10004C)
 #endif
 
 #ifdef CONFIG_M5275
@@ -212,6 +216,8 @@
 #define MCFGPIO_PIN_MAX			148
 #define MCFGPIO_IRQ_MAX			8
 #define MCFGPIO_IRQ_VECBASE		MCFINT_VECBASE
+
+#define MCFGPIO_PAR_QSPI	(MCF_IPSBAR + 0x10007E)
 #endif
 
 /*
@@ -223,6 +229,7 @@
 #define MCFEPORT_EPPDR		(MCF_IPSBAR + 0x130005)
 
 
+
 /*
  *	GPIO pins setups to enable the UARTs.
  */

+ 1 - 66
arch/m68k/include/asm/m528xsim.h

@@ -29,6 +29,7 @@
 
 #define	MCFINT_VECBASE		64		/* Vector base number */
 #define	MCFINT_UART0		13		/* Interrupt number for UART0 */
+#define	MCFINT_QSPI		18		/* Interrupt number for QSPI */
 #define	MCFINT_PIT1		55		/* Interrupt number for PIT1 */
 
 /*
@@ -249,70 +250,4 @@
 #define MCF5282_I2C_I2SR_RXAK   (0x01)  // received acknowledge
 
 
-
-/*********************************************************************
-*
-* Queued Serial Peripheral Interface (QSPI) Module
-*
-*********************************************************************/
-/* Derek - 21 Feb 2005 */
-/* change to the format used in I2C */
-/* Read/Write access macros for general use */
-#define MCF5282_QSPI_QMR        MCF_IPSBAR + 0x0340
-#define MCF5282_QSPI_QDLYR      MCF_IPSBAR + 0x0344
-#define MCF5282_QSPI_QWR        MCF_IPSBAR + 0x0348
-#define MCF5282_QSPI_QIR        MCF_IPSBAR + 0x034C
-#define MCF5282_QSPI_QAR        MCF_IPSBAR + 0x0350
-#define MCF5282_QSPI_QDR        MCF_IPSBAR + 0x0354
-#define MCF5282_QSPI_QCR        MCF_IPSBAR + 0x0354
-
-/* Bit level definitions and macros */
-#define MCF5282_QSPI_QMR_MSTR                           (0x8000)
-#define MCF5282_QSPI_QMR_DOHIE                          (0x4000)
-#define MCF5282_QSPI_QMR_BITS_16                        (0x0000)
-#define MCF5282_QSPI_QMR_BITS_8                         (0x2000)
-#define MCF5282_QSPI_QMR_BITS_9                         (0x2400)
-#define MCF5282_QSPI_QMR_BITS_10                        (0x2800)
-#define MCF5282_QSPI_QMR_BITS_11                        (0x2C00)
-#define MCF5282_QSPI_QMR_BITS_12                        (0x3000)
-#define MCF5282_QSPI_QMR_BITS_13                        (0x3400)
-#define MCF5282_QSPI_QMR_BITS_14                        (0x3800)
-#define MCF5282_QSPI_QMR_BITS_15                        (0x3C00)
-#define MCF5282_QSPI_QMR_CPOL                           (0x0200)
-#define MCF5282_QSPI_QMR_CPHA                           (0x0100)
-#define MCF5282_QSPI_QMR_BAUD(x)                        (((x)&0x00FF))
-
-#define MCF5282_QSPI_QDLYR_SPE                          (0x80)
-#define MCF5282_QSPI_QDLYR_QCD(x)                       (((x)&0x007F)<<8)
-#define MCF5282_QSPI_QDLYR_DTL(x)                       (((x)&0x00FF))
-
-#define MCF5282_QSPI_QWR_HALT                           (0x8000)
-#define MCF5282_QSPI_QWR_WREN                           (0x4000)
-#define MCF5282_QSPI_QWR_WRTO                           (0x2000)
-#define MCF5282_QSPI_QWR_CSIV                           (0x1000)
-#define MCF5282_QSPI_QWR_ENDQP(x)                       (((x)&0x000F)<<8)
-#define MCF5282_QSPI_QWR_CPTQP(x)                       (((x)&0x000F)<<4)
-#define MCF5282_QSPI_QWR_NEWQP(x)                       (((x)&0x000F))
-
-#define MCF5282_QSPI_QIR_WCEFB                          (0x8000)
-#define MCF5282_QSPI_QIR_ABRTB                          (0x4000)
-#define MCF5282_QSPI_QIR_ABRTL                          (0x1000)
-#define MCF5282_QSPI_QIR_WCEFE                          (0x0800)
-#define MCF5282_QSPI_QIR_ABRTE                          (0x0400)
-#define MCF5282_QSPI_QIR_SPIFE                          (0x0100)
-#define MCF5282_QSPI_QIR_WCEF                           (0x0008)
-#define MCF5282_QSPI_QIR_ABRT                           (0x0004)
-#define MCF5282_QSPI_QIR_SPIF                           (0x0001)
-
-#define MCF5282_QSPI_QAR_ADDR(x)                        (((x)&0x003F))
-
-#define MCF5282_QSPI_QDR_COMMAND(x)                     (((x)&0xFF00))
-#define MCF5282_QSPI_QCR_DATA(x)                        (((x)&0x00FF)<<8)
-#define MCF5282_QSPI_QCR_CONT                           (0x8000)
-#define MCF5282_QSPI_QCR_BITSE                          (0x4000)
-#define MCF5282_QSPI_QCR_DT                             (0x2000)
-#define MCF5282_QSPI_QCR_DSCK                           (0x1000)
-#define MCF5282_QSPI_QCR_CS                             (((x)&0x000F)<<8)
-
-/****************************************************************************/
 #endif	/* m528xsim_h */

+ 1 - 0
arch/m68k/include/asm/m532xsim.h

@@ -17,6 +17,7 @@
 #define MCFINT_UART0        26          /* Interrupt number for UART0 */
 #define MCFINT_UART1        27          /* Interrupt number for UART1 */
 #define MCFINT_UART2        28          /* Interrupt number for UART2 */
+#define MCFINT_QSPI         31          /* Interrupt number for QSPI */
 
 #define MCF_WTM_WCR	MCF_REG16(0xFC098000)
 

+ 64 - 0
arch/m68k/include/asm/mcfqspi.h

@@ -0,0 +1,64 @@
+/*
+ * Definitions for Freescale Coldfire QSPI module
+ *
+ * Copyright 2010 Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+*/
+
+#ifndef mcfqspi_h
+#define mcfqspi_h
+
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#define	MCFQSPI_IOBASE		(MCF_IPSBAR + 0x340)
+#elif defined(CONFIG_M5249)
+#define MCFQSPI_IOBASE		(MCF_MBAR + 0x300)
+#elif defined(CONFIG_M520x) || defined(CONFIG_M532x)
+#define MCFQSPI_IOBASE		0xFC058000
+#endif
+#define MCFQSPI_IOSIZE		0x40
+
+/**
+ * struct mcfqspi_cs_control - chip select control for the coldfire qspi driver
+ * @setup: setup the control; allocate gpio's, etc. May be NULL.
+ * @teardown: finish with the control; free gpio's, etc. May be NULL.
+ * @select: output the signals to select the device.  Can not be NULL.
+ * @deselect: output the signals to deselect the device. Can not be NULL.
+ *
+ * The QSPI module has 4 hardware chip selects.  We don't use them.  Instead
+ * platforms are required to supply a mcfqspi_cs_control as a part of the
+ * platform data for each QSPI master controller.  Only the select and
+ * deselect functions are required.
+*/
+struct mcfqspi_cs_control {
+	int 	(*setup)(struct mcfqspi_cs_control *);
+	void	(*teardown)(struct mcfqspi_cs_control *);
+	void	(*select)(struct mcfqspi_cs_control *, u8, bool);
+	void	(*deselect)(struct mcfqspi_cs_control *, u8, bool);
+};
+
+/**
+ * struct mcfqspi_platform_data - platform data for the coldfire qspi driver
+ * @bus_num: board specific identifier for this qspi driver.
+ * @num_chipselects: number of chip selects supported by this qspi driver.
+ * @cs_control: platform dependent chip select control.
+*/
+struct mcfqspi_platform_data {
+	s16	bus_num;
+	u16	num_chipselect;
+	struct mcfqspi_cs_control *cs_control;
+};
+
+#endif /* mcfqspi_h */

+ 0 - 187
arch/m68k/include/asm/mcfsmc.h

@@ -1,187 +0,0 @@
-/****************************************************************************/
-
-/*
- *	mcfsmc.h -- SMC ethernet support for ColdFire environments.
- *
- *	(C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com)
- *	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
- */
-
-/****************************************************************************/
-#ifndef	mcfsmc_h
-#define	mcfsmc_h
-/****************************************************************************/
-
-/*
- *	None of the current ColdFire targets that use the SMC91x111
- *	allow 8 bit accesses. So this code is 16bit access only.
- */
-
-
-#undef	outb
-#undef	inb
-#undef	outw
-#undef	outwd
-#undef	inw	
-#undef	outl
-#undef	inl
-
-#undef	outsb
-#undef	outsw
-#undef	outsl
-#undef	insb
-#undef	insw
-#undef	insl
-
-/*
- *	Re-defines for ColdFire environment... The SMC part is
- *	mapped into memory space, so remap the PC-style in/out
- *	routines to handle that.
- */
-#define	outb	smc_outb
-#define	inb	smc_inb
-#define	outw	smc_outw
-#define	outwd	smc_outwd
-#define	inw	smc_inw
-#define	outl	smc_outl
-#define	inl	smc_inl
-
-#define	outsb	smc_outsb
-#define	outsw	smc_outsw
-#define	outsl	smc_outsl
-#define	insb	smc_insb
-#define	insw	smc_insw
-#define	insl	smc_insl
-
-
-static inline int smc_inb(unsigned int addr)
-{
-	register unsigned short	w;
-	w = *((volatile unsigned short *) (addr & ~0x1));
-	return(((addr & 0x1) ? w : (w >> 8)) & 0xff);
-}
-
-static inline void smc_outw(unsigned int val, unsigned int addr)
-{
-	*((volatile unsigned short *) addr) = (val << 8) | (val >> 8);
-}
-
-static inline int smc_inw(unsigned int addr)
-{
-	register unsigned short	w;
-	w = *((volatile unsigned short *) addr);
-	return(((w << 8) | (w >> 8)) & 0xffff);
-}
-
-static inline void smc_outl(unsigned long val, unsigned int addr)
-{
-	*((volatile unsigned long *) addr) = 
-		((val << 8) & 0xff000000) | ((val >> 8) & 0x00ff0000) |
-		((val << 8) & 0x0000ff00) | ((val >> 8) & 0x000000ff);
-}
-
-static inline void smc_outwd(unsigned int val, unsigned int addr)
-{
-	*((volatile unsigned short *) addr) = val;
-}
-
-
-/*
- *	The rep* functions are used to feed the data port with
- *	raw data. So we do not byte swap them when copying.
- */
-
-static inline void smc_insb(unsigned int addr, void *vbuf, int unsigned long len)
-{
-	volatile unsigned short	*rp;
-	unsigned short		*buf, *ebuf;
-
-	buf = (unsigned short *) vbuf;
-	rp = (volatile unsigned short *) addr;
-
-	/* Copy as words for as long as possible */
-	for (ebuf = buf + (len >> 1); (buf < ebuf); )
-		*buf++ = *rp;
-
-	/* Lastly, handle left over byte */
-	if (len & 0x1)
-		*((unsigned char *) buf) = (*rp >> 8) & 0xff;
-}
-
-static inline void smc_insw(unsigned int addr, void *vbuf, unsigned long len)
-{
-	volatile unsigned short	*rp;
-	unsigned short		*buf, *ebuf;
-
-	buf = (unsigned short *) vbuf;
-	rp = (volatile unsigned short *) addr;
-	for (ebuf = buf + len; (buf < ebuf); )
-		*buf++ = *rp;
-}
-
-static inline void smc_insl(unsigned int addr, void *vbuf, unsigned long len)
-{
-	volatile unsigned long	*rp;
-	unsigned long		*buf, *ebuf;
-
-	buf = (unsigned long *) vbuf;
-	rp = (volatile unsigned long *) addr;
-	for (ebuf = buf + len; (buf < ebuf); )
-		*buf++ = *rp;
-}
-
-static inline void smc_outsw(unsigned int addr, const void *vbuf, unsigned long len)
-{
-	volatile unsigned short	*rp;
-	unsigned short		*buf, *ebuf;
-
-	buf = (unsigned short *) vbuf;
-	rp = (volatile unsigned short *) addr;
-	for (ebuf = buf + len; (buf < ebuf); )
-		*rp = *buf++;
-}
-
-static inline void smc_outsl(unsigned int addr, void *vbuf, unsigned long len)
-{
-	volatile unsigned long	*rp;
-	unsigned long		*buf, *ebuf;
-
-	buf = (unsigned long *) vbuf;
-	rp = (volatile unsigned long *) addr;
-	for (ebuf = buf + len; (buf < ebuf); )
-		*rp = *buf++;
-}
-
-
-#ifdef CONFIG_NETtel
-/*
- *	Re-map the address space of at least one of the SMC ethernet
- *	parts. Both parts power up decoding the same address, so we
- *	need to move one of them first, before doing enything else.
- *
- *	We also increase the number of wait states for this part by one.
- */
-
-void smc_remap(unsigned int ioaddr)
-{
-	static int		once = 0;
-	extern unsigned short	ppdata;
-	if (once++ == 0) {
-		*((volatile unsigned short *)MCFSIM_PADDR) = 0x00ec;
-		ppdata |= 0x0080;
-		*((volatile unsigned short *)MCFSIM_PADAT) = ppdata;
-		outw(0x0001, ioaddr + BANK_SELECT);
-		outw(0x0001, ioaddr + BANK_SELECT);
-		outw(0x0067, ioaddr + BASE);
-
-		ppdata &= ~0x0080;
-		*((volatile unsigned short *)MCFSIM_PADAT) = ppdata;
-	}
-	
-	*((volatile unsigned short *)(MCF_MBAR+MCFSIM_CSCR3)) = 0x1180;
-}
-
-#endif
-
-/****************************************************************************/
-#endif	/* mcfsmc_h */

+ 4 - 0
arch/m68k/include/asm/processor.h

@@ -44,11 +44,15 @@ static inline void wrusp(unsigned long usp)
  * User space process size: 3.75GB. This is hardcoded into a few places,
  * so don't change it unless you know what you are doing.
  */
+#ifdef CONFIG_MMU
 #ifndef CONFIG_SUN3
 #define TASK_SIZE	(0xF0000000UL)
 #else
 #define TASK_SIZE	(0x0E000000UL)
 #endif
+#else
+#define TASK_SIZE	(0xFFFFFFFFUL)
+#endif
 
 #ifdef __KERNEL__
 #define STACK_TOP	TASK_SIZE

+ 1 - 1
arch/m68knommu/Kconfig

@@ -566,7 +566,7 @@ config RAMBASE
 	  processor address space.
 
 config RAMSIZE
-	hex "Size of RAM (in bytes)"
+	hex "Size of RAM (in bytes), or 0 for automatic"
 	default "0x400000"
 	help
 	  Define the size of the system RAM. If you select 0 then the

+ 5 - 5
arch/m68knommu/mm/fault.c

@@ -2,7 +2,7 @@
  *  linux/arch/m68knommu/mm/fault.c
  *
  *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
- *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com) 
+ *  Copyright (C) 2000  Lineo, Inc.  (www.lineo.com)
  *
  *  Based on:
  *
@@ -36,7 +36,7 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
 			      unsigned long error_code)
 {
 #ifdef DEBUG
-	printk (KERN_DEBUG "regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n",
+	printk(KERN_DEBUG "regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n",
 		regs->sr, regs->pc, address, error_code);
 #endif
 
@@ -44,11 +44,11 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
 	 * Oops. The kernel tried to access some bad page. We'll have to
 	 * terminate things with extreme prejudice.
 	 */
-	if ((unsigned long) address < PAGE_SIZE) {
+	if ((unsigned long) address < PAGE_SIZE)
 		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
-	} else
+	else
 		printk(KERN_ALERT "Unable to handle kernel access");
-	printk(KERN_ALERT " at virtual address %08lx\n",address);
+	printk(KERN_ALERT " at virtual address %08lx\n", address);
 	die_if_kernel("Oops", regs, error_code);
 	do_exit(SIGKILL);
 

+ 149 - 0
arch/m68knommu/platform/520x/config.c

@@ -15,10 +15,13 @@
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfuart.h>
+#include <asm/mcfqspi.h>
 
 /***************************************************************************/
 
@@ -74,9 +77,152 @@ static struct platform_device m520x_fec = {
 	.resource		= m520x_fec_resources,
 };
 
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+static struct resource m520x_qspi_resources[] = {
+	{
+		.start		= MCFQSPI_IOBASE,
+		.end		= MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= MCFINT_VECBASE + MCFINT_QSPI,
+		.end		= MCFINT_VECBASE + MCFINT_QSPI,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+#define MCFQSPI_CS0    62
+#define MCFQSPI_CS1    63
+#define MCFQSPI_CS2    44
+
+static int m520x_cs_setup(struct mcfqspi_cs_control *cs_control)
+{
+	int status;
+
+	status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
+		goto fail0;
+	}
+	status = gpio_direction_output(MCFQSPI_CS0, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
+		goto fail1;
+	}
+
+	status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
+		goto fail1;
+	}
+	status = gpio_direction_output(MCFQSPI_CS1, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
+		goto fail2;
+	}
+
+	status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
+		goto fail2;
+	}
+	status = gpio_direction_output(MCFQSPI_CS2, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
+		goto fail3;
+	}
+
+	return 0;
+
+fail3:
+	gpio_free(MCFQSPI_CS2);
+fail2:
+	gpio_free(MCFQSPI_CS1);
+fail1:
+	gpio_free(MCFQSPI_CS0);
+fail0:
+	return status;
+}
+
+static void m520x_cs_teardown(struct mcfqspi_cs_control *cs_control)
+{
+	gpio_free(MCFQSPI_CS2);
+	gpio_free(MCFQSPI_CS1);
+	gpio_free(MCFQSPI_CS0);
+}
+
+static void m520x_cs_select(struct mcfqspi_cs_control *cs_control,
+			    u8 chip_select, bool cs_high)
+{
+	switch (chip_select) {
+	case 0:
+		gpio_set_value(MCFQSPI_CS0, cs_high);
+		break;
+	case 1:
+		gpio_set_value(MCFQSPI_CS1, cs_high);
+		break;
+	case 2:
+		gpio_set_value(MCFQSPI_CS2, cs_high);
+		break;
+	}
+}
+
+static void m520x_cs_deselect(struct mcfqspi_cs_control *cs_control,
+			      u8 chip_select, bool cs_high)
+{
+	switch (chip_select) {
+	case 0:
+		gpio_set_value(MCFQSPI_CS0, !cs_high);
+		break;
+	case 1:
+		gpio_set_value(MCFQSPI_CS1, !cs_high);
+		break;
+	case 2:
+		gpio_set_value(MCFQSPI_CS2, !cs_high);
+		break;
+	}
+}
+
+static struct mcfqspi_cs_control m520x_cs_control = {
+	.setup                  = m520x_cs_setup,
+	.teardown               = m520x_cs_teardown,
+	.select                 = m520x_cs_select,
+	.deselect               = m520x_cs_deselect,
+};
+
+static struct mcfqspi_platform_data m520x_qspi_data = {
+	.bus_num		= 0,
+	.num_chipselect		= 3,
+	.cs_control		= &m520x_cs_control,
+};
+
+static struct platform_device m520x_qspi = {
+	.name			= "mcfqspi",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(m520x_qspi_resources),
+	.resource		= m520x_qspi_resources,
+	.dev.platform_data	= &m520x_qspi_data,
+};
+
+static void __init m520x_qspi_init(void)
+{
+	u16 par;
+	/* setup Port QS for QSPI with gpio CS control */
+	writeb(0x3f, MCF_IPSBAR + MCF_GPIO_PAR_QSPI);
+	/* make U1CTS and U2RTS gpio for cs_control */
+	par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
+	par &= 0x00ff;
+	writew(par, MCF_IPSBAR + MCF_GPIO_PAR_UART);
+}
+#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
+
+
 static struct platform_device *m520x_devices[] __initdata = {
 	&m520x_uart,
 	&m520x_fec,
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+	&m520x_qspi,
+#endif
 };
 
 /***************************************************************************/
@@ -147,6 +293,9 @@ void __init config_BSP(char *commandp, int size)
 	mach_reset = m520x_cpu_reset;
 	m520x_uarts_init();
 	m520x_fec_init();
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+	m520x_qspi_init();
+#endif
 }
 
 /***************************************************************************/

+ 170 - 0
arch/m68knommu/platform/523x/config.c

@@ -16,10 +16,13 @@
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfuart.h>
+#include <asm/mcfqspi.h>
 
 /***************************************************************************/
 
@@ -75,9 +78,173 @@ static struct platform_device m523x_fec = {
 	.resource		= m523x_fec_resources,
 };
 
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+static struct resource m523x_qspi_resources[] = {
+	{
+		.start		= MCFQSPI_IOBASE,
+		.end		= MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= MCFINT_VECBASE + MCFINT_QSPI,
+		.end		= MCFINT_VECBASE + MCFINT_QSPI,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+#define MCFQSPI_CS0    91
+#define MCFQSPI_CS1    92
+#define MCFQSPI_CS2    103
+#define MCFQSPI_CS3    99
+
+static int m523x_cs_setup(struct mcfqspi_cs_control *cs_control)
+{
+	int status;
+
+	status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
+		goto fail0;
+	}
+	status = gpio_direction_output(MCFQSPI_CS0, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
+		goto fail1;
+	}
+
+	status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
+		goto fail1;
+	}
+	status = gpio_direction_output(MCFQSPI_CS1, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
+		goto fail2;
+	}
+
+	status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
+		goto fail2;
+	}
+	status = gpio_direction_output(MCFQSPI_CS2, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
+		goto fail3;
+	}
+
+	status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
+		goto fail3;
+	}
+	status = gpio_direction_output(MCFQSPI_CS3, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
+		goto fail4;
+	}
+
+	return 0;
+
+fail4:
+	gpio_free(MCFQSPI_CS3);
+fail3:
+	gpio_free(MCFQSPI_CS2);
+fail2:
+	gpio_free(MCFQSPI_CS1);
+fail1:
+	gpio_free(MCFQSPI_CS0);
+fail0:
+	return status;
+}
+
+static void m523x_cs_teardown(struct mcfqspi_cs_control *cs_control)
+{
+	gpio_free(MCFQSPI_CS3);
+	gpio_free(MCFQSPI_CS2);
+	gpio_free(MCFQSPI_CS1);
+	gpio_free(MCFQSPI_CS0);
+}
+
+static void m523x_cs_select(struct mcfqspi_cs_control *cs_control,
+			    u8 chip_select, bool cs_high)
+{
+	switch (chip_select) {
+	case 0:
+		gpio_set_value(MCFQSPI_CS0, cs_high);
+		break;
+	case 1:
+		gpio_set_value(MCFQSPI_CS1, cs_high);
+		break;
+	case 2:
+		gpio_set_value(MCFQSPI_CS2, cs_high);
+		break;
+	case 3:
+		gpio_set_value(MCFQSPI_CS3, cs_high);
+		break;
+	}
+}
+
+static void m523x_cs_deselect(struct mcfqspi_cs_control *cs_control,
+			      u8 chip_select, bool cs_high)
+{
+	switch (chip_select) {
+	case 0:
+		gpio_set_value(MCFQSPI_CS0, !cs_high);
+		break;
+	case 1:
+		gpio_set_value(MCFQSPI_CS1, !cs_high);
+		break;
+	case 2:
+		gpio_set_value(MCFQSPI_CS2, !cs_high);
+		break;
+	case 3:
+		gpio_set_value(MCFQSPI_CS3, !cs_high);
+		break;
+	}
+}
+
+static struct mcfqspi_cs_control m523x_cs_control = {
+	.setup                  = m523x_cs_setup,
+	.teardown               = m523x_cs_teardown,
+	.select                 = m523x_cs_select,
+	.deselect               = m523x_cs_deselect,
+};
+
+static struct mcfqspi_platform_data m523x_qspi_data = {
+	.bus_num		= 0,
+	.num_chipselect		= 4,
+	.cs_control		= &m523x_cs_control,
+};
+
+static struct platform_device m523x_qspi = {
+	.name			= "mcfqspi",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(m523x_qspi_resources),
+	.resource		= m523x_qspi_resources,
+	.dev.platform_data	= &m523x_qspi_data,
+};
+
+static void __init m523x_qspi_init(void)
+{
+	u16 par;
+
+	/* setup QSPS pins for QSPI with gpio CS control */
+	writeb(0x1f, MCFGPIO_PAR_QSPI);
+	/* and CS2 & CS3 as gpio */
+	par = readw(MCFGPIO_PAR_TIMER);
+	par &= 0x3f3f;
+	writew(par, MCFGPIO_PAR_TIMER);
+}
+#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
+
 static struct platform_device *m523x_devices[] __initdata = {
 	&m523x_uart,
 	&m523x_fec,
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+	&m523x_qspi,
+#endif
 };
 
 /***************************************************************************/
@@ -114,6 +281,9 @@ void __init config_BSP(char *commandp, int size)
 static int __init init_BSP(void)
 {
 	m523x_fec_init();
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+	m523x_qspi_init();
+#endif
 	platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices));
 	return 0;
 }

+ 215 - 0
arch/m68knommu/platform/5249/config.c

@@ -12,10 +12,13 @@
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfuart.h>
+#include <asm/mcfqspi.h>
 
 /***************************************************************************/
 
@@ -37,8 +40,196 @@ static struct platform_device m5249_uart = {
 	.dev.platform_data	= m5249_uart_platform,
 };
 
+#ifdef CONFIG_M5249C3
+
+static struct resource m5249_smc91x_resources[] = {
+	{
+		.start		= 0xe0000300,
+		.end		= 0xe0000300 + 0x100,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= MCFINTC2_GPIOIRQ6,
+		.end		= MCFINTC2_GPIOIRQ6,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device m5249_smc91x = {
+	.name			= "smc91x",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(m5249_smc91x_resources),
+	.resource		= m5249_smc91x_resources,
+};
+
+#endif /* CONFIG_M5249C3 */
+
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+static struct resource m5249_qspi_resources[] = {
+	{
+		.start		= MCFQSPI_IOBASE,
+		.end		= MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= MCF_IRQ_QSPI,
+		.end		= MCF_IRQ_QSPI,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+#define MCFQSPI_CS0    29
+#define MCFQSPI_CS1    24
+#define MCFQSPI_CS2    21
+#define MCFQSPI_CS3    22
+
+static int m5249_cs_setup(struct mcfqspi_cs_control *cs_control)
+{
+	int status;
+
+	status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
+		goto fail0;
+	}
+	status = gpio_direction_output(MCFQSPI_CS0, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
+		goto fail1;
+	}
+
+	status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
+		goto fail1;
+	}
+	status = gpio_direction_output(MCFQSPI_CS1, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
+		goto fail2;
+	}
+
+	status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
+		goto fail2;
+	}
+	status = gpio_direction_output(MCFQSPI_CS2, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
+		goto fail3;
+	}
+
+	status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
+		goto fail3;
+	}
+	status = gpio_direction_output(MCFQSPI_CS3, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
+		goto fail4;
+	}
+
+	return 0;
+
+fail4:
+	gpio_free(MCFQSPI_CS3);
+fail3:
+	gpio_free(MCFQSPI_CS2);
+fail2:
+	gpio_free(MCFQSPI_CS1);
+fail1:
+	gpio_free(MCFQSPI_CS0);
+fail0:
+	return status;
+}
+
+static void m5249_cs_teardown(struct mcfqspi_cs_control *cs_control)
+{
+	gpio_free(MCFQSPI_CS3);
+	gpio_free(MCFQSPI_CS2);
+	gpio_free(MCFQSPI_CS1);
+	gpio_free(MCFQSPI_CS0);
+}
+
+static void m5249_cs_select(struct mcfqspi_cs_control *cs_control,
+			    u8 chip_select, bool cs_high)
+{
+	switch (chip_select) {
+	case 0:
+		gpio_set_value(MCFQSPI_CS0, cs_high);
+		break;
+	case 1:
+		gpio_set_value(MCFQSPI_CS1, cs_high);
+		break;
+	case 2:
+		gpio_set_value(MCFQSPI_CS2, cs_high);
+		break;
+	case 3:
+		gpio_set_value(MCFQSPI_CS3, cs_high);
+		break;
+	}
+}
+
+static void m5249_cs_deselect(struct mcfqspi_cs_control *cs_control,
+			      u8 chip_select, bool cs_high)
+{
+	switch (chip_select) {
+	case 0:
+		gpio_set_value(MCFQSPI_CS0, !cs_high);
+		break;
+	case 1:
+		gpio_set_value(MCFQSPI_CS1, !cs_high);
+		break;
+	case 2:
+		gpio_set_value(MCFQSPI_CS2, !cs_high);
+		break;
+	case 3:
+		gpio_set_value(MCFQSPI_CS3, !cs_high);
+		break;
+	}
+}
+
+static struct mcfqspi_cs_control m5249_cs_control = {
+	.setup                  = m5249_cs_setup,
+	.teardown               = m5249_cs_teardown,
+	.select                 = m5249_cs_select,
+	.deselect               = m5249_cs_deselect,
+};
+
+static struct mcfqspi_platform_data m5249_qspi_data = {
+	.bus_num		= 0,
+	.num_chipselect		= 4,
+	.cs_control		= &m5249_cs_control,
+};
+
+static struct platform_device m5249_qspi = {
+	.name			= "mcfqspi",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(m5249_qspi_resources),
+	.resource		= m5249_qspi_resources,
+	.dev.platform_data	= &m5249_qspi_data,
+};
+
+static void __init m5249_qspi_init(void)
+{
+	/* QSPI irq setup */
+	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI0,
+	       MCF_MBAR + MCFSIM_QSPIICR);
+	mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI);
+}
+#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
+
+
 static struct platform_device *m5249_devices[] __initdata = {
 	&m5249_uart,
+#ifdef CONFIG_M5249C3
+	&m5249_smc91x,
+#endif
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+	&m5249_qspi,
+#endif
 };
 
 /***************************************************************************/
@@ -67,6 +258,24 @@ static void __init m5249_uarts_init(void)
 
 /***************************************************************************/
 
+#ifdef CONFIG_M5249C3
+
+static void __init m5249_smc91x_init(void)
+{
+	u32  gpio;
+
+	/* Set the GPIO line as interrupt source for smc91x device */
+	gpio = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+	writel(gpio | 0x40, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+
+	gpio = readl(MCF_MBAR2 + MCFSIM2_INTLEVEL5);
+	writel(gpio | 0x04000000, MCF_MBAR2 + MCFSIM2_INTLEVEL5);
+}
+
+#endif /* CONFIG_M5249C3 */
+
+/***************************************************************************/
+
 static void __init m5249_timers_init(void)
 {
 	/* Timer1 is always used as system timer */
@@ -100,6 +309,12 @@ void __init config_BSP(char *commandp, int size)
 	mach_reset = m5249_cpu_reset;
 	m5249_timers_init();
 	m5249_uarts_init();
+#ifdef CONFIG_M5249C3
+	m5249_smc91x_init();
+#endif
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+	m5249_qspi_init();
+#endif
 }
 
 /***************************************************************************/

+ 182 - 0
arch/m68knommu/platform/527x/config.c

@@ -16,10 +16,13 @@
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfuart.h>
+#include <asm/mcfqspi.h>
 
 /***************************************************************************/
 
@@ -106,12 +109,188 @@ static struct platform_device m527x_fec[] = {
 	},
 };
 
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+static struct resource m527x_qspi_resources[] = {
+	{
+		.start		= MCFQSPI_IOBASE,
+		.end		= MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= MCFINT_VECBASE + MCFINT_QSPI,
+		.end		= MCFINT_VECBASE + MCFINT_QSPI,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+#if defined(CONFIG_M5271)
+#define MCFQSPI_CS0    91
+#define MCFQSPI_CS1    92
+#define MCFQSPI_CS2    99
+#define MCFQSPI_CS3    103
+#elif defined(CONFIG_M5275)
+#define MCFQSPI_CS0    59
+#define MCFQSPI_CS1    60
+#define MCFQSPI_CS2    61
+#define MCFQSPI_CS3    62
+#endif
+
+static int m527x_cs_setup(struct mcfqspi_cs_control *cs_control)
+{
+	int status;
+
+	status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
+		goto fail0;
+	}
+	status = gpio_direction_output(MCFQSPI_CS0, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
+		goto fail1;
+	}
+
+	status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
+		goto fail1;
+	}
+	status = gpio_direction_output(MCFQSPI_CS1, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
+		goto fail2;
+	}
+
+	status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
+		goto fail2;
+	}
+	status = gpio_direction_output(MCFQSPI_CS2, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
+		goto fail3;
+	}
+
+	status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
+		goto fail3;
+	}
+	status = gpio_direction_output(MCFQSPI_CS3, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
+		goto fail4;
+	}
+
+	return 0;
+
+fail4:
+	gpio_free(MCFQSPI_CS3);
+fail3:
+	gpio_free(MCFQSPI_CS2);
+fail2:
+	gpio_free(MCFQSPI_CS1);
+fail1:
+	gpio_free(MCFQSPI_CS0);
+fail0:
+	return status;
+}
+
+static void m527x_cs_teardown(struct mcfqspi_cs_control *cs_control)
+{
+	gpio_free(MCFQSPI_CS3);
+	gpio_free(MCFQSPI_CS2);
+	gpio_free(MCFQSPI_CS1);
+	gpio_free(MCFQSPI_CS0);
+}
+
+static void m527x_cs_select(struct mcfqspi_cs_control *cs_control,
+			    u8 chip_select, bool cs_high)
+{
+	switch (chip_select) {
+	case 0:
+		gpio_set_value(MCFQSPI_CS0, cs_high);
+		break;
+	case 1:
+		gpio_set_value(MCFQSPI_CS1, cs_high);
+		break;
+	case 2:
+		gpio_set_value(MCFQSPI_CS2, cs_high);
+		break;
+	case 3:
+		gpio_set_value(MCFQSPI_CS3, cs_high);
+		break;
+	}
+}
+
+static void m527x_cs_deselect(struct mcfqspi_cs_control *cs_control,
+			      u8 chip_select, bool cs_high)
+{
+	switch (chip_select) {
+	case 0:
+		gpio_set_value(MCFQSPI_CS0, !cs_high);
+		break;
+	case 1:
+		gpio_set_value(MCFQSPI_CS1, !cs_high);
+		break;
+	case 2:
+		gpio_set_value(MCFQSPI_CS2, !cs_high);
+		break;
+	case 3:
+		gpio_set_value(MCFQSPI_CS3, !cs_high);
+		break;
+	}
+}
+
+static struct mcfqspi_cs_control m527x_cs_control = {
+	.setup                  = m527x_cs_setup,
+	.teardown               = m527x_cs_teardown,
+	.select                 = m527x_cs_select,
+	.deselect               = m527x_cs_deselect,
+};
+
+static struct mcfqspi_platform_data m527x_qspi_data = {
+	.bus_num		= 0,
+	.num_chipselect		= 4,
+	.cs_control		= &m527x_cs_control,
+};
+
+static struct platform_device m527x_qspi = {
+	.name			= "mcfqspi",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(m527x_qspi_resources),
+	.resource		= m527x_qspi_resources,
+	.dev.platform_data	= &m527x_qspi_data,
+};
+
+static void __init m527x_qspi_init(void)
+{
+#if defined(CONFIG_M5271)
+	u16 par;
+
+	/* setup QSPS pins for QSPI with gpio CS control */
+	writeb(0x1f, MCFGPIO_PAR_QSPI);
+	/* and CS2 & CS3 as gpio */
+	par = readw(MCFGPIO_PAR_TIMER);
+	par &= 0x3f3f;
+	writew(par, MCFGPIO_PAR_TIMER);
+#elif defined(CONFIG_M5275)
+	/* setup QSPS pins for QSPI with gpio CS control */
+	writew(0x003e, MCFGPIO_PAR_QSPI);
+#endif
+}
+#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
+
 static struct platform_device *m527x_devices[] __initdata = {
 	&m527x_uart,
 	&m527x_fec[0],
 #ifdef CONFIG_FEC2
 	&m527x_fec[1],
 #endif
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+	&m527x_qspi,
+#endif
 };
 
 /***************************************************************************/
@@ -187,6 +366,9 @@ void __init config_BSP(char *commandp, int size)
 	mach_reset = m527x_cpu_reset;
 	m527x_uarts_init();
 	m527x_fec_init();
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+	m527x_qspi_init();
+#endif
 }
 
 /***************************************************************************/

+ 137 - 0
arch/m68knommu/platform/528x/config.c

@@ -17,10 +17,13 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfuart.h>
+#include <asm/mcfqspi.h>
 
 /***************************************************************************/
 
@@ -76,10 +79,141 @@ static struct platform_device m528x_fec = {
 	.resource		= m528x_fec_resources,
 };
 
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+static struct resource m528x_qspi_resources[] = {
+	{
+		.start		= MCFQSPI_IOBASE,
+		.end		= MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= MCFINT_VECBASE + MCFINT_QSPI,
+		.end		= MCFINT_VECBASE + MCFINT_QSPI,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+#define MCFQSPI_CS0    147
+#define MCFQSPI_CS1    148
+#define MCFQSPI_CS2    149
+#define MCFQSPI_CS3    150
+
+static int m528x_cs_setup(struct mcfqspi_cs_control *cs_control)
+{
+	int status;
+
+	status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
+		goto fail0;
+	}
+	status = gpio_direction_output(MCFQSPI_CS0, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
+		goto fail1;
+	}
+
+	status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
+		goto fail1;
+	}
+	status = gpio_direction_output(MCFQSPI_CS1, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
+		goto fail2;
+	}
+
+	status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
+		goto fail2;
+	}
+	status = gpio_direction_output(MCFQSPI_CS2, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
+		goto fail3;
+	}
+
+	status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
+		goto fail3;
+	}
+	status = gpio_direction_output(MCFQSPI_CS3, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
+		goto fail4;
+	}
+
+	return 0;
+
+fail4:
+	gpio_free(MCFQSPI_CS3);
+fail3:
+	gpio_free(MCFQSPI_CS2);
+fail2:
+	gpio_free(MCFQSPI_CS1);
+fail1:
+	gpio_free(MCFQSPI_CS0);
+fail0:
+	return status;
+}
+
+static void m528x_cs_teardown(struct mcfqspi_cs_control *cs_control)
+{
+	gpio_free(MCFQSPI_CS3);
+	gpio_free(MCFQSPI_CS2);
+	gpio_free(MCFQSPI_CS1);
+	gpio_free(MCFQSPI_CS0);
+}
+
+static void m528x_cs_select(struct mcfqspi_cs_control *cs_control,
+			    u8 chip_select, bool cs_high)
+{
+	gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high);
+}
+
+static void m528x_cs_deselect(struct mcfqspi_cs_control *cs_control,
+			      u8 chip_select, bool cs_high)
+{
+	gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high);
+}
+
+static struct mcfqspi_cs_control m528x_cs_control = {
+	.setup                  = m528x_cs_setup,
+	.teardown               = m528x_cs_teardown,
+	.select                 = m528x_cs_select,
+	.deselect               = m528x_cs_deselect,
+};
+
+static struct mcfqspi_platform_data m528x_qspi_data = {
+	.bus_num		= 0,
+	.num_chipselect		= 4,
+	.cs_control		= &m528x_cs_control,
+};
+
+static struct platform_device m528x_qspi = {
+	.name			= "mcfqspi",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(m528x_qspi_resources),
+	.resource		= m528x_qspi_resources,
+	.dev.platform_data	= &m528x_qspi_data,
+};
+
+static void __init m528x_qspi_init(void)
+{
+	/* setup Port QS for QSPI with gpio CS control */
+	__raw_writeb(0x07, MCFGPIO_PQSPAR);
+}
+#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
 
 static struct platform_device *m528x_devices[] __initdata = {
 	&m528x_uart,
 	&m528x_fec,
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+	&m528x_qspi,
+#endif
 };
 
 /***************************************************************************/
@@ -174,6 +308,9 @@ static int __init init_BSP(void)
 	mach_reset = m528x_cpu_reset;
 	m528x_uarts_init();
 	m528x_fec_init();
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+	m528x_qspi_init();
+#endif
 	platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
 	return 0;
 }

+ 3 - 1
arch/m68knommu/platform/5307/Makefile

@@ -14,5 +14,7 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y	+= config.o gpio.o
+obj-y			+= config.o gpio.o
+obj-$(CONFIG_NETtel)	+= nettel.o
+obj-$(CONFIG_CLEOPATRA)	+= nettel.o
 

+ 153 - 0
arch/m68knommu/platform/5307/nettel.c

@@ -0,0 +1,153 @@
+/***************************************************************************/
+
+/*
+ *	nettel.c -- startup code support for the NETtel boards
+ *
+ *	Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/nettel.h>
+
+/***************************************************************************/
+
+/*
+ * Define the IO and interrupt resources of the 2 SMC9196 interfaces.
+ */
+#define	NETTEL_SMC0_ADDR	0x30600300
+#define	NETTEL_SMC0_IRQ		29
+
+#define	NETTEL_SMC1_ADDR	0x30600000
+#define	NETTEL_SMC1_IRQ		27
+
+/*
+ * We need some access into the SMC9196 registers. Define those registers
+ * we will need here (including the smc91x.h doesn't seem to give us these
+ * in a simple form).
+ */
+#define	SMC91xx_BANKSELECT	14
+#define	SMC91xx_BASEADDR	2
+#define	SMC91xx_BASEMAC		4
+
+/***************************************************************************/
+
+static struct resource nettel_smc91x_0_resources[] = {
+	{
+		.start		= NETTEL_SMC0_ADDR,
+		.end		= NETTEL_SMC0_ADDR + 0x20,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= NETTEL_SMC0_IRQ,
+		.end		= NETTEL_SMC0_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource nettel_smc91x_1_resources[] = {
+	{
+		.start		= NETTEL_SMC1_ADDR,
+		.end		= NETTEL_SMC1_ADDR + 0x20,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= NETTEL_SMC1_IRQ,
+		.end		= NETTEL_SMC1_IRQ,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device nettel_smc91x[] = {
+	{
+		.name			= "smc91x",
+		.id			= 0,
+		.num_resources		= ARRAY_SIZE(nettel_smc91x_0_resources),
+		.resource		= nettel_smc91x_0_resources,
+	},
+	{
+		.name			= "smc91x",
+		.id			= 1,
+		.num_resources		= ARRAY_SIZE(nettel_smc91x_1_resources),
+		.resource		= nettel_smc91x_1_resources,
+	},
+};
+
+static struct platform_device *nettel_devices[] __initdata = {
+	&nettel_smc91x[0],
+	&nettel_smc91x[1],
+};
+
+/***************************************************************************/
+
+static u8 nettel_macdefault[] __initdata = {
+	0x00, 0xd0, 0xcf, 0x00, 0x00, 0x01,
+};
+
+/*
+ * Set flash contained MAC address into SMC9196 core. Make sure the flash
+ * MAC address is sane, and not an empty flash. If no good use the Moreton
+ * Bay default MAC address instead.
+ */
+
+static void __init nettel_smc91x_setmac(unsigned int ioaddr, unsigned int flashaddr)
+{
+	u16 *macp;
+
+	macp = (u16 *) flashaddr;
+	if ((macp[0] == 0xffff) && (macp[1] == 0xffff) && (macp[2] == 0xffff))
+		macp = (u16 *) &nettel_macdefault[0];
+
+	writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT);
+	writew(macp[0], ioaddr + SMC91xx_BASEMAC);
+	writew(macp[1], ioaddr + SMC91xx_BASEMAC + 2);
+	writew(macp[2], ioaddr + SMC91xx_BASEMAC + 4);
+}
+
+/***************************************************************************/
+
+/*
+ * Re-map the address space of at least one of the SMC ethernet
+ * parts. Both parts power up decoding the same address, so we
+ * need to move one of them first, before doing anything else.
+ */
+
+static void __init nettel_smc91x_init(void)
+{
+	writew(0x00ec, MCF_MBAR + MCFSIM_PADDR);
+	mcf_setppdata(0, 0x0080);
+	writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT);
+	writew(0x0067, NETTEL_SMC0_ADDR + SMC91xx_BASEADDR);
+	mcf_setppdata(0x0080, 0);
+
+	/* Set correct chip select timing for SMC9196 accesses */
+	writew(0x1180, MCF_MBAR + MCFSIM_CSCR3);
+
+	/* Set the SMC interrupts to be auto-vectored */
+	mcf_autovector(NETTEL_SMC0_IRQ);
+	mcf_autovector(NETTEL_SMC1_IRQ);
+
+	/* Set MAC addresses from flash for both interfaces */
+	nettel_smc91x_setmac(NETTEL_SMC0_ADDR, 0xf0006000);
+	nettel_smc91x_setmac(NETTEL_SMC1_ADDR, 0xf0006006);
+}
+
+/***************************************************************************/
+
+static int __init init_nettel(void)
+{
+	nettel_smc91x_init();
+	platform_add_devices(nettel_devices, ARRAY_SIZE(nettel_devices));
+	return 0;
+}
+
+arch_initcall(init_nettel);
+
+/***************************************************************************/

+ 124 - 0
arch/m68knommu/platform/532x/config.c

@@ -21,12 +21,15 @@
 #include <linux/param.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfuart.h>
 #include <asm/mcfdma.h>
 #include <asm/mcfwdebug.h>
+#include <asm/mcfqspi.h>
 
 /***************************************************************************/
 
@@ -82,9 +85,127 @@ static struct platform_device m532x_fec = {
 	.resource		= m532x_fec_resources,
 };
 
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+static struct resource m532x_qspi_resources[] = {
+	{
+		.start		= MCFQSPI_IOBASE,
+		.end		= MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= MCFINT_VECBASE + MCFINT_QSPI,
+		.end		= MCFINT_VECBASE + MCFINT_QSPI,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+#define MCFQSPI_CS0    84
+#define MCFQSPI_CS1    85
+#define MCFQSPI_CS2    86
+
+static int m532x_cs_setup(struct mcfqspi_cs_control *cs_control)
+{
+	int status;
+
+	status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
+		goto fail0;
+	}
+	status = gpio_direction_output(MCFQSPI_CS0, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
+		goto fail1;
+	}
+
+	status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
+		goto fail1;
+	}
+	status = gpio_direction_output(MCFQSPI_CS1, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
+		goto fail2;
+	}
+
+	status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
+	if (status) {
+		pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
+		goto fail2;
+	}
+	status = gpio_direction_output(MCFQSPI_CS2, 1);
+	if (status) {
+		pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
+		goto fail3;
+	}
+
+	return 0;
+
+fail3:
+	gpio_free(MCFQSPI_CS2);
+fail2:
+	gpio_free(MCFQSPI_CS1);
+fail1:
+	gpio_free(MCFQSPI_CS0);
+fail0:
+	return status;
+}
+
+static void m532x_cs_teardown(struct mcfqspi_cs_control *cs_control)
+{
+	gpio_free(MCFQSPI_CS2);
+	gpio_free(MCFQSPI_CS1);
+	gpio_free(MCFQSPI_CS0);
+}
+
+static void m532x_cs_select(struct mcfqspi_cs_control *cs_control,
+			    u8 chip_select, bool cs_high)
+{
+	gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high);
+}
+
+static void m532x_cs_deselect(struct mcfqspi_cs_control *cs_control,
+			      u8 chip_select, bool cs_high)
+{
+	gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high);
+}
+
+static struct mcfqspi_cs_control m532x_cs_control = {
+	.setup                  = m532x_cs_setup,
+	.teardown               = m532x_cs_teardown,
+	.select                 = m532x_cs_select,
+	.deselect               = m532x_cs_deselect,
+};
+
+static struct mcfqspi_platform_data m532x_qspi_data = {
+	.bus_num		= 0,
+	.num_chipselect		= 3,
+	.cs_control		= &m532x_cs_control,
+};
+
+static struct platform_device m532x_qspi = {
+	.name			= "mcfqspi",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(m532x_qspi_resources),
+	.resource		= m532x_qspi_resources,
+	.dev.platform_data	= &m532x_qspi_data,
+};
+
+static void __init m532x_qspi_init(void)
+{
+	/* setup QSPS pins for QSPI with gpio CS control */
+	writew(0x01f0, MCF_GPIO_PAR_QSPI);
+}
+#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
+
+
 static struct platform_device *m532x_devices[] __initdata = {
 	&m532x_uart,
 	&m532x_fec,
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+	&m532x_qspi,
+#endif
 };
 
 /***************************************************************************/
@@ -158,6 +279,9 @@ static int __init init_BSP(void)
 {
 	m532x_uarts_init();
 	m532x_fec_init();
+#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
+	m532x_qspi_init();
+#endif
 	platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
 	return 0;
 }

+ 2 - 2
arch/m68knommu/platform/68360/commproc.c

@@ -110,7 +110,7 @@ void m360_cpm_reset()
 	/* 	pte = find_pte(&init_mm, host_page_addr); */
 	/* 	pte_val(*pte) |= _PAGE_NO_CACHE; */
 	/* 	flush_tlb_page(current->mm->mmap, host_buffer); */
-	
+
 	/* Tell everyone where the comm processor resides.
 	*/
 /* 	cpmp = (cpm360_t *)commproc; */
@@ -191,7 +191,7 @@ cpm_interrupt(int irq, void * dev, struct pt_regs * regs)
 	 */
 	((immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr |= (1 << vec);
 #endif
-	
+
 }
 
 /* The CPM can generate the error interrupt when there is a race condition