Commit 66bc4a6f 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: (53 commits)
  m68knommu: Make PAGE_SIZE available to assembly files.
  m68knommu: fix ColdFire definition of CLOCK_TICK_RATE
  m68knommu: set multi-function pins for ethernet when enabled
  m68knommu: remove special interrupt handling code for ne2k support
  m68knommu: relax IO_SPACE_LIMIT setting
  m68knommu: remove ColdFire direct interrupt register access
  m68knommu: create a speciailized ColdFire 5272 interrupt controller
  m68knommu: add support for second interrupt controller of ColdFire 5249
  m68knommu: clean up old ColdFire timer irq setup
  m68knommu: map ColdFire interrupts to correct masking bits
  m68knommu: clean up ColdFire 532x CPU timer setup
  m68knommu: simplify ColdFire "timers" clock initialization
  m68knommu: support code to mask external interrupts on old ColdFire CPU's
  m68knommu: merge old ColdFire interrupt controller masking macros
  m68knommu: remove duplicate ColdFire mcf_autovector() code
  m68knommu: move ColdFire INTC definitions to new include file
  m68knommu: mask off all interrupts in ColdFire intc-simr controller
  m68knommu: remove timer device interrupt setup for ColdFire 532x
  m68knommu: remove interrupt masking from ColdFire pit timer
  m68knommu: remove unecessary interrupt level setting in ColdFire 520x setup
  ...
parents 96c015b7 2985709d
#ifdef __uClinux__
#include "checksum_no.h"
#ifndef _M68K_CHECKSUM_H
#define _M68K_CHECKSUM_H
#include <linux/in6.h>
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
__wsum csum_partial(const void *buff, int len, __wsum sum);
/*
* the same as csum_partial, but copies from src while it
* checksums
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
extern __wsum csum_partial_copy_from_user(const void __user *src,
void *dst,
int len, __wsum sum,
int *csum_err);
extern __wsum csum_partial_copy_nocheck(const void *src,
void *dst, int len,
__wsum sum);
#ifdef CONFIG_COLDFIRE
/*
* The ColdFire cores don't support all the 68k instructions used
* in the optimized checksum code below. So it reverts back to using
* more standard C coded checksums. The fast checksum code is
* significantly larger than the optimized version, so it is not
* inlined here.
*/
__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
static inline __sum16 csum_fold(__wsum sum)
{
unsigned int tmp = (__force u32)sum;
tmp = (tmp & 0xffff) + (tmp >> 16);
tmp = (tmp & 0xffff) + (tmp >> 16);
return (__force __sum16)~tmp;
}
#else
#include "checksum_mm.h"
#endif
/*
* This is a version of ip_fast_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries.
*/
static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
{
unsigned int sum = 0;
unsigned long tmp;
__asm__ ("subqw #1,%2\n"
"1:\t"
"movel %1@+,%3\n\t"
"addxl %3,%0\n\t"
"dbra %2,1b\n\t"
"movel %0,%3\n\t"
"swap %3\n\t"
"addxw %3,%0\n\t"
"clrw %3\n\t"
"addxw %3,%0\n\t"
: "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp)
: "0" (sum), "1" (iph), "2" (ihl)
: "memory");
return (__force __sum16)~sum;
}
static inline __sum16 csum_fold(__wsum sum)
{
unsigned int tmp = (__force u32)sum;
__asm__("swap %1\n\t"
"addw %1, %0\n\t"
"clrw %1\n\t"
"addxw %1, %0"
: "=&d" (sum), "=&d" (tmp)
: "0" (sum), "1" (tmp));
return (__force __sum16)~sum;
}
#endif /* CONFIG_COLDFIRE */
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
__asm__ ("addl %2,%0\n\t"
"addxl %3,%0\n\t"
"addxl %4,%0\n\t"
"clrl %1\n\t"
"addxl %1,%0"
: "=&d" (sum), "=d" (saddr)
: "g" (daddr), "1" (saddr), "d" (len + proto),
"0" (sum));
return sum;
}
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
static inline __sum16 ip_compute_csum(const void *buff, int len)
{
return csum_fold (csum_partial(buff, len, 0));
}
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, unsigned short proto, __wsum sum)
{
register unsigned long tmp;
__asm__("addl %2@,%0\n\t"
"movel %2@(4),%1\n\t"
"addxl %1,%0\n\t"
"movel %2@(8),%1\n\t"
"addxl %1,%0\n\t"
"movel %2@(12),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@,%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(4),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(8),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(12),%1\n\t"
"addxl %1,%0\n\t"
"addxl %4,%0\n\t"
"clrl %1\n\t"
"addxl %1,%0"
: "=&d" (sum), "=&d" (tmp)
: "a" (saddr), "a" (daddr), "d" (len + proto),
"0" (sum));
return csum_fold(sum);
}
#endif /* _M68K_CHECKSUM_H */
#ifndef _M68K_CHECKSUM_H
#define _M68K_CHECKSUM_H
#include <linux/in6.h>
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
__wsum csum_partial(const void *buff, int len, __wsum sum);
/*
* the same as csum_partial, but copies from src while it
* checksums
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
extern __wsum csum_partial_copy_from_user(const void __user *src,
void *dst,
int len, __wsum sum,
int *csum_err);
extern __wsum csum_partial_copy_nocheck(const void *src,
void *dst, int len,
__wsum sum);
/*
* This is a version of ip_compute_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries.
*
*/
static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
{
unsigned int sum = 0;
unsigned long tmp;
__asm__ ("subqw #1,%2\n"
"1:\t"
"movel %1@+,%3\n\t"
"addxl %3,%0\n\t"
"dbra %2,1b\n\t"
"movel %0,%3\n\t"
"swap %3\n\t"
"addxw %3,%0\n\t"
"clrw %3\n\t"
"addxw %3,%0\n\t"
: "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp)
: "0" (sum), "1" (iph), "2" (ihl)
: "memory");
return (__force __sum16)~sum;
}
/*
* Fold a partial checksum
*/
static inline __sum16 csum_fold(__wsum sum)
{
unsigned int tmp = (__force u32)sum;
__asm__("swap %1\n\t"
"addw %1, %0\n\t"
"clrw %1\n\t"
"addxw %1, %0"
: "=&d" (sum), "=&d" (tmp)
: "0" (sum), "1" (tmp));
return (__force __sum16)~sum;
}
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
__asm__ ("addl %2,%0\n\t"
"addxl %3,%0\n\t"
"addxl %4,%0\n\t"
"clrl %1\n\t"
"addxl %1,%0"
: "=&d" (sum), "=d" (saddr)
: "g" (daddr), "1" (saddr), "d" (len + proto),
"0" (sum));
return sum;
}
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
static inline __sum16 ip_compute_csum(const void *buff, int len)
{
return csum_fold (csum_partial(buff, len, 0));
}
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, unsigned short proto, __wsum sum)
{
register unsigned long tmp;
__asm__("addl %2@,%0\n\t"
"movel %2@(4),%1\n\t"
"addxl %1,%0\n\t"
"movel %2@(8),%1\n\t"
"addxl %1,%0\n\t"
"movel %2@(12),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@,%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(4),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(8),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(12),%1\n\t"
"addxl %1,%0\n\t"
"addxl %4,%0\n\t"
"clrl %1\n\t"
"addxl %1,%0"
: "=&d" (sum), "=&d" (tmp)
: "a" (saddr), "a" (daddr), "d" (len + proto),
"0" (sum));
return csum_fold(sum);
}
#endif /* _M68K_CHECKSUM_H */
#ifndef _M68K_CHECKSUM_H
#define _M68K_CHECKSUM_H
#include <linux/in6.h>
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
__wsum csum_partial(const void *buff, int len, __wsum sum);
/*
* the same as csum_partial, but copies from src while it
* checksums
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
__wsum csum_partial_copy_nocheck(const void *src, void *dst,
int len, __wsum sum);
/*
* the same as csum_partial_copy, but copies from user space.
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
extern __wsum csum_partial_copy_from_user(const void __user *src,
void *dst, int len, __wsum sum, int *csum_err);
__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
/*
* Fold a partial checksum
*/
static inline __sum16 csum_fold(__wsum sum)
{
unsigned int tmp = (__force u32)sum;
#ifdef CONFIG_COLDFIRE
tmp = (tmp & 0xffff) + (tmp >> 16);
tmp = (tmp & 0xffff) + (tmp >> 16);
return (__force __sum16)~tmp;
#else
__asm__("swap %1\n\t"
"addw %1, %0\n\t"
"clrw %1\n\t"
"addxw %1, %0"
: "=&d" (sum), "=&d" (tmp)
: "0" (sum), "1" (sum));
return (__force __sum16)~sum;
#endif
}
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
__asm__ ("addl %1,%0\n\t"
"addxl %4,%0\n\t"
"addxl %5,%0\n\t"
"clrl %1\n\t"
"addxl %1,%0"
: "=&d" (sum), "=&d" (saddr)
: "0" (daddr), "1" (saddr), "d" (len + proto),
"d"(sum));
return sum;
}
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
extern __sum16 ip_compute_csum(const void *buff, int len);
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, unsigned short proto, __wsum sum)
{
register unsigned long tmp;
__asm__("addl %2@,%0\n\t"
"movel %2@(4),%1\n\t"
"addxl %1,%0\n\t"
"movel %2@(8),%1\n\t"
"addxl %1,%0\n\t"
"movel %2@(12),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@,%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(4),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(8),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(12),%1\n\t"
"addxl %1,%0\n\t"
"addxl %4,%0\n\t"
"clrl %1\n\t"
"addxl %1,%0"
: "=&d" (sum), "=&d" (tmp)
: "a" (saddr), "a" (daddr), "d" (len + proto),
"0" (sum));
return csum_fold(sum);
}
#endif /* _M68K_CHECKSUM_H */
#ifdef __uClinux__
#include "dma_no.h"
#ifndef _M68K_DMA_H
#define _M68K_DMA_H 1
#ifdef CONFIG_COLDFIRE
/*
* ColdFire DMA Model:
* ColdFire DMA supports two forms of DMA: Single and Dual address. Single
* address mode emits a source address, and expects that the device will either
* pick up the data (DMA READ) or source data (DMA WRITE). This implies that
* the device will place data on the correct byte(s) of the data bus, as the
* memory transactions are always 32 bits. This implies that only 32 bit
* devices will find single mode transfers useful. Dual address DMA mode
* performs two cycles: source read and destination write. ColdFire will
* align the data so that the device will always get the correct bytes, thus
* is useful for 8 and 16 bit devices. This is the mode that is supported
* below.
*
* AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000
* Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
*
* AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000
* Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
*
* APR/18/2002 : added proper support for MCF5272 DMA controller.
* Arthur Shipkowski (art@videon-central.com)
*/
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfdma.h>
/*
* Set number of channels of DMA on ColdFire for different implementations.
*/
#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \
defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
#define MAX_M68K_DMA_CHANNELS 4
#elif defined(CONFIG_M5272)
#define MAX_M68K_DMA_CHANNELS 1
#elif defined(CONFIG_M532x)
#define MAX_M68K_DMA_CHANNELS 0
#else
#include "dma_mm.h"
#define MAX_M68K_DMA_CHANNELS 2
#endif
extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
#if !defined(CONFIG_M5272)
#define DMA_MODE_WRITE_BIT 0x01 /* Memory/IO to IO/Memory select */
#define DMA_MODE_WORD_BIT 0x02 /* 8 or 16 bit transfers */
#define DMA_MODE_LONG_BIT 0x04 /* or 32 bit transfers */
#define DMA_MODE_SINGLE_BIT 0x08 /* single-address-mode */
/* I/O to memory, 8 bits, mode */
#define DMA_MODE_READ 0
/* memory to I/O, 8 bits, mode */
#define DMA_MODE_WRITE 1
/* I/O to memory, 16 bits, mode */
#define DMA_MODE_READ_WORD 2
/* memory to I/O, 16 bits, mode */
#define DMA_MODE_WRITE_WORD 3
/* I/O to memory, 32 bits, mode */
#define DMA_MODE_READ_LONG 4
/* memory to I/O, 32 bits, mode */
#define DMA_MODE_WRITE_LONG 5
/* I/O to memory, 8 bits, single-address-mode */
#define DMA_MODE_READ_SINGLE 8
/* memory to I/O, 8 bits, single-address-mode */
#define DMA_MODE_WRITE_SINGLE 9
/* I/O to memory, 16 bits, single-address-mode */
#define DMA_MODE_READ_WORD_SINGLE 10
/* memory to I/O, 16 bits, single-address-mode */
#define DMA_MODE_WRITE_WORD_SINGLE 11
/* I/O to memory, 32 bits, single-address-mode */
#define DMA_MODE_READ_LONG_SINGLE 12
/* memory to I/O, 32 bits, single-address-mode */
#define DMA_MODE_WRITE_LONG_SINGLE 13
#else /* CONFIG_M5272 is defined */
/* Source static-address mode */
#define DMA_MODE_SRC_SA_BIT 0x01
/* Two bits to select between all four modes */
#define DMA_MODE_SSIZE_MASK 0x06
/* Offset to shift bits in */
#define DMA_MODE_SSIZE_OFF 0x01
/* Destination static-address mode */
#define DMA_MODE_DES_SA_BIT 0x10
/* Two bits to select between all four modes */
#define DMA_MODE_DSIZE_MASK 0x60
/* Offset to shift bits in */
#define DMA_MODE_DSIZE_OFF 0x05
/* Size modifiers */
#define DMA_MODE_SIZE_LONG 0x00
#define DMA_MODE_SIZE_BYTE 0x01
#define DMA_MODE_SIZE_WORD 0x02
#define DMA_MODE_SIZE_LINE 0x03
/*
* Aliases to help speed quick ports; these may be suboptimal, however. They
* do not include the SINGLE mode modifiers since the MCF5272 does not have a
* mode where the device is in control of its addressing.
*/
/* I/O to memory, 8 bits, mode */
#define DMA_MODE_READ ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
/* memory to I/O, 8 bits, mode */
#define DMA_MODE_WRITE ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
/* I/O to memory, 16 bits, mode */
#define DMA_MODE_READ_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
/* memory to I/O, 16 bits, mode */
#define DMA_MODE_WRITE_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
/* I/O to memory, 32 bits, mode */
#define DMA_MODE_READ_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
/* memory to I/O, 32 bits, mode */
#define DMA_MODE_WRITE_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
#endif /* !defined(CONFIG_M5272) */
#if !defined(CONFIG_M5272)
/* enable/disable a specific DMA channel */
static __inline__ void enable_dma(unsigned int dmanr)
{
volatile unsigned short *dmawp;
#ifdef DMA_DEBUG
printk("enable_dma(dmanr=%d)\n", dmanr);
#endif
dmawp = (unsigned short *) dma_base_addr[dmanr];
dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT;
}
static __inline__ void disable_dma(unsigned int dmanr)
{
volatile unsigned short *dmawp;
volatile unsigned char *dmapb;
#ifdef DMA_DEBUG
printk("disable_dma(dmanr=%d)\n", dmanr);
#endif
dmawp = (unsigned short *) dma_base_addr[dmanr];
dmapb = (unsigned char *) dma_base_addr[dmanr];
/* Turn off external requests, and stop any DMA in progress */
dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT;
dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE;
}
/*
* Clear the 'DMA Pointer Flip Flop'.
* Write 0 for LSB/MSB, 1 for MSB/LSB access.
* Use this once to initialize the FF to a known state.
* After that, keep track of it. :-)
* --- In order to do that, the DMA routines below should ---
* --- only be used while interrupts are disabled! ---
*
* This is a NOP for ColdFire. Provide a stub for compatibility.
*/
static __inline__ void clear_dma_ff(unsigned int dmanr)
{
}
/* set mode (above) for a specific DMA channel */
static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
{
volatile unsigned char *dmabp;
volatile unsigned short *dmawp;
#ifdef DMA_DEBUG
printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
#endif
dmabp = (unsigned char *) dma_base_addr[dmanr];
dmawp = (unsigned short *) dma_base_addr[dmanr];
/* Clear config errors */
dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE;
/* Set command register */
dmawp[MCFDMA_DCR] =
MCFDMA_DCR_INT | /* Enable completion irq */
MCFDMA_DCR_CS | /* Force one xfer per request */
MCFDMA_DCR_AA | /* Enable auto alignment */
/* single-address-mode */
((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) |
/* sets s_rw (-> r/w) high if Memory to I/0 */
((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) |
/* Memory to I/O or I/O to Memory */
((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) |
/* 32 bit, 16 bit or 8 bit transfers */
((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_SSIZE_WORD :
((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG :
MCFDMA_DCR_SSIZE_BYTE)) |
((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_DSIZE_WORD :
((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG :
MCFDMA_DCR_DSIZE_BYTE));
#ifdef DEBUG_DMA
printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__,
dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR],
(int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]);
#endif
}
/* Set transfer address for specific DMA channel */
static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
{
volatile unsigned short *dmawp;
volatile unsigned int *dmalp;
#ifdef DMA_DEBUG
printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
#endif
dmawp = (unsigned short *) dma_base_addr[dmanr];
dmalp = (unsigned int *) dma_base_addr[dmanr];
/* Determine which address registers are used for memory/device accesses */
if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) {
/* Source incrementing, must be memory */
dmalp[MCFDMA_SAR] = a;
/* Set dest address, must be device */
dmalp[MCFDMA_DAR] = dma_device_address[dmanr];
} else {
/* Destination incrementing, must be memory */
dmalp[MCFDMA_DAR] = a;
/* Set source address, must be device */
dmalp[MCFDMA_SAR] = dma_device_address[dmanr];
}
#ifdef DEBUG_DMA
printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
__FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR],
(int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR],
(int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]);
#endif
}
/*
* Specific for Coldfire - sets device address.
* Should be called after the mode set call, and before set DMA address.
*/
static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
{
#ifdef DMA_DEBUG
printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
#endif
dma_device_address[dmanr] = a;
}
/*
* NOTE 2: "count" represents _bytes_.
*/
static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
{
volatile unsigned short *dmawp;
#ifdef DMA_DEBUG
printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
#endif
dmawp = (unsigned short *) dma_base_addr[dmanr];
dmawp[MCFDMA_BCR] = (unsigned short)count;
}
/*
* Get DMA residue count. After a DMA transfer, this
* should return zero. Reading this while a DMA transfer is
* still in progress will return unpredictable results.
* Otherwise, it returns the number of _bytes_ left to transfer.
*/
static __inline__ int get_dma_residue(unsigned int dmanr)
{
volatile unsigned short *dmawp;
unsigned short count;
#ifdef DMA_DEBUG
printk("get_dma_residue(dmanr=%d)\n", dmanr);
#endif
dmawp = (unsigned short *) dma_base_addr[dmanr];
count = dmawp[MCFDMA_BCR];
return((int) count);
}
#else /* CONFIG_M5272 is defined */
/*
* The MCF5272 DMA controller is very different than the controller defined above
* in terms of register mapping. For instance, with the exception of the 16-bit
* interrupt register (IRQ#85, for reference), all of the registers are 32-bit.
*
* The big difference, however, is the lack of device-requested DMA. All modes
* are dual address transfer, and there is no 'device' setup or direction bit.
* You can DMA between a device and memory, between memory and memory, or even between
* two devices directly, with any combination of incrementing and non-incrementing
* addresses you choose. This puts a crimp in distinguishing between the 'device
* address' set up by set_dma_device_addr.
*
* Therefore, there are two options. One is to use set_dma_addr and set_dma_device_addr,
* which will act exactly as above in -- it will look to see if the source is set to
* autoincrement, and if so it will make the source use the set_dma_addr value and the
* destination the set_dma_device_addr value. Otherwise the source will be set to the
* set_dma_device_addr value and the destination will get the set_dma_addr value.
*
* The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions
* and make it explicit. Depending on what you're doing, one of these two should work
* for you, but don't mix them in the same transfer setup.
*/
/* enable/disable a specific DMA channel */
static __inline__ void enable_dma(unsigned int dmanr)
{
volatile unsigned int *dmalp;
#ifdef DMA_DEBUG
printk("enable_dma(dmanr=%d)\n", dmanr);
#endif
dmalp = (unsigned int *) dma_base_addr[dmanr];
dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN;
}
static __inline__ void disable_dma(unsigned int dmanr)
{
volatile unsigned int *dmalp;
#ifdef DMA_DEBUG
printk("disable_dma(dmanr=%d)\n", dmanr);
#endif
dmalp = (unsigned int *) dma_base_addr[dmanr];
/* Turn off external requests, and stop any DMA in progress */
dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN;
dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
}
/*
* Clear the 'DMA Pointer Flip Flop'.
* Write 0 for LSB/MSB, 1 for MSB/LSB access.
* Use this once to initialize the FF to a known state.
* After that, keep track of it. :-)
* --- In order to do that, the DMA routines below should ---
* --- only be used while interrupts are disabled! ---
*
* This is a NOP for ColdFire. Provide a stub for compatibility.
*/
static __inline__ void clear_dma_ff(unsigned int dmanr)
{
}
/* set mode (above) for a specific DMA channel */
static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
{
volatile unsigned int *dmalp;
volatile unsigned short *dmawp;
#ifdef DMA_DEBUG
printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
#endif
dmalp = (unsigned int *) dma_base_addr[dmanr];
dmawp = (unsigned short *) dma_base_addr[dmanr];
/* Clear config errors */
dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
/* Set command register */
dmalp[MCFDMA_DMR] =
MCFDMA_DMR_RQM_DUAL | /* Mandatory Request Mode setting */
MCFDMA_DMR_DSTT_SD | /* Set up addressing types; set to supervisor-data. */
MCFDMA_DMR_SRCT_SD | /* Set up addressing types; set to supervisor-data. */
/* source static-address-mode */
((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) |
/* dest static-address-mode */
((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) |
/* burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272 */
(((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) |
(((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF);
dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN; /* Enable completion interrupts */
#ifdef DEBUG_DMA
printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__,
dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR],
(int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]);
#endif
}
/* Set transfer address for specific DMA channel */
static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
{
volatile unsigned int *dmalp;
#ifdef DMA_DEBUG
printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
#endif
dmalp = (unsigned int *) dma_base_addr[dmanr];
/* Determine which address registers are used for memory/device accesses */
if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) {
/* Source incrementing, must be memory */
dmalp[MCFDMA_DSAR] = a;
/* Set dest address, must be device */
dmalp[MCFDMA_DDAR] = dma_device_address[dmanr];
} else {
/* Destination incrementing, must be memory */
dmalp[MCFDMA_DDAR] = a;
/* Set source address, must be device */
dmalp[MCFDMA_DSAR] = dma_device_address[dmanr];
}
#ifdef DEBUG_DMA
printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
__FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR],
(int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR],
(int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]);
#endif
}
/*
* Specific for Coldfire - sets device address.
* Should be called after the mode set call, and before set DMA address.
*/
static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
{
#ifdef DMA_DEBUG
printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
#endif
dma_device_address[dmanr] = a;
}
/*
* NOTE 2: "count" represents _bytes_.
*
* NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value.
*/
static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
{
volatile unsigned int *dmalp;
#ifdef DMA_DEBUG
printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
#endif
dmalp = (unsigned int *) dma_base_addr[dmanr];
dmalp[MCFDMA_DBCR] = count;
}
/*
* Get DMA residue count. After a DMA transfer, this
* should return zero. Reading this while a DMA transfer is
* still in progress will return unpredictable results.
* Otherwise, it returns the number of _bytes_ left to transfer.
*/
static __inline__ int get_dma_residue(unsigned int dmanr)
{
volatile unsigned int *dmalp;
unsigned int count;
#ifdef DMA_DEBUG
printk("get_dma_residue(dmanr=%d)\n", dmanr);
#endif
dmalp = (unsigned int *) dma_base_addr[dmanr];
count = dmalp[MCFDMA_DBCR];
return(count);
}
#endif /* !defined(CONFIG_M5272) */
#endif /* CONFIG_COLDFIRE */
/* it's useless on the m68k, but unfortunately needed by the new
bootmem allocator (but this should do it for this) */
#define MAX_DMA_ADDRESS PAGE_OFFSET
#define MAX_DMA_CHANNELS 8
extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
extern void free_dma(unsigned int dmanr); /* release it again */
#define isa_dma_bridge_buggy (0)
#endif /* _M68K_DMA_H */
#ifndef _M68K_DMA_H
#define _M68K_DMA_H 1
/* it's useless on the m68k, but unfortunately needed by the new
bootmem allocator (but this should do it for this) */
#define MAX_DMA_ADDRESS PAGE_OFFSET
#define MAX_DMA_CHANNELS 8
extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
extern void free_dma(unsigned int dmanr); /* release it again */
#define isa_dma_bridge_buggy (0)
#endif /* _M68K_DMA_H */
#ifndef _M68K_DMA_H
#define _M68K_DMA_H 1
//#define DMA_DEBUG 1
#ifdef CONFIG_COLDFIRE
/*
* ColdFire DMA Model:
* ColdFire DMA supports two forms of DMA: Single and Dual address. Single
* address mode emits a source address, and expects that the device will either
* pick up the data (DMA READ) or source data (DMA WRITE). This implies that
* the device will place data on the correct byte(s) of the data bus, as the
* memory transactions are always 32 bits. This implies that only 32 bit
* devices will find single mode transfers useful. Dual address DMA mode
* performs two cycles: source read and destination write. ColdFire will
* align the data so that the device will always get the correct bytes, thus
* is useful for 8 and 16 bit devices. This is the mode that is supported
* below.
*
* AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000
* Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
*
* AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000
* Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
*
* APR/18/2002 : added proper support for MCF5272 DMA controller.
* Arthur Shipkowski (art@videon-central.com)
*/
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfdma.h>
/*
* Set number of channels of DMA on ColdFire for different implementations.
*/
#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \
defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
#define MAX_M68K_DMA_CHANNELS 4
#elif defined(CONFIG_M5272)
#define MAX_M68K_DMA_CHANNELS 1
#elif defined(CONFIG_M532x)
#define MAX_M68K_DMA_CHANNELS 0
#else
#define MAX_M68K_DMA_CHANNELS 2
#endif
extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
#if !defined(CONFIG_M5272)
#define DMA_MODE_WRITE_BIT 0x01 /* Memory/IO to IO/Memory select */
#define DMA_MODE_WORD_BIT 0x02 /* 8 or 16 bit transfers */
#define DMA_MODE_LONG_BIT 0x04 /* or 32 bit transfers */
#define DMA_MODE_SINGLE_BIT 0x08 /* single-address-mode */
/* I/O to memory, 8 bits, mode */
#define DMA_MODE_READ 0
/* memory to I/O, 8 bits, mode */
#define DMA_MODE_WRITE 1
/* I/O to memory, 16 bits, mode */
#define DMA_MODE_READ_WORD 2
/* memory to I/O, 16 bits, mode */
#define DMA_MODE_WRITE_WORD 3
/* I/O to memory, 32 bits, mode */
#define DMA_MODE_READ_LONG 4
/* memory to I/O, 32 bits, mode */
#define DMA_MODE_WRITE_LONG 5
/* I/O to memory, 8 bits, single-address-mode */
#define DMA_MODE_READ_SINGLE 8
/* memory to I/O, 8 bits, single-address-mode */
#define DMA_MODE_WRITE_SINGLE 9
/* I/O to memory, 16 bits, single-address-mode */
#define DMA_MODE_READ_WORD_SINGLE 10
/* memory to I/O, 16 bits, single-address-mode */
#define DMA_MODE_WRITE_WORD_SINGLE 11
/* I/O to memory, 32 bits, single-address-mode */
#define DMA_MODE_READ_LONG_SINGLE 12
/* memory to I/O, 32 bits, single-address-mode */
#define DMA_MODE_WRITE_LONG_SINGLE 13
#else /* CONFIG_M5272 is defined */
/* Source static-address mode */
#define DMA_MODE_SRC_SA_BIT 0x01
/* Two bits to select between all four modes */
#define DMA_MODE_SSIZE_MASK 0x06
/* Offset to shift bits in */
#define DMA_MODE_SSIZE_OFF 0x01
/* Destination static-address mode */
#define DMA_MODE_DES_SA_BIT 0x10
/* Two bits to select between all four modes */
#define DMA_MODE_DSIZE_MASK 0x60
/* Offset to shift bits in */
#define DMA_MODE_DSIZE_OFF 0x05
/* Size modifiers */
#define DMA_MODE_SIZE_LONG 0x00
#define DMA_MODE_SIZE_BYTE 0x01
#define DMA_MODE_SIZE_WORD 0x02
#define DMA_MODE_SIZE_LINE 0x03
/*
* Aliases to help speed quick ports; these may be suboptimal, however. They
* do not include the SINGLE mode modifiers since the MCF5272 does not have a
* mode where the device is in control of its addressing.
*/
/* I/O to memory, 8 bits, mode */
#define DMA_MODE_READ ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
/* memory to I/O, 8 bits, mode */
#define DMA_MODE_WRITE ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
/* I/O to memory, 16 bits, mode */
#define DMA_MODE_READ_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
/* memory to I/O, 16 bits, mode */
#define DMA_MODE_WRITE_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
/* I/O to memory, 32 bits, mode */
#define DMA_MODE_READ_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
/* memory to I/O, 32 bits, mode */
#define DMA_MODE_WRITE_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
#endif /* !defined(CONFIG_M5272) */
#if !defined(CONFIG_M5272)
/* enable/disable a specific DMA channel */
static __inline__ void enable_dma(unsigned int dmanr)
{
volatile unsigned short *dmawp;
#ifdef DMA_DEBUG
printk("enable_dma(dmanr=%d)\n", dmanr);
#endif
dmawp = (unsigned short *) dma_base_addr[dmanr];
dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT;
}
static __inline__ void disable_dma(unsigned int dmanr)
{
volatile unsigned short *dmawp;
volatile unsigned char *dmapb;
#ifdef DMA_DEBUG
printk("disable_dma(dmanr=%d)\n", dmanr);
#endif
dmawp = (unsigned short *) dma_base_addr[dmanr];
dmapb = (unsigned char *) dma_base_addr[dmanr];
/* Turn off external requests, and stop any DMA in progress */
dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT;
dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE;
}
/*
* Clear the 'DMA Pointer Flip Flop'.
* Write 0 for LSB/MSB, 1 for MSB/LSB access.
* Use this once to initialize the FF to a known state.
* After that, keep track of it. :-)
* --- In order to do that, the DMA routines below should ---
* --- only be used while interrupts are disabled! ---
*
* This is a NOP for ColdFire. Provide a stub for compatibility.
*/
static __inline__ void clear_dma_ff(unsigned int dmanr)
{
}
/* set mode (above) for a specific DMA channel */
static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
{
volatile unsigned char *dmabp;
volatile unsigned short *dmawp;
#ifdef DMA_DEBUG
printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
#endif
dmabp = (unsigned char *) dma_base_addr[dmanr];
dmawp = (unsigned short *) dma_base_addr[dmanr];
// Clear config errors
dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE;
// Set command register
dmawp[MCFDMA_DCR] =
MCFDMA_DCR_INT | // Enable completion irq
MCFDMA_DCR_CS | // Force one xfer per request
MCFDMA_DCR_AA | // Enable auto alignment
// single-address-mode
((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) |
// sets s_rw (-> r/w) high if Memory to I/0
((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) |
// Memory to I/O or I/O to Memory
((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) |
// 32 bit, 16 bit or 8 bit transfers
((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_SSIZE_WORD :
((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG :
MCFDMA_DCR_SSIZE_BYTE)) |
((mode & DMA_MODE_WORD_BIT) ? MCFDMA_DCR_DSIZE_WORD :
((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG :
MCFDMA_DCR_DSIZE_BYTE));
#ifdef DEBUG_DMA
printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__,
dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR],
(int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]);
#endif
}
/* Set transfer address for specific DMA channel */
static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
{
volatile unsigned short *dmawp;
volatile unsigned int *dmalp;
#ifdef DMA_DEBUG
printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
#endif
dmawp = (unsigned short *) dma_base_addr[dmanr];
dmalp = (unsigned int *) dma_base_addr[dmanr];
// Determine which address registers are used for memory/device accesses
if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) {
// Source incrementing, must be memory
dmalp[MCFDMA_SAR] = a;
// Set dest address, must be device
dmalp[MCFDMA_DAR] = dma_device_address[dmanr];
} else {
// Destination incrementing, must be memory
dmalp[MCFDMA_DAR] = a;
// Set source address, must be device
dmalp[MCFDMA_SAR] = dma_device_address[dmanr];
}
#ifdef DEBUG_DMA
printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
__FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR],
(int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR],
(int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]);
#endif
}
/*
* Specific for Coldfire - sets device address.
* Should be called after the mode set call, and before set DMA address.
*/
static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
{
#ifdef DMA_DEBUG
printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
#endif
dma_device_address[dmanr] = a;
}
/*
* NOTE 2: "count" represents _bytes_.
*/
static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
{
volatile unsigned short *dmawp;
#ifdef DMA_DEBUG
printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
#endif
dmawp = (unsigned short *) dma_base_addr[dmanr];
dmawp[MCFDMA_BCR] = (unsigned short)count;
}
/*
* Get DMA residue count. After a DMA transfer, this
* should return zero. Reading this while a DMA transfer is
* still in progress will return unpredictable results.
* Otherwise, it returns the number of _bytes_ left to transfer.
*/
static __inline__ int get_dma_residue(unsigned int dmanr)
{
volatile unsigned short *dmawp;
unsigned short count;
#ifdef DMA_DEBUG
printk("get_dma_residue(dmanr=%d)\n", dmanr);
#endif
dmawp = (unsigned short *) dma_base_addr[dmanr];
count = dmawp[MCFDMA_BCR];
return((int) count);
}
#else /* CONFIG_M5272 is defined */
/*
* The MCF5272 DMA controller is very different than the controller defined above
* in terms of register mapping. For instance, with the exception of the 16-bit
* interrupt register (IRQ#85, for reference), all of the registers are 32-bit.
*
* The big difference, however, is the lack of device-requested DMA. All modes
* are dual address transfer, and there is no 'device' setup or direction bit.
* You can DMA between a device and memory, between memory and memory, or even between
* two devices directly, with any combination of incrementing and non-incrementing
* addresses you choose. This puts a crimp in distinguishing between the 'device
* address' set up by set_dma_device_addr.
*
* Therefore, there are two options. One is to use set_dma_addr and set_dma_device_addr,
* which will act exactly as above in -- it will look to see if the source is set to
* autoincrement, and if so it will make the source use the set_dma_addr value and the
* destination the set_dma_device_addr value. Otherwise the source will be set to the
* set_dma_device_addr value and the destination will get the set_dma_addr value.
*
* The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions
* and make it explicit. Depending on what you're doing, one of these two should work
* for you, but don't mix them in the same transfer setup.
*/
/* enable/disable a specific DMA channel */
static __inline__ void enable_dma(unsigned int dmanr)
{
volatile unsigned int *dmalp;
#ifdef DMA_DEBUG
printk("enable_dma(dmanr=%d)\n", dmanr);
#endif
dmalp = (unsigned int *) dma_base_addr[dmanr];
dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN;
}
static __inline__ void disable_dma(unsigned int dmanr)
{
volatile unsigned int *dmalp;
#ifdef DMA_DEBUG
printk("disable_dma(dmanr=%d)\n", dmanr);
#endif
dmalp = (unsigned int *) dma_base_addr[dmanr];
/* Turn off external requests, and stop any DMA in progress */
dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN;
dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
}
/*
* Clear the 'DMA Pointer Flip Flop'.
* Write 0 for LSB/MSB, 1 for MSB/LSB access.
* Use this once to initialize the FF to a known state.
* After that, keep track of it. :-)
* --- In order to do that, the DMA routines below should ---
* --- only be used while interrupts are disabled! ---
*
* This is a NOP for ColdFire. Provide a stub for compatibility.
*/
static __inline__ void clear_dma_ff(unsigned int dmanr)
{
}
/* set mode (above) for a specific DMA channel */
static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
{
volatile unsigned int *dmalp;
volatile unsigned short *dmawp;
#ifdef DMA_DEBUG
printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
#endif
dmalp = (unsigned int *) dma_base_addr[dmanr];
dmawp = (unsigned short *) dma_base_addr[dmanr];
// Clear config errors
dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
// Set command register
dmalp[MCFDMA_DMR] =
MCFDMA_DMR_RQM_DUAL | // Mandatory Request Mode setting
MCFDMA_DMR_DSTT_SD | // Set up addressing types; set to supervisor-data.
MCFDMA_DMR_SRCT_SD | // Set up addressing types; set to supervisor-data.
// source static-address-mode
((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) |
// dest static-address-mode
((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) |
// burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272
(((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) |
(((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF);
dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN; /* Enable completion interrupts */
#ifdef DEBUG_DMA
printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__,
dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR],
(int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]);
#endif
}
/* Set transfer address for specific DMA channel */
static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
{
volatile unsigned int *dmalp;
#ifdef DMA_DEBUG
printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
#endif
dmalp = (unsigned int *) dma_base_addr[dmanr];
// Determine which address registers are used for memory/device accesses
if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) {
// Source incrementing, must be memory
dmalp[MCFDMA_DSAR] = a;
// Set dest address, must be device
dmalp[MCFDMA_DDAR] = dma_device_address[dmanr];
} else {
// Destination incrementing, must be memory
dmalp[MCFDMA_DDAR] = a;
// Set source address, must be device
dmalp[MCFDMA_DSAR] = dma_device_address[dmanr];
}
#ifdef DEBUG_DMA
printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
__FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR],
(int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR],
(int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]);
#endif
}
/*
* Specific for Coldfire - sets device address.
* Should be called after the mode set call, and before set DMA address.
*/
static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
{
#ifdef DMA_DEBUG
printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
#endif
dma_device_address[dmanr] = a;
}
/*
* NOTE 2: "count" represents _bytes_.
*
* NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value.
*/
static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
{
volatile unsigned int *dmalp;
#ifdef DMA_DEBUG
printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
#endif
dmalp = (unsigned int *) dma_base_addr[dmanr];
dmalp[MCFDMA_DBCR] = count;
}
/*
* Get DMA residue count. After a DMA transfer, this
* should return zero. Reading this while a DMA transfer is
* still in progress will return unpredictable results.
* Otherwise, it returns the number of _bytes_ left to transfer.
*/
static __inline__ int get_dma_residue(unsigned int dmanr)
{
volatile unsigned int *dmalp;
unsigned int count;
#ifdef DMA_DEBUG
printk("get_dma_residue(dmanr=%d)\n", dmanr);
#endif
dmalp = (unsigned int *) dma_base_addr[dmanr];
count = dmalp[MCFDMA_DBCR];
return(count);
}
#endif /* !defined(CONFIG_M5272) */
#endif /* CONFIG_COLDFIRE */
#define MAX_DMA_CHANNELS 8
/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k/coldfire and any
occurrence should be flagged as an error. */
/* under 2.4 it is actually needed by the new bootmem allocator */
#define MAX_DMA_ADDRESS PAGE_OFFSET
/* These are in kernel/dma.c: */
extern int request_dma(unsigned int dmanr, const char *device_id); /* reserve a DMA channel */
extern void free_dma(unsigned int dmanr); /* release it again */
#endif /* _M68K_DMA_H */
/****************************************************************************/
/*
* elia.h -- Lineo (formerly Moreton Bay) eLIA platform support.
*
* (C) Copyright 1999-2000, Moreton Bay (www.moreton.com.au)
* (C) Copyright 1999-2000, Lineo (www.lineo.com)
*/
/****************************************************************************/
#ifndef elia_h
#define elia_h
/****************************************************************************/
#include <asm/coldfire.h>
#ifdef CONFIG_eLIA
/*
* The serial port DTR and DCD lines are also on the Parallel I/O
* as well, so define those too.
*/
#define eLIA_DCD1 0x0001
#define eLIA_DCD0 0x0002
#define eLIA_DTR1 0x0004
#define eLIA_DTR0 0x0008
#define eLIA_PCIRESET 0x0020
/*
* Kernel macros to set and unset the LEDs.
*/
#ifndef __ASSEMBLY__
extern unsigned short ppdata;
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_eLIA */
/****************************************************************************/
#endif /* elia_h */
/*
* Coldfire generic GPIO support
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#ifndef coldfire_gpio_h
#define coldfire_gpio_h
#include <linux/io.h>
#include <asm-generic/gpio.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
/*
* The Freescale Coldfire family is quite varied in how they implement GPIO.
* Some parts have 8 bit ports, some have 16bit and some have 32bit; some have
* only one port, others have multiple ports; some have a single data latch
* for both input and output, others have a separate pin data register to read
* input; some require a read-modify-write access to change an output, others
* have set and clear registers for some of the outputs; Some have all the
* GPIOs in a single control area, others have some GPIOs implemented in
* different modules.
*
* This implementation attempts accomodate the differences while presenting
* a generic interface that will optimize to as few instructions as possible.
*/
#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
/* These parts have GPIO organized by 8 bit ports */
#define MCFGPIO_PORTTYPE u8
#define MCFGPIO_PORTSIZE 8
#define mcfgpio_read(port) __raw_readb(port)
#define mcfgpio_write(data, port) __raw_writeb(data, port)
#elif defined(CONFIG_M5307) || defined(CONFIG_M5407) || defined(CONFIG_M5272)
/* These parts have GPIO organized by 16 bit ports */
#define MCFGPIO_PORTTYPE u16
#define MCFGPIO_PORTSIZE 16
#define mcfgpio_read(port) __raw_readw(port)
#define mcfgpio_write(data, port) __raw_writew(data, port)
#elif defined(CONFIG_M5249)
/* These parts have GPIO organized by 32 bit ports */
#define MCFGPIO_PORTTYPE u32
#define MCFGPIO_PORTSIZE 32
#define mcfgpio_read(port) __raw_readl(port)
#define mcfgpio_write(data, port) __raw_writel(data, port)
#endif
#define mcfgpio_bit(gpio) (1 << ((gpio) % MCFGPIO_PORTSIZE))
#define mcfgpio_port(gpio) ((gpio) / MCFGPIO_PORTSIZE)
#if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
/*
* These parts have an 'Edge' Port module (external interrupt/GPIO) which uses
* read-modify-write to change an output and a GPIO module which has separate
* set/clr registers to directly change outputs with a single write access.
*/
#if defined(CONFIG_M528x)
/*
* The 528x also has GPIOs in other modules (GPT, QADC) which use
* read-modify-write as well as those controlled by the EPORT and GPIO modules.
*/
#define MCFGPIO_SCR_START 40
#else
#define MCFGPIO_SCR_START 8
#endif
#define MCFGPIO_SETR_PORT(gpio) (MCFGPIO_SETR + \
mcfgpio_port(gpio - MCFGPIO_SCR_START))
#define MCFGPIO_CLRR_PORT(gpio) (MCFGPIO_CLRR + \
mcfgpio_port(gpio - MCFGPIO_SCR_START))
#else
#define MCFGPIO_SCR_START MCFGPIO_PIN_MAX
/* with MCFGPIO_SCR == MCFGPIO_PIN_MAX, these will be optimized away */
#define MCFGPIO_SETR_PORT(gpio) 0
#define MCFGPIO_CLRR_PORT(gpio) 0
#endif
/*
* Coldfire specific helper functions
*/
/* return the port pin data register for a gpio */
static inline u32 __mcf_gpio_ppdr(unsigned gpio)
{
#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
defined(CONFIG_M5307) || defined(CONFIG_M5407)
return MCFSIM_PADAT;
#elif defined(CONFIG_M5272)
if (gpio < 16)
return MCFSIM_PADAT;
else if (gpio < 32)
return MCFSIM_PBDAT;
else
return MCFSIM_PCDAT;
#elif defined(CONFIG_M5249)
if (gpio < 32)
return MCFSIM2_GPIOREAD;
else
return MCFSIM2_GPIO1READ;
#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
if (gpio < 8)
return MCFEPORT_EPPDR;
#if defined(CONFIG_M528x)
else if (gpio < 16)
return MCFGPTA_GPTPORT;
else if (gpio < 24)
return MCFGPTB_GPTPORT;
else if (gpio < 32)
return MCFQADC_PORTQA;
else if (gpio < 40)
return MCFQADC_PORTQB;
#endif
else
return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
#endif
}
/* return the port output data register for a gpio */
static inline u32 __mcf_gpio_podr(unsigned gpio)
{
#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
defined(CONFIG_M5307) || defined(CONFIG_M5407)
return MCFSIM_PADAT;
#elif defined(CONFIG_M5272)
if (gpio < 16)
return MCFSIM_PADAT;
else if (gpio < 32)
return MCFSIM_PBDAT;
else
return MCFSIM_PCDAT;
#elif defined(CONFIG_M5249)
if (gpio < 32)
return MCFSIM2_GPIOWRITE;
else
return MCFSIM2_GPIO1WRITE;
#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
if (gpio < 8)
return MCFEPORT_EPDR;
#if defined(CONFIG_M528x)
else if (gpio < 16)
return MCFGPTA_GPTPORT;
else if (gpio < 24)
return MCFGPTB_GPTPORT;
else if (gpio < 32)
return MCFQADC_PORTQA;
else if (gpio < 40)
return MCFQADC_PORTQB;
#endif
else
return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
#endif
}
/*
* The Generic GPIO functions
*
* If the gpio is a compile time constant and is one of the Coldfire gpios,
* use the inline version, otherwise dispatch thru gpiolib.
*/
static inline int gpio_get_value(unsigned gpio)
{
if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX)
return mcfgpio_read(__mcf_gpio_ppdr(gpio)) & mcfgpio_bit(gpio);
else
return __gpio_get_value(gpio);
}
static inline void gpio_set_value(unsigned gpio, int value)
{
if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) {
if (gpio < MCFGPIO_SCR_START) {
unsigned long flags;
MCFGPIO_PORTTYPE data;
local_irq_save(flags);
data = mcfgpio_read(__mcf_gpio_podr(gpio));
if (value)
data |= mcfgpio_bit(gpio);
else
data &= ~mcfgpio_bit(gpio);
mcfgpio_write(data, __mcf_gpio_podr(gpio));
local_irq_restore(flags);
} else {
if (value)
mcfgpio_write(mcfgpio_bit(gpio),
MCFGPIO_SETR_PORT(gpio));
else
mcfgpio_write(~mcfgpio_bit(gpio),
MCFGPIO_CLRR_PORT(gpio));
}
} else
__gpio_set_value(gpio, value);
}
static inline int gpio_to_irq(unsigned gpio)
{
return (gpio < MCFGPIO_IRQ_MAX) ? gpio + MCFGPIO_IRQ_VECBASE : -EINVAL;
}
static inline int irq_to_gpio(unsigned irq)
{
return (irq >= MCFGPIO_IRQ_VECBASE &&
irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) ?
irq - MCFGPIO_IRQ_VECBASE : -ENXIO;
}
static inline int gpio_cansleep(unsigned gpio)
{
return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio);
}
#endif
#ifndef __M68K_HARDIRQ_H
#define __M68K_HARDIRQ_H
#include <linux/cache.h>
#include <linux/threads.h>
#include <asm/irq.h>
typedef struct {
unsigned int __softirq_pending;
} ____cacheline_aligned irq_cpustat_t;
#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
#define HARDIRQ_BITS 8
/*
......@@ -22,6 +14,6 @@ typedef struct {
# error HARDIRQ_BITS is too low!
#endif
void ack_bad_irq(unsigned int irq);
#include <asm-generic/hardirq.h>
#endif /* __M68K_HARDIRQ_H */
......@@ -134,7 +134,7 @@ static inline void io_insl(unsigned int addr, void *buf, int len)
#define insw(a,b,l) io_insw(a,b,l)
#define insl(a,b,l) io_insl(a,b,l)
#define IO_SPACE_LIMIT 0xffff
#define IO_SPACE_LIMIT 0xffffffff
/* Values for nocacheflag and cmode */
......
#ifdef __uClinux__
#include "irq_no.h"
#ifndef _M68K_IRQ_H_
#define _M68K_IRQ_H_
/*
* This should be the same as the max(NUM_X_SOURCES) for all the
* different m68k hosts compiled into the kernel.
* Currently the Atari has 72 and the Amiga 24, but if both are
* supported in the kernel it is better to make room for 72.
*/
#if defined(CONFIG_COLDFIRE)
#define NR_IRQS 256
#elif defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
#define NR_IRQS 200
#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC)
#define NR_IRQS 72
#elif defined(CONFIG_Q40)
#define NR_IRQS 43
#elif defined(CONFIG_AMIGA) || !defined(CONFIG_MMU)
#define NR_IRQS 32
#elif defined(CONFIG_APOLLO)
#define NR_IRQS 24
#elif defined(CONFIG_HP300)
#define NR_IRQS 8
#else
#include "irq_mm.h"
#define NR_IRQS 0
#endif
#ifdef CONFIG_MMU
#include <linux/linkage.h>
#include <linux/hardirq.h>
#include <linux/irqreturn.h>
#include <linux/spinlock_types.h>
/*
* The hardirq mask has to be large enough to have
* space for potentially all IRQ sources in the system
* nesting on a single CPU:
*/
#if (1 << HARDIRQ_BITS) < NR_IRQS
# error HARDIRQ_BITS is too low!
#endif
/*
* Interrupt source definitions
* General interrupt sources are the level 1-7.
* Adding an interrupt service routine for one of these sources
* results in the addition of that routine to a chain of routines.
* Each one is called in succession. Each individual interrupt
* service routine should determine if the device associated with
* that routine requires service.
*/
#define IRQ_SPURIOUS 0
#define IRQ_AUTO_1 1 /* level 1 interrupt */
#define IRQ_AUTO_2 2 /* level 2 interrupt */
#define IRQ_AUTO_3 3 /* level 3 interrupt */
#define IRQ_AUTO_4 4 /* level 4 interrupt */
#define IRQ_AUTO_5 5 /* level 5 interrupt */
#define IRQ_AUTO_6 6 /* level 6 interrupt */
#define IRQ_AUTO_7 7 /* level 7 interrupt (non-maskable) */
#define IRQ_USER 8
extern unsigned int irq_canonicalize(unsigned int irq);
struct pt_regs;
/*
* various flags for request_irq() - the Amiga now uses the standard
* mechanism like all other architectures - IRQF_DISABLED and
* IRQF_SHARED are your friends.
*/
#ifndef MACH_AMIGA_ONLY
#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */
#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */
#define IRQ_FLG_FAST (0x0004)
#define IRQ_FLG_SLOW (0x0008)
#define IRQ_FLG_STD (0x8000) /* internally used */
#endif
/*
* This structure is used to chain together the ISRs for a particular
* interrupt source (if it supports chaining).
*/
typedef struct irq_node {
irqreturn_t (*handler)(int, void *);
void *dev_id;
struct irq_node *next;
unsigned long flags;
const char *devname;
} irq_node_t;
/*
* This structure has only 4 elements for speed reasons
*/
struct irq_handler {
int (*handler)(int, void *);
unsigned long flags;
void *dev_id;
const char *devname;
};
struct irq_controller {
const char *name;
spinlock_t lock;
int (*startup)(unsigned int irq);
void (*shutdown)(unsigned int irq);
void (*enable)(unsigned int irq);
void (*disable)(unsigned int irq);
};
extern int m68k_irq_startup(unsigned int);
extern void m68k_irq_shutdown(unsigned int);
/*
* This function returns a new irq_node_t
*/
extern irq_node_t *new_irq_node(void);
extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *));
extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
void (*handler)(unsigned int, struct pt_regs *));
extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int);
asmlinkage void m68k_handle_int(unsigned int);
asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *);
#else
#define irq_canonicalize(irq) (irq)
#endif /* CONFIG_MMU */
#endif /* _M68K_IRQ_H_ */
#ifndef _M68K_IRQ_H_
#define _M68K_IRQ_H_
#include <linux/linkage.h>
#include <linux/hardirq.h>
#include <linux/irqreturn.h>
#include <linux/spinlock_types.h>
/*
* This should be the same as the max(NUM_X_SOURCES) for all the
* different m68k hosts compiled into the kernel.
* Currently the Atari has 72 and the Amiga 24, but if both are
* supported in the kernel it is better to make room for 72.
*/
#if defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
#define NR_IRQS 200
#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC)
#define NR_IRQS 72
#elif defined(CONFIG_Q40)
#define NR_IRQS 43
#elif defined(CONFIG_AMIGA)
#define NR_IRQS 32
#elif defined(CONFIG_APOLLO)
#define NR_IRQS 24
#elif defined(CONFIG_HP300)
#define NR_IRQS 8
#else
#define NR_IRQS 0
#endif
/*
* The hardirq mask has to be large enough to have
* space for potentially all IRQ sources in the system
* nesting on a single CPU:
*/
#if (1 << HARDIRQ_BITS) < NR_IRQS
# error HARDIRQ_BITS is too low!
#endif
/*
* Interrupt source definitions
* General interrupt sources are the level 1-7.
* Adding an interrupt service routine for one of these sources
* results in the addition of that routine to a chain of routines.
* Each one is called in succession. Each individual interrupt
* service routine should determine if the device associated with
* that routine requires service.
*/
#define IRQ_SPURIOUS 0
#define IRQ_AUTO_1 1 /* level 1 interrupt */
#define IRQ_AUTO_2 2 /* level 2 interrupt */
#define IRQ_AUTO_3 3 /* level 3 interrupt */
#define IRQ_AUTO_4 4 /* level 4 interrupt */
#define IRQ_AUTO_5 5 /* level 5 interrupt */
#define IRQ_AUTO_6 6 /* level 6 interrupt */
#define IRQ_AUTO_7 7 /* level 7 interrupt (non-maskable) */
#define IRQ_USER 8
extern unsigned int irq_canonicalize(unsigned int irq);
struct pt_regs;
/*
* various flags for request_irq() - the Amiga now uses the standard
* mechanism like all other architectures - IRQF_DISABLED and
* IRQF_SHARED are your friends.
*/
#ifndef MACH_AMIGA_ONLY
#define IRQ_FLG_LOCK (0x0001) /* handler is not replaceable */
#define IRQ_FLG_REPLACE (0x0002) /* replace existing handler */
#define IRQ_FLG_FAST (0x0004)
#define IRQ_FLG_SLOW (0x0008)
#define IRQ_FLG_STD (0x8000) /* internally used */
#endif
/*
* This structure is used to chain together the ISRs for a particular
* interrupt source (if it supports chaining).
*/
typedef struct irq_node {
irqreturn_t (*handler)(int, void *);
void *dev_id;
struct irq_node *next;
unsigned long flags;
const char *devname;
} irq_node_t;
/*
* This structure has only 4 elements for speed reasons
*/
struct irq_handler {
int (*handler)(int, void *);
unsigned long flags;
void *dev_id;
const char *devname;
};
struct irq_controller {
const char *name;
spinlock_t lock;
int (*startup)(unsigned int irq);
void (*shutdown)(unsigned int irq);
void (*enable)(unsigned int irq);
void (*disable)(unsigned int irq);
};
extern int m68k_irq_startup(unsigned int);
extern void m68k_irq_shutdown(unsigned int);
/*
* This function returns a new irq_node_t
*/
extern irq_node_t *new_irq_node(void);
extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *));
extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
void (*handler)(unsigned int, struct pt_regs *));
extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int);
asmlinkage void m68k_handle_int(unsigned int);
asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *);
#endif /* _M68K_IRQ_H_ */
#ifndef _M68KNOMMU_IRQ_H_
#define _M68KNOMMU_IRQ_H_
#ifdef CONFIG_COLDFIRE
/*
* On the ColdFire we keep track of all vectors. That way drivers
* can register whatever vector number they wish, and we can deal
* with it.
*/
#define SYS_IRQS 256
#define NR_IRQS SYS_IRQS
#else
/*
* # of m68k interrupts
*/
#define SYS_IRQS 8
#define NR_IRQS (24 + SYS_IRQS)
#endif /* CONFIG_COLDFIRE */
#define irq_canonicalize(irq) (irq)
#endif /* _M68KNOMMU_IRQ_H_ */
......@@ -85,8 +85,21 @@
#define MCFSIM_PAR 0xcb /* Pin Assignment reg (r/w) */
#endif
#define MCFSIM_PADDR 0x1c5 /* Parallel Direction (r/w) */
#define MCFSIM_PADAT 0x1c9 /* Parallel Port Value (r/w) */
#define MCFSIM_PADDR (MCF_MBAR + 0x1c5) /* Parallel Direction (r/w) */
#define MCFSIM_PADAT (MCF_MBAR + 0x1c9) /* Parallel Port Value (r/w) */
/*
* Define system peripheral IRQ usage.
*/
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
/*
* Generic GPIO
*/
#define MCFGPIO_PIN_MAX 8
#define MCFGPIO_IRQ_VECBASE -1
#define MCFGPIO_IRQ_MAX -1
/*
* Some symbol defines for the Parallel Port Pin Assignment Register
......@@ -111,21 +124,5 @@
#define MCFSIM_DMA2ICR MCFSIM_ICR15 /* DMA 2 ICR */
#endif
#if defined(CONFIG_M5206e)
#define MCFSIM_IMR_MASKALL 0xfffe /* All SIM intr sources */
#endif
/*
* Macro to get and set IMR register. It is 16 bits on the 5206.
*/
#define mcf_getimr() \
*((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR))
#define mcf_setimr(imr) \
*((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR)) = (imr)
#define mcf_getipr() \
*((volatile unsigned short *) (MCF_MBAR + MCFSIM_IPR))
/****************************************************************************/
#endif /* m5206sim_h */
......@@ -11,9 +11,8 @@
#define m520xsim_h
/****************************************************************************/
/*
* Define the 5282 SIM register set addresses.
* Define the 520x SIM register set addresses.
*/
#define MCFICM_INTC0 0x48000 /* Base for Interrupt Ctrl 0 */
#define MCFINTC_IPRH 0x00 /* Interrupt pending 32-63 */
......@@ -22,8 +21,22 @@
#define MCFINTC_IMRL 0x0c /* Interrupt mask 1-31 */
#define MCFINTC_INTFRCH 0x10 /* Interrupt force 32-63 */
#define MCFINTC_INTFRCL 0x14 /* Interrupt force 1-31 */
#define MCFINTC_SIMR 0x1c /* Set interrupt mask 0-63 */
#define MCFINTC_CIMR 0x1d /* Clear interrupt mask 0-63 */
#define MCFINTC_ICR0 0x40 /* Base ICR register */
/*
* The common interrupt controller code just wants to know the absolute
* address to the SIMR and CIMR registers (not offsets into IPSBAR).
* The 520x family only has a single INTC unit.
*/
#define MCFINTC0_SIMR (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_SIMR)
#define MCFINTC0_CIMR (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_CIMR)
#define MCFINTC0_ICR0 (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0)
#define MCFINTC1_SIMR (0)
#define MCFINTC1_CIMR (0)
#define MCFINTC1_ICR0 (0)
#define MCFINT_VECBASE 64
#define MCFINT_UART0 26 /* Interrupt number for UART0 */
#define MCFINT_UART1 27 /* Interrupt number for UART1 */
......@@ -41,6 +54,62 @@
#define MCFSIM_SDCS0 0x000a8110 /* SDRAM Chip Select 0 Configuration */
#define MCFSIM_SDCS1 0x000a8114 /* SDRAM Chip Select 1 Configuration */
#define MCFEPORT_EPDDR 0xFC088002
#define MCFEPORT_EPDR 0xFC088004
#define MCFEPORT_EPPDR 0xFC088005
#define MCFGPIO_PODR_BUSCTL 0xFC0A4000
#define MCFGPIO_PODR_BE 0xFC0A4001
#define MCFGPIO_PODR_CS 0xFC0A4002
#define MCFGPIO_PODR_FECI2C 0xFC0A4003
#define MCFGPIO_PODR_QSPI 0xFC0A4004
#define MCFGPIO_PODR_TIMER 0xFC0A4005
#define MCFGPIO_PODR_UART 0xFC0A4006
#define MCFGPIO_PODR_FECH 0xFC0A4007
#define MCFGPIO_PODR_FECL 0xFC0A4008
#define MCFGPIO_PDDR_BUSCTL 0xFC0A400C
#define MCFGPIO_PDDR_BE 0xFC0A400D
#define MCFGPIO_PDDR_CS 0xFC0A400E
#define MCFGPIO_PDDR_FECI2C 0xFC0A400F
#define MCFGPIO_PDDR_QSPI 0xFC0A4010
#define MCFGPIO_PDDR_TIMER 0xFC0A4011
#define MCFGPIO_PDDR_UART 0xFC0A4012
#define MCFGPIO_PDDR_FECH 0xFC0A4013
#define MCFGPIO_PDDR_FECL 0xFC0A4014
#define MCFGPIO_PPDSDR_BUSCTL 0xFC0A401A
#define MCFGPIO_PPDSDR_BE 0xFC0A401B
#define MCFGPIO_PPDSDR_CS 0xFC0A401C
#define MCFGPIO_PPDSDR_FECI2C 0xFC0A401D
#define MCFGPIO_PPDSDR_QSPI 0xFC0A401E
#define MCFGPIO_PPDSDR_TIMER 0xFC0A401F
#define MCFGPIO_PPDSDR_UART 0xFC0A4021
#define MCFGPIO_PPDSDR_FECH 0xFC0A4021
#define MCFGPIO_PPDSDR_FECL 0xFC0A4022
#define MCFGPIO_PCLRR_BUSCTL 0xFC0A4024
#define MCFGPIO_PCLRR_BE 0xFC0A4025
#define MCFGPIO_PCLRR_CS 0xFC0A4026
#define MCFGPIO_PCLRR_FECI2C 0xFC0A4027
#define MCFGPIO_PCLRR_QSPI 0xFC0A4028
#define MCFGPIO_PCLRR_TIMER 0xFC0A4029
#define MCFGPIO_PCLRR_UART 0xFC0A402A
#define MCFGPIO_PCLRR_FECH 0xFC0A402B
#define MCFGPIO_PCLRR_FECL 0xFC0A402C
/*
* Generic GPIO support
*/
#define MCFGPIO_PODR MCFGPIO_PODR_BUSCTL
#define MCFGPIO_PDDR MCFGPIO_PDDR_BUSCTL
#define MCFGPIO_PPDR MCFGPIO_PPDSDR_BUSCTL
#define MCFGPIO_SETR MCFGPIO_PPDSDR_BUSCTL
#define MCFGPIO_CLRR MCFGPIO_PCLRR_BUSCTL
#define MCFGPIO_PIN_MAX 80
#define MCFGPIO_IRQ_MAX 8
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
/****************************************************************************/
#define MCF_GPIO_PAR_UART (0xA4036)
#define MCF_GPIO_PAR_FECI2C (0xA4033)
......@@ -55,10 +124,6 @@
#define MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2 (0x02)
#define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 (0x04)
#define ICR_INTRCONF 0x05
#define MCFPIT_IMR MCFINTC_IMRL
#define MCFPIT_IMR_IBIT (1 << MCFINT_PIT1)
/*
* Reset Controll Unit.
*/
......
......@@ -50,5 +50,82 @@
#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000)
#define MCFGPIO_PODR_DATAH (MCF_IPSBAR + 0x100001)
#define MCFGPIO_PODR_DATAL (MCF_IPSBAR + 0x100002)
#define MCFGPIO_PODR_BUSCTL (MCF_IPSBAR + 0x100003)
#define MCFGPIO_PODR_BS (MCF_IPSBAR + 0x100004)
#define MCFGPIO_PODR_CS (MCF_IPSBAR + 0x100005)
#define MCFGPIO_PODR_SDRAM (MCF_IPSBAR + 0x100006)
#define MCFGPIO_PODR_FECI2C (MCF_IPSBAR + 0x100007)
#define MCFGPIO_PODR_UARTH (MCF_IPSBAR + 0x100008)
#define MCFGPIO_PODR_UARTL (MCF_IPSBAR + 0x100009)
#define MCFGPIO_PODR_QSPI (MCF_IPSBAR + 0x10000A)
#define MCFGPIO_PODR_TIMER (MCF_IPSBAR + 0x10000B)
#define MCFGPIO_PODR_ETPU (MCF_IPSBAR + 0x10000C)
#define MCFGPIO_PDDR_ADDR (MCF_IPSBAR + 0x100010)
#define MCFGPIO_PDDR_DATAH (MCF_IPSBAR + 0x100011)
#define MCFGPIO_PDDR_DATAL (MCF_IPSBAR + 0x100012)
#define MCFGPIO_PDDR_BUSCTL (MCF_IPSBAR + 0x100013)
#define MCFGPIO_PDDR_BS (MCF_IPSBAR + 0x100014)
#define MCFGPIO_PDDR_CS (MCF_IPSBAR + 0x100015)
#define MCFGPIO_PDDR_SDRAM (MCF_IPSBAR + 0x100016)
#define MCFGPIO_PDDR_FECI2C (MCF_IPSBAR + 0x100017)
#define MCFGPIO_PDDR_UARTH (MCF_IPSBAR + 0x100018)
#define MCFGPIO_PDDR_UARTL (MCF_IPSBAR + 0x100019)
#define MCFGPIO_PDDR_QSPI (MCF_IPSBAR + 0x10001A)
#define MCFGPIO_PDDR_TIMER (MCF_IPSBAR + 0x10001B)
#define MCFGPIO_PDDR_ETPU (MCF_IPSBAR + 0x10001C)
#define MCFGPIO_PPDSDR_ADDR (MCF_IPSBAR + 0x100020)
#define MCFGPIO_PPDSDR_DATAH (MCF_IPSBAR + 0x100021)
#define MCFGPIO_PPDSDR_DATAL (MCF_IPSBAR + 0x100022)
#define MCFGPIO_PPDSDR_BUSCTL (MCF_IPSBAR + 0x100023)
#define MCFGPIO_PPDSDR_BS (MCF_IPSBAR + 0x100024)
#define MCFGPIO_PPDSDR_CS (MCF_IPSBAR + 0x100025)
#define MCFGPIO_PPDSDR_SDRAM (MCF_IPSBAR + 0x100026)
#define MCFGPIO_PPDSDR_FECI2C (MCF_IPSBAR + 0x100027)
#define MCFGPIO_PPDSDR_UARTH (MCF_IPSBAR + 0x100028)
#define MCFGPIO_PPDSDR_UARTL (MCF_IPSBAR + 0x100029)
#define MCFGPIO_PPDSDR_QSPI (MCF_IPSBAR + 0x10002A)
#define MCFGPIO_PPDSDR_TIMER (MCF_IPSBAR + 0x10002B)
#define MCFGPIO_PPDSDR_ETPU (MCF_IPSBAR + 0x10002C)
#define MCFGPIO_PCLRR_ADDR (MCF_IPSBAR + 0x100030)
#define MCFGPIO_PCLRR_DATAH (MCF_IPSBAR + 0x100031)
#define MCFGPIO_PCLRR_DATAL (MCF_IPSBAR + 0x100032)
#define MCFGPIO_PCLRR_BUSCTL (MCF_IPSBAR + 0x100033)
#define MCFGPIO_PCLRR_BS (MCF_IPSBAR + 0x100034)
#define MCFGPIO_PCLRR_CS (MCF_IPSBAR + 0x100035)
#define MCFGPIO_PCLRR_SDRAM (MCF_IPSBAR + 0x100036)
#define MCFGPIO_PCLRR_FECI2C (MCF_IPSBAR + 0x100037)
#define MCFGPIO_PCLRR_UARTH (MCF_IPSBAR + 0x100038)
#define MCFGPIO_PCLRR_UARTL (MCF_IPSBAR + 0x100039)
#define MCFGPIO_PCLRR_QSPI (MCF_IPSBAR + 0x10003A)
#define MCFGPIO_PCLRR_TIMER (MCF_IPSBAR + 0x10003B)
#define MCFGPIO_PCLRR_ETPU (MCF_IPSBAR + 0x10003C)
/*
* EPort
*/
#define MCFEPORT_EPDDR (MCF_IPSBAR + 0x130002)
#define MCFEPORT_EPDR (MCF_IPSBAR + 0x130004)
#define MCFEPORT_EPPDR (MCF_IPSBAR + 0x130005)
/*
* Generic GPIO support
*/
#define MCFGPIO_PODR MCFGPIO_PODR_ADDR
#define MCFGPIO_PDDR MCFGPIO_PDDR_ADDR
#define MCFGPIO_PPDR MCFGPIO_PPDSDR_ADDR
#define MCFGPIO_SETR MCFGPIO_PPDSDR_ADDR
#define MCFGPIO_CLRR MCFGPIO_PCLRR_ADDR
#define MCFGPIO_PIN_MAX 107
#define MCFGPIO_IRQ_MAX 8
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
/****************************************************************************/
#endif /* m523xsim_h */
......@@ -70,17 +70,23 @@
#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */
#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */
/*
* Define system peripheral IRQ usage.
*/
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
/*
* General purpose IO registers (in MBAR2).
*/
#define MCFSIM2_GPIOREAD 0x0 /* GPIO read values */
#define MCFSIM2_GPIOWRITE 0x4 /* GPIO write values */
#define MCFSIM2_GPIOENABLE 0x8 /* GPIO enabled */
#define MCFSIM2_GPIOFUNC 0xc /* GPIO function */
#define MCFSIM2_GPIO1READ 0xb0 /* GPIO1 read values */
#define MCFSIM2_GPIO1WRITE 0xb4 /* GPIO1 write values */
#define MCFSIM2_GPIO1ENABLE 0xb8 /* GPIO1 enabled */
#define MCFSIM2_GPIO1FUNC 0xbc /* GPIO1 function */
#define MCFSIM2_GPIOREAD (MCF_MBAR2 + 0x000) /* GPIO read values */
#define MCFSIM2_GPIOWRITE (MCF_MBAR2 + 0x004) /* GPIO write values */
#define MCFSIM2_GPIOENABLE (MCF_MBAR2 + 0x008) /* GPIO enabled */
#define MCFSIM2_GPIOFUNC (MCF_MBAR2 + 0x00C) /* GPIO function */
#define MCFSIM2_GPIO1READ (MCF_MBAR2 + 0x0B0) /* GPIO1 read values */
#define MCFSIM2_GPIO1WRITE (MCF_MBAR2 + 0x0B4) /* GPIO1 write values */
#define MCFSIM2_GPIO1ENABLE (MCF_MBAR2 + 0x0B8) /* GPIO1 enabled */
#define MCFSIM2_GPIO1FUNC (MCF_MBAR2 + 0x0BC) /* GPIO1 function */
#define MCFSIM2_GPIOINTSTAT 0xc0 /* GPIO interrupt status */
#define MCFSIM2_GPIOINTCLEAR 0xc0 /* GPIO interrupt clear */
......@@ -100,20 +106,28 @@
#define MCFSIM2_IDECONFIG1 0x18c /* IDEconfig1 */
#define MCFSIM2_IDECONFIG2 0x190 /* IDEconfig2 */
/*
* Macro to set IMR register. It is 32 bits on the 5249.
* Define the base interrupt for the second interrupt controller.
* We set it to 128, out of the way of the base interrupts, and plenty
* of room for its 64 interrupts.
*/
#define MCFSIM_IMR_MASKALL 0x7fffe /* All SIM intr sources */
#define MCFINTC2_VECBASE 128
#define mcf_getimr() \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
#define MCFINTC2_GPIOIRQ0 (MCFINTC2_VECBASE + 32)
#define MCFINTC2_GPIOIRQ1 (MCFINTC2_VECBASE + 33)
#define MCFINTC2_GPIOIRQ2 (MCFINTC2_VECBASE + 34)
#define MCFINTC2_GPIOIRQ3 (MCFINTC2_VECBASE + 35)
#define MCFINTC2_GPIOIRQ4 (MCFINTC2_VECBASE + 36)
#define MCFINTC2_GPIOIRQ5 (MCFINTC2_VECBASE + 37)
#define MCFINTC2_GPIOIRQ6 (MCFINTC2_VECBASE + 38)
#define MCFINTC2_GPIOIRQ7 (MCFINTC2_VECBASE + 39)
#define mcf_setimr(imr) \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
#define mcf_getipr() \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
/*
* Generic GPIO support
*/
#define MCFGPIO_PIN_MAX 64
#define MCFGPIO_IRQ_MAX -1
#define MCFGPIO_IRQ_VECBASE -1
/****************************************************************************/
......@@ -137,9 +151,9 @@
subql #1,%a1 /* get MBAR2 address in a1 */
/*
* Move secondary interrupts to base at 128.
* Move secondary interrupts to their base (128).
*/
moveb #0x80,%d0
moveb #MCFINTC2_VECBASE,%d0
moveb %d0,0x16b(%a1) /* interrupt base register */
/*
......
......@@ -12,7 +12,6 @@
#define m5272sim_h
/****************************************************************************/
/*
* Define the 5272 SIM register set addresses.
*/
......@@ -63,16 +62,59 @@
#define MCFSIM_DCMR1 0x5c /* DRAM 1 Mask reg (r/w) */
#define MCFSIM_DCCR1 0x63 /* DRAM 1 Control reg (r/w) */
#define MCFSIM_PACNT 0x80 /* Port A Control (r/w) */
#define MCFSIM_PADDR 0x84 /* Port A Direction (r/w) */
#define MCFSIM_PADAT 0x86 /* Port A Data (r/w) */
#define MCFSIM_PBCNT 0x88 /* Port B Control (r/w) */
#define MCFSIM_PBDDR 0x8c /* Port B Direction (r/w) */
#define MCFSIM_PBDAT 0x8e /* Port B Data (r/w) */
#define MCFSIM_PCDDR 0x94 /* Port C Direction (r/w) */
#define MCFSIM_PCDAT 0x96 /* Port C Data (r/w) */
#define MCFSIM_PDCNT 0x98 /* Port D Control (r/w) */
#define MCFSIM_PACNT (MCF_MBAR + 0x80) /* Port A Control (r/w) */
#define MCFSIM_PADDR (MCF_MBAR + 0x84) /* Port A Direction (r/w) */
#define MCFSIM_PADAT (MCF_MBAR + 0x86) /* Port A Data (r/w) */
#define MCFSIM_PBCNT (MCF_MBAR + 0x88) /* Port B Control (r/w) */
#define MCFSIM_PBDDR (MCF_MBAR + 0x8c) /* Port B Direction (r/w) */
#define MCFSIM_PBDAT (MCF_MBAR + 0x8e) /* Port B Data (r/w) */
#define MCFSIM_PCDDR (MCF_MBAR + 0x94) /* Port C Direction (r/w) */
#define MCFSIM_PCDAT (MCF_MBAR + 0x96) /* Port C Data (r/w) */
#define MCFSIM_PDCNT (MCF_MBAR + 0x98) /* Port D Control (r/w) */
/*
* Define system peripheral IRQ usage.
*/
#define MCFINT_VECBASE 64 /* Base of interrupts */
#define MCF_IRQ_SPURIOUS 64 /* User Spurious */
#define MCF_IRQ_EINT1 65 /* External Interrupt 1 */
#define MCF_IRQ_EINT2 66 /* External Interrupt 2 */
#define MCF_IRQ_EINT3 67 /* External Interrupt 3 */
#define MCF_IRQ_EINT4 68 /* External Interrupt 4 */
#define MCF_IRQ_TIMER1 69 /* Timer 1 */
#define MCF_IRQ_TIMER2 70 /* Timer 2 */
#define MCF_IRQ_TIMER3 71 /* Timer 3 */
#define MCF_IRQ_TIMER4 72 /* Timer 4 */
#define MCF_IRQ_UART1 73 /* UART 1 */
#define MCF_IRQ_UART2 74 /* UART 2 */
#define MCF_IRQ_PLIP 75 /* PLIC 2Khz Periodic */
#define MCF_IRQ_PLIA 76 /* PLIC Asynchronous */
#define MCF_IRQ_USB0 77 /* USB Endpoint 0 */
#define MCF_IRQ_USB1 78 /* USB Endpoint 1 */
#define MCF_IRQ_USB2 79 /* USB Endpoint 2 */
#define MCF_IRQ_USB3 80 /* USB Endpoint 3 */
#define MCF_IRQ_USB4 81 /* USB Endpoint 4 */
#define MCF_IRQ_USB5 82 /* USB Endpoint 5 */
#define MCF_IRQ_USB6 83 /* USB Endpoint 6 */
#define MCF_IRQ_USB7 84 /* USB Endpoint 7 */
#define MCF_IRQ_DMA 85 /* DMA Controller */
#define MCF_IRQ_ERX 86 /* Ethernet Receiver */
#define MCF_IRQ_ETX 87 /* Ethernet Transmitter */
#define MCF_IRQ_ENTC 88 /* Ethernet Non-Time Critical */
#define MCF_IRQ_QSPI 89 /* Queued Serial Interface */
#define MCF_IRQ_EINT5 90 /* External Interrupt 5 */
#define MCF_IRQ_EINT6 91 /* External Interrupt 6 */
#define MCF_IRQ_SWTO 92 /* Software Watchdog */
#define MCFINT_VECMAX 95 /* Maxmum interrupt */
#define MCF_IRQ_TIMER MCF_IRQ_TIMER1
#define MCF_IRQ_PROFILER MCF_IRQ_TIMER2
/*
* Generic GPIO support
*/
#define MCFGPIO_PIN_MAX 48
#define MCFGPIO_IRQ_MAX -1
#define MCFGPIO_IRQ_VECBASE -1
/****************************************************************************/
#endif /* m5272sim_h */
......@@ -54,6 +54,175 @@
#define MCFSIM_DMR1 0x5c /* SDRAM address mask 1 */
#endif
#ifdef CONFIG_M5271
#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000)
#define MCFGPIO_PODR_DATAH (MCF_IPSBAR + 0x100001)
#define MCFGPIO_PODR_DATAL (MCF_IPSBAR + 0x100002)
#define MCFGPIO_PODR_BUSCTL (MCF_IPSBAR + 0x100003)
#define MCFGPIO_PODR_BS (MCF_IPSBAR + 0x100004)
#define MCFGPIO_PODR_CS (MCF_IPSBAR + 0x100005)
#define MCFGPIO_PODR_SDRAM (MCF_IPSBAR + 0x100006)
#define MCFGPIO_PODR_FECI2C (MCF_IPSBAR + 0x100007)
#define MCFGPIO_PODR_UARTH (MCF_IPSBAR + 0x100008)
#define MCFGPIO_PODR_UARTL (MCF_IPSBAR + 0x100009)
#define MCFGPIO_PODR_QSPI (MCF_IPSBAR + 0x10000A)
#define MCFGPIO_PODR_TIMER (MCF_IPSBAR + 0x10000B)
#define MCFGPIO_PDDR_ADDR (MCF_IPSBAR + 0x100010)
#define MCFGPIO_PDDR_DATAH (MCF_IPSBAR + 0x100011)
#define MCFGPIO_PDDR_DATAL (MCF_IPSBAR + 0x100012)
#define MCFGPIO_PDDR_BUSCTL (MCF_IPSBAR + 0x100013)
#define MCFGPIO_PDDR_BS (MCF_IPSBAR + 0x100014)
#define MCFGPIO_PDDR_CS (MCF_IPSBAR + 0x100015)
#define MCFGPIO_PDDR_SDRAM (MCF_IPSBAR + 0x100016)
#define MCFGPIO_PDDR_FECI2C (MCF_IPSBAR + 0x100017)
#define MCFGPIO_PDDR_UARTH (MCF_IPSBAR + 0x100018)
#define MCFGPIO_PDDR_UARTL (MCF_IPSBAR + 0x100019)
#define MCFGPIO_PDDR_QSPI (MCF_IPSBAR + 0x10001A)
#define MCFGPIO_PDDR_TIMER (MCF_IPSBAR + 0x10001B)
#define MCFGPIO_PPDSDR_ADDR (MCF_IPSBAR + 0x100020)
#define MCFGPIO_PPDSDR_DATAH (MCF_IPSBAR + 0x100021)
#define MCFGPIO_PPDSDR_DATAL (MCF_IPSBAR + 0x100022)
#define MCFGPIO_PPDSDR_BUSCTL (MCF_IPSBAR + 0x100023)
#define MCFGPIO_PPDSDR_BS (MCF_IPSBAR + 0x100024)
#define MCFGPIO_PPDSDR_CS (MCF_IPSBAR + 0x100025)
#define MCFGPIO_PPDSDR_SDRAM (MCF_IPSBAR + 0x100026)
#define MCFGPIO_PPDSDR_FECI2C (MCF_IPSBAR + 0x100027)
#define MCFGPIO_PPDSDR_UARTH (MCF_IPSBAR + 0x100028)
#define MCFGPIO_PPDSDR_UARTL (MCF_IPSBAR + 0x100029)
#define MCFGPIO_PPDSDR_QSPI (MCF_IPSBAR + 0x10002A)
#define MCFGPIO_PPDSDR_TIMER (MCF_IPSBAR + 0x10002B)
#define MCFGPIO_PCLRR_ADDR (MCF_IPSBAR + 0x100030)
#define MCFGPIO_PCLRR_DATAH (MCF_IPSBAR + 0x100031)
#define MCFGPIO_PCLRR_DATAL (MCF_IPSBAR + 0x100032)
#define MCFGPIO_PCLRR_BUSCTL (MCF_IPSBAR + 0x100033)
#define MCFGPIO_PCLRR_BS (MCF_IPSBAR + 0x100034)
#define MCFGPIO_PCLRR_CS (MCF_IPSBAR + 0x100035)
#define MCFGPIO_PCLRR_SDRAM (MCF_IPSBAR + 0x100036)
#define MCFGPIO_PCLRR_FECI2C (MCF_IPSBAR + 0x100037)
#define MCFGPIO_PCLRR_UARTH (MCF_IPSBAR + 0x100038)
#define MCFGPIO_PCLRR_UARTL (MCF_IPSBAR + 0x100039)
#define MCFGPIO_PCLRR_QSPI (MCF_IPSBAR + 0x10003A)
#define MCFGPIO_PCLRR_TIMER (MCF_IPSBAR + 0x10003B)
/*
* Generic GPIO support
*/
#define MCFGPIO_PODR MCFGPIO_PODR_ADDR
#define MCFGPIO_PDDR MCFGPIO_PDDR_ADDR
#define MCFGPIO_PPDR MCFGPIO_PPDSDR_ADDR
#define MCFGPIO_SETR MCFGPIO_PPDSDR_ADDR
#define MCFGPIO_CLRR MCFGPIO_PCLRR_ADDR
#define MCFGPIO_PIN_MAX 100
#define MCFGPIO_IRQ_MAX 8
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
#endif
#ifdef CONFIG_M5275
#define MCFGPIO_PODR_BUSCTL (MCF_IPSBAR + 0x100004)
#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100005)
#define MCFGPIO_PODR_CS (MCF_IPSBAR + 0x100008)
#define MCFGPIO_PODR_FEC0H (MCF_IPSBAR + 0x10000A)
#define MCFGPIO_PODR_FEC0L (MCF_IPSBAR + 0x10000B)
#define MCFGPIO_PODR_FECI2C (MCF_IPSBAR + 0x10000C)
#define MCFGPIO_PODR_QSPI (MCF_IPSBAR + 0x10000D)
#define MCFGPIO_PODR_SDRAM (MCF_IPSBAR + 0x10000E)
#define MCFGPIO_PODR_TIMERH (MCF_IPSBAR + 0x10000F)
#define MCFGPIO_PODR_TIMERL (MCF_IPSBAR + 0x100010)
#define MCFGPIO_PODR_UARTL (MCF_IPSBAR + 0x100011)
#define MCFGPIO_PODR_FEC1H (MCF_IPSBAR + 0x100012)
#define MCFGPIO_PODR_FEC1L (MCF_IPSBAR + 0x100013)
#define MCFGPIO_PODR_BS (MCF_IPSBAR + 0x100014)
#define MCFGPIO_PODR_IRQ (MCF_IPSBAR + 0x100015)
#define MCFGPIO_PODR_USBH (MCF_IPSBAR + 0x100016)
#define MCFGPIO_PODR_USBL (MCF_IPSBAR + 0x100017)
#define MCFGPIO_PODR_UARTH (MCF_IPSBAR + 0x100018)
#define MCFGPIO_PDDR_BUSCTL (MCF_IPSBAR + 0x100020)
#define MCFGPIO_PDDR_ADDR (MCF_IPSBAR + 0x100021)
#define MCFGPIO_PDDR_CS (MCF_IPSBAR + 0x100024)
#define MCFGPIO_PDDR_FEC0H (MCF_IPSBAR + 0x100026)
#define MCFGPIO_PDDR_FEC0L (MCF_IPSBAR + 0x100027)
#define MCFGPIO_PDDR_FECI2C (MCF_IPSBAR + 0x100028)
#define MCFGPIO_PDDR_QSPI (MCF_IPSBAR + 0x100029)
#define MCFGPIO_PDDR_SDRAM (MCF_IPSBAR + 0x10002A)
#define MCFGPIO_PDDR_TIMERH (MCF_IPSBAR + 0x10002B)
#define MCFGPIO_PDDR_TIMERL (MCF_IPSBAR + 0x10002C)
#define MCFGPIO_PDDR_UARTL (MCF_IPSBAR + 0x10002D)
#define MCFGPIO_PDDR_FEC1H (MCF_IPSBAR + 0x10002E)
#define MCFGPIO_PDDR_FEC1L (MCF_IPSBAR + 0x10002F)
#define MCFGPIO_PDDR_BS (MCF_IPSBAR + 0x100030)
#define MCFGPIO_PDDR_IRQ (MCF_IPSBAR + 0x100031)
#define MCFGPIO_PDDR_USBH (MCF_IPSBAR + 0x100032)
#define MCFGPIO_PDDR_USBL (MCF_IPSBAR + 0x100033)
#define MCFGPIO_PDDR_UARTH (MCF_IPSBAR + 0x100034)
#define MCFGPIO_PPDSDR_BUSCTL (MCF_IPSBAR + 0x10003C)
#define MCFGPIO_PPDSDR_ADDR (MCF_IPSBAR + 0x10003D)
#define MCFGPIO_PPDSDR_CS (MCF_IPSBAR + 0x100040)
#define MCFGPIO_PPDSDR_FEC0H (MCF_IPSBAR + 0x100042)
#define MCFGPIO_PPDSDR_FEC0L (MCF_IPSBAR + 0x100043)
#define MCFGPIO_PPDSDR_FECI2C (MCF_IPSBAR + 0x100044)
#define MCFGPIO_PPDSDR_QSPI (MCF_IPSBAR + 0x100045)
#define MCFGPIO_PPDSDR_SDRAM (MCF_IPSBAR + 0x100046)
#define MCFGPIO_PPDSDR_TIMERH (MCF_IPSBAR + 0x100047)
#define MCFGPIO_PPDSDR_TIMERL (MCF_IPSBAR + 0x100048)
#define MCFGPIO_PPDSDR_UARTL (MCF_IPSBAR + 0x100049)
#define MCFGPIO_PPDSDR_FEC1H (MCF_IPSBAR + 0x10004A)
#define MCFGPIO_PPDSDR_FEC1L (MCF_IPSBAR + 0x10004B)
#define MCFGPIO_PPDSDR_BS (MCF_IPSBAR + 0x10004C)
#define MCFGPIO_PPDSDR_IRQ (MCF_IPSBAR + 0x10004D)
#define MCFGPIO_PPDSDR_USBH (MCF_IPSBAR + 0x10004E)
#define MCFGPIO_PPDSDR_USBL (MCF_IPSBAR + 0x10004F)
#define MCFGPIO_PPDSDR_UARTH (MCF_IPSBAR + 0x100050)
#define MCFGPIO_PCLRR_BUSCTL (MCF_IPSBAR + 0x100058)
#define MCFGPIO_PCLRR_ADDR (MCF_IPSBAR + 0x100059)
#define MCFGPIO_PCLRR_CS (MCF_IPSBAR + 0x10005C)
#define MCFGPIO_PCLRR_FEC0H (MCF_IPSBAR + 0x10005E)
#define MCFGPIO_PCLRR_FEC0L (MCF_IPSBAR + 0x10005F)
#define MCFGPIO_PCLRR_FECI2C (MCF_IPSBAR + 0x100060)
#define MCFGPIO_PCLRR_QSPI (MCF_IPSBAR + 0x100061)
#define MCFGPIO_PCLRR_SDRAM (MCF_IPSBAR + 0x100062)
#define MCFGPIO_PCLRR_TIMERH (MCF_IPSBAR + 0x100063)
#define MCFGPIO_PCLRR_TIMERL (MCF_IPSBAR + 0x100064)
#define MCFGPIO_PCLRR_UARTL (MCF_IPSBAR + 0x100065)
#define MCFGPIO_PCLRR_FEC1H (MCF_IPSBAR + 0x100066)
#define MCFGPIO_PCLRR_FEC1L (MCF_IPSBAR + 0x100067)
#define MCFGPIO_PCLRR_BS (MCF_IPSBAR + 0x100068)
#define MCFGPIO_PCLRR_IRQ (MCF_IPSBAR + 0x100069)
#define MCFGPIO_PCLRR_USBH (MCF_IPSBAR + 0x10006A)
#define MCFGPIO_PCLRR_USBL (MCF_IPSBAR + 0x10006B)
#define MCFGPIO_PCLRR_UARTH (MCF_IPSBAR + 0x10006C)
/*
* Generic GPIO support
*/
#define MCFGPIO_PODR MCFGPIO_PODR_BUSCTL
#define MCFGPIO_PDDR MCFGPIO_PDDR_BUSCTL
#define MCFGPIO_PPDR MCFGPIO_PPDSDR_BUSCTL
#define MCFGPIO_SETR MCFGPIO_PPDSDR_BUSCTL
#define MCFGPIO_CLRR MCFGPIO_PCLRR_BUSCTL
#define MCFGPIO_PIN_MAX 148
#define MCFGPIO_IRQ_MAX 8
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
#endif
/*
* EPort
*/
#define MCFEPORT_EPDDR (MCF_IPSBAR + 0x130002)
#define MCFEPORT_EPDR (MCF_IPSBAR + 0x130004)
#define MCFEPORT_EPPDR (MCF_IPSBAR + 0x130005)
/*
* GPIO pins setups to enable the UARTs.
*/
......
......@@ -40,6 +40,157 @@
#define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */
#define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */
/*
* GPIO registers
*/
#define MCFGPIO_PORTA (MCF_IPSBAR + 0x00100000)
#define MCFGPIO_PORTB (MCF_IPSBAR + 0x00100001)
#define MCFGPIO_PORTC (MCF_IPSBAR + 0x00100002)
#define MCFGPIO_PORTD (MCF_IPSBAR + 0x00100003)
#define MCFGPIO_PORTE (MCF_IPSBAR + 0x00100004)
#define MCFGPIO_PORTF (MCF_IPSBAR + 0x00100005)
#define MCFGPIO_PORTG (MCF_IPSBAR + 0x00100006)
#define MCFGPIO_PORTH (MCF_IPSBAR + 0x00100007)
#define MCFGPIO_PORTJ (MCF_IPSBAR + 0x00100008)
#define MCFGPIO_PORTDD (MCF_IPSBAR + 0x00100009)
#define MCFGPIO_PORTEH (MCF_IPSBAR + 0x0010000A)
#define MCFGPIO_PORTEL (MCF_IPSBAR + 0x0010000B)
#define MCFGPIO_PORTAS (MCF_IPSBAR + 0x0010000C)
#define MCFGPIO_PORTQS (MCF_IPSBAR + 0x0010000D)
#define MCFGPIO_PORTSD (MCF_IPSBAR + 0x0010000E)
#define MCFGPIO_PORTTC (MCF_IPSBAR + 0x0010000F)
#define MCFGPIO_PORTTD (MCF_IPSBAR + 0x00100010)
#define MCFGPIO_PORTUA (MCF_IPSBAR + 0x00100011)
#define MCFGPIO_DDRA (MCF_IPSBAR + 0x00100014)
#define MCFGPIO_DDRB (MCF_IPSBAR + 0x00100015)
#define MCFGPIO_DDRC (MCF_IPSBAR + 0x00100016)
#define MCFGPIO_DDRD (MCF_IPSBAR + 0x00100017)
#define MCFGPIO_DDRE (MCF_IPSBAR + 0x00100018)
#define MCFGPIO_DDRF (MCF_IPSBAR + 0x00100019)
#define MCFGPIO_DDRG (MCF_IPSBAR + 0x0010001A)
#define MCFGPIO_DDRH (MCF_IPSBAR + 0x0010001B)
#define MCFGPIO_DDRJ (MCF_IPSBAR + 0x0010001C)
#define MCFGPIO_DDRDD (MCF_IPSBAR + 0x0010001D)
#define MCFGPIO_DDREH (MCF_IPSBAR + 0x0010001E)
#define MCFGPIO_DDREL (MCF_IPSBAR + 0x0010001F)
#define MCFGPIO_DDRAS (MCF_IPSBAR + 0x00100020)
#define MCFGPIO_DDRQS (MCF_IPSBAR + 0x00100021)
#define MCFGPIO_DDRSD (MCF_IPSBAR + 0x00100022)
#define MCFGPIO_DDRTC (MCF_IPSBAR + 0x00100023)
#define MCFGPIO_DDRTD (MCF_IPSBAR + 0x00100024)
#define MCFGPIO_DDRUA (MCF_IPSBAR + 0x00100025)
#define MCFGPIO_PORTAP (MCF_IPSBAR + 0x00100028)
#define MCFGPIO_PORTBP (MCF_IPSBAR + 0x00100029)
#define MCFGPIO_PORTCP (MCF_IPSBAR + 0x0010002A)
#define MCFGPIO_PORTDP (MCF_IPSBAR + 0x0010002B)
#define MCFGPIO_PORTEP (MCF_IPSBAR + 0x0010002C)
#define MCFGPIO_PORTFP (MCF_IPSBAR + 0x0010002D)
#define MCFGPIO_PORTGP (MCF_IPSBAR + 0x0010002E)
#define MCFGPIO_PORTHP (MCF_IPSBAR + 0x0010002F)
#define MCFGPIO_PORTJP (MCF_IPSBAR + 0x00100030)
#define MCFGPIO_PORTDDP (MCF_IPSBAR + 0x00100031)
#define MCFGPIO_PORTEHP (MCF_IPSBAR + 0x00100032)
#define MCFGPIO_PORTELP (MCF_IPSBAR + 0x00100033)
#define MCFGPIO_PORTASP (MCF_IPSBAR + 0x00100034)
#define MCFGPIO_PORTQSP (MCF_IPSBAR + 0x00100035)
#define MCFGPIO_PORTSDP (MCF_IPSBAR + 0x00100036)
#define MCFGPIO_PORTTCP (MCF_IPSBAR + 0x00100037)
#define MCFGPIO_PORTTDP (MCF_IPSBAR + 0x00100038)
#define MCFGPIO_PORTUAP (MCF_IPSBAR + 0x00100039)
#define MCFGPIO_SETA (MCF_IPSBAR + 0x00100028)
#define MCFGPIO_SETB (MCF_IPSBAR + 0x00100029)
#define MCFGPIO_SETC (MCF_IPSBAR + 0x0010002A)
#define MCFGPIO_SETD (MCF_IPSBAR + 0x0010002B)
#define MCFGPIO_SETE (MCF_IPSBAR + 0x0010002C)
#define MCFGPIO_SETF (MCF_IPSBAR + 0x0010002D)
#define MCFGPIO_SETG (MCF_IPSBAR + 0x0010002E)
#define MCFGPIO_SETH (MCF_IPSBAR + 0x0010002F)
#define MCFGPIO_SETJ (MCF_IPSBAR + 0x00100030)
#define MCFGPIO_SETDD (MCF_IPSBAR + 0x00100031)
#define MCFGPIO_SETEH (MCF_IPSBAR + 0x00100032)
#define MCFGPIO_SETEL (MCF_IPSBAR + 0x00100033)
#define MCFGPIO_SETAS (MCF_IPSBAR + 0x00100034)
#define MCFGPIO_SETQS (MCF_IPSBAR + 0x00100035)
#define MCFGPIO_SETSD (MCF_IPSBAR + 0x00100036)
#define MCFGPIO_SETTC (MCF_IPSBAR + 0x00100037)
#define MCFGPIO_SETTD (MCF_IPSBAR + 0x00100038)
#define MCFGPIO_SETUA (MCF_IPSBAR + 0x00100039)
#define MCFGPIO_CLRA (MCF_IPSBAR + 0x0010003C)
#define MCFGPIO_CLRB (MCF_IPSBAR + 0x0010003D)
#define MCFGPIO_CLRC (MCF_IPSBAR + 0x0010003E)
#define MCFGPIO_CLRD (MCF_IPSBAR + 0x0010003F)
#define MCFGPIO_CLRE (MCF_IPSBAR + 0x00100040)
#define MCFGPIO_CLRF (MCF_IPSBAR + 0x00100041)
#define MCFGPIO_CLRG (MCF_IPSBAR + 0x00100042)
#define MCFGPIO_CLRH (MCF_IPSBAR + 0x00100043)
#define MCFGPIO_CLRJ (MCF_IPSBAR + 0x00100044)
#define MCFGPIO_CLRDD (MCF_IPSBAR + 0x00100045)
#define MCFGPIO_CLREH (MCF_IPSBAR + 0x00100046)
#define MCFGPIO_CLREL (MCF_IPSBAR + 0x00100047)
#define MCFGPIO_CLRAS (MCF_IPSBAR + 0x00100048)
#define MCFGPIO_CLRQS (MCF_IPSBAR + 0x00100049)
#define MCFGPIO_CLRSD (MCF_IPSBAR + 0x0010004A)
#define MCFGPIO_CLRTC (MCF_IPSBAR + 0x0010004B)
#define MCFGPIO_CLRTD (MCF_IPSBAR + 0x0010004C)
#define MCFGPIO_CLRUA (MCF_IPSBAR + 0x0010004D)
#define MCFGPIO_PBCDPAR (MCF_IPSBAR + 0x00100050)
#define MCFGPIO_PFPAR (MCF_IPSBAR + 0x00100051)
#define MCFGPIO_PEPAR (MCF_IPSBAR + 0x00100052)
#define MCFGPIO_PJPAR (MCF_IPSBAR + 0x00100054)
#define MCFGPIO_PSDPAR (MCF_IPSBAR + 0x00100055)
#define MCFGPIO_PASPAR (MCF_IPSBAR + 0x00100056)
#define MCFGPIO_PEHLPAR (MCF_IPSBAR + 0x00100058)
#define MCFGPIO_PQSPAR (MCF_IPSBAR + 0x00100059)
#define MCFGPIO_PTCPAR (MCF_IPSBAR + 0x0010005A)
#define MCFGPIO_PTDPAR (MCF_IPSBAR + 0x0010005B)
#define MCFGPIO_PUAPAR (MCF_IPSBAR + 0x0010005C)
/*
* Edge Port registers
*/
#define MCFEPORT_EPPAR (MCF_IPSBAR + 0x00130000)
#define MCFEPORT_EPDDR (MCF_IPSBAR + 0x00130002)
#define MCFEPORT_EPIER (MCF_IPSBAR + 0x00130003)
#define MCFEPORT_EPDR (MCF_IPSBAR + 0x00130004)
#define MCFEPORT_EPPDR (MCF_IPSBAR + 0x00130005)
#define MCFEPORT_EPFR (MCF_IPSBAR + 0x00130006)
/*
* Queued ADC registers
*/
#define MCFQADC_PORTQA (MCF_IPSBAR + 0x00190006)
#define MCFQADC_PORTQB (MCF_IPSBAR + 0x00190007)
#define MCFQADC_DDRQA (MCF_IPSBAR + 0x00190008)
#define MCFQADC_DDRQB (MCF_IPSBAR + 0x00190009)
/*
* General Purpose Timers registers
*/
#define MCFGPTA_GPTPORT (MCF_IPSBAR + 0x001A001D)
#define MCFGPTA_GPTDDR (MCF_IPSBAR + 0x001A001E)
#define MCFGPTB_GPTPORT (MCF_IPSBAR + 0x001B001D)
#define MCFGPTB_GPTDDR (MCF_IPSBAR + 0x001B001E)
/*
*
* definitions for generic gpio support
*
*/
#define MCFGPIO_PODR MCFGPIO_PORTA /* port output data */
#define MCFGPIO_PDDR MCFGPIO_DDRA /* port data direction */
#define MCFGPIO_PPDR MCFGPIO_PORTAP /* port pin data */
#define MCFGPIO_SETR MCFGPIO_SETA /* set output */
#define MCFGPIO_CLRR MCFGPIO_CLRA /* clr output */
#define MCFGPIO_IRQ_MAX 8
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
#define MCFGPIO_PIN_MAX 180
/*
* Derek Cheung - 6 Feb 2005
* add I2C and QSPI register definition using Freescale's MCF5282
......
......@@ -90,8 +90,15 @@
#define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */
#define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */
#define MCFSIM_PADDR 0x244 /* Parallel Direction (r/w) */
#define MCFSIM_PADAT 0x248 /* Parallel Data (r/w) */
#define MCFSIM_PADDR (MCF_MBAR + 0x244)
#define MCFSIM_PADAT (MCF_MBAR + 0x248)
/*
* Generic GPIO support
*/
#define MCFGPIO_PIN_MAX 16
#define MCFGPIO_IRQ_MAX -1
#define MCFGPIO_IRQ_VECBASE -1
/* Definition offset address for CS2-7 -- old mask 5307 */
......@@ -117,22 +124,6 @@
#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */
#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */
#if defined(CONFIG_M5307)
#define MCFSIM_IMR_MASKALL 0x3fffe /* All SIM intr sources */
#endif
/*
* Macro to set IMR register. It is 32 bits on the 5307.
*/
#define mcf_getimr() \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
#define mcf_setimr(imr) \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
#define mcf_getipr() \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
/*
* Some symbol defines for the Parallel Port Pin Assignment Register
......@@ -149,6 +140,11 @@
#define IRQ3_LEVEL6 0x40
#define IRQ1_LEVEL2 0x20
/*
* Define system peripheral IRQ usage.
*/
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
/*
* Define the Cache register flags.
......
......@@ -56,47 +56,21 @@
#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */
#define MCFSIM_IMR_MASKALL 0xFFFFFFFF /* All SIM intr sources */
#define MCFSIM_IMR_SIMR0 0xFC04801C
#define MCFSIM_IMR_SIMR1 0xFC04C01C
#define MCFSIM_IMR_CIMR0 0xFC04801D
#define MCFSIM_IMR_CIMR1 0xFC04C01D
#define MCFINTC0_SIMR 0xFC04801C
#define MCFINTC0_CIMR 0xFC04801D
#define MCFINTC0_ICR0 0xFC048040
#define MCFINTC1_SIMR 0xFC04C01C
#define MCFINTC1_CIMR 0xFC04C01D
#define MCFINTC1_ICR0 0xFC04C040
#define MCFSIM_ICR_TIMER1 (0xFC048040+32)
#define MCFSIM_ICR_TIMER2 (0xFC048040+33)
/*
* Macro to set IMR register. It is 32 bits on the 5307.
* Define system peripheral IRQ usage.
*/
#define mcf_getimr() \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
#define mcf_setimr(imr) \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
#define mcf_getipr() \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
#define mcf_getiprl() \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRL))
#define mcf_getiprh() \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRH))
#define mcf_enable_irq0(irq) \
*((volatile unsigned char*) (MCFSIM_IMR_CIMR0)) = (irq);
#define mcf_enable_irq1(irq) \
*((volatile unsigned char*) (MCFSIM_IMR_CIMR1)) = (irq);
#define mcf_disable_irq0(irq) \
*((volatile unsigned char*) (MCFSIM_IMR_SIMR0)) = (irq);
#define mcf_disable_irq1(irq) \
*((volatile unsigned char*) (MCFSIM_IMR_SIMR1)) = (irq);
#define MCF_IRQ_TIMER (64 + 32) /* Timer0 */
#define MCF_IRQ_PROFILER (64 + 33) /* Timer1 */
/*
* Define the Cache register flags.
......@@ -422,70 +396,70 @@
*********************************************************************/
/* Register read/write macros */
#define MCF_GPIO_PODR_FECH MCF_REG08(0xFC0A4000)
#define MCF_GPIO_PODR_FECL MCF_REG08(0xFC0A4001)
#define MCF_GPIO_PODR_SSI MCF_REG08(0xFC0A4002)
#define MCF_GPIO_PODR_BUSCTL MCF_REG08(0xFC0A4003)
#define MCF_GPIO_PODR_BE MCF_REG08(0xFC0A4004)
#define MCF_GPIO_PODR_CS MCF_REG08(0xFC0A4005)
#define MCF_GPIO_PODR_PWM MCF_REG08(0xFC0A4006)
#define MCF_GPIO_PODR_FECI2C MCF_REG08(0xFC0A4007)
#define MCF_GPIO_PODR_UART MCF_REG08(0xFC0A4009)
#define MCF_GPIO_PODR_QSPI MCF_REG08(0xFC0A400A)
#define MCF_GPIO_PODR_TIMER MCF_REG08(0xFC0A400B)
#define MCF_GPIO_PODR_LCDDATAH MCF_REG08(0xFC0A400D)
#define MCF_GPIO_PODR_LCDDATAM MCF_REG08(0xFC0A400E)
#define MCF_GPIO_PODR_LCDDATAL MCF_REG08(0xFC0A400F)
#define MCF_GPIO_PODR_LCDCTLH MCF_REG08(0xFC0A4010)
#define MCF_GPIO_PODR_LCDCTLL MCF_REG08(0xFC0A4011)
#define MCF_GPIO_PDDR_FECH MCF_REG08(0xFC0A4014)
#define MCF_GPIO_PDDR_FECL MCF_REG08(0xFC0A4015)
#define MCF_GPIO_PDDR_SSI MCF_REG08(0xFC0A4016)
#define MCF_GPIO_PDDR_BUSCTL MCF_REG08(0xFC0A4017)
#define MCF_GPIO_PDDR_BE MCF_REG08(0xFC0A4018)
#define MCF_GPIO_PDDR_CS MCF_REG08(0xFC0A4019)
#define MCF_GPIO_PDDR_PWM MCF_REG08(0xFC0A401A)
#define MCF_GPIO_PDDR_FECI2C MCF_REG08(0xFC0A401B)
#define MCF_GPIO_PDDR_UART MCF_REG08(0xFC0A401C)
#define MCF_GPIO_PDDR_QSPI MCF_REG08(0xFC0A401E)
#define MCF_GPIO_PDDR_TIMER MCF_REG08(0xFC0A401F)
#define MCF_GPIO_PDDR_LCDDATAH MCF_REG08(0xFC0A4021)
#define MCF_GPIO_PDDR_LCDDATAM MCF_REG08(0xFC0A4022)
#define MCF_GPIO_PDDR_LCDDATAL MCF_REG08(0xFC0A4023)
#define MCF_GPIO_PDDR_LCDCTLH MCF_REG08(0xFC0A4024)
#define MCF_GPIO_PDDR_LCDCTLL MCF_REG08(0xFC0A4025)
#define MCF_GPIO_PPDSDR_FECH MCF_REG08(0xFC0A4028)
#define MCF_GPIO_PPDSDR_FECL MCF_REG08(0xFC0A4029)
#define MCF_GPIO_PPDSDR_SSI MCF_REG08(0xFC0A402A)
#define MCF_GPIO_PPDSDR_BUSCTL MCF_REG08(0xFC0A402B)
#define MCF_GPIO_PPDSDR_BE MCF_REG08(0xFC0A402C)
#define MCF_GPIO_PPDSDR_CS MCF_REG08(0xFC0A402D)
#define MCF_GPIO_PPDSDR_PWM MCF_REG08(0xFC0A402E)
#define MCF_GPIO_PPDSDR_FECI2C MCF_REG08(0xFC0A402F)
#define MCF_GPIO_PPDSDR_UART MCF_REG08(0xFC0A4031)
#define MCF_GPIO_PPDSDR_QSPI MCF_REG08(0xFC0A4032)
#define MCF_GPIO_PPDSDR_TIMER MCF_REG08(0xFC0A4033)
#define MCF_GPIO_PPDSDR_LCDDATAH MCF_REG08(0xFC0A4035)
#define MCF_GPIO_PPDSDR_LCDDATAM MCF_REG08(0xFC0A4036)
#define MCF_GPIO_PPDSDR_LCDDATAL MCF_REG08(0xFC0A4037)
#define MCF_GPIO_PPDSDR_LCDCTLH MCF_REG08(0xFC0A4038)
#define MCF_GPIO_PPDSDR_LCDCTLL MCF_REG08(0xFC0A4039)
#define MCF_GPIO_PCLRR_FECH MCF_REG08(0xFC0A403C)
#define MCF_GPIO_PCLRR_FECL MCF_REG08(0xFC0A403D)
#define MCF_GPIO_PCLRR_SSI MCF_REG08(0xFC0A403E)
#define MCF_GPIO_PCLRR_BUSCTL MCF_REG08(0xFC0A403F)
#define MCF_GPIO_PCLRR_BE MCF_REG08(0xFC0A4040)
#define MCF_GPIO_PCLRR_CS MCF_REG08(0xFC0A4041)
#define MCF_GPIO_PCLRR_PWM MCF_REG08(0xFC0A4042)
#define MCF_GPIO_PCLRR_FECI2C MCF_REG08(0xFC0A4043)
#define MCF_GPIO_PCLRR_UART MCF_REG08(0xFC0A4045)
#define MCF_GPIO_PCLRR_QSPI MCF_REG08(0xFC0A4046)
#define MCF_GPIO_PCLRR_TIMER MCF_REG08(0xFC0A4047)
#define MCF_GPIO_PCLRR_LCDDATAH MCF_REG08(0xFC0A4049)
#define MCF_GPIO_PCLRR_LCDDATAM MCF_REG08(0xFC0A404A)
#define MCF_GPIO_PCLRR_LCDDATAL MCF_REG08(0xFC0A404B)
#define MCF_GPIO_PCLRR_LCDCTLH MCF_REG08(0xFC0A404C)
#define MCF_GPIO_PCLRR_LCDCTLL MCF_REG08(0xFC0A404D)
#define MCFGPIO_PODR_FECH (0xFC0A4000)
#define MCFGPIO_PODR_FECL (0xFC0A4001)
#define MCFGPIO_PODR_SSI (0xFC0A4002)
#define MCFGPIO_PODR_BUSCTL (0xFC0A4003)
#define MCFGPIO_PODR_BE (0xFC0A4004)
#define MCFGPIO_PODR_CS (0xFC0A4005)
#define MCFGPIO_PODR_PWM (0xFC0A4006)
#define MCFGPIO_PODR_FECI2C (0xFC0A4007)
#define MCFGPIO_PODR_UART (0xFC0A4009)
#define MCFGPIO_PODR_QSPI (0xFC0A400A)
#define MCFGPIO_PODR_TIMER (0xFC0A400B)
#define MCFGPIO_PODR_LCDDATAH (0xFC0A400D)
#define MCFGPIO_PODR_LCDDATAM (0xFC0A400E)
#define MCFGPIO_PODR_LCDDATAL (0xFC0A400F)
#define MCFGPIO_PODR_LCDCTLH (0xFC0A4010)
#define MCFGPIO_PODR_LCDCTLL (0xFC0A4011)
#define MCFGPIO_PDDR_FECH (0xFC0A4014)
#define MCFGPIO_PDDR_FECL (0xFC0A4015)
#define MCFGPIO_PDDR_SSI (0xFC0A4016)
#define MCFGPIO_PDDR_BUSCTL (0xFC0A4017)
#define MCFGPIO_PDDR_BE (0xFC0A4018)
#define MCFGPIO_PDDR_CS (0xFC0A4019)
#define MCFGPIO_PDDR_PWM (0xFC0A401A)
#define MCFGPIO_PDDR_FECI2C (0xFC0A401B)
#define MCFGPIO_PDDR_UART (0xFC0A401C)
#define MCFGPIO_PDDR_QSPI (0xFC0A401E)
#define MCFGPIO_PDDR_TIMER (0xFC0A401F)
#define MCFGPIO_PDDR_LCDDATAH (0xFC0A4021)
#define MCFGPIO_PDDR_LCDDATAM (0xFC0A4022)
#define MCFGPIO_PDDR_LCDDATAL (0xFC0A4023)
#define MCFGPIO_PDDR_LCDCTLH (0xFC0A4024)
#define MCFGPIO_PDDR_LCDCTLL (0xFC0A4025)
#define MCFGPIO_PPDSDR_FECH (0xFC0A4028)
#define MCFGPIO_PPDSDR_FECL (0xFC0A4029)
#define MCFGPIO_PPDSDR_SSI (0xFC0A402A)
#define MCFGPIO_PPDSDR_BUSCTL (0xFC0A402B)
#define MCFGPIO_PPDSDR_BE (0xFC0A402C)
#define MCFGPIO_PPDSDR_CS (0xFC0A402D)
#define MCFGPIO_PPDSDR_PWM (0xFC0A402E)
#define MCFGPIO_PPDSDR_FECI2C (0xFC0A402F)
#define MCFGPIO_PPDSDR_UART (0xFC0A4031)
#define MCFGPIO_PPDSDR_QSPI (0xFC0A4032)
#define MCFGPIO_PPDSDR_TIMER (0xFC0A4033)
#define MCFGPIO_PPDSDR_LCDDATAH (0xFC0A4035)
#define MCFGPIO_PPDSDR_LCDDATAM (0xFC0A4036)
#define MCFGPIO_PPDSDR_LCDDATAL (0xFC0A4037)
#define MCFGPIO_PPDSDR_LCDCTLH (0xFC0A4038)
#define MCFGPIO_PPDSDR_LCDCTLL (0xFC0A4039)
#define MCFGPIO_PCLRR_FECH (0xFC0A403C)
#define MCFGPIO_PCLRR_FECL (0xFC0A403D)
#define MCFGPIO_PCLRR_SSI (0xFC0A403E)
#define MCFGPIO_PCLRR_BUSCTL (0xFC0A403F)
#define MCFGPIO_PCLRR_BE (0xFC0A4040)
#define MCFGPIO_PCLRR_CS (0xFC0A4041)
#define MCFGPIO_PCLRR_PWM (0xFC0A4042)
#define MCFGPIO_PCLRR_FECI2C (0xFC0A4043)
#define MCFGPIO_PCLRR_UART (0xFC0A4045)
#define MCFGPIO_PCLRR_QSPI (0xFC0A4046)
#define MCFGPIO_PCLRR_TIMER (0xFC0A4047)
#define MCFGPIO_PCLRR_LCDDATAH (0xFC0A4049)
#define MCFGPIO_PCLRR_LCDDATAM (0xFC0A404A)
#define MCFGPIO_PCLRR_LCDDATAL (0xFC0A404B)
#define MCFGPIO_PCLRR_LCDCTLH (0xFC0A404C)
#define MCFGPIO_PCLRR_LCDCTLL (0xFC0A404D)
#define MCF_GPIO_PAR_FEC MCF_REG08(0xFC0A4050)
#define MCF_GPIO_PAR_PWM MCF_REG08(0xFC0A4051)
#define MCF_GPIO_PAR_BUSCTL MCF_REG08(0xFC0A4052)
......@@ -1187,6 +1161,20 @@
/* Bit definitions and macros for MCF_GPIO_DSCR_IRQ */
#define MCF_GPIO_DSCR_IRQ_IRQ_DSE(x) (((x)&0x03)<<0)
/*
* Generic GPIO support
*/
#define MCFGPIO_PODR MCFGPIO_PODR_FECH
#define MCFGPIO_PDDR MCFGPIO_PDDR_FECH
#define MCFGPIO_PPDR MCFGPIO_PPDSDR_FECH
#define MCFGPIO_SETR MCFGPIO_PPDSDR_FECH
#define MCFGPIO_CLRR MCFGPIO_PCLRR_FECH
#define MCFGPIO_PIN_MAX 136
#define MCFGPIO_IRQ_MAX 8
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
/*********************************************************************
*
* Interrupt Controller (INTC)
......@@ -2154,12 +2142,12 @@
*********************************************************************/
/* Register read/write macros */
#define MCF_EPORT_EPPAR MCF_REG16(0xFC094000)
#define MCF_EPORT_EPDDR MCF_REG08(0xFC094002)
#define MCF_EPORT_EPIER MCF_REG08(0xFC094003)
#define MCF_EPORT_EPDR MCF_REG08(0xFC094004)
#define MCF_EPORT_EPPDR MCF_REG08(0xFC094005)
#define MCF_EPORT_EPFR MCF_REG08(0xFC094006)
#define MCFEPORT_EPPAR (0xFC094000)
#define MCFEPORT_EPDDR (0xFC094002)
#define MCFEPORT_EPIER (0xFC094003)
#define MCFEPORT_EPDR (0xFC094004)
#define MCFEPORT_EPPDR (0xFC094005)
#define MCFEPORT_EPFR (0xFC094006)
/* Bit definitions and macros for MCF_EPORT_EPPAR */
#define MCF_EPORT_EPPAR_EPPA1(x) (((x)&0x0003)<<2)
......
......@@ -73,9 +73,15 @@
#define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */
#define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */
#define MCFSIM_PADDR 0x244 /* Parallel Direction (r/w) */
#define MCFSIM_PADAT 0x248 /* Parallel Data (r/w) */
#define MCFSIM_PADDR (MCF_MBAR + 0x244)
#define MCFSIM_PADAT (MCF_MBAR + 0x248)
/*
* Generic GPIO support
*/
#define MCFGPIO_PIN_MAX 16
#define MCFGPIO_IRQ_MAX -1
#define MCFGPIO_IRQ_VECBASE -1
/*
* Some symbol defines for the above...
......@@ -90,19 +96,6 @@
#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */
#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */
/*
* Macro to set IMR register. It is 32 bits on the 5407.
*/
#define mcf_getimr() \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
#define mcf_setimr(imr) \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
#define mcf_getipr() \
*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
/*
* Some symbol defines for the Parallel Port Pin Assignment Register
*/
......@@ -118,6 +111,11 @@
#define IRQ3_LEVEL6 0x40
#define IRQ1_LEVEL2 0x20
/*
* Define system peripheral IRQ usage.
*/
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
/*
* Define the Cache register flags.
......
/*
* Coldfire generic GPIO support.
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#ifndef mcfgpio_h
#define mcfgpio_h
#include <linux/io.h>
#include <asm-generic/gpio.h>
struct mcf_gpio_chip {
struct gpio_chip gpio_chip;
void __iomem *pddr;
void __iomem *podr;
void __iomem *ppdr;
void __iomem *setr;
void __iomem *clrr;
const u8 *gpio_to_pinmux;
};
int mcf_gpio_direction_input(struct gpio_chip *, unsigned);
int mcf_gpio_get_value(struct gpio_chip *, unsigned);
int mcf_gpio_direction_output(struct gpio_chip *, unsigned, int);
void mcf_gpio_set_value(struct gpio_chip *, unsigned, int);
void mcf_gpio_set_value_fast(struct gpio_chip *, unsigned, int);
int mcf_gpio_request(struct gpio_chip *, unsigned);
void mcf_gpio_free(struct gpio_chip *, unsigned);
#endif
/****************************************************************************/
/*
* mcfintc.h -- support definitions for the simple ColdFire
* Interrupt Controller
*
* (C) Copyright 2009, Greg Ungerer <gerg@uclinux.org>
*/
/****************************************************************************/
#ifndef mcfintc_h
#define mcfintc_h
/****************************************************************************/
/*
* Most of the older ColdFire parts use the same simple interrupt
* controller. This is currently used on the 5206, 5206e, 5249, 5307
* and 5407 parts.
*
* The builtin peripherals are masked through dedicated bits in the
* Interrupt Mask register (IMR) - and this is not indexed (or in any way
* related to) the actual interrupt number they use. So knowing the IRQ
* number doesn't explicitly map to a certain internal device for
* interrupt control purposes.
*/
/*
* Bit definitions for the ICR family of registers.
*/
#define MCFSIM_ICR_AUTOVEC 0x80 /* Auto-vectored intr */
#define MCFSIM_ICR_LEVEL0 0x00 /* Level 0 intr */
#define MCFSIM_ICR_LEVEL1 0x04 /* Level 1 intr */
#define MCFSIM_ICR_LEVEL2 0x08 /* Level 2 intr */
#define MCFSIM_ICR_LEVEL3 0x0c /* Level 3 intr */
#define MCFSIM_ICR_LEVEL4 0x10 /* Level 4 intr */
#define MCFSIM_ICR_LEVEL5 0x14 /* Level 5 intr */
#define MCFSIM_ICR_LEVEL6 0x18 /* Level 6 intr */
#define MCFSIM_ICR_LEVEL7 0x1c /* Level 7 intr */
#define MCFSIM_ICR_PRI0 0x00 /* Priority 0 intr */
#define MCFSIM_ICR_PRI1 0x01 /* Priority 1 intr */
#define MCFSIM_ICR_PRI2 0x02 /* Priority 2 intr */
#define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */
/*
* IMR bit position definitions. Not all ColdFire parts with this interrupt
* controller actually support all of these interrupt sources. But the bit
* numbers are the same in all cores.
*/
#define MCFINTC_EINT1 1 /* External int #1 */
#define MCFINTC_EINT2 2 /* External int #2 */
#define MCFINTC_EINT3 3 /* External int #3 */
#define MCFINTC_EINT4 4 /* External int #4 */
#define MCFINTC_EINT5 5 /* External int #5 */
#define MCFINTC_EINT6 6 /* External int #6 */
#define MCFINTC_EINT7 7 /* External int #7 */
#define MCFINTC_SWT 8 /* Software Watchdog */
#define MCFINTC_TIMER1 9
#define MCFINTC_TIMER2 10
#define MCFINTC_I2C 11 /* I2C / MBUS */
#define MCFINTC_UART0 12
#define MCFINTC_UART1 13
#define MCFINTC_DMA0 14
#define MCFINTC_DMA1 15
#define MCFINTC_DMA2 16
#define MCFINTC_DMA3 17
#define MCFINTC_QSPI 18
#ifndef __ASSEMBLER__
/*
* There is no one-is-one correspondance between the interrupt number (irq)
* and the bit fields on the mask register. So we create a per-cpu type
* mapping of irq to mask bit. The CPU platform code needs to register
* its supported irq's at init time, using this function.
*/
extern unsigned char mcf_irq2imr[];
static inline void mcf_mapirq2imr(int irq, int imr)
{
mcf_irq2imr[irq] = imr;
}
void mcf_autovector(int irq);
void mcf_setimr(int index);
void mcf_clrimr(int index);
#endif
/****************************************************************************/
#endif /* mcfintc_h */
......@@ -238,88 +238,5 @@ void ne2000_outsw(unsigned int addr, const void *vbuf, unsigned long len)
#endif /* COLDFIRE_NE2000_FUNCS */
#endif /* NE2000_OFFOFFSET */
/****************************************************************************/
#ifdef COLDFIRE_NE2000_FUNCS
/*
* Lastly the interrupt set up code...
* Minor differences between the different board types.
*/
#if defined(CONFIG_ARN5206)
void ne2000_irqsetup(int irq)
{
volatile unsigned char *icrp;
icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4);
*icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2;
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4);
}
#endif
#if defined(CONFIG_M5206eC3)
void ne2000_irqsetup(int irq)
{
volatile unsigned char *icrp;
icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4);
*icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2 | MCFSIM_ICR_AUTOVEC;
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4);
}
#endif
#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel)
void ne2000_irqsetup(int irq)
{
mcf_autovector(irq);
}
#endif
#if defined(CONFIG_M5272) && defined(CONFIG_NETtel)
void ne2000_irqsetup(int irq)
{
volatile unsigned long *icrp;
volatile unsigned long *pitr;
/* The NE2000 device uses external IRQ3 */
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
*icrp = (*icrp & 0x77077777) | 0x00d00000;
pitr = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PITR);
*pitr = *pitr | 0x20000000;
}
void ne2000_irqack(int irq)
{
volatile unsigned long *icrp;
/* The NE2000 device uses external IRQ3 */
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
*icrp = (*icrp & 0x77777777) | 0x00800000;
}
#endif
#if defined(CONFIG_M5307) || defined(CONFIG_M5407)
#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
void ne2000_irqsetup(int irq)
{
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3);
mcf_autovector(irq);
}
#else
void ne2000_irqsetup(int irq)
{
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3);
}
#endif /* ! CONFIG_NETtel || CONFIG_SECUREEDGEMP3 */
#endif /* CONFIG_M5307 || CONFIG_M5407 */
#endif /* COLDFIRE_NE2000_FUNCS */
/****************************************************************************/
#endif /* mcfne_h */
......@@ -4,7 +4,7 @@
* mcfsim.h -- ColdFire System Integration Module support.
*
* (C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com)
* (C) Copyright 2000, Lineo Inc. (www.lineo.com)
* (C) Copyright 2000, Lineo Inc. (www.lineo.com)
*/
/****************************************************************************/
......@@ -12,19 +12,21 @@
#define mcfsim_h
/****************************************************************************/
/*
* Include 5204, 5206/e, 5235, 5249, 5270/5271, 5272, 5280/5282,
* 5307 or 5407 specific addresses.
* Include the appropriate ColdFire CPU specific System Integration Module
* (SIM) definitions.
*/
#if defined(CONFIG_M5206) || defined(CONFIG_M5206e)
#include <asm/m5206sim.h>
#include <asm/mcfintc.h>
#elif defined(CONFIG_M520x)
#include <asm/m520xsim.h>
#elif defined(CONFIG_M523x)
#include <asm/m523xsim.h>
#include <asm/mcfintc.h>
#elif defined(CONFIG_M5249)
#include <asm/m5249sim.h>
#include <asm/mcfintc.h>
#elif defined(CONFIG_M527x)
#include <asm/m527xsim.h>
#elif defined(CONFIG_M5272)
......@@ -33,94 +35,13 @@
#include <asm/m528xsim.h>
#elif defined(CONFIG_M5307)
#include <asm/m5307sim.h>
#include <asm/mcfintc.h>
#elif defined(CONFIG_M532x)
#include <asm/m532xsim.h>
#elif defined(CONFIG_M5407)
#include <asm/m5407sim.h>
#include <asm/mcfintc.h>
#endif
/*
* Define the base address of the SIM within the MBAR address space.
*/
#define MCFSIM_BASE 0x0 /* Base address of SIM */
/*
* Bit definitions for the ICR family of registers.
*/
#define MCFSIM_ICR_AUTOVEC 0x80 /* Auto-vectored intr */
#define MCFSIM_ICR_LEVEL0 0x00 /* Level 0 intr */
#define MCFSIM_ICR_LEVEL1 0x04 /* Level 1 intr */
#define MCFSIM_ICR_LEVEL2 0x08 /* Level 2 intr */
#define MCFSIM_ICR_LEVEL3 0x0c /* Level 3 intr */
#define MCFSIM_ICR_LEVEL4 0x10 /* Level 4 intr */
#define MCFSIM_ICR_LEVEL5 0x14 /* Level 5 intr */
#define MCFSIM_ICR_LEVEL6 0x18 /* Level 6 intr */
#define MCFSIM_ICR_LEVEL7 0x1c /* Level 7 intr */
#define MCFSIM_ICR_PRI0 0x00 /* Priority 0 intr */
#define MCFSIM_ICR_PRI1 0x01 /* Priority 1 intr */
#define MCFSIM_ICR_PRI2 0x02 /* Priority 2 intr */
#define MCFSIM_ICR_PRI3 0x03 /* Priority 3 intr */
/*
* Bit definitions for the Interrupt Mask register (IMR).
*/
#define MCFSIM_IMR_EINT1 0x0002 /* External intr # 1 */
#define MCFSIM_IMR_EINT2 0x0004 /* External intr # 2 */
#define MCFSIM_IMR_EINT3 0x0008 /* External intr # 3 */
#define MCFSIM_IMR_EINT4 0x0010 /* External intr # 4 */
#define MCFSIM_IMR_EINT5 0x0020 /* External intr # 5 */
#define MCFSIM_IMR_EINT6 0x0040 /* External intr # 6 */
#define MCFSIM_IMR_EINT7 0x0080 /* External intr # 7 */
#define MCFSIM_IMR_SWD 0x0100 /* Software Watchdog intr */
#define MCFSIM_IMR_TIMER1 0x0200 /* TIMER 1 intr */
#define MCFSIM_IMR_TIMER2 0x0400 /* TIMER 2 intr */
#define MCFSIM_IMR_MBUS 0x0800 /* MBUS intr */
#define MCFSIM_IMR_UART1 0x1000 /* UART 1 intr */
#define MCFSIM_IMR_UART2 0x2000 /* UART 2 intr */
#if defined(CONFIG_M5206e)
#define MCFSIM_IMR_DMA1 0x4000 /* DMA 1 intr */
#define MCFSIM_IMR_DMA2 0x8000 /* DMA 2 intr */
#elif defined(CONFIG_M5249) || defined(CONFIG_M5307)
#define MCFSIM_IMR_DMA0 0x4000 /* DMA 0 intr */
#define MCFSIM_IMR_DMA1 0x8000 /* DMA 1 intr */
#define MCFSIM_IMR_DMA2 0x10000 /* DMA 2 intr */
#define MCFSIM_IMR_DMA3 0x20000 /* DMA 3 intr */
#endif
/*
* Mask for all of the SIM devices. Some parts have more or less
* SIM devices. This is a catchall for the sandard set.
*/
#ifndef MCFSIM_IMR_MASKALL
#define MCFSIM_IMR_MASKALL 0x3ffe /* All intr sources */
#endif
/*
* PIT interrupt settings, if not found in mXXXXsim.h file.
*/
#ifndef ICR_INTRCONF
#define ICR_INTRCONF 0x2b /* PIT1 level 5, priority 3 */
#endif
#ifndef MCFPIT_IMR
#define MCFPIT_IMR MCFINTC_IMRH
#endif
#ifndef MCFPIT_IMR_IBIT
#define MCFPIT_IMR_IBIT (1 << (MCFINT_PIT1 - 32))
#endif
#ifndef __ASSEMBLY__
/*
* Definition for the interrupt auto-vectoring support.
*/
extern void mcf_autovector(unsigned int vec);
#endif /* __ASSEMBLY__ */
/****************************************************************************/
#endif /* mcfsim_h */
......@@ -167,15 +167,15 @@ void smc_remap(unsigned int ioaddr)
static int once = 0;
extern unsigned short ppdata;
if (once++ == 0) {
*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADDR)) = 0x00ec;
*((volatile unsigned short *)MCFSIM_PADDR) = 0x00ec;
ppdata |= 0x0080;
*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
*((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 *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
*((volatile unsigned short *)MCFSIM_PADAT) = ppdata;
}
*((volatile unsigned short *)(MCF_MBAR+MCFSIM_CSCR3)) = 0x1180;
......
......@@ -48,14 +48,14 @@ extern volatile unsigned short ppdata;
static __inline__ unsigned int mcf_getppdata(void)
{
volatile unsigned short *pp;
pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
pp = (volatile unsigned short *) MCFSIM_PADAT;
return((unsigned int) *pp);
}
static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits)
{
volatile unsigned short *pp;
pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
pp = (volatile unsigned short *) MCFSIM_PADAT;
ppdata = (ppdata & ~mask) | bits;
*pp = ppdata;
}
......
#ifndef _M68KNOMMU_PAGE_H
#define _M68KNOMMU_PAGE_H
#include <linux/const.h>
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT (12)
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#include <asm/setup.h>
......
/*
* Coldfire generic GPIO pinmux support.
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#ifndef pinmux_h
#define pinmux_h
#define MCFPINMUX_NONE -1
extern int mcf_pinmux_request(unsigned, unsigned);
extern void mcf_pinmux_release(unsigned, unsigned);
static inline int mcf_pinmux_is_valid(unsigned pinmux)
{
return pinmux != MCFPINMUX_NONE;
}
#endif
#ifdef __uClinux__
#include "processor_no.h"
/*
* include/asm-m68k/processor.h
*
* Copyright (C) 1995 Hamish Macdonald
*/
#ifndef __ASM_M68K_PROCESSOR_H
#define __ASM_M68K_PROCESSOR_H
/*
* Default implementation of macro that returns current
* instruction pointer ("program counter").
*/
#define current_text_addr() ({ __label__ _l; _l: &&_l;})
#include <linux/thread_info.h>
#include <asm/segment.h>
#include <asm/fpu.h>
#include <asm/ptrace.h>
static inline unsigned long rdusp(void)
{
#ifdef CONFIG_COLDFIRE
extern unsigned int sw_usp;
return sw_usp;
#else
#include "processor_mm.h"
unsigned long usp;
__asm__ __volatile__("move %/usp,%0" : "=a" (usp));
return usp;
#endif
}
static inline void wrusp(unsigned long usp)
{
#ifdef CONFIG_COLDFIRE
extern unsigned int sw_usp;
sw_usp = usp;
#else
__asm__ __volatile__("move %0,%/usp" : : "a" (usp));
#endif
}
/*
* 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.
*/
#ifndef CONFIG_SUN3
#define TASK_SIZE (0xF0000000UL)
#else
#define TASK_SIZE (0x0E000000UL)
#endif
#ifdef __KERNEL__
#define STACK_TOP TASK_SIZE
#define STACK_TOP_MAX STACK_TOP
#endif
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
*/
#ifdef CONFIG_MMU
#ifndef CONFIG_SUN3
#define TASK_UNMAPPED_BASE 0xC0000000UL
#else
#define TASK_UNMAPPED_BASE 0x0A000000UL
#endif
#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
#else
#define TASK_UNMAPPED_BASE 0
#endif
struct thread_struct {
unsigned long ksp; /* kernel stack pointer */
unsigned long usp; /* user stack pointer */
unsigned short sr; /* saved status register */
unsigned short fs; /* saved fs (sfc, dfc) */
unsigned long crp[2]; /* cpu root pointer */
unsigned long esp0; /* points to SR of stack frame */
unsigned long faddr; /* info about last fault */
int signo, code;
unsigned long fp[8*3];
unsigned long fpcntl[3]; /* fp control regs */
unsigned char fpstate[FPSTATESIZE]; /* floating point state */
struct thread_info info;
};
#define INIT_THREAD { \
.ksp = sizeof(init_stack) + (unsigned long) init_stack, \
.sr = PS_S, \
.fs = __KERNEL_DS, \
.info = INIT_THREAD_INFO(init_task), \
}
#ifdef CONFIG_MMU
/*
* Do necessary setup to start up a newly executed thread.
*/
static inline void start_thread(struct pt_regs * regs, unsigned long pc,
unsigned long usp)
{
/* reads from user space */
set_fs(USER_DS);
regs->pc = pc;
regs->sr &= ~0x2000;
wrusp(usp);
}
#else
/*
* Coldfire stacks need to be re-aligned on trap exit, conventional
* 68k can handle this case cleanly.
*/
#ifdef CONFIG_COLDFIRE
#define reformat(_regs) do { (_regs)->format = 0x4; } while(0)
#else
#define reformat(_regs) do { } while (0)
#endif
#define start_thread(_regs, _pc, _usp) \
do { \
set_fs(USER_DS); /* reads from user space */ \
(_regs)->pc = (_pc); \
((struct switch_stack *)(_regs))[-1].a6 = 0; \
reformat(_regs); \
if (current->mm) \
(_regs)->d5 = current->mm->start_data; \
(_regs)->sr &= ~0x2000; \
wrusp(_usp); \
} while(0)
#endif
/* Forward declaration, a strange C thing */
struct task_struct;
/* Free all resources held by a thread. */
static inline void release_thread(struct task_struct *dead_task)
{
}
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/*
* Free current thread data structures etc..
*/
static inline void exit_thread(void)
{
}
extern unsigned long thread_saved_pc(struct task_struct *tsk);
unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) \
({ \
unsigned long eip = 0; \
if ((tsk)->thread.esp0 > PAGE_SIZE && \
(virt_addr_valid((tsk)->thread.esp0))) \
eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
eip; })
#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp)
#define cpu_relax() barrier()
#endif
/*
* include/asm-m68k/processor.h
*
* Copyright (C) 1995 Hamish Macdonald
*/
#ifndef __ASM_M68K_PROCESSOR_H
#define __ASM_M68K_PROCESSOR_H
/*
* Default implementation of macro that returns current
* instruction pointer ("program counter").
*/
#define current_text_addr() ({ __label__ _l; _l: &&_l;})
#include <linux/thread_info.h>
#include <asm/segment.h>
#include <asm/fpu.h>
#include <asm/ptrace.h>
static inline unsigned long rdusp(void)
{
unsigned long usp;
__asm__ __volatile__("move %/usp,%0" : "=a" (usp));
return usp;
}
static inline void wrusp(unsigned long usp)
{
__asm__ __volatile__("move %0,%/usp" : : "a" (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.
*/
#ifndef CONFIG_SUN3
#define TASK_SIZE (0xF0000000UL)
#else
#define TASK_SIZE (0x0E000000UL)
#endif
#ifdef __KERNEL__
#define STACK_TOP TASK_SIZE
#define STACK_TOP_MAX STACK_TOP
#endif
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
*/
#ifndef CONFIG_SUN3
#define TASK_UNMAPPED_BASE 0xC0000000UL
#else
#define TASK_UNMAPPED_BASE 0x0A000000UL
#endif
#define TASK_UNMAPPED_ALIGN(addr, off) PAGE_ALIGN(addr)
struct thread_struct {
unsigned long ksp; /* kernel stack pointer */
unsigned long usp; /* user stack pointer */
unsigned short sr; /* saved status register */
unsigned short fs; /* saved fs (sfc, dfc) */
unsigned long crp[2]; /* cpu root pointer */
unsigned long esp0; /* points to SR of stack frame */
unsigned long faddr; /* info about last fault */
int signo, code;
unsigned long fp[8*3];
unsigned long fpcntl[3]; /* fp control regs */
unsigned char fpstate[FPSTATESIZE]; /* floating point state */
struct thread_info info;
};
#define INIT_THREAD { \
.ksp = sizeof(init_stack) + (unsigned long) init_stack, \
.sr = PS_S, \
.fs = __KERNEL_DS, \
.info = INIT_THREAD_INFO(init_task), \
}
/*
* Do necessary setup to start up a newly executed thread.
*/
static inline void start_thread(struct pt_regs * regs, unsigned long pc,
unsigned long usp)
{
/* reads from user space */
set_fs(USER_DS);
regs->pc = pc;
regs->sr &= ~0x2000;
wrusp(usp);
}
/* Forward declaration, a strange C thing */
struct task_struct;
/* Free all resources held by a thread. */
static inline void release_thread(struct task_struct *dead_task)
{
}
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/*
* Free current thread data structures etc..
*/
static inline void exit_thread(void)
{
}
extern unsigned long thread_saved_pc(struct task_struct *tsk);
unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) \
({ \
unsigned long eip = 0; \
if ((tsk)->thread.esp0 > PAGE_SIZE && \
(virt_addr_valid((tsk)->thread.esp0))) \
eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
eip; })
#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp)
#define cpu_relax() barrier()
#endif
/*
* include/asm-m68knommu/processor.h
*
* Copyright (C) 1995 Hamish Macdonald
*/
#ifndef __ASM_M68K_PROCESSOR_H
#define __ASM_M68K_PROCESSOR_H
/*
* Default implementation of macro that returns current
* instruction pointer ("program counter").
*/
#define current_text_addr() ({ __label__ _l; _l: &&_l;})
#include <linux/compiler.h>
#include <linux/threads.h>
#include <asm/types.h>
#include <asm/segment.h>
#include <asm/fpu.h>
#include <asm/ptrace.h>
#include <asm/current.h>
static inline unsigned long rdusp(void)
{
#ifdef CONFIG_COLDFIRE
extern unsigned int sw_usp;
return(sw_usp);
#else
unsigned long usp;
__asm__ __volatile__("move %/usp,%0" : "=a" (usp));
return usp;
#endif
}
static inline void wrusp(unsigned long usp)
{
#ifdef CONFIG_COLDFIRE
extern unsigned int sw_usp;
sw_usp = usp;
#else
__asm__ __volatile__("move %0,%/usp" : : "a" (usp));
#endif
}
/*
* 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.
*/
#define TASK_SIZE (0xF0000000UL)
/*
* This decides where the kernel will search for a free chunk of vm
* space during mmap's. We won't be using it
*/
#define TASK_UNMAPPED_BASE 0
/*
* if you change this structure, you must change the code and offsets
* in m68k/machasm.S
*/
struct thread_struct {
unsigned long ksp; /* kernel stack pointer */
unsigned long usp; /* user stack pointer */
unsigned short sr; /* saved status register */
unsigned short fs; /* saved fs (sfc, dfc) */
unsigned long crp[2]; /* cpu root pointer */
unsigned long esp0; /* points to SR of stack frame */
unsigned long fp[8*3];
unsigned long fpcntl[3]; /* fp control regs */
unsigned char fpstate[FPSTATESIZE]; /* floating point state */
};
#define INIT_THREAD { \
.ksp = sizeof(init_stack) + (unsigned long) init_stack, \
.sr = PS_S, \
.fs = __KERNEL_DS, \
}
/*
* Coldfire stacks need to be re-aligned on trap exit, conventional
* 68k can handle this case cleanly.
*/
#if defined(CONFIG_COLDFIRE)
#define reformat(_regs) do { (_regs)->format = 0x4; } while(0)
#else
#define reformat(_regs) do { } while (0)
#endif
/*
* Do necessary setup to start up a newly executed thread.
*
* pass the data segment into user programs if it exists,
* it can't hurt anything as far as I can tell
*/
#define start_thread(_regs, _pc, _usp) \
do { \
set_fs(USER_DS); /* reads from user space */ \
(_regs)->pc = (_pc); \
((struct switch_stack *)(_regs))[-1].a6 = 0; \
reformat(_regs); \
if (current->mm) \
(_regs)->d5 = current->mm->start_data; \
(_regs)->sr &= ~0x2000; \
wrusp(_usp); \
} while(0)
/* Forward declaration, a strange C thing */
struct task_struct;
/* Free all resources held by a thread. */
static inline void release_thread(struct task_struct *dead_task)
{
}
/* Prepare to copy thread state - unlazy all lazy status */
#define prepare_to_copy(tsk) do { } while (0)
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/*
* Free current thread data structures etc..
*/
static inline void exit_thread(void)
{
}
unsigned long thread_saved_pc(struct task_struct *tsk);
unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) \
({ \
unsigned long eip = 0; \
if ((tsk)->thread.esp0 > PAGE_SIZE && \
(virt_addr_valid((tsk)->thread.esp0))) \
eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
eip; })
#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp)
#define cpu_relax() barrier()
#endif
......@@ -3,10 +3,23 @@
*
* m68k architecture timex specifications
*/
#ifndef _ASMm68k_TIMEX_H
#define _ASMm68k_TIMEX_H
#ifndef _ASMm68K_TIMEX_H
#define _ASMm68K_TIMEX_H
#ifdef CONFIG_COLDFIRE
/*
* CLOCK_TICK_RATE should give the underlying frequency of the tick timer
* to make ntp work best. For Coldfires, that's the main clock.
*/
#include <asm/coldfire.h>
#define CLOCK_TICK_RATE MCF_CLK
#else
/*
* This default CLOCK_TICK_RATE is probably wrong for many 68k boards
* Users of those boards will need to check and modify accordingly
*/
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
#endif
typedef unsigned long cycles_t;
......
......@@ -47,6 +47,10 @@ config GENERIC_FIND_NEXT_BIT
bool
default y
config GENERIC_GPIO
bool
default n
config GENERIC_HWEIGHT
bool
default y
......@@ -182,6 +186,8 @@ config M527x
config COLDFIRE
bool
depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407)
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
default y
config CLOCK_SET
......
......@@ -29,32 +29,6 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
set_irq_regs(oldregs);
}
void ack_bad_irq(unsigned int irq)
{
printk(KERN_ERR "IRQ: unexpected irq=%d\n", irq);
}
static struct irq_chip m_irq_chip = {
.name = "M68K-INTC",
.enable = enable_vector,
.disable = disable_vector,
.ack = ack_vector,
};
void __init init_IRQ(void)
{
int irq;
init_vectors();
for (irq = 0; (irq < NR_IRQS); irq++) {
irq_desc[irq].status = IRQ_DISABLED;
irq_desc[irq].action = NULL;
irq_desc[irq].depth = 1;
irq_desc[irq].chip = &m_irq_chip;
}
}
int show_interrupts(struct seq_file *p, void *v)
{
struct irqaction *ap;
......
......@@ -69,7 +69,7 @@ static unsigned long read_rtc_mmss(void)
if ((year += 1900) < 1970)
year += 100;
return mktime(year, mon, day, hour, min, sec);;
return mktime(year, mon, day, hour, min, sec);
}
unsigned long read_persistent_clock(void)
......
......@@ -92,6 +92,7 @@ static unsigned long do_csum(const unsigned char * buff, int len)
return result;
}
#ifdef CONFIG_COLDFIRE
/*
* This is a version of ip_compute_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries.
......@@ -100,6 +101,7 @@ __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
{
return (__force __sum16)~do_csum(iph,ihl*4);
}
#endif
/*
* computes the checksum of a memory block at buff, length len,
......@@ -126,15 +128,6 @@ __wsum csum_partial(const void *buff, int len, __wsum sum)
EXPORT_SYMBOL(csum_partial);
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
__sum16 ip_compute_csum(const void *buff, int len)
{
return (__force __sum16)~do_csum(buff,len);
}
/*
* copy from fs while checksumming, otherwise like csum_partial
*/
......
......@@ -14,5 +14,5 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
obj-y := config.o
obj-y := config.o gpio.o
......@@ -49,11 +49,11 @@ static void __init m5206_uart_init_line(int line, int irq)
if (line == 0) {
writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
mcf_mapirq2imr(irq, MCFINTC_UART0);
} else if (line == 1) {
writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
mcf_mapirq2imr(irq, MCFINTC_UART1);
}
}
......@@ -68,38 +68,19 @@ static void __init m5206_uarts_init(void)
/***************************************************************************/
void mcf_autovector(unsigned int vec)
static void __init m5206_timers_init(void)
{
volatile unsigned char *mbar;
unsigned char icr;
if ((vec >= 25) && (vec <= 31)) {
vec -= 25;
mbar = (volatile unsigned char *) MCF_MBAR;
icr = MCFSIM_ICR_AUTOVEC | (vec << 3);
*(mbar + MCFSIM_ICR1 + vec) = icr;
vec = 0x1 << (vec + 1);
mcf_setimr(mcf_getimr() & ~vec);
}
}
/***************************************************************************/
void mcf_settimericr(unsigned int timer, unsigned int level)
{
volatile unsigned char *icrp;
unsigned int icr, imr;
if (timer <= 2) {
switch (timer) {
case 2: icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
}
icrp = (volatile unsigned char *) (MCF_MBAR + icr);
*icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
mcf_setimr(mcf_getimr() & ~imr);
}
/* Timer1 is always used as system timer */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
MCF_MBAR + MCFSIM_TIMER1ICR);
mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
#ifdef CONFIG_HIGHPROFILE
/* Timer2 is to be used as a high speed profile timer */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
MCF_MBAR + MCFSIM_TIMER2ICR);
mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
#endif
}
/***************************************************************************/
......@@ -117,15 +98,20 @@ void m5206_cpu_reset(void)
void __init config_BSP(char *commandp, int size)
{
mcf_setimr(MCFSIM_IMR_MASKALL);
mach_reset = m5206_cpu_reset;
m5206_timers_init();
m5206_uarts_init();
/* Only support the external interrupts on their primary level */
mcf_mapirq2imr(25, MCFINTC_EINT1);
mcf_mapirq2imr(28, MCFINTC_EINT4);
mcf_mapirq2imr(31, MCFINTC_EINT7);
}
/***************************************************************************/
static int __init init_BSP(void)
{
m5206_uarts_init();
platform_add_devices(m5206_devices, ARRAY_SIZE(m5206_devices));
return 0;
}
......
/*
* Coldfire generic GPIO support
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfgpio.h>
static struct mcf_gpio_chip mcf_gpio_chips[] = {
{
.gpio_chip = {
.label = "PP",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.ngpio = 8,
},
.pddr = MCFSIM_PADDR,
.podr = MCFSIM_PADAT,
.ppdr = MCFSIM_PADAT,
},
};
static int __init mcf_gpio_init(void)
{
unsigned i = 0;
while (i < ARRAY_SIZE(mcf_gpio_chips))
(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
return 0;
}
core_initcall(mcf_gpio_init);
......@@ -14,5 +14,5 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
obj-y := config.o
obj-y := config.o gpio.o
......@@ -15,6 +15,7 @@
#include <asm/machdep.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
#include <asm/mcfdma.h>
#include <asm/mcfuart.h>
......@@ -49,11 +50,11 @@ static void __init m5206e_uart_init_line(int line, int irq)
if (line == 0) {
writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
mcf_mapirq2imr(irq, MCFINTC_UART0);
} else if (line == 1) {
writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
mcf_mapirq2imr(irq, MCFINTC_UART1);
}
}
......@@ -68,38 +69,19 @@ static void __init m5206e_uarts_init(void)
/***************************************************************************/
void mcf_autovector(unsigned int vec)
{
volatile unsigned char *mbar;
unsigned char icr;
if ((vec >= 25) && (vec <= 31)) {
vec -= 25;
mbar = (volatile unsigned char *) MCF_MBAR;
icr = MCFSIM_ICR_AUTOVEC | (vec << 3);
*(mbar + MCFSIM_ICR1 + vec) = icr;
vec = 0x1 << (vec + 1);
mcf_setimr(mcf_getimr() & ~vec);
}
}
/***************************************************************************/
void mcf_settimericr(unsigned int timer, unsigned int level)
static void __init m5206e_timers_init(void)
{
volatile unsigned char *icrp;
unsigned int icr, imr;
if (timer <= 2) {
switch (timer) {
case 2: icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
}
icrp = (volatile unsigned char *) (MCF_MBAR + icr);
*icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
mcf_setimr(mcf_getimr() & ~imr);
}
/* Timer1 is always used as system timer */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
MCF_MBAR + MCFSIM_TIMER1ICR);
mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
#ifdef CONFIG_HIGHPROFILE
/* Timer2 is to be used as a high speed profile timer */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
MCF_MBAR + MCFSIM_TIMER2ICR);
mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
#endif
}
/***************************************************************************/
......@@ -117,8 +99,6 @@ void m5206e_cpu_reset(void)
void __init config_BSP(char *commandp, int size)
{
mcf_setimr(MCFSIM_IMR_MASKALL);
#if defined(CONFIG_NETtel)
/* Copy command line from FLASH to local buffer... */
memcpy(commandp, (char *) 0xf0004000, size);
......@@ -126,13 +106,19 @@ void __init config_BSP(char *commandp, int size)
#endif /* CONFIG_NETtel */
mach_reset = m5206e_cpu_reset;
m5206e_timers_init();
m5206e_uarts_init();
/* Only support the external interrupts on their primary level */
mcf_mapirq2imr(25, MCFINTC_EINT1);
mcf_mapirq2imr(28, MCFINTC_EINT4);
mcf_mapirq2imr(31, MCFINTC_EINT7);
}
/***************************************************************************/
static int __init init_BSP(void)
{
m5206e_uarts_init();
platform_add_devices(m5206e_devices, ARRAY_SIZE(m5206e_devices));
return 0;
}
......
/*
* Coldfire generic GPIO support
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfgpio.h>
static struct mcf_gpio_chip mcf_gpio_chips[] = {
{
.gpio_chip = {
.label = "PP",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.ngpio = 8,
},
.pddr = MCFSIM_PADDR,
.podr = MCFSIM_PADAT,
.ppdr = MCFSIM_PADAT,
},
};
static int __init mcf_gpio_init(void)
{
unsigned i = 0;
while (i < ARRAY_SIZE(mcf_gpio_chips))
(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
return 0;
}
core_initcall(mcf_gpio_init);
......@@ -14,4 +14,4 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
obj-y := config.o
obj-y := config.o gpio.o
......@@ -81,20 +81,11 @@ static struct platform_device *m520x_devices[] __initdata = {
/***************************************************************************/
#define INTC0 (MCF_MBAR + MCFICM_INTC0)
static void __init m520x_uart_init_line(int line, int irq)
{
u32 imr;
u16 par;
u8 par2;
writeb(0x03, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
imr = readl(INTC0 + MCFINTC_IMRL);
imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
writel(imr, INTC0 + MCFINTC_IMRL);
switch (line) {
case 0:
par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
......@@ -131,18 +122,8 @@ static void __init m520x_uarts_init(void)
static void __init m520x_fec_init(void)
{
u32 imr;
u8 v;
/* Unmask FEC interrupts at ColdFire interrupt controller */
writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 36);
writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 40);
writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 42);
imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
imr &= ~0x0001FFF0;
writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
/* Set multi-function pins to ethernet mode */
v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FEC);
writeb(v | 0xf0, MCF_IPSBAR + MCF_GPIO_PAR_FEC);
......@@ -153,17 +134,6 @@ static void __init m520x_fec_init(void)
/***************************************************************************/
/*
* Program the vector to be an auto-vectored.
*/
void mcf_autovector(unsigned int vec)
{
/* Everything is auto-vectored on the 520x devices */
}
/***************************************************************************/
static void m520x_cpu_reset(void)
{
local_irq_disable();
......
/*
* Coldfire generic GPIO support
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfgpio.h>
static struct mcf_gpio_chip mcf_gpio_chips[] = {
{
.gpio_chip = {
.label = "PIRQ",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.ngpio = 8,
},
.pddr = MCFEPORT_EPDDR,
.podr = MCFEPORT_EPDR,
.ppdr = MCFEPORT_EPPDR,
},
{
.gpio_chip = {
.label = "BUSCTL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 8,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_BUSCTL,
.podr = MCFGPIO_PODR_BUSCTL,
.ppdr = MCFGPIO_PPDSDR_BUSCTL,
.setr = MCFGPIO_PPDSDR_BUSCTL,
.clrr = MCFGPIO_PCLRR_BUSCTL,
},
{
.gpio_chip = {
.label = "BE",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 16,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_BE,
.podr = MCFGPIO_PODR_BE,
.ppdr = MCFGPIO_PPDSDR_BE,
.setr = MCFGPIO_PPDSDR_BE,
.clrr = MCFGPIO_PCLRR_BE,
},
{
.gpio_chip = {
.label = "CS",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 25,
.ngpio = 3,
},
.pddr = MCFGPIO_PDDR_CS,
.podr = MCFGPIO_PODR_CS,
.ppdr = MCFGPIO_PPDSDR_CS,
.setr = MCFGPIO_PPDSDR_CS,
.clrr = MCFGPIO_PCLRR_CS,
},
{
.gpio_chip = {
.label = "FECI2C",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 32,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_FECI2C,
.podr = MCFGPIO_PODR_FECI2C,
.ppdr = MCFGPIO_PPDSDR_FECI2C,
.setr = MCFGPIO_PPDSDR_FECI2C,
.clrr = MCFGPIO_PCLRR_FECI2C,
},
{
.gpio_chip = {
.label = "QSPI",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 40,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_QSPI,
.podr = MCFGPIO_PODR_QSPI,
.ppdr = MCFGPIO_PPDSDR_QSPI,
.setr = MCFGPIO_PPDSDR_QSPI,
.clrr = MCFGPIO_PCLRR_QSPI,
},
{
.gpio_chip = {
.label = "TIMER",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 48,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_TIMER,
.podr = MCFGPIO_PODR_TIMER,
.ppdr = MCFGPIO_PPDSDR_TIMER,
.setr = MCFGPIO_PPDSDR_TIMER,
.clrr = MCFGPIO_PCLRR_TIMER,
},
{
.gpio_chip = {
.label = "UART",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 56,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_UART,
.podr = MCFGPIO_PODR_UART,
.ppdr = MCFGPIO_PPDSDR_UART,
.setr = MCFGPIO_PPDSDR_UART,
.clrr = MCFGPIO_PCLRR_UART,
},
{
.gpio_chip = {
.label = "FECH",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 64,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_FECH,
.podr = MCFGPIO_PODR_FECH,
.ppdr = MCFGPIO_PPDSDR_FECH,
.setr = MCFGPIO_PPDSDR_FECH,
.clrr = MCFGPIO_PCLRR_FECH,
},
{
.gpio_chip = {
.label = "FECL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 72,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_FECL,
.podr = MCFGPIO_PODR_FECL,
.ppdr = MCFGPIO_PPDSDR_FECL,
.setr = MCFGPIO_PPDSDR_FECL,
.clrr = MCFGPIO_PCLRR_FECL,
},
};
static int __init mcf_gpio_init(void)
{
unsigned i = 0;
while (i < ARRAY_SIZE(mcf_gpio_chips))
(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
return 0;
}
core_initcall(mcf_gpio_init);
......@@ -14,4 +14,4 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
obj-y := config.o
obj-y := config.o gpio.o
......@@ -82,66 +82,20 @@ static struct platform_device *m523x_devices[] __initdata = {
/***************************************************************************/
#define INTC0 (MCF_MBAR + MCFICM_INTC0)
static void __init m523x_uart_init_line(int line, int irq)
{
u32 imr;
if ((line < 0) || (line > 2))
return;
writeb(0x30+line, (INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line));
imr = readl(INTC0 + MCFINTC_IMRL);
imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
writel(imr, INTC0 + MCFINTC_IMRL);
}
static void __init m523x_uarts_init(void)
{
const int nrlines = ARRAY_SIZE(m523x_uart_platform);
int line;
for (line = 0; (line < nrlines); line++)
m523x_uart_init_line(line, m523x_uart_platform[line].irq);
}
/***************************************************************************/
static void __init m523x_fec_init(void)
{
u32 imr;
/* Unmask FEC interrupts at ColdFire interrupt controller */
writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
imr &= ~0xf;
writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
imr &= ~0xff800001;
writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
}
/***************************************************************************/
void mcf_disableall(void)
{
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
u16 par;
u8 v;
/* Set multi-function pins to ethernet use */
par = readw(MCF_IPSBAR + 0x100082);
writew(par | 0xf00, MCF_IPSBAR + 0x100082);
v = readb(MCF_IPSBAR + 0x100078);
writeb(v | 0xc0, MCF_IPSBAR + 0x100078);
}
/***************************************************************************/
void mcf_autovector(unsigned int vec)
{
/* Everything is auto-vectored on the 523x */
}
/***************************************************************************/
static void m523x_cpu_reset(void)
{
local_irq_disable();
......@@ -152,16 +106,14 @@ static void m523x_cpu_reset(void)
void __init config_BSP(char *commandp, int size)
{
mcf_disableall();
mach_reset = m523x_cpu_reset;
m523x_uarts_init();
m523x_fec_init();
}
/***************************************************************************/
static int __init init_BSP(void)
{
m523x_fec_init();
platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices));
return 0;
}
......
/*
* Coldfire generic GPIO support
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfgpio.h>
static struct mcf_gpio_chip mcf_gpio_chips[] = {
{
.gpio_chip = {
.label = "PIRQ",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.ngpio = 8,
},
.pddr = MCFEPORT_EPDDR,
.podr = MCFEPORT_EPDR,
.ppdr = MCFEPORT_EPPDR,
},
{
.gpio_chip = {
.label = "ADDR",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 13,
.ngpio = 3,
},
.pddr = MCFGPIO_PDDR_ADDR,
.podr = MCFGPIO_PODR_ADDR,
.ppdr = MCFGPIO_PPDSDR_ADDR,
.setr = MCFGPIO_PPDSDR_ADDR,
.clrr = MCFGPIO_PCLRR_ADDR,
},
{
.gpio_chip = {
.label = "DATAH",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 16,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_DATAH,
.podr = MCFGPIO_PODR_DATAH,
.ppdr = MCFGPIO_PPDSDR_DATAH,
.setr = MCFGPIO_PPDSDR_DATAH,
.clrr = MCFGPIO_PCLRR_DATAH,
},
{
.gpio_chip = {
.label = "DATAL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 24,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_DATAL,
.podr = MCFGPIO_PODR_DATAL,
.ppdr = MCFGPIO_PPDSDR_DATAL,
.setr = MCFGPIO_PPDSDR_DATAL,
.clrr = MCFGPIO_PCLRR_DATAL,
},
{
.gpio_chip = {
.label = "BUSCTL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 32,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_BUSCTL,
.podr = MCFGPIO_PODR_BUSCTL,
.ppdr = MCFGPIO_PPDSDR_BUSCTL,
.setr = MCFGPIO_PPDSDR_BUSCTL,
.clrr = MCFGPIO_PCLRR_BUSCTL,
},
{
.gpio_chip = {
.label = "BS",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 40,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_BS,
.podr = MCFGPIO_PODR_BS,
.ppdr = MCFGPIO_PPDSDR_BS,
.setr = MCFGPIO_PPDSDR_BS,
.clrr = MCFGPIO_PCLRR_BS,
},
{
.gpio_chip = {
.label = "CS",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 49,
.ngpio = 7,
},
.pddr = MCFGPIO_PDDR_CS,
.podr = MCFGPIO_PODR_CS,
.ppdr = MCFGPIO_PPDSDR_CS,
.setr = MCFGPIO_PPDSDR_CS,
.clrr = MCFGPIO_PCLRR_CS,
},
{
.gpio_chip = {
.label = "SDRAM",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 56,
.ngpio = 6,
},
.pddr = MCFGPIO_PDDR_SDRAM,
.podr = MCFGPIO_PODR_SDRAM,
.ppdr = MCFGPIO_PPDSDR_SDRAM,
.setr = MCFGPIO_PPDSDR_SDRAM,
.clrr = MCFGPIO_PCLRR_SDRAM,
},
{
.gpio_chip = {
.label = "FECI2C",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 64,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_FECI2C,
.podr = MCFGPIO_PODR_FECI2C,
.ppdr = MCFGPIO_PPDSDR_FECI2C,
.setr = MCFGPIO_PPDSDR_FECI2C,
.clrr = MCFGPIO_PCLRR_FECI2C,
},
{
.gpio_chip = {
.label = "UARTH",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 72,
.ngpio = 2,
},
.pddr = MCFGPIO_PDDR_UARTH,
.podr = MCFGPIO_PODR_UARTH,
.ppdr = MCFGPIO_PPDSDR_UARTH,
.setr = MCFGPIO_PPDSDR_UARTH,
.clrr = MCFGPIO_PCLRR_UARTH,
},
{
.gpio_chip = {
.label = "UARTL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 80,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_UARTL,
.podr = MCFGPIO_PODR_UARTL,
.ppdr = MCFGPIO_PPDSDR_UARTL,
.setr = MCFGPIO_PPDSDR_UARTL,
.clrr = MCFGPIO_PCLRR_UARTL,
},
{
.gpio_chip = {
.label = "QSPI",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 88,
.ngpio = 5,
},
.pddr = MCFGPIO_PDDR_QSPI,
.podr = MCFGPIO_PODR_QSPI,
.ppdr = MCFGPIO_PPDSDR_QSPI,
.setr = MCFGPIO_PPDSDR_QSPI,
.clrr = MCFGPIO_PCLRR_QSPI,
},
{
.gpio_chip = {
.label = "TIMER",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 96,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_TIMER,
.podr = MCFGPIO_PODR_TIMER,
.ppdr = MCFGPIO_PPDSDR_TIMER,
.setr = MCFGPIO_PPDSDR_TIMER,
.clrr = MCFGPIO_PCLRR_TIMER,
},
{
.gpio_chip = {
.label = "ETPU",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 104,
.ngpio = 3,
},
.pddr = MCFGPIO_PDDR_ETPU,
.podr = MCFGPIO_PODR_ETPU,
.ppdr = MCFGPIO_PPDSDR_ETPU,
.setr = MCFGPIO_PPDSDR_ETPU,
.clrr = MCFGPIO_PCLRR_ETPU,
},
};
static int __init mcf_gpio_init(void)
{
unsigned i = 0;
while (i < ARRAY_SIZE(mcf_gpio_chips))
(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
return 0;
}
core_initcall(mcf_gpio_init);
......@@ -14,5 +14,5 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
obj-y := config.o
obj-y := config.o gpio.o intc2.o
......@@ -48,11 +48,11 @@ static void __init m5249_uart_init_line(int line, int irq)
if (line == 0) {
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
mcf_mapirq2imr(irq, MCFINTC_UART0);
} else if (line == 1) {
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
mcf_mapirq2imr(irq, MCFINTC_UART1);
}
}
......@@ -65,38 +65,21 @@ static void __init m5249_uarts_init(void)
m5249_uart_init_line(line, m5249_uart_platform[line].irq);
}
/***************************************************************************/
void mcf_autovector(unsigned int vec)
static void __init m5249_timers_init(void)
{
volatile unsigned char *mbar;
if ((vec >= 25) && (vec <= 31)) {
mbar = (volatile unsigned char *) MCF_MBAR;
vec = 0x1 << (vec - 24);
*(mbar + MCFSIM_AVR) |= vec;
mcf_setimr(mcf_getimr() & ~vec);
}
}
/***************************************************************************/
void mcf_settimericr(unsigned int timer, unsigned int level)
{
volatile unsigned char *icrp;
unsigned int icr, imr;
if (timer <= 2) {
switch (timer) {
case 2: icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
}
icrp = (volatile unsigned char *) (MCF_MBAR + icr);
*icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
mcf_setimr(mcf_getimr() & ~imr);
}
/* Timer1 is always used as system timer */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
MCF_MBAR + MCFSIM_TIMER1ICR);
mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
#ifdef CONFIG_HIGHPROFILE
/* Timer2 is to be used as a high speed profile timer */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
MCF_MBAR + MCFSIM_TIMER2ICR);
mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
#endif
}
/***************************************************************************/
......@@ -114,15 +97,15 @@ void m5249_cpu_reset(void)
void __init config_BSP(char *commandp, int size)
{
mcf_setimr(MCFSIM_IMR_MASKALL);
mach_reset = m5249_cpu_reset;
m5249_timers_init();
m5249_uarts_init();
}
/***************************************************************************/
static int __init init_BSP(void)
{
m5249_uarts_init();
platform_add_devices(m5249_devices, ARRAY_SIZE(m5249_devices));
return 0;
}
......
/*
* Coldfire generic GPIO support
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfgpio.h>
static struct mcf_gpio_chip mcf_gpio_chips[] = {
{
.gpio_chip = {
.label = "GPIO0",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.ngpio = 32,
},
.pddr = MCFSIM2_GPIOENABLE,
.podr = MCFSIM2_GPIOWRITE,
.ppdr = MCFSIM2_GPIOREAD,
},
{
.gpio_chip = {
.label = "GPIO1",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.base = 32,
.ngpio = 32,
},
.pddr = MCFSIM2_GPIO1ENABLE,
.podr = MCFSIM2_GPIO1WRITE,
.ppdr = MCFSIM2_GPIO1READ,
},
};
static int __init mcf_gpio_init(void)
{
unsigned i = 0;
while (i < ARRAY_SIZE(mcf_gpio_chips))
(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
return 0;
}
core_initcall(mcf_gpio_init);
/*
* intc2.c -- support for the 2nd INTC controller of the 5249
*
* (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
static void intc2_irq_gpio_mask(unsigned int irq)
{
u32 imr;
imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
imr &= ~(0x1 << (irq - MCFINTC2_GPIOIRQ0));
writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
}
static void intc2_irq_gpio_unmask(unsigned int irq)
{
u32 imr;
imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
imr |= (0x1 << (irq - MCFINTC2_GPIOIRQ0));
writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
}
static void intc2_irq_gpio_ack(unsigned int irq)
{
writel(0x1 << (irq - MCFINTC2_GPIOIRQ0), MCF_MBAR2 + MCFSIM2_GPIOINTCLEAR);
}
static struct irq_chip intc2_irq_gpio_chip = {
.name = "CF-INTC2",
.mask = intc2_irq_gpio_mask,
.unmask = intc2_irq_gpio_unmask,
.ack = intc2_irq_gpio_ack,
};
static int __init mcf_intc2_init(void)
{
int irq;
/* GPIO interrupt sources */
for (irq = MCFINTC2_GPIOIRQ0; (irq <= MCFINTC2_GPIOIRQ7); irq++)
irq_desc[irq].chip = &intc2_irq_gpio_chip;
return 0;
}
arch_initcall(mcf_intc2_init);
......@@ -14,5 +14,5 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
obj-y := config.o
obj-y := config.o gpio.o intc.o
......@@ -20,12 +20,6 @@
/***************************************************************************/
extern unsigned int mcf_timervector;
extern unsigned int mcf_profilevector;
extern unsigned int mcf_timerlevel;
/***************************************************************************/
/*
* Some platforms need software versions of the GPIO data registers.
*/
......@@ -37,11 +31,11 @@ unsigned char ledbank = 0xff;
static struct mcf_platform_uart m5272_uart_platform[] = {
{
.mapbase = MCF_MBAR + MCFUART_BASE1,
.irq = 73,
.irq = MCF_IRQ_UART1,
},
{
.mapbase = MCF_MBAR + MCFUART_BASE2,
.irq = 74,
.irq = MCF_IRQ_UART2,
},
{ },
};
......@@ -59,18 +53,18 @@ static struct resource m5272_fec_resources[] = {
.flags = IORESOURCE_MEM,
},
{
.start = 86,
.end = 86,
.start = MCF_IRQ_ERX,
.end = MCF_IRQ_ERX,
.flags = IORESOURCE_IRQ,
},
{
.start = 87,
.end = 87,
.start = MCF_IRQ_ETX,
.end = MCF_IRQ_ETX,
.flags = IORESOURCE_IRQ,
},
{
.start = 88,
.end = 88,
.start = MCF_IRQ_ENTC,
.end = MCF_IRQ_ENTC,
.flags = IORESOURCE_IRQ,
},
};
......@@ -94,9 +88,6 @@ static void __init m5272_uart_init_line(int line, int irq)
u32 v;
if ((line >= 0) && (line < 2)) {
v = (line) ? 0x0e000000 : 0xe0000000;
writel(v, MCF_MBAR + MCFSIM_ICR2);
/* Enable the output lines for the serial ports */
v = readl(MCF_MBAR + MCFSIM_PBCNT);
v = (v & ~0x000000ff) | 0x00000055;
......@@ -119,54 +110,6 @@ static void __init m5272_uarts_init(void)
/***************************************************************************/
static void __init m5272_fec_init(void)
{
u32 imr;
/* Unmask FEC interrupts at ColdFire interrupt controller */
imr = readl(MCF_MBAR + MCFSIM_ICR3);
imr = (imr & ~0x00000fff) | 0x00000ddd;
writel(imr, MCF_MBAR + MCFSIM_ICR3);
imr = readl(MCF_MBAR + MCFSIM_ICR1);
imr = (imr & ~0x0f000000) | 0x0d000000;
writel(imr, MCF_MBAR + MCFSIM_ICR1);
}
/***************************************************************************/
void mcf_disableall(void)
{
volatile unsigned long *icrp;
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
icrp[0] = 0x88888888;
icrp[1] = 0x88888888;
icrp[2] = 0x88888888;
icrp[3] = 0x88888888;
}
/***************************************************************************/
void mcf_autovector(unsigned int vec)
{
/* Everything is auto-vectored on the 5272 */
}
/***************************************************************************/
void mcf_settimericr(int timer, int level)
{
volatile unsigned long *icrp;
if ((timer >= 1 ) && (timer <= 4)) {
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
*icrp = (0x8 | level) << ((4 - timer) * 4);
}
}
/***************************************************************************/
static void m5272_cpu_reset(void)
{
local_irq_disable();
......@@ -190,8 +133,6 @@ void __init config_BSP(char *commandp, int size)
*pivrp = 0x40;
#endif
mcf_disableall();
#if defined(CONFIG_NETtel) || defined(CONFIG_SCALES)
/* Copy command line from FLASH to local buffer... */
memcpy(commandp, (char *) 0xf0004000, size);
......@@ -202,8 +143,6 @@ void __init config_BSP(char *commandp, int size)
commandp[size-1] = 0;
#endif
mcf_timervector = 69;
mcf_profilevector = 70;
mach_reset = m5272_cpu_reset;
}
......@@ -212,7 +151,6 @@ void __init config_BSP(char *commandp, int size)
static int __init init_BSP(void)
{
m5272_uarts_init();
m5272_fec_init();
platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices));
return 0;
}
......
/*
* Coldfire generic GPIO support
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfgpio.h>
static struct mcf_gpio_chip mcf_gpio_chips[] = {
{
.gpio_chip = {
.label = "PA",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.ngpio = 16,
},
.pddr = MCFSIM_PADDR,
.podr = MCFSIM_PADAT,
.ppdr = MCFSIM_PADAT,
},
{
.gpio_chip = {
.label = "PB",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.base = 16,
.ngpio = 16,
},
.pddr = MCFSIM_PBDDR,
.podr = MCFSIM_PBDAT,
.ppdr = MCFSIM_PBDAT,
},
{
.gpio_chip = {
.label = "PC",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.base = 32,
.ngpio = 16,
},
.pddr = MCFSIM_PCDDR,
.podr = MCFSIM_PCDAT,
.ppdr = MCFSIM_PCDAT,
},
};
static int __init mcf_gpio_init(void)
{
unsigned i = 0;
while (i < ARRAY_SIZE(mcf_gpio_chips))
(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
return 0;
}
core_initcall(mcf_gpio_init);
/*
* intc.c -- interrupt controller or ColdFire 5272 SoC
*
* (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/traps.h>
/*
* The 5272 ColdFire interrupt controller is nothing like any other
* ColdFire interrupt controller - it truly is completely different.
* Given its age it is unlikely to be used on any other ColdFire CPU.
*/
/*
* The masking and priproty setting of interrupts on the 5272 is done
* via a set of 4 "Interrupt Controller Registers" (ICR). There is a
* loose mapping of vector number to register and internal bits, but
* a table is the easiest and quickest way to map them.
*/
struct irqmap {
unsigned char icr;
unsigned char index;
unsigned char ack;
};
static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = {
/*MCF_IRQ_SPURIOUS*/ { .icr = 0, .index = 0, .ack = 0, },
/*MCF_IRQ_EINT1*/ { .icr = MCFSIM_ICR1, .index = 28, .ack = 1, },
/*MCF_IRQ_EINT2*/ { .icr = MCFSIM_ICR1, .index = 24, .ack = 1, },
/*MCF_IRQ_EINT3*/ { .icr = MCFSIM_ICR1, .index = 20, .ack = 1, },
/*MCF_IRQ_EINT4*/ { .icr = MCFSIM_ICR1, .index = 16, .ack = 1, },
/*MCF_IRQ_TIMER1*/ { .icr = MCFSIM_ICR1, .index = 12, .ack = 0, },
/*MCF_IRQ_TIMER2*/ { .icr = MCFSIM_ICR1, .index = 8, .ack = 0, },
/*MCF_IRQ_TIMER3*/ { .icr = MCFSIM_ICR1, .index = 4, .ack = 0, },
/*MCF_IRQ_TIMER4*/ { .icr = MCFSIM_ICR1, .index = 0, .ack = 0, },
/*MCF_IRQ_UART1*/ { .icr = MCFSIM_ICR2, .index = 28, .ack = 0, },
/*MCF_IRQ_UART2*/ { .icr = MCFSIM_ICR2, .index = 24, .ack = 0, },
/*MCF_IRQ_PLIP*/ { .icr = MCFSIM_ICR2, .index = 20, .ack = 0, },
/*MCF_IRQ_PLIA*/ { .icr = MCFSIM_ICR2, .index = 16, .ack = 0, },
/*MCF_IRQ_USB0*/ { .icr = MCFSIM_ICR2, .index = 12, .ack = 0, },
/*MCF_IRQ_USB1*/ { .icr = MCFSIM_ICR2, .index = 8, .ack = 0, },
/*MCF_IRQ_USB2*/ { .icr = MCFSIM_ICR2, .index = 4, .ack = 0, },
/*MCF_IRQ_USB3*/ { .icr = MCFSIM_ICR2, .index = 0, .ack = 0, },
/*MCF_IRQ_USB4*/ { .icr = MCFSIM_ICR3, .index = 28, .ack = 0, },
/*MCF_IRQ_USB5*/ { .icr = MCFSIM_ICR3, .index = 24, .ack = 0, },
/*MCF_IRQ_USB6*/ { .icr = MCFSIM_ICR3, .index = 20, .ack = 0, },
/*MCF_IRQ_USB7*/ { .icr = MCFSIM_ICR3, .index = 16, .ack = 0, },
/*MCF_IRQ_DMA*/ { .icr = MCFSIM_ICR3, .index = 12, .ack = 0, },
/*MCF_IRQ_ERX*/ { .icr = MCFSIM_ICR3, .index = 8, .ack = 0, },
/*MCF_IRQ_ETX*/ { .icr = MCFSIM_ICR3, .index = 4, .ack = 0, },
/*MCF_IRQ_ENTC*/ { .icr = MCFSIM_ICR3, .index = 0, .ack = 0, },
/*MCF_IRQ_QSPI*/ { .icr = MCFSIM_ICR4, .index = 28, .ack = 0, },
/*MCF_IRQ_EINT5*/ { .icr = MCFSIM_ICR4, .index = 24, .ack = 1, },
/*MCF_IRQ_EINT6*/ { .icr = MCFSIM_ICR4, .index = 20, .ack = 1, },
/*MCF_IRQ_SWTO*/ { .icr = MCFSIM_ICR4, .index = 16, .ack = 0, },
};
static void intc_irq_mask(unsigned int irq)
{
if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
u32 v;
irq -= MCFINT_VECBASE;
v = 0x8 << intc_irqmap[irq].index;
writel(v, MCF_MBAR + intc_irqmap[irq].icr);
}
}
static void intc_irq_unmask(unsigned int irq)
{
if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
u32 v;
irq -= MCFINT_VECBASE;
v = 0xd << intc_irqmap[irq].index;
writel(v, MCF_MBAR + intc_irqmap[irq].icr);
}
}
static void intc_irq_ack(unsigned int irq)
{
/* Only external interrupts are acked */
if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
irq -= MCFINT_VECBASE;
if (intc_irqmap[irq].ack) {
u32 v;
v = 0xd << intc_irqmap[irq].index;
writel(v, MCF_MBAR + intc_irqmap[irq].icr);
}
}
}
static int intc_irq_set_type(unsigned int irq, unsigned int type)
{
/* We can set the edge type here for external interrupts */
return 0;
}
static struct irq_chip intc_irq_chip = {
.name = "CF-INTC",
.mask = intc_irq_mask,
.unmask = intc_irq_unmask,
.ack = intc_irq_ack,
.set_type = intc_irq_set_type,
};
void __init init_IRQ(void)
{
int irq;
init_vectors();
/* Mask all interrupt sources */
writel(0x88888888, MCF_MBAR + MCFSIM_ICR1);
writel(0x88888888, MCF_MBAR + MCFSIM_ICR2);
writel(0x88888888, MCF_MBAR + MCFSIM_ICR3);
writel(0x88888888, MCF_MBAR + MCFSIM_ICR4);
for (irq = 0; (irq < NR_IRQS); irq++) {
irq_desc[irq].status = IRQ_DISABLED;
irq_desc[irq].action = NULL;
irq_desc[irq].depth = 1;
irq_desc[irq].chip = &intc_irq_chip;
intc_irq_set_type(irq, 0);
}
}
......@@ -14,5 +14,5 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
obj-y := config.o
obj-y := config.o gpio.o
......@@ -116,23 +116,13 @@ static struct platform_device *m527x_devices[] __initdata = {
/***************************************************************************/
#define INTC0 (MCF_MBAR + MCFICM_INTC0)
static void __init m527x_uart_init_line(int line, int irq)
{
u16 sepmask;
u32 imr;
if ((line < 0) || (line > 2))
return;
/* level 6, line based priority */
writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
imr = readl(INTC0 + MCFINTC_IMRL);
imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
writel(imr, INTC0 + MCFINTC_IMRL);
/*
* External Pin Mask Setting & Enable External Pin for Interface
*/
......@@ -157,32 +147,11 @@ static void __init m527x_uarts_init(void)
/***************************************************************************/
static void __init m527x_fec_irq_init(int nr)
{
unsigned long base;
u32 imr;
base = MCF_IPSBAR + (nr ? MCFICM_INTC1 : MCFICM_INTC0);
writeb(0x28, base + MCFINTC_ICR0 + 23);
writeb(0x27, base + MCFINTC_ICR0 + 27);
writeb(0x26, base + MCFINTC_ICR0 + 29);
imr = readl(base + MCFINTC_IMRH);
imr &= ~0xf;
writel(imr, base + MCFINTC_IMRH);
imr = readl(base + MCFINTC_IMRL);
imr &= ~0xff800001;
writel(imr, base + MCFINTC_IMRL);
}
static void __init m527x_fec_init(void)
{
u16 par;
u8 v;
m527x_fec_irq_init(0);
/* Set multi-function pins to ethernet mode for fec0 */
#if defined(CONFIG_M5271)
v = readb(MCF_IPSBAR + 0x100047);
......@@ -195,8 +164,6 @@ static void __init m527x_fec_init(void)
#endif
#ifdef CONFIG_FEC2
m527x_fec_irq_init(1);
/* Set multi-function pins to ethernet mode for fec1 */
par = readw(MCF_IPSBAR + 0x100082);
writew(par | 0xa0, MCF_IPSBAR + 0x100082);
......@@ -207,21 +174,6 @@ static void __init m527x_fec_init(void)
/***************************************************************************/
void mcf_disableall(void)
{
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
}
/***************************************************************************/
void mcf_autovector(unsigned int vec)
{
/* Everything is auto-vectored on the 5272 */
}
/***************************************************************************/
static void m527x_cpu_reset(void)
{
local_irq_disable();
......@@ -232,7 +184,6 @@ static void m527x_cpu_reset(void)
void __init config_BSP(char *commandp, int size)
{
mcf_disableall();
mach_reset = m527x_cpu_reset;
m527x_uarts_init();
m527x_fec_init();
......
/*
* Coldfire generic GPIO support
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfgpio.h>
static struct mcf_gpio_chip mcf_gpio_chips[] = {
#if defined(CONFIG_M5271)
{
.gpio_chip = {
.label = "PIRQ",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.ngpio = 8,
},
.pddr = MCFEPORT_EPDDR,
.podr = MCFEPORT_EPDR,
.ppdr = MCFEPORT_EPPDR,
},
{
.gpio_chip = {
.label = "ADDR",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 13,
.ngpio = 3,
},
.pddr = MCFGPIO_PDDR_ADDR,
.podr = MCFGPIO_PODR_ADDR,
.ppdr = MCFGPIO_PPDSDR_ADDR,
.setr = MCFGPIO_PPDSDR_ADDR,
.clrr = MCFGPIO_PCLRR_ADDR,
},
{
.gpio_chip = {
.label = "DATAH",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 16,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_DATAH,
.podr = MCFGPIO_PODR_DATAH,
.ppdr = MCFGPIO_PPDSDR_DATAH,
.setr = MCFGPIO_PPDSDR_DATAH,
.clrr = MCFGPIO_PCLRR_DATAH,
},
{
.gpio_chip = {
.label = "DATAL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 24,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_DATAL,
.podr = MCFGPIO_PODR_DATAL,
.ppdr = MCFGPIO_PPDSDR_DATAL,
.setr = MCFGPIO_PPDSDR_DATAL,
.clrr = MCFGPIO_PCLRR_DATAL,
},
{
.gpio_chip = {
.label = "BUSCTL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 32,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_BUSCTL,
.podr = MCFGPIO_PODR_BUSCTL,
.ppdr = MCFGPIO_PPDSDR_BUSCTL,
.setr = MCFGPIO_PPDSDR_BUSCTL,
.clrr = MCFGPIO_PCLRR_BUSCTL,
},
{
.gpio_chip = {
.label = "BS",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 40,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_BS,
.podr = MCFGPIO_PODR_BS,
.ppdr = MCFGPIO_PPDSDR_BS,
.setr = MCFGPIO_PPDSDR_BS,
.clrr = MCFGPIO_PCLRR_BS,
},
{
.gpio_chip = {
.label = "CS",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 49,
.ngpio = 7,
},
.pddr = MCFGPIO_PDDR_CS,
.podr = MCFGPIO_PODR_CS,
.ppdr = MCFGPIO_PPDSDR_CS,
.setr = MCFGPIO_PPDSDR_CS,
.clrr = MCFGPIO_PCLRR_CS,
},
{
.gpio_chip = {
.label = "SDRAM",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 56,
.ngpio = 6,
},
.pddr = MCFGPIO_PDDR_SDRAM,
.podr = MCFGPIO_PODR_SDRAM,
.ppdr = MCFGPIO_PPDSDR_SDRAM,
.setr = MCFGPIO_PPDSDR_SDRAM,
.clrr = MCFGPIO_PCLRR_SDRAM,
},
{
.gpio_chip = {
.label = "FECI2C",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 64,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_FECI2C,
.podr = MCFGPIO_PODR_FECI2C,
.ppdr = MCFGPIO_PPDSDR_FECI2C,
.setr = MCFGPIO_PPDSDR_FECI2C,
.clrr = MCFGPIO_PCLRR_FECI2C,
},
{
.gpio_chip = {
.label = "UARTH",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 72,
.ngpio = 2,
},
.pddr = MCFGPIO_PDDR_UARTH,
.podr = MCFGPIO_PODR_UARTH,
.ppdr = MCFGPIO_PPDSDR_UARTH,
.setr = MCFGPIO_PPDSDR_UARTH,
.clrr = MCFGPIO_PCLRR_UARTH,
},
{
.gpio_chip = {
.label = "UARTL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 80,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_UARTL,
.podr = MCFGPIO_PODR_UARTL,
.ppdr = MCFGPIO_PPDSDR_UARTL,
.setr = MCFGPIO_PPDSDR_UARTL,
.clrr = MCFGPIO_PCLRR_UARTL,
},
{
.gpio_chip = {
.label = "QSPI",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 88,
.ngpio = 5,
},
.pddr = MCFGPIO_PDDR_QSPI,
.podr = MCFGPIO_PODR_QSPI,
.ppdr = MCFGPIO_PPDSDR_QSPI,
.setr = MCFGPIO_PPDSDR_QSPI,
.clrr = MCFGPIO_PCLRR_QSPI,
},
{
.gpio_chip = {
.label = "TIMER",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 96,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_TIMER,
.podr = MCFGPIO_PODR_TIMER,
.ppdr = MCFGPIO_PPDSDR_TIMER,
.setr = MCFGPIO_PPDSDR_TIMER,
.clrr = MCFGPIO_PCLRR_TIMER,
},
#elif defined(CONFIG_M5275)
{
.gpio_chip = {
.label = "PIRQ",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.ngpio = 8,
},
.pddr = MCFEPORT_EPDDR,
.podr = MCFEPORT_EPDR,
.ppdr = MCFEPORT_EPPDR,
},
{
.gpio_chip = {
.label = "BUSCTL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 8,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_BUSCTL,
.podr = MCFGPIO_PODR_BUSCTL,
.ppdr = MCFGPIO_PPDSDR_BUSCTL,
.setr = MCFGPIO_PPDSDR_BUSCTL,
.clrr = MCFGPIO_PCLRR_BUSCTL,
},
{
.gpio_chip = {
.label = "ADDR",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 21,
.ngpio = 3,
},
.pddr = MCFGPIO_PDDR_ADDR,
.podr = MCFGPIO_PODR_ADDR,
.ppdr = MCFGPIO_PPDSDR_ADDR,
.setr = MCFGPIO_PPDSDR_ADDR,
.clrr = MCFGPIO_PCLRR_ADDR,
},
{
.gpio_chip = {
.label = "CS",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 25,
.ngpio = 7,
},
.pddr = MCFGPIO_PDDR_CS,
.podr = MCFGPIO_PODR_CS,
.ppdr = MCFGPIO_PPDSDR_CS,
.setr = MCFGPIO_PPDSDR_CS,
.clrr = MCFGPIO_PCLRR_CS,
},
{
.gpio_chip = {
.label = "FEC0H",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 32,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_FEC0H,
.podr = MCFGPIO_PODR_FEC0H,
.ppdr = MCFGPIO_PPDSDR_FEC0H,
.setr = MCFGPIO_PPDSDR_FEC0H,
.clrr = MCFGPIO_PCLRR_FEC0H,
},
{
.gpio_chip = {
.label = "FEC0L",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 40,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_FEC0L,
.podr = MCFGPIO_PODR_FEC0L,
.ppdr = MCFGPIO_PPDSDR_FEC0L,
.setr = MCFGPIO_PPDSDR_FEC0L,
.clrr = MCFGPIO_PCLRR_FEC0L,
},
{
.gpio_chip = {
.label = "FECI2C",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 48,
.ngpio = 6,
},
.pddr = MCFGPIO_PDDR_FECI2C,
.podr = MCFGPIO_PODR_FECI2C,
.ppdr = MCFGPIO_PPDSDR_FECI2C,
.setr = MCFGPIO_PPDSDR_FECI2C,
.clrr = MCFGPIO_PCLRR_FECI2C,
},
{
.gpio_chip = {
.label = "QSPI",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 56,
.ngpio = 7,
},
.pddr = MCFGPIO_PDDR_QSPI,
.podr = MCFGPIO_PODR_QSPI,
.ppdr = MCFGPIO_PPDSDR_QSPI,
.setr = MCFGPIO_PPDSDR_QSPI,
.clrr = MCFGPIO_PCLRR_QSPI,
},
{
.gpio_chip = {
.label = "SDRAM",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 64,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_SDRAM,
.podr = MCFGPIO_PODR_SDRAM,
.ppdr = MCFGPIO_PPDSDR_SDRAM,
.setr = MCFGPIO_PPDSDR_SDRAM,
.clrr = MCFGPIO_PCLRR_SDRAM,
},
{
.gpio_chip = {
.label = "TIMERH",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 72,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_TIMERH,
.podr = MCFGPIO_PODR_TIMERH,
.ppdr = MCFGPIO_PPDSDR_TIMERH,
.setr = MCFGPIO_PPDSDR_TIMERH,
.clrr = MCFGPIO_PCLRR_TIMERH,
},
{
.gpio_chip = {
.label = "TIMERL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 80,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_TIMERL,
.podr = MCFGPIO_PODR_TIMERL,
.ppdr = MCFGPIO_PPDSDR_TIMERL,
.setr = MCFGPIO_PPDSDR_TIMERL,
.clrr = MCFGPIO_PCLRR_TIMERL,
},
{
.gpio_chip = {
.label = "UARTL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 88,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_UARTL,
.podr = MCFGPIO_PODR_UARTL,
.ppdr = MCFGPIO_PPDSDR_UARTL,
.setr = MCFGPIO_PPDSDR_UARTL,
.clrr = MCFGPIO_PCLRR_UARTL,
},
{
.gpio_chip = {
.label = "FEC1H",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 96,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_FEC1H,
.podr = MCFGPIO_PODR_FEC1H,
.ppdr = MCFGPIO_PPDSDR_FEC1H,
.setr = MCFGPIO_PPDSDR_FEC1H,
.clrr = MCFGPIO_PCLRR_FEC1H,
},
{
.gpio_chip = {
.label = "FEC1L",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 104,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_FEC1L,
.podr = MCFGPIO_PODR_FEC1L,
.ppdr = MCFGPIO_PPDSDR_FEC1L,
.setr = MCFGPIO_PPDSDR_FEC1L,
.clrr = MCFGPIO_PCLRR_FEC1L,
},
{
.gpio_chip = {
.label = "BS",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 114,
.ngpio = 2,
},
.pddr = MCFGPIO_PDDR_BS,
.podr = MCFGPIO_PODR_BS,
.ppdr = MCFGPIO_PPDSDR_BS,
.setr = MCFGPIO_PPDSDR_BS,
.clrr = MCFGPIO_PCLRR_BS,
},
{
.gpio_chip = {
.label = "IRQ",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 121,
.ngpio = 7,
},
.pddr = MCFGPIO_PDDR_IRQ,
.podr = MCFGPIO_PODR_IRQ,
.ppdr = MCFGPIO_PPDSDR_IRQ,
.setr = MCFGPIO_PPDSDR_IRQ,
.clrr = MCFGPIO_PCLRR_IRQ,
},
{
.gpio_chip = {
.label = "USBH",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 128,
.ngpio = 1,
},
.pddr = MCFGPIO_PDDR_USBH,
.podr = MCFGPIO_PODR_USBH,
.ppdr = MCFGPIO_PPDSDR_USBH,
.setr = MCFGPIO_PPDSDR_USBH,
.clrr = MCFGPIO_PCLRR_USBH,
},
{
.gpio_chip = {
.label = "USBL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 136,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_USBL,
.podr = MCFGPIO_PODR_USBL,
.ppdr = MCFGPIO_PPDSDR_USBL,
.setr = MCFGPIO_PPDSDR_USBL,
.clrr = MCFGPIO_PCLRR_USBL,
},
{
.gpio_chip = {
.label = "UARTH",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 144,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_UARTH,
.podr = MCFGPIO_PODR_UARTH,
.ppdr = MCFGPIO_PPDSDR_UARTH,
.setr = MCFGPIO_PPDSDR_UARTH,
.clrr = MCFGPIO_PCLRR_UARTH,
},
#endif
};
static int __init mcf_gpio_init(void)
{
unsigned i = 0;
while (i < ARRAY_SIZE(mcf_gpio_chips))
(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
return 0;
}
core_initcall(mcf_gpio_init);
......@@ -14,5 +14,5 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
obj-y := config.o
obj-y := config.o gpio.o
......@@ -3,8 +3,8 @@
/*
* linux/arch/m68knommu/platform/528x/config.c
*
* Sub-architcture dependant initialization code for the Motorola
* 5280 and 5282 CPUs.
* Sub-architcture dependant initialization code for the Freescale
* 5280, 5281 and 5282 CPUs.
*
* Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
* Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
......@@ -15,20 +15,13 @@
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
#ifdef CONFIG_MTD_PARTITIONS
#include <linux/mtd/partitions.h>
#endif
/***************************************************************************/
static struct mcf_platform_uart m528x_uart_platform[] = {
......@@ -91,23 +84,13 @@ static struct platform_device *m528x_devices[] __initdata = {
/***************************************************************************/
#define INTC0 (MCF_MBAR + MCFICM_INTC0)
static void __init m528x_uart_init_line(int line, int irq)
{
u8 port;
u32 imr;
if ((line < 0) || (line > 2))
return;
/* level 6, line based priority */
writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
imr = readl(INTC0 + MCFINTC_IMRL);
imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
writel(imr, INTC0 + MCFINTC_IMRL);
/* make sure PUAPAR is set for UART0 and UART1 */
if (line < 2) {
port = readb(MCF_MBAR + MCF5282_GPIO_PUAPAR);
......@@ -129,21 +112,8 @@ static void __init m528x_uarts_init(void)
static void __init m528x_fec_init(void)
{
u32 imr;
u16 v16;
/* Unmask FEC interrupts at ColdFire interrupt controller */
writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
imr &= ~0xf;
writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
imr &= ~0xff800001;
writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
/* Set multi-function pins to ethernet mode for fec0 */
v16 = readw(MCF_IPSBAR + 0x100056);
writew(v16 | 0xf00, MCF_IPSBAR + 0x100056);
......@@ -152,21 +122,6 @@ static void __init m528x_fec_init(void)
/***************************************************************************/
void mcf_disableall(void)
{
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
}
/***************************************************************************/
void mcf_autovector(unsigned int vec)
{
/* Everything is auto-vectored on the 5272 */
}
/***************************************************************************/
static void m528x_cpu_reset(void)
{
local_irq_disable();
......@@ -204,8 +159,6 @@ void wildfiremod_halt(void)
void __init config_BSP(char *commandp, int size)
{
mcf_disableall();
#ifdef CONFIG_WILDFIRE
mach_halt = wildfire_halt;
#endif
......
/*
* Coldfire generic GPIO support
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfgpio.h>
static struct mcf_gpio_chip mcf_gpio_chips[] = {
{
.gpio_chip = {
.label = "NQ",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.base = 1,
.ngpio = 8,
},
.pddr = MCFEPORT_EPDDR,
.podr = MCFEPORT_EPDR,
.ppdr = MCFEPORT_EPPDR,
},
{
.gpio_chip = {
.label = "TA",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 8,
.ngpio = 4,
},
.pddr = MCFGPTA_GPTDDR,
.podr = MCFGPTA_GPTPORT,
.ppdr = MCFGPTB_GPTPORT,
},
{
.gpio_chip = {
.label = "TB",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 16,
.ngpio = 4,
},
.pddr = MCFGPTB_GPTDDR,
.podr = MCFGPTB_GPTPORT,
.ppdr = MCFGPTB_GPTPORT,
},
{
.gpio_chip = {
.label = "QA",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 24,
.ngpio = 4,
},
.pddr = MCFQADC_DDRQA,
.podr = MCFQADC_PORTQA,
.ppdr = MCFQADC_PORTQA,
},
{
.gpio_chip = {
.label = "QB",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 32,
.ngpio = 4,
},
.pddr = MCFQADC_DDRQB,
.podr = MCFQADC_PORTQB,
.ppdr = MCFQADC_PORTQB,
},
{
.gpio_chip = {
.label = "A",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 40,
.ngpio = 8,
},
.pddr = MCFGPIO_DDRA,
.podr = MCFGPIO_PORTA,
.ppdr = MCFGPIO_PORTAP,
.setr = MCFGPIO_SETA,
.clrr = MCFGPIO_CLRA,
},
{
.gpio_chip = {
.label = "B",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 48,
.ngpio = 8,
},
.pddr = MCFGPIO_DDRB,
.podr = MCFGPIO_PORTB,
.ppdr = MCFGPIO_PORTBP,
.setr = MCFGPIO_SETB,
.clrr = MCFGPIO_CLRB,
},
{
.gpio_chip = {
.label = "C",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 56,
.ngpio = 8,
},
.pddr = MCFGPIO_DDRC,
.podr = MCFGPIO_PORTC,
.ppdr = MCFGPIO_PORTCP,
.setr = MCFGPIO_SETC,
.clrr = MCFGPIO_CLRC,
},
{
.gpio_chip = {
.label = "D",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 64,
.ngpio = 8,
},
.pddr = MCFGPIO_DDRD,
.podr = MCFGPIO_PORTD,
.ppdr = MCFGPIO_PORTDP,
.setr = MCFGPIO_SETD,
.clrr = MCFGPIO_CLRD,
},
{
.gpio_chip = {
.label = "E",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 72,
.ngpio = 8,
},
.pddr = MCFGPIO_DDRE,
.podr = MCFGPIO_PORTE,
.ppdr = MCFGPIO_PORTEP,
.setr = MCFGPIO_SETE,
.clrr = MCFGPIO_CLRE,
},
{
.gpio_chip = {
.label = "F",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 80,
.ngpio = 8,
},
.pddr = MCFGPIO_DDRF,
.podr = MCFGPIO_PORTF,
.ppdr = MCFGPIO_PORTFP,
.setr = MCFGPIO_SETF,
.clrr = MCFGPIO_CLRF,
},
{
.gpio_chip = {
.label = "G",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 88,
.ngpio = 8,
},
.pddr = MCFGPIO_DDRG,
.podr = MCFGPIO_PORTG,
.ppdr = MCFGPIO_PORTGP,
.setr = MCFGPIO_SETG,
.clrr = MCFGPIO_CLRG,
},
{
.gpio_chip = {
.label = "H",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 96,
.ngpio = 8,
},
.pddr = MCFGPIO_DDRH,
.podr = MCFGPIO_PORTH,
.ppdr = MCFGPIO_PORTHP,
.setr = MCFGPIO_SETH,
.clrr = MCFGPIO_CLRH,
},
{
.gpio_chip = {
.label = "J",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 104,
.ngpio = 8,
},
.pddr = MCFGPIO_DDRJ,
.podr = MCFGPIO_PORTJ,
.ppdr = MCFGPIO_PORTJP,
.setr = MCFGPIO_SETJ,
.clrr = MCFGPIO_CLRJ,
},
{
.gpio_chip = {
.label = "DD",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 112,
.ngpio = 8,
},
.pddr = MCFGPIO_DDRDD,
.podr = MCFGPIO_PORTDD,
.ppdr = MCFGPIO_PORTDDP,
.setr = MCFGPIO_SETDD,
.clrr = MCFGPIO_CLRDD,
},
{
.gpio_chip = {
.label = "EH",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 120,
.ngpio = 8,
},
.pddr = MCFGPIO_DDREH,
.podr = MCFGPIO_PORTEH,
.ppdr = MCFGPIO_PORTEHP,
.setr = MCFGPIO_SETEH,
.clrr = MCFGPIO_CLREH,
},
{
.gpio_chip = {
.label = "EL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 128,
.ngpio = 8,
},
.pddr = MCFGPIO_DDREL,
.podr = MCFGPIO_PORTEL,
.ppdr = MCFGPIO_PORTELP,
.setr = MCFGPIO_SETEL,
.clrr = MCFGPIO_CLREL,
},
{
.gpio_chip = {
.label = "AS",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 136,
.ngpio = 6,
},
.pddr = MCFGPIO_DDRAS,
.podr = MCFGPIO_PORTAS,
.ppdr = MCFGPIO_PORTASP,
.setr = MCFGPIO_SETAS,
.clrr = MCFGPIO_CLRAS,
},
{
.gpio_chip = {
.label = "QS",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 144,
.ngpio = 7,
},
.pddr = MCFGPIO_DDRQS,
.podr = MCFGPIO_PORTQS,
.ppdr = MCFGPIO_PORTQSP,
.setr = MCFGPIO_SETQS,
.clrr = MCFGPIO_CLRQS,
},
{
.gpio_chip = {
.label = "SD",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 152,
.ngpio = 6,
},
.pddr = MCFGPIO_DDRSD,
.podr = MCFGPIO_PORTSD,
.ppdr = MCFGPIO_PORTSDP,
.setr = MCFGPIO_SETSD,
.clrr = MCFGPIO_CLRSD,
},
{
.gpio_chip = {
.label = "TC",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 160,
.ngpio = 4,
},
.pddr = MCFGPIO_DDRTC,
.podr = MCFGPIO_PORTTC,
.ppdr = MCFGPIO_PORTTCP,
.setr = MCFGPIO_SETTC,
.clrr = MCFGPIO_CLRTC,
},
{
.gpio_chip = {
.label = "TD",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 168,
.ngpio = 4,
},
.pddr = MCFGPIO_DDRTD,
.podr = MCFGPIO_PORTTD,
.ppdr = MCFGPIO_PORTTDP,
.setr = MCFGPIO_SETTD,
.clrr = MCFGPIO_CLRTD,
},
{
.gpio_chip = {
.label = "UA",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 176,
.ngpio = 4,
},
.pddr = MCFGPIO_DDRUA,
.podr = MCFGPIO_PORTUA,
.ppdr = MCFGPIO_PORTUAP,
.setr = MCFGPIO_SETUA,
.clrr = MCFGPIO_CLRUA,
},
};
static int __init mcf_gpio_init(void)
{
unsigned i = 0;
while (i < ARRAY_SIZE(mcf_gpio_chips))
(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
return 0;
}
core_initcall(mcf_gpio_init);
......@@ -14,5 +14,5 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
obj-y += config.o
obj-y += config.o gpio.o
......@@ -21,12 +21,6 @@
/***************************************************************************/
extern unsigned int mcf_timervector;
extern unsigned int mcf_profilevector;
extern unsigned int mcf_timerlevel;
/***************************************************************************/
/*
* Some platforms need software versions of the GPIO data registers.
*/
......@@ -64,11 +58,11 @@ static void __init m5307_uart_init_line(int line, int irq)
if (line == 0) {
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
mcf_mapirq2imr(irq, MCFINTC_UART0);
} else if (line == 1) {
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
mcf_mapirq2imr(irq, MCFINTC_UART1);
}
}
......@@ -83,35 +77,19 @@ static void __init m5307_uarts_init(void)
/***************************************************************************/
void mcf_autovector(unsigned int vec)
{
volatile unsigned char *mbar;
if ((vec >= 25) && (vec <= 31)) {
mbar = (volatile unsigned char *) MCF_MBAR;
vec = 0x1 << (vec - 24);
*(mbar + MCFSIM_AVR) |= vec;
mcf_setimr(mcf_getimr() & ~vec);
}
}
/***************************************************************************/
void mcf_settimericr(unsigned int timer, unsigned int level)
static void __init m5307_timers_init(void)
{
volatile unsigned char *icrp;
unsigned int icr, imr;
if (timer <= 2) {
switch (timer) {
case 2: icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
}
icrp = (volatile unsigned char *) (MCF_MBAR + icr);
*icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
mcf_setimr(mcf_getimr() & ~imr);
}
/* Timer1 is always used as system timer */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
MCF_MBAR + MCFSIM_TIMER1ICR);
mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
#ifdef CONFIG_HIGHPROFILE
/* Timer2 is to be used as a high speed profile timer */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
MCF_MBAR + MCFSIM_TIMER2ICR);
mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
#endif
}
/***************************************************************************/
......@@ -129,20 +107,22 @@ void m5307_cpu_reset(void)
void __init config_BSP(char *commandp, int size)
{
mcf_setimr(MCFSIM_IMR_MASKALL);
#if defined(CONFIG_NETtel) || \
defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA)
/* Copy command line from FLASH to local buffer... */
memcpy(commandp, (char *) 0xf0004000, size);
commandp[size-1] = 0;
/* Different timer setup - to prevent device clash */
mcf_timervector = 30;
mcf_profilevector = 31;
mcf_timerlevel = 6;
#endif
mach_reset = m5307_cpu_reset;
m5307_timers_init();
m5307_uarts_init();
/* Only support the external interrupts on their primary level */
mcf_mapirq2imr(25, MCFINTC_EINT1);
mcf_mapirq2imr(27, MCFINTC_EINT3);
mcf_mapirq2imr(29, MCFINTC_EINT5);
mcf_mapirq2imr(31, MCFINTC_EINT7);
#ifdef CONFIG_BDM_DISABLE
/*
......@@ -158,7 +138,6 @@ void __init config_BSP(char *commandp, int size)
static int __init init_BSP(void)
{
m5307_uarts_init();
platform_add_devices(m5307_devices, ARRAY_SIZE(m5307_devices));
return 0;
}
......
/*
* Coldfire generic GPIO support
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfgpio.h>
static struct mcf_gpio_chip mcf_gpio_chips[] = {
{
.gpio_chip = {
.label = "PP",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.ngpio = 16,
},
.pddr = MCFSIM_PADDR,
.podr = MCFSIM_PADAT,
.ppdr = MCFSIM_PADAT,
},
};
static int __init mcf_gpio_init(void)
{
unsigned i = 0;
while (i < ARRAY_SIZE(mcf_gpio_chips))
(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
return 0;
}
core_initcall(mcf_gpio_init);
......@@ -15,4 +15,4 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
#obj-y := config.o usb-mcf532x.o spi-mcf532x.o
obj-y := config.o
obj-y := config.o gpio.o
......@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
......@@ -31,12 +30,6 @@
/***************************************************************************/
extern unsigned int mcf_timervector;
extern unsigned int mcf_profilevector;
extern unsigned int mcf_timerlevel;
/***************************************************************************/
static struct mcf_platform_uart m532x_uart_platform[] = {
{
.mapbase = MCFUART_BASE1,
......@@ -88,6 +81,7 @@ static struct platform_device m532x_fec = {
.num_resources = ARRAY_SIZE(m532x_fec_resources),
.resource = m532x_fec_resources,
};
static struct platform_device *m532x_devices[] __initdata = {
&m532x_uart,
&m532x_fec,
......@@ -98,18 +92,11 @@ static struct platform_device *m532x_devices[] __initdata = {
static void __init m532x_uart_init_line(int line, int irq)
{
if (line == 0) {
MCF_INTC0_ICR26 = 0x3;
MCF_INTC0_CIMR = 26;
/* GPIO initialization */
MCF_GPIO_PAR_UART |= 0x000F;
} else if (line == 1) {
MCF_INTC0_ICR27 = 0x3;
MCF_INTC0_CIMR = 27;
/* GPIO initialization */
MCF_GPIO_PAR_UART |= 0x0FF0;
} else if (line == 2) {
MCF_INTC0_ICR28 = 0x3;
MCF_INTC0_CIMR = 28;
}
}
......@@ -125,14 +112,6 @@ static void __init m532x_uarts_init(void)
static void __init m532x_fec_init(void)
{
/* Unmask FEC interrupts at ColdFire interrupt controller */
MCF_INTC0_ICR36 = 0x2;
MCF_INTC0_ICR40 = 0x2;
MCF_INTC0_ICR42 = 0x2;
MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK36 |
MCF_INTC_IMRH_INT_MASK40 | MCF_INTC_IMRH_INT_MASK42);
/* Set multi-function pins to ethernet mode for fec0 */
MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
......@@ -142,26 +121,6 @@ static void __init m532x_fec_init(void)
/***************************************************************************/
void mcf_settimericr(unsigned int timer, unsigned int level)
{
volatile unsigned char *icrp;
unsigned int icr;
unsigned char irq;
if (timer <= 2) {
switch (timer) {
case 2: irq = 33; icr = MCFSIM_ICR_TIMER2; break;
default: irq = 32; icr = MCFSIM_ICR_TIMER1; break;
}
icrp = (volatile unsigned char *) (icr);
*icrp = level;
mcf_enable_irq0(irq);
}
}
/***************************************************************************/
static void m532x_cpu_reset(void)
{
local_irq_disable();
......@@ -172,8 +131,6 @@ static void m532x_cpu_reset(void)
void __init config_BSP(char *commandp, int size)
{
mcf_setimr(MCFSIM_IMR_MASKALL);
#if !defined(CONFIG_BOOTPARAM)
/* Copy command line from FLASH to local buffer... */
memcpy(commandp, (char *) 0x4000, 4);
......@@ -185,10 +142,6 @@ void __init config_BSP(char *commandp, int size)
}
#endif
mcf_timervector = 64+32;
mcf_profilevector = 64+33;
mach_reset = m532x_cpu_reset;
#ifdef CONFIG_BDM_DISABLE
/*
* Disable the BDM clocking. This also turns off most of the rest of
......@@ -438,8 +391,8 @@ void gpio_init(void)
/* Initialize TIN3 as a GPIO output to enable the write
half of the latch */
MCF_GPIO_PAR_TIMER = 0x00;
MCF_GPIO_PDDR_TIMER = 0x08;
MCF_GPIO_PCLRR_TIMER = 0x0;
__raw_writeb(0x08, MCFGPIO_PDDR_TIMER);
__raw_writeb(0x00, MCFGPIO_PCLRR_TIMER);
}
......
/*
* Coldfire generic GPIO support
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfgpio.h>
static struct mcf_gpio_chip mcf_gpio_chips[] = {
{
.gpio_chip = {
.label = "PIRQ",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.ngpio = 8,
},
.pddr = MCFEPORT_EPDDR,
.podr = MCFEPORT_EPDR,
.ppdr = MCFEPORT_EPPDR,
},
{
.gpio_chip = {
.label = "FECH",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 8,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_FECH,
.podr = MCFGPIO_PODR_FECH,
.ppdr = MCFGPIO_PPDSDR_FECH,
.setr = MCFGPIO_PPDSDR_FECH,
.clrr = MCFGPIO_PCLRR_FECH,
},
{
.gpio_chip = {
.label = "FECL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 16,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_FECL,
.podr = MCFGPIO_PODR_FECL,
.ppdr = MCFGPIO_PPDSDR_FECL,
.setr = MCFGPIO_PPDSDR_FECL,
.clrr = MCFGPIO_PCLRR_FECL,
},
{
.gpio_chip = {
.label = "SSI",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 24,
.ngpio = 5,
},
.pddr = MCFGPIO_PDDR_SSI,
.podr = MCFGPIO_PODR_SSI,
.ppdr = MCFGPIO_PPDSDR_SSI,
.setr = MCFGPIO_PPDSDR_SSI,
.clrr = MCFGPIO_PCLRR_SSI,
},
{
.gpio_chip = {
.label = "BUSCTL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 32,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_BUSCTL,
.podr = MCFGPIO_PODR_BUSCTL,
.ppdr = MCFGPIO_PPDSDR_BUSCTL,
.setr = MCFGPIO_PPDSDR_BUSCTL,
.clrr = MCFGPIO_PCLRR_BUSCTL,
},
{
.gpio_chip = {
.label = "BE",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 40,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_BE,
.podr = MCFGPIO_PODR_BE,
.ppdr = MCFGPIO_PPDSDR_BE,
.setr = MCFGPIO_PPDSDR_BE,
.clrr = MCFGPIO_PCLRR_BE,
},
{
.gpio_chip = {
.label = "CS",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 49,
.ngpio = 5,
},
.pddr = MCFGPIO_PDDR_CS,
.podr = MCFGPIO_PODR_CS,
.ppdr = MCFGPIO_PPDSDR_CS,
.setr = MCFGPIO_PPDSDR_CS,
.clrr = MCFGPIO_PCLRR_CS,
},
{
.gpio_chip = {
.label = "PWM",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 58,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_PWM,
.podr = MCFGPIO_PODR_PWM,
.ppdr = MCFGPIO_PPDSDR_PWM,
.setr = MCFGPIO_PPDSDR_PWM,
.clrr = MCFGPIO_PCLRR_PWM,
},
{
.gpio_chip = {
.label = "FECI2C",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 64,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_FECI2C,
.podr = MCFGPIO_PODR_FECI2C,
.ppdr = MCFGPIO_PPDSDR_FECI2C,
.setr = MCFGPIO_PPDSDR_FECI2C,
.clrr = MCFGPIO_PCLRR_FECI2C,
},
{
.gpio_chip = {
.label = "UART",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 72,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_UART,
.podr = MCFGPIO_PODR_UART,
.ppdr = MCFGPIO_PPDSDR_UART,
.setr = MCFGPIO_PPDSDR_UART,
.clrr = MCFGPIO_PCLRR_UART,
},
{
.gpio_chip = {
.label = "QSPI",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 80,
.ngpio = 6,
},
.pddr = MCFGPIO_PDDR_QSPI,
.podr = MCFGPIO_PODR_QSPI,
.ppdr = MCFGPIO_PPDSDR_QSPI,
.setr = MCFGPIO_PPDSDR_QSPI,
.clrr = MCFGPIO_PCLRR_QSPI,
},
{
.gpio_chip = {
.label = "TIMER",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 88,
.ngpio = 4,
},
.pddr = MCFGPIO_PDDR_TIMER,
.podr = MCFGPIO_PODR_TIMER,
.ppdr = MCFGPIO_PPDSDR_TIMER,
.setr = MCFGPIO_PPDSDR_TIMER,
.clrr = MCFGPIO_PCLRR_TIMER,
},
{
.gpio_chip = {
.label = "LCDDATAH",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 96,
.ngpio = 2,
},
.pddr = MCFGPIO_PDDR_LCDDATAH,
.podr = MCFGPIO_PODR_LCDDATAH,
.ppdr = MCFGPIO_PPDSDR_LCDDATAH,
.setr = MCFGPIO_PPDSDR_LCDDATAH,
.clrr = MCFGPIO_PCLRR_LCDDATAH,
},
{
.gpio_chip = {
.label = "LCDDATAM",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 104,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_LCDDATAM,
.podr = MCFGPIO_PODR_LCDDATAM,
.ppdr = MCFGPIO_PPDSDR_LCDDATAM,
.setr = MCFGPIO_PPDSDR_LCDDATAM,
.clrr = MCFGPIO_PCLRR_LCDDATAM,
},
{
.gpio_chip = {
.label = "LCDDATAL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 112,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_LCDDATAL,
.podr = MCFGPIO_PODR_LCDDATAL,
.ppdr = MCFGPIO_PPDSDR_LCDDATAL,
.setr = MCFGPIO_PPDSDR_LCDDATAL,
.clrr = MCFGPIO_PCLRR_LCDDATAL,
},
{
.gpio_chip = {
.label = "LCDCTLH",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 120,
.ngpio = 1,
},
.pddr = MCFGPIO_PDDR_LCDCTLH,
.podr = MCFGPIO_PODR_LCDCTLH,
.ppdr = MCFGPIO_PPDSDR_LCDCTLH,
.setr = MCFGPIO_PPDSDR_LCDCTLH,
.clrr = MCFGPIO_PCLRR_LCDCTLH,
},
{
.gpio_chip = {
.label = "LCDCTLL",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value_fast,
.base = 128,
.ngpio = 8,
},
.pddr = MCFGPIO_PDDR_LCDCTLL,
.podr = MCFGPIO_PODR_LCDCTLL,
.ppdr = MCFGPIO_PPDSDR_LCDCTLL,
.setr = MCFGPIO_PPDSDR_LCDCTLL,
.clrr = MCFGPIO_PCLRR_LCDCTLL,
},
};
static int __init mcf_gpio_init(void)
{
unsigned i = 0;
while (i < ARRAY_SIZE(mcf_gpio_chips))
(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
return 0;
}
core_initcall(mcf_gpio_init);
......@@ -14,5 +14,5 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
obj-y := config.o
obj-y := config.o gpio.o
......@@ -20,12 +20,6 @@
/***************************************************************************/
extern unsigned int mcf_timervector;
extern unsigned int mcf_profilevector;
extern unsigned int mcf_timerlevel;
/***************************************************************************/
static struct mcf_platform_uart m5407_uart_platform[] = {
{
.mapbase = MCF_MBAR + MCFUART_BASE1,
......@@ -55,11 +49,11 @@ static void __init m5407_uart_init_line(int line, int irq)
if (line == 0) {
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
mcf_mapirq2imr(irq, MCFINTC_UART0);
} else if (line == 1) {
writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
mcf_mapirq2imr(irq, MCFINTC_UART1);
}
}
......@@ -74,35 +68,19 @@ static void __init m5407_uarts_init(void)
/***************************************************************************/
void mcf_autovector(unsigned int vec)
{
volatile unsigned char *mbar;
if ((vec >= 25) && (vec <= 31)) {
mbar = (volatile unsigned char *) MCF_MBAR;
vec = 0x1 << (vec - 24);
*(mbar + MCFSIM_AVR) |= vec;
mcf_setimr(mcf_getimr() & ~vec);
}
}
/***************************************************************************/
void mcf_settimericr(unsigned int timer, unsigned int level)
static void __init m5407_timers_init(void)
{
volatile unsigned char *icrp;
unsigned int icr, imr;
if (timer <= 2) {
switch (timer) {
case 2: icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
}
icrp = (volatile unsigned char *) (MCF_MBAR + icr);
*icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
mcf_setimr(mcf_getimr() & ~imr);
}
/* Timer1 is always used as system timer */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
MCF_MBAR + MCFSIM_TIMER1ICR);
mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
#ifdef CONFIG_HIGHPROFILE
/* Timer2 is to be used as a high speed profile timer */
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
MCF_MBAR + MCFSIM_TIMER2ICR);
mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
#endif
}
/***************************************************************************/
......@@ -120,23 +98,21 @@ void m5407_cpu_reset(void)
void __init config_BSP(char *commandp, int size)
{
mcf_setimr(MCFSIM_IMR_MASKALL);
#if defined(CONFIG_CLEOPATRA)
/* Different timer setup - to prevent device clash */
mcf_timervector = 30;
mcf_profilevector = 31;
mcf_timerlevel = 6;
#endif
mach_reset = m5407_cpu_reset;
m5407_timers_init();
m5407_uarts_init();
/* Only support the external interrupts on their primary level */
mcf_mapirq2imr(25, MCFINTC_EINT1);
mcf_mapirq2imr(27, MCFINTC_EINT3);
mcf_mapirq2imr(29, MCFINTC_EINT5);
mcf_mapirq2imr(31, MCFINTC_EINT7);
}
/***************************************************************************/
static int __init init_BSP(void)
{
m5407_uarts_init();
platform_add_devices(m5407_devices, ARRAY_SIZE(m5407_devices));
return 0;
}
......
/*
* Coldfire generic GPIO support
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfgpio.h>
static struct mcf_gpio_chip mcf_gpio_chips[] = {
{
.gpio_chip = {
.label = "PP",
.request = mcf_gpio_request,
.free = mcf_gpio_free,
.direction_input = mcf_gpio_direction_input,
.direction_output = mcf_gpio_direction_output,
.get = mcf_gpio_get_value,
.set = mcf_gpio_set_value,
.ngpio = 16,
},
.pddr = MCFSIM_PADDR,
.podr = MCFSIM_PADAT,
.ppdr = MCFSIM_PADAT,
},
};
static int __init mcf_gpio_init(void)
{
unsigned i = 0;
while (i < ARRAY_SIZE(mcf_gpio_chips))
(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
return 0;
}
core_initcall(mcf_gpio_init);
......@@ -73,34 +73,6 @@ extern e_vector *_ramvec;
/* The number of spurious interrupts */
volatile unsigned int num_spurious;
/*
* This function should be called during kernel startup to initialize
* the machine vector table.
*/
void __init init_vectors(void)
{
int i;
/* set up the vectors */
for (i = 72; i < 256; ++i)
_ramvec[i] = (e_vector) bad_interrupt;
_ramvec[32] = system_call;
_ramvec[65] = (e_vector) inthandler1;
_ramvec[66] = (e_vector) inthandler2;
_ramvec[67] = (e_vector) inthandler3;
_ramvec[68] = (e_vector) inthandler4;
_ramvec[69] = (e_vector) inthandler5;
_ramvec[70] = (e_vector) inthandler6;
_ramvec[71] = (e_vector) inthandler7;
IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
/* turn off all interrupts */
IMR = ~0;
}
/* The 68k family did not have a good way to determine the source
* of interrupts until later in the family. The EC000 core does
* not provide the vector number on the stack, we vector everything
......@@ -163,18 +135,54 @@ void process_int(int vec, struct pt_regs *fp)
}
}
void enable_vector(unsigned int irq)
static void intc_irq_unmask(unsigned int irq)
{
IMR &= ~(1<<irq);
}
void disable_vector(unsigned int irq)
static void intc_irq_mask(unsigned int irq)
{
IMR |= (1<<irq);
}
void ack_vector(unsigned int irq)
static struct irq_chip intc_irq_chip = {
.name = "M68K-INTC",
.mask = intc_irq_mask,
.unmask = intc_irq_unmask,
};
/*
* This function should be called during kernel startup to initialize
* the machine vector table.
*/
void __init init_IRQ(void)
{
/* Nothing needed */
int i;
/* set up the vectors */
for (i = 72; i < 256; ++i)
_ramvec[i] = (e_vector) bad_interrupt;
_ramvec[32] = system_call;
_ramvec[65] = (e_vector) inthandler1;
_ramvec[66] = (e_vector) inthandler2;
_ramvec[67] = (e_vector) inthandler3;
_ramvec[68] = (e_vector) inthandler4;
_ramvec[69] = (e_vector) inthandler5;
_ramvec[70] = (e_vector) inthandler6;
_ramvec[71] = (e_vector) inthandler7;
IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
/* turn off all interrupts */
IMR = ~0;
for (i = 0; (i < NR_IRQS); i++) {
irq_desc[i].status = IRQ_DISABLED;
irq_desc[i].action = NULL;
irq_desc[i].depth = 1;
irq_desc[i].chip = &intc_irq_chip;
}
}
......@@ -37,11 +37,33 @@ extern void *_ramvec[];
/* The number of spurious interrupts */
volatile unsigned int num_spurious;
static void intc_irq_unmask(unsigned int irq)
{
pquicc->intr_cimr |= (1 << irq);
}
static void intc_irq_mask(unsigned int irq)
{
pquicc->intr_cimr &= ~(1 << irq);
}
static void intc_irq_ack(unsigned int irq)
{
pquicc->intr_cisr = (1 << irq);
}
static struct irq_chip intc_irq_chip = {
.name = "M68K-INTC",
.mask = intc_irq_mask,
.unmask = intc_irq_unmask,
.ack = intc_irq_ack,
};
/*
* This function should be called during kernel startup to initialize
* the vector table.
*/
void init_vectors(void)
void init_IRQ(void)
{
int i;
int vba = (CPM_VECTOR_BASE<<4);
......@@ -109,20 +131,12 @@ void init_vectors(void)
/* turn off all CPM interrupts */
pquicc->intr_cimr = 0x00000000;
}
void enable_vector(unsigned int irq)
{
pquicc->intr_cimr |= (1 << irq);
}
void disable_vector(unsigned int irq)
{
pquicc->intr_cimr &= ~(1 << irq);
}
void ack_vector(unsigned int irq)
{
pquicc->intr_cisr = (1 << irq);
for (i = 0; (i < NR_IRQS); i++) {
irq_desc[i].status = IRQ_DISABLED;
irq_desc[i].action = NULL;
irq_desc[i].depth = 1;
irq_desc[i].chip = &intc_irq_chip;
}
}
......@@ -15,16 +15,17 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
obj-$(CONFIG_COLDFIRE) += clk.o dma.o entry.o vectors.o
obj-$(CONFIG_M5206) += timers.o
obj-$(CONFIG_M5206e) += timers.o
obj-$(CONFIG_M520x) += pit.o
obj-$(CONFIG_M523x) += pit.o dma_timer.o
obj-$(CONFIG_M5249) += timers.o
obj-$(CONFIG_M527x) += pit.o
obj-$(CONFIG_M5206) += timers.o intc.o
obj-$(CONFIG_M5206e) += timers.o intc.o
obj-$(CONFIG_M520x) += pit.o intc-simr.o
obj-$(CONFIG_M523x) += pit.o dma_timer.o intc-2.o
obj-$(CONFIG_M5249) += timers.o intc.o
obj-$(CONFIG_M527x) += pit.o intc-2.o
obj-$(CONFIG_M5272) += timers.o
obj-$(CONFIG_M528x) += pit.o
obj-$(CONFIG_M5307) += timers.o
obj-$(CONFIG_M532x) += timers.o
obj-$(CONFIG_M5407) += timers.o
obj-$(CONFIG_M528x) += pit.o intc-2.o
obj-$(CONFIG_M5307) += timers.o intc.o
obj-$(CONFIG_M532x) += timers.o intc-simr.o
obj-$(CONFIG_M5407) += timers.o intc.o
obj-y += pinmux.o gpio.o
extra-y := head.o
/*
* Coldfire generic GPIO support.
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sysdev.h>
#include <asm/gpio.h>
#include <asm/pinmux.h>
#include <asm/mcfgpio.h>
#define MCF_CHIP(chip) container_of(chip, struct mcf_gpio_chip, gpio_chip)
int mcf_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
unsigned long flags;
MCFGPIO_PORTTYPE dir;
struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
local_irq_save(flags);
dir = mcfgpio_read(mcf_chip->pddr);
dir &= ~mcfgpio_bit(chip->base + offset);
mcfgpio_write(dir, mcf_chip->pddr);
local_irq_restore(flags);
return 0;
}
int mcf_gpio_get_value(struct gpio_chip *chip, unsigned offset)
{
struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
return mcfgpio_read(mcf_chip->ppdr) & mcfgpio_bit(chip->base + offset);
}
int mcf_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
int value)
{
unsigned long flags;
MCFGPIO_PORTTYPE data;
struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
local_irq_save(flags);
/* write the value to the output latch */
data = mcfgpio_read(mcf_chip->podr);
if (value)
data |= mcfgpio_bit(chip->base + offset);
else
data &= ~mcfgpio_bit(chip->base + offset);
mcfgpio_write(data, mcf_chip->podr);
/* now set the direction to output */
data = mcfgpio_read(mcf_chip->pddr);
data |= mcfgpio_bit(chip->base + offset);
mcfgpio_write(data, mcf_chip->pddr);
local_irq_restore(flags);
return 0;
}
void mcf_gpio_set_value(struct gpio_chip *chip, unsigned offset, int value)
{
struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
unsigned long flags;
MCFGPIO_PORTTYPE data;
local_irq_save(flags);
data = mcfgpio_read(mcf_chip->podr);
if (value)
data |= mcfgpio_bit(chip->base + offset);
else
data &= ~mcfgpio_bit(chip->base + offset);
mcfgpio_write(data, mcf_chip->podr);
local_irq_restore(flags);
}
void mcf_gpio_set_value_fast(struct gpio_chip *chip, unsigned offset, int value)
{
struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
if (value)
mcfgpio_write(mcfgpio_bit(chip->base + offset), mcf_chip->setr);
else
mcfgpio_write(~mcfgpio_bit(chip->base + offset), mcf_chip->clrr);
}
int mcf_gpio_request(struct gpio_chip *chip, unsigned offset)
{
struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
return mcf_chip->gpio_to_pinmux ?
mcf_pinmux_request(mcf_chip->gpio_to_pinmux[offset], 0) : 0;
}
void mcf_gpio_free(struct gpio_chip *chip, unsigned offset)
{
struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
mcf_gpio_direction_input(chip, offset);
if (mcf_chip->gpio_to_pinmux)
mcf_pinmux_release(mcf_chip->gpio_to_pinmux[offset], 0);
}
struct sysdev_class mcf_gpio_sysclass = {
.name = "gpio",
};
static int __init mcf_gpio_sysinit(void)
{
return sysdev_class_register(&mcf_gpio_sysclass);
}
core_initcall(mcf_gpio_sysinit);
/*
* intc-1.c
*
* (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/traps.h>
/*
* Each vector needs a unique priority and level asscoiated with it.
* We don't really care so much what they are, we don't rely on the
* tranditional priority interrupt scheme of the m68k/ColdFire.
*/
static u8 intc_intpri = 0x36;
static void intc_irq_mask(unsigned int irq)
{
if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
unsigned long imraddr;
u32 val, imrbit;
irq -= MCFINT_VECBASE;
imraddr = MCF_IPSBAR;
imraddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
imraddr += (irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL;
imrbit = 0x1 << (irq & 0x1f);
val = __raw_readl(imraddr);
__raw_writel(val | imrbit, imraddr);
}
}
static void intc_irq_unmask(unsigned int irq)
{
if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
unsigned long intaddr, imraddr, icraddr;
u32 val, imrbit;
irq -= MCFINT_VECBASE;
intaddr = MCF_IPSBAR;
intaddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
imraddr = intaddr + ((irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL);
icraddr = intaddr + MCFINTC_ICR0 + (irq & 0x3f);
imrbit = 0x1 << (irq & 0x1f);
/* Don't set the "maskall" bit! */
if ((irq & 0x20) == 0)
imrbit |= 0x1;
if (__raw_readb(icraddr) == 0)
__raw_writeb(intc_intpri--, icraddr);
val = __raw_readl(imraddr);
__raw_writel(val & ~imrbit, imraddr);
}
}
static struct irq_chip intc_irq_chip = {
.name = "CF-INTC",
.mask = intc_irq_mask,
.unmask = intc_irq_unmask,
};
void __init init_IRQ(void)
{
int irq;
init_vectors();
/* Mask all interrupt sources */
__raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
__raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC1 + MCFINTC_IMRL);
for (irq = 0; (irq < NR_IRQS); irq++) {
irq_desc[irq].status = IRQ_DISABLED;
irq_desc[irq].action = NULL;
irq_desc[irq].depth = 1;
irq_desc[irq].chip = &intc_irq_chip;
}
}
/*
* intc-simr.c
*
* (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/traps.h>
static void intc_irq_mask(unsigned int irq)
{
if (irq >= MCFINT_VECBASE) {
if (irq < MCFINT_VECBASE + 64)
__raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_SIMR);
else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_SIMR)
__raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_SIMR);
}
}
static void intc_irq_unmask(unsigned int irq)
{
if (irq >= MCFINT_VECBASE) {
if (irq < MCFINT_VECBASE + 64)
__raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_CIMR);
else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_CIMR)
__raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_CIMR);
}
}
static int intc_irq_set_type(unsigned int irq, unsigned int type)
{
if (irq >= MCFINT_VECBASE) {
if (irq < MCFINT_VECBASE + 64)
__raw_writeb(5, MCFINTC0_ICR0 + irq - MCFINT_VECBASE);
else if ((irq < MCFINT_VECBASE) && MCFINTC1_ICR0)
__raw_writeb(5, MCFINTC1_ICR0 + irq - MCFINT_VECBASE - 64);
}
return 0;
}
static struct irq_chip intc_irq_chip = {
.name = "CF-INTC",
.mask = intc_irq_mask,
.unmask = intc_irq_unmask,
.set_type = intc_irq_set_type,
};
void __init init_IRQ(void)
{
int irq;
init_vectors();
/* Mask all interrupt sources */
__raw_writeb(0xff, MCFINTC0_SIMR);
if (MCFINTC1_SIMR)
__raw_writeb(0xff, MCFINTC1_SIMR);
for (irq = 0; (irq < NR_IRQS); irq++) {
irq_desc[irq].status = IRQ_DISABLED;
irq_desc[irq].action = NULL;
irq_desc[irq].depth = 1;
irq_desc[irq].chip = &intc_irq_chip;
intc_irq_set_type(irq, 0);
}
}
/*
* intc.c -- support for the old ColdFire interrupt controller
*
* (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/traps.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
/*
* The mapping of irq number to a mask register bit is not one-to-one.
* The irq numbers are either based on "level" of interrupt or fixed
* for an autovector-able interrupt. So we keep a local data structure
* that maps from irq to mask register. Not all interrupts will have
* an IMR bit.
*/
unsigned char mcf_irq2imr[NR_IRQS];
/*
* Define the miniumun and maximum external interrupt numbers.
* This is also used as the "level" interrupt numbers.
*/
#define EIRQ1 25
#define EIRQ7 31
/*
* In the early version 2 core ColdFire parts the IMR register was 16 bits
* in size. Version 3 (and later version 2) core parts have a 32 bit
* sized IMR register. Provide some size independant methods to access the
* IMR register.
*/
#ifdef MCFSIM_IMR_IS_16BITS
void mcf_setimr(int index)
{
u16 imr;
imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
__raw_writew(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
}
void mcf_clrimr(int index)
{
u16 imr;
imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
__raw_writew(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
}
void mcf_maskimr(unsigned int mask)
{
u16 imr;
imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
imr |= mask;
__raw_writew(imr, MCF_MBAR + MCFSIM_IMR);
}
#else
void mcf_setimr(int index)
{
u32 imr;
imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
__raw_writel(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
}
void mcf_clrimr(int index)
{
u32 imr;
imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
__raw_writel(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
}
void mcf_maskimr(unsigned int mask)
{
u32 imr;
imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
imr |= mask;
__raw_writel(imr, MCF_MBAR + MCFSIM_IMR);
}
#endif
/*
* Interrupts can be "vectored" on the ColdFire cores that support this old
* interrupt controller. That is, the device raising the interrupt can also
* supply the vector number to interrupt through. The AVR register of the
* interrupt controller enables or disables this for each external interrupt,
* so provide generic support for this. Setting this up is out-of-band for
* the interrupt system API's, and needs to be done by the driver that
* supports this device. Very few devices actually use this.
*/
void mcf_autovector(int irq)
{
#ifdef MCFSIM_AVR
if ((irq >= EIRQ1) && (irq <= EIRQ7)) {
u8 avec;
avec = __raw_readb(MCF_MBAR + MCFSIM_AVR);
avec |= (0x1 << (irq - EIRQ1 + 1));
__raw_writeb(avec, MCF_MBAR + MCFSIM_AVR);
}
#endif
}
static void intc_irq_mask(unsigned int irq)
{
if (mcf_irq2imr[irq])
mcf_setimr(mcf_irq2imr[irq]);
}
static void intc_irq_unmask(unsigned int irq)
{
if (mcf_irq2imr[irq])
mcf_clrimr(mcf_irq2imr[irq]);
}
static int intc_irq_set_type(unsigned int irq, unsigned int type)
{
return 0;
}
static struct irq_chip intc_irq_chip = {
.name = "CF-INTC",
.mask = intc_irq_mask,
.unmask = intc_irq_unmask,
.set_type = intc_irq_set_type,
};
void __init init_IRQ(void)
{
int irq;
init_vectors();
mcf_maskimr(0xffffffff);
for (irq = 0; (irq < NR_IRQS); irq++) {
irq_desc[irq].status = IRQ_DISABLED;
irq_desc[irq].action = NULL;
irq_desc[irq].depth = 1;
irq_desc[irq].chip = &intc_irq_chip;
intc_irq_set_type(irq, 0);
}
}
/*
* Coldfire generic GPIO pinmux support.
*
* (C) Copyright 2009, 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 as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*
*/
#include <linux/kernel.h>
#include <asm/pinmux.h>
int mcf_pinmux_request(unsigned pinmux, unsigned func)
{
return 0;
}
void mcf_pinmux_release(unsigned pinmux, unsigned func)
{
}
......@@ -32,7 +32,6 @@
*/
#define FREQ ((MCF_CLK / 2) / 64)
#define TA(a) (MCF_IPSBAR + MCFPIT_BASE1 + (a))
#define INTC0 (MCF_IPSBAR + MCFICM_INTC0)
#define PIT_CYCLES_PER_JIFFY (FREQ / HZ)
static u32 pit_cnt;
......@@ -154,8 +153,6 @@ static struct clocksource pit_clk = {
void hw_timer_init(void)
{
u32 imr;
cf_pit_clockevent.cpumask = cpumask_of(smp_processor_id());
cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32);
cf_pit_clockevent.max_delta_ns =
......@@ -166,11 +163,6 @@ void hw_timer_init(void)
setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &pit_irq);
__raw_writeb(ICR_INTRCONF, INTC0 + MCFINTC_ICR0 + MCFINT_PIT1);
imr = __raw_readl(INTC0 + MCFPIT_IMR);
imr &= ~MCFPIT_IMR_IBIT;
__raw_writel(imr, INTC0 + MCFPIT_IMR);
pit_clk.mult = clocksource_hz2mult(FREQ, pit_clk.shift);
clocksource_register(&pit_clk);
}
......
......@@ -30,20 +30,10 @@
#define FREQ (MCF_BUSCLK / 16)
#define TA(a) (MCF_MBAR + MCFTIMER_BASE1 + (a))
/*
* Default the timer and vector to use for ColdFire. Some ColdFire
* CPU's and some boards may want different. Their sub-architecture
* startup code (in config.c) can change these if they want.
*/
unsigned int mcf_timervector = 29;
unsigned int mcf_profilevector = 31;
unsigned int mcf_timerlevel = 5;
/*
* These provide the underlying interrupt vector support.
* Unfortunately it is a little different on each ColdFire.
*/
extern void mcf_settimericr(int timer, int level);
void coldfire_profile_init(void);
#if defined(CONFIG_M532x)
......@@ -107,8 +97,6 @@ static struct clocksource mcftmr_clk = {
void hw_timer_init(void)
{
setup_irq(mcf_timervector, &mcftmr_timer_irq);
__raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
mcftmr_cycles_per_jiffy = FREQ / HZ;
/*
......@@ -124,7 +112,7 @@ void hw_timer_init(void)
mcftmr_clk.mult = clocksource_hz2mult(FREQ, mcftmr_clk.shift);
clocksource_register(&mcftmr_clk);
mcf_settimericr(1, mcf_timerlevel);
setup_irq(MCF_IRQ_TIMER, &mcftmr_timer_irq);
#ifdef CONFIG_HIGHPROFILE
coldfire_profile_init();
......@@ -171,8 +159,6 @@ void coldfire_profile_init(void)
printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n",
PROFILEHZ);
setup_irq(mcf_profilevector, &coldfire_profile_irq);
/* Set up TIMER 2 as high speed profile clock */
__raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR));
......@@ -180,7 +166,7 @@ void coldfire_profile_init(void)
__raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR));
mcf_settimericr(2, 7);
setup_irq(MCF_IRQ_PROFILER, &coldfire_profile_irq);
}
/***************************************************************************/
......
/***************************************************************************/
/*
* linux/arch/m68knommu/platform/5307/vectors.c
* linux/arch/m68knommu/platform/coldfire/vectors.c
*
* Copyright (C) 1999-2007, Greg Ungerer <gerg@snapgear.com>
*/
......@@ -15,7 +15,6 @@
#include <asm/machdep.h>
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfdma.h>
#include <asm/mcfwdebug.h>
/***************************************************************************/
......@@ -79,20 +78,3 @@ void __init init_vectors(void)
}
/***************************************************************************/
void enable_vector(unsigned int irq)
{
/* Currently no action on ColdFire */
}
void disable_vector(unsigned int irq)
{
/* Currently no action on ColdFire */
}
void ack_vector(unsigned int irq)
{
/* Currently no action on ColdFire */
}
/***************************************************************************/
......@@ -1154,19 +1154,9 @@ static void __inline__ fec_request_mii_intr(struct net_device *dev)
printk("FEC: Could not allocate fec(MII) IRQ(66)!\n");
}
static void __inline__ fec_disable_phy_intr(void)
static void __inline__ fec_disable_phy_intr(struct net_device *dev)
{
volatile unsigned long *icrp;
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
*icrp = 0x08000000;
}
static void __inline__ fec_phy_ack_intr(void)
{
volatile unsigned long *icrp;
/* Acknowledge the interrupt */
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
*icrp = 0x0d000000;
free_irq(66, dev);
}
#endif
......@@ -1398,7 +1388,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
writel(0, fep->hwp + FEC_MII_SPEED);
fep->phy_speed = 0;
#ifdef HAVE_mii_link_interrupt
fec_disable_phy_intr();
fec_disable_phy_intr(dev);
#endif
}
}
......@@ -1411,8 +1401,6 @@ mii_link_interrupt(int irq, void * dev_id)
struct net_device *dev = dev_id;
struct fec_enet_private *fep = netdev_priv(dev);
fec_phy_ack_intr();
mii_do_cmd(dev, fep->phy->ack_int);
mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */
......
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