Commit c19eb8f0 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 99765cc7 724b62b5
...@@ -113,6 +113,7 @@ ...@@ -113,6 +113,7 @@
#define MCF_GPIO_PAR_UART (0xA4036) #define MCF_GPIO_PAR_UART (0xA4036)
#define MCF_GPIO_PAR_FECI2C (0xA4033) #define MCF_GPIO_PAR_FECI2C (0xA4033)
#define MCF_GPIO_PAR_QSPI (0xA4034)
#define MCF_GPIO_PAR_FEC (0xA4038) #define MCF_GPIO_PAR_FEC (0xA4038)
#define MCF_GPIO_PAR_UART_PAR_URXD0 (0x0001) #define MCF_GPIO_PAR_UART_PAR_URXD0 (0x0001)
......
...@@ -127,5 +127,10 @@ ...@@ -127,5 +127,10 @@
#define MCFGPIO_IRQ_MAX 8 #define MCFGPIO_IRQ_MAX 8
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE #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 */ #endif /* m523xsim_h */
...@@ -69,10 +69,12 @@ ...@@ -69,10 +69,12 @@
#define MCFSIM_DMA1ICR MCFSIM_ICR7 /* DMA 1 ICR */ #define MCFSIM_DMA1ICR MCFSIM_ICR7 /* DMA 1 ICR */
#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ #define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */
#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ #define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */
#define MCFSIM_QSPIICR MCFSIM_ICR10 /* QSPI ICR */
/* /*
* Define system peripheral IRQ usage. * Define system peripheral IRQ usage.
*/ */
#define MCF_IRQ_QSPI 28 /* QSPI, Level 4 */
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */ #define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */ #define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#define MCFINT_UART0 13 /* Interrupt number for UART0 */ #define MCFINT_UART0 13 /* Interrupt number for UART0 */
#define MCFINT_UART1 14 /* Interrupt number for UART1 */ #define MCFINT_UART1 14 /* Interrupt number for UART1 */
#define MCFINT_UART2 15 /* Interrupt number for UART2 */ #define MCFINT_UART2 15 /* Interrupt number for UART2 */
#define MCFINT_QSPI 18 /* Interrupt number for QSPI */
#define MCFINT_PIT1 36 /* Interrupt number for PIT1 */ #define MCFINT_PIT1 36 /* Interrupt number for PIT1 */
/* /*
...@@ -120,6 +121,9 @@ ...@@ -120,6 +121,9 @@
#define MCFGPIO_PIN_MAX 100 #define MCFGPIO_PIN_MAX 100
#define MCFGPIO_IRQ_MAX 8 #define MCFGPIO_IRQ_MAX 8
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE #define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
#define MCFGPIO_PAR_QSPI (MCF_IPSBAR + 0x10004A)
#define MCFGPIO_PAR_TIMER (MCF_IPSBAR + 0x10004C)
#endif #endif
#ifdef CONFIG_M5275 #ifdef CONFIG_M5275
...@@ -212,6 +216,8 @@ ...@@ -212,6 +216,8 @@
#define MCFGPIO_PIN_MAX 148 #define MCFGPIO_PIN_MAX 148
#define MCFGPIO_IRQ_MAX 8 #define MCFGPIO_IRQ_MAX 8
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE #define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
#define MCFGPIO_PAR_QSPI (MCF_IPSBAR + 0x10007E)
#endif #endif
/* /*
...@@ -223,6 +229,7 @@ ...@@ -223,6 +229,7 @@
#define MCFEPORT_EPPDR (MCF_IPSBAR + 0x130005) #define MCFEPORT_EPPDR (MCF_IPSBAR + 0x130005)
/* /*
* GPIO pins setups to enable the UARTs. * GPIO pins setups to enable the UARTs.
*/ */
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define MCFINT_VECBASE 64 /* Vector base number */ #define MCFINT_VECBASE 64 /* Vector base number */
#define MCFINT_UART0 13 /* Interrupt number for UART0 */ #define MCFINT_UART0 13 /* Interrupt number for UART0 */
#define MCFINT_QSPI 18 /* Interrupt number for QSPI */
#define MCFINT_PIT1 55 /* Interrupt number for PIT1 */ #define MCFINT_PIT1 55 /* Interrupt number for PIT1 */
/* /*
...@@ -249,70 +250,4 @@ ...@@ -249,70 +250,4 @@
#define MCF5282_I2C_I2SR_RXAK (0x01) // received acknowledge #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 */ #endif /* m528xsim_h */
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#define MCFINT_UART0 26 /* Interrupt number for UART0 */ #define MCFINT_UART0 26 /* Interrupt number for UART0 */
#define MCFINT_UART1 27 /* Interrupt number for UART1 */ #define MCFINT_UART1 27 /* Interrupt number for UART1 */
#define MCFINT_UART2 28 /* Interrupt number for UART2 */ #define MCFINT_UART2 28 /* Interrupt number for UART2 */
#define MCFINT_QSPI 31 /* Interrupt number for QSPI */
#define MCF_WTM_WCR MCF_REG16(0xFC098000) #define MCF_WTM_WCR MCF_REG16(0xFC098000)
......
/*
* 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 */
/****************************************************************************/
/*
* 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 */
...@@ -44,11 +44,15 @@ static inline void wrusp(unsigned long usp) ...@@ -44,11 +44,15 @@ static inline void wrusp(unsigned long usp)
* User space process size: 3.75GB. This is hardcoded into a few places, * 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. * so don't change it unless you know what you are doing.
*/ */
#ifdef CONFIG_MMU
#ifndef CONFIG_SUN3 #ifndef CONFIG_SUN3
#define TASK_SIZE (0xF0000000UL) #define TASK_SIZE (0xF0000000UL)
#else #else
#define TASK_SIZE (0x0E000000UL) #define TASK_SIZE (0x0E000000UL)
#endif #endif
#else
#define TASK_SIZE (0xFFFFFFFFUL)
#endif
#ifdef __KERNEL__ #ifdef __KERNEL__
#define STACK_TOP TASK_SIZE #define STACK_TOP TASK_SIZE
......
...@@ -566,7 +566,7 @@ config RAMBASE ...@@ -566,7 +566,7 @@ config RAMBASE
processor address space. processor address space.
config RAMSIZE config RAMSIZE
hex "Size of RAM (in bytes)" hex "Size of RAM (in bytes), or 0 for automatic"
default "0x400000" default "0x400000"
help help
Define the size of the system RAM. If you select 0 then the Define the size of the system RAM. If you select 0 then the
......
...@@ -36,7 +36,7 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, ...@@ -36,7 +36,7 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
unsigned long error_code) unsigned long error_code)
{ {
#ifdef DEBUG #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); regs->sr, regs->pc, address, error_code);
#endif #endif
...@@ -44,11 +44,11 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address, ...@@ -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 * Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice. * 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"); printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
} else else
printk(KERN_ALERT "Unable to handle kernel access"); 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); die_if_kernel("Oops", regs, error_code);
do_exit(SIGKILL); do_exit(SIGKILL);
......
...@@ -15,10 +15,13 @@ ...@@ -15,10 +15,13 @@
#include <linux/param.h> #include <linux/param.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/spi/spi.h>
#include <linux/gpio.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/coldfire.h> #include <asm/coldfire.h>
#include <asm/mcfsim.h> #include <asm/mcfsim.h>
#include <asm/mcfuart.h> #include <asm/mcfuart.h>
#include <asm/mcfqspi.h>
/***************************************************************************/ /***************************************************************************/
...@@ -74,9 +77,152 @@ static struct platform_device m520x_fec = { ...@@ -74,9 +77,152 @@ static struct platform_device m520x_fec = {
.resource = m520x_fec_resources, .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 = { static struct platform_device *m520x_devices[] __initdata = {
&m520x_uart, &m520x_uart,
&m520x_fec, &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) ...@@ -147,6 +293,9 @@ void __init config_BSP(char *commandp, int size)
mach_reset = m520x_cpu_reset; mach_reset = m520x_cpu_reset;
m520x_uarts_init(); m520x_uarts_init();
m520x_fec_init(); m520x_fec_init();
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
m520x_qspi_init();
#endif
} }
/***************************************************************************/ /***************************************************************************/
......
...@@ -16,10 +16,13 @@ ...@@ -16,10 +16,13 @@
#include <linux/param.h> #include <linux/param.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/spi/spi.h>
#include <linux/gpio.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/coldfire.h> #include <asm/coldfire.h>
#include <asm/mcfsim.h> #include <asm/mcfsim.h>
#include <asm/mcfuart.h> #include <asm/mcfuart.h>
#include <asm/mcfqspi.h>
/***************************************************************************/ /***************************************************************************/
...@@ -75,9 +78,173 @@ static struct platform_device m523x_fec = { ...@@ -75,9 +78,173 @@ static struct platform_device m523x_fec = {
.resource = m523x_fec_resources, .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 = { static struct platform_device *m523x_devices[] __initdata = {
&m523x_uart, &m523x_uart,
&m523x_fec, &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) ...@@ -114,6 +281,9 @@ void __init config_BSP(char *commandp, int size)
static int __init init_BSP(void) static int __init init_BSP(void)
{ {
m523x_fec_init(); 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)); platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices));
return 0; return 0;
} }
......
...@@ -12,10 +12,13 @@ ...@@ -12,10 +12,13 @@
#include <linux/param.h> #include <linux/param.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/spi/spi.h>
#include <linux/gpio.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/coldfire.h> #include <asm/coldfire.h>
#include <asm/mcfsim.h> #include <asm/mcfsim.h>
#include <asm/mcfuart.h> #include <asm/mcfuart.h>
#include <asm/mcfqspi.h>
/***************************************************************************/ /***************************************************************************/
...@@ -37,8 +40,196 @@ static struct platform_device m5249_uart = { ...@@ -37,8 +40,196 @@ static struct platform_device m5249_uart = {
.dev.platform_data = m5249_uart_platform, .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 = { static struct platform_device *m5249_devices[] __initdata = {
&m5249_uart, &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) ...@@ -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) static void __init m5249_timers_init(void)
{ {
/* Timer1 is always used as system timer */ /* Timer1 is always used as system timer */
...@@ -100,6 +309,12 @@ void __init config_BSP(char *commandp, int size) ...@@ -100,6 +309,12 @@ void __init config_BSP(char *commandp, int size)
mach_reset = m5249_cpu_reset; mach_reset = m5249_cpu_reset;
m5249_timers_init(); m5249_timers_init();
m5249_uarts_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
} }
/***************************************************************************/ /***************************************************************************/
......
...@@ -16,10 +16,13 @@ ...@@ -16,10 +16,13 @@
#include <linux/param.h> #include <linux/param.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/spi/spi.h>
#include <linux/gpio.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/coldfire.h> #include <asm/coldfire.h>
#include <asm/mcfsim.h> #include <asm/mcfsim.h>
#include <asm/mcfuart.h> #include <asm/mcfuart.h>
#include <asm/mcfqspi.h>
/***************************************************************************/ /***************************************************************************/
...@@ -106,12 +109,188 @@ static struct platform_device m527x_fec[] = { ...@@ -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 = { static struct platform_device *m527x_devices[] __initdata = {
&m527x_uart, &m527x_uart,
&m527x_fec[0], &m527x_fec[0],
#ifdef CONFIG_FEC2 #ifdef CONFIG_FEC2
&m527x_fec[1], &m527x_fec[1],
#endif #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) ...@@ -187,6 +366,9 @@ void __init config_BSP(char *commandp, int size)
mach_reset = m527x_cpu_reset; mach_reset = m527x_cpu_reset;
m527x_uarts_init(); m527x_uarts_init();
m527x_fec_init(); m527x_fec_init();
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
m527x_qspi_init();
#endif
} }
/***************************************************************************/ /***************************************************************************/
......
...@@ -17,10 +17,13 @@ ...@@ -17,10 +17,13 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/spi/spi.h>
#include <linux/gpio.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/coldfire.h> #include <asm/coldfire.h>
#include <asm/mcfsim.h> #include <asm/mcfsim.h>
#include <asm/mcfuart.h> #include <asm/mcfuart.h>
#include <asm/mcfqspi.h>
/***************************************************************************/ /***************************************************************************/
...@@ -76,10 +79,141 @@ static struct platform_device m528x_fec = { ...@@ -76,10 +79,141 @@ static struct platform_device m528x_fec = {
.resource = m528x_fec_resources, .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 = { static struct platform_device *m528x_devices[] __initdata = {
&m528x_uart, &m528x_uart,
&m528x_fec, &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) ...@@ -174,6 +308,9 @@ static int __init init_BSP(void)
mach_reset = m528x_cpu_reset; mach_reset = m528x_cpu_reset;
m528x_uarts_init(); m528x_uarts_init();
m528x_fec_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)); platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
return 0; return 0;
} }
......
...@@ -15,4 +15,6 @@ ...@@ -15,4 +15,6 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 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
/***************************************************************************/
/*
* 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);
/***************************************************************************/
...@@ -21,12 +21,15 @@ ...@@ -21,12 +21,15 @@
#include <linux/param.h> #include <linux/param.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/spi/spi.h>
#include <linux/gpio.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/coldfire.h> #include <asm/coldfire.h>
#include <asm/mcfsim.h> #include <asm/mcfsim.h>
#include <asm/mcfuart.h> #include <asm/mcfuart.h>
#include <asm/mcfdma.h> #include <asm/mcfdma.h>
#include <asm/mcfwdebug.h> #include <asm/mcfwdebug.h>
#include <asm/mcfqspi.h>
/***************************************************************************/ /***************************************************************************/
...@@ -82,9 +85,127 @@ static struct platform_device m532x_fec = { ...@@ -82,9 +85,127 @@ static struct platform_device m532x_fec = {
.resource = m532x_fec_resources, .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 = { static struct platform_device *m532x_devices[] __initdata = {
&m532x_uart, &m532x_uart,
&m532x_fec, &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) ...@@ -158,6 +279,9 @@ static int __init init_BSP(void)
{ {
m532x_uarts_init(); m532x_uarts_init();
m532x_fec_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)); platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment