diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-05-18 10:37:05 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-05-18 10:37:05 +1000 |
commit | fe66b6e6b11e7f28a0d0dc82c4934fbaf7ed64a3 (patch) | |
tree | 4e46c049a6c2ba02038a91d23525b2926ea08ebd /arch | |
parent | 61925b96da374ad56b9ca39aa4becf56be46eec3 (diff) | |
parent | 28e2d111964379b902c98aaadf557b8b100887de (diff) |
Merge commit 'm68knommu/for-next'
Diffstat (limited to 'arch')
44 files changed, 1439 insertions, 1819 deletions
diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h index 1cf544767453..87cabc334249 100644 --- a/arch/m68k/include/asm/checksum.h +++ b/arch/m68k/include/asm/checksum.h @@ -1,5 +1,159 @@ -#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_MMU +/* + * 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; +} #else -#include "checksum_mm.h" +__sum16 ip_fast_csum(const void *iph, unsigned int ihl); #endif + +/* + * 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" (tmp)); + return (__force __sum16)~sum; +#endif +} + + +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 */ diff --git a/arch/m68k/include/asm/checksum_mm.h b/arch/m68k/include/asm/checksum_mm.h deleted file mode 100644 index 494f9aec37ea..000000000000 --- a/arch/m68k/include/asm/checksum_mm.h +++ /dev/null @@ -1,148 +0,0 @@ -#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 */ diff --git a/arch/m68k/include/asm/checksum_no.h b/arch/m68k/include/asm/checksum_no.h deleted file mode 100644 index 81883482ffb1..000000000000 --- a/arch/m68k/include/asm/checksum_no.h +++ /dev/null @@ -1,132 +0,0 @@ -#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 */ diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h index b82e660cf1c2..1f1fcdf5e49e 100644 --- a/arch/m68k/include/asm/dma.h +++ b/arch/m68k/include/asm/dma.h @@ -1,5 +1,492 @@ -#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 */ diff --git a/arch/m68k/include/asm/dma_mm.h b/arch/m68k/include/asm/dma_mm.h deleted file mode 100644 index 4240fbc946f8..000000000000 --- a/arch/m68k/include/asm/dma_mm.h +++ /dev/null @@ -1,16 +0,0 @@ -#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 */ diff --git a/arch/m68k/include/asm/dma_no.h b/arch/m68k/include/asm/dma_no.h deleted file mode 100644 index 939a02056217..000000000000 --- a/arch/m68k/include/asm/dma_no.h +++ /dev/null @@ -1,494 +0,0 @@ -#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 */ diff --git a/arch/m68k/include/asm/hardirq.h b/arch/m68k/include/asm/hardirq.h index 56d0d5db231c..7167ed209823 100644 --- a/arch/m68k/include/asm/hardirq.h +++ b/arch/m68k/include/asm/hardirq.h @@ -1,5 +1,18 @@ -#ifdef __uClinux__ -#include "hardirq_no.h" -#else -#include "hardirq_mm.h" +#ifndef __M68K_HARDIRQ_H +#define __M68K_HARDIRQ_H + +#include <linux/threads.h> +#include <linux/cache.h> + +/* entry.S is sensitive to the offsets of these fields */ +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 + +void ack_bad_irq(unsigned int irq); + #endif diff --git a/arch/m68k/include/asm/hardirq_mm.h b/arch/m68k/include/asm/hardirq_mm.h deleted file mode 100644 index 394ee946015c..000000000000 --- a/arch/m68k/include/asm/hardirq_mm.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __M68K_HARDIRQ_H -#define __M68K_HARDIRQ_H - -#include <linux/threads.h> -#include <linux/cache.h> - -/* entry.S is sensitive to the offsets of these fields */ -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 - -#endif diff --git a/arch/m68k/include/asm/hardirq_no.h b/arch/m68k/include/asm/hardirq_no.h deleted file mode 100644 index bfad28149a49..000000000000 --- a/arch/m68k/include/asm/hardirq_no.h +++ /dev/null @@ -1,27 +0,0 @@ -#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 - -/* - * 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 - -void ack_bad_irq(unsigned int irq); - -#endif /* __M68K_HARDIRQ_H */ diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index d031416595b2..cc0614a6deeb 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -1,5 +1,134 @@ -#ifdef __uClinux__ -#include "irq_no.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_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 + +/* + * 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 + +#ifdef CONFIG_MMU + +/* + * 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_ */ diff --git a/arch/m68k/include/asm/irq_mm.h b/arch/m68k/include/asm/irq_mm.h deleted file mode 100644 index 0cab42cad79e..000000000000 --- a/arch/m68k/include/asm/irq_mm.h +++ /dev/null @@ -1,126 +0,0 @@ -#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_ */ diff --git a/arch/m68k/include/asm/irq_no.h b/arch/m68k/include/asm/irq_no.h deleted file mode 100644 index 9373c31ac87d..000000000000 --- a/arch/m68k/include/asm/irq_no.h +++ /dev/null @@ -1,26 +0,0 @@ -#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_ */ diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h index 49d016e6391a..7d76b8747e35 100644 --- a/arch/m68k/include/asm/m520xsim.h +++ b/arch/m68k/include/asm/m520xsim.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 */ @@ -55,9 +68,14 @@ #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. + */ +#define MCF_RCR 0xFC0A0000 +#define MCF_RSR 0xFC0A0001 + +#define MCF_RCR_SWRESET 0x80 /* Software reset bit */ +#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */ /****************************************************************************/ #endif /* m520xsim_h */ diff --git a/arch/m68k/include/asm/m523xsim.h b/arch/m68k/include/asm/m523xsim.h index bf397313e93f..55183b5df1b8 100644 --- a/arch/m68k/include/asm/m523xsim.h +++ b/arch/m68k/include/asm/m523xsim.h @@ -41,5 +41,14 @@ #define MCFSIM_DACR1 0x50 /* SDRAM base address 1 */ #define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */ +/* + * Reset Controll Unit (relative to IPSBAR). + */ +#define MCF_RCR 0x110000 +#define MCF_RSR 0x110001 + +#define MCF_RCR_SWRESET 0x80 /* Software reset bit */ +#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */ + /****************************************************************************/ #endif /* m523xsim_h */ diff --git a/arch/m68k/include/asm/m527xsim.h b/arch/m68k/include/asm/m527xsim.h index 1f63ab3fb3e6..95f4f8ee8f7c 100644 --- a/arch/m68k/include/asm/m527xsim.h +++ b/arch/m68k/include/asm/m527xsim.h @@ -70,5 +70,14 @@ #define UART2_ENABLE_MASK 0x3f00 #endif +/* + * Reset Controll Unit (relative to IPSBAR). + */ +#define MCF_RCR 0x110000 +#define MCF_RSR 0x110001 + +#define MCF_RCR_SWRESET 0x80 /* Software reset bit */ +#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */ + /****************************************************************************/ #endif /* m527xsim_h */ diff --git a/arch/m68k/include/asm/m528xsim.h b/arch/m68k/include/asm/m528xsim.h index 28bf783a5d6d..d79c49f8134a 100644 --- a/arch/m68k/include/asm/m528xsim.h +++ b/arch/m68k/include/asm/m528xsim.h @@ -56,6 +56,14 @@ #define MCF5282_INTC0_ICR17 (volatile u8 *) (MCF_IPSBAR + 0x0C51) +/* + * Reset Control Unit (relative to IPSBAR). + */ +#define MCF_RCR 0x110000 +#define MCF_RSR 0x110001 + +#define MCF_RCR_SWRESET 0x80 /* Software reset bit */ +#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */ /********************************************************************* * diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h index ce603451b55e..d563b6bcc738 100644 --- a/arch/m68k/include/asm/m532xsim.h +++ b/arch/m68k/include/asm/m532xsim.h @@ -56,49 +56,18 @@ #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 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 the Cache register flags. */ #define CACR_EC (1<<31) @@ -127,6 +96,18 @@ /********************************************************************* * + * Reset Controller Module + * + *********************************************************************/ + +#define MCF_RCR 0xFC0A0000 +#define MCF_RSR 0xFC0A0001 + +#define MCF_RCR_SWRESET 0x80 /* Software reset bit */ +#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */ + +/********************************************************************* + * * Inter-IC (I2C) Module * *********************************************************************/ diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h index da3f2ceff3a4..b90425fb50fe 100644 --- a/arch/m68k/include/asm/mcfsim.h +++ b/arch/m68k/include/asm/mcfsim.h @@ -101,20 +101,6 @@ #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. diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h index fc3f2c22f2b8..74fd674b15ad 100644 --- a/arch/m68k/include/asm/processor.h +++ b/arch/m68k/include/asm/processor.h @@ -1,5 +1,170 @@ -#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 diff --git a/arch/m68k/include/asm/processor_mm.h b/arch/m68k/include/asm/processor_mm.h deleted file mode 100644 index 1f61ef53f0e0..000000000000 --- a/arch/m68k/include/asm/processor_mm.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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 diff --git a/arch/m68k/include/asm/processor_no.h b/arch/m68k/include/asm/processor_no.h deleted file mode 100644 index 91cba18acdd3..000000000000 --- a/arch/m68k/include/asm/processor_no.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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 { \ - sizeof(init_stack) + (unsigned long) init_stack, 0, \ - PS_S, __KERNEL_DS, \ - {0, 0}, 0, {0,}, {0, 0, 0}, {0,}, \ -} - -/* - * 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 diff --git a/arch/m68k/include/asm/system_no.h b/arch/m68k/include/asm/system_no.h index 4496c0aa8379..3c0718d74398 100644 --- a/arch/m68k/include/asm/system_no.h +++ b/arch/m68k/include/asm/system_no.h @@ -203,113 +203,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz #include <asm-generic/cmpxchg.h> #endif -#if defined( CONFIG_M68328 ) || defined( CONFIG_M68EZ328 ) || \ - defined (CONFIG_M68360) || defined( CONFIG_M68VZ328 ) -#define HARD_RESET_NOW() ({ \ - local_irq_disable(); \ - asm(" \ - moveal #0x10c00000, %a0; \ - moveb #0, 0xFFFFF300; \ - moveal 0(%a0), %sp; \ - moveal 4(%a0), %a0; \ - jmp (%a0); \ - "); \ -}) -#endif - -#ifdef CONFIG_COLDFIRE -#if defined(CONFIG_M5272) && defined(CONFIG_NETtel) -/* - * Need to account for broken early mask of 5272 silicon. So don't - * jump through the original start address. Jump strait into the - * known start of the FLASH code. - */ -#define HARD_RESET_NOW() ({ \ - asm(" \ - movew #0x2700, %sr; \ - jmp 0xf0000400; \ - "); \ -}) -#elif defined(CONFIG_NETtel) || \ - defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA) -#define HARD_RESET_NOW() ({ \ - asm(" \ - movew #0x2700, %sr; \ - moveal #0x10000044, %a0; \ - movel #0xffffffff, (%a0); \ - moveal #0x10000001, %a0; \ - moveb #0x00, (%a0); \ - moveal #0xf0000004, %a0; \ - moveal (%a0), %a0; \ - jmp (%a0); \ - "); \ -}) -#elif defined(CONFIG_M5272) -/* - * Retrieve the boot address in flash using CSBR0 and CSOR0 - * find the reset vector at flash_address + 4 (e.g. 0x400) - * remap it in the flash's current location (e.g. 0xf0000400) - * and jump there. - */ -#define HARD_RESET_NOW() ({ \ - asm(" \ - movew #0x2700, %%sr; \ - move.l %0+0x40,%%d0; \ - and.l %0+0x44,%%d0; \ - andi.l #0xfffff000,%%d0; \ - mov.l %%d0,%%a0; \ - or.l 4(%%a0),%%d0; \ - mov.l %%d0,%%a0; \ - jmp (%%a0);" \ - : /* No output */ \ - : "o" (*(char *)MCF_MBAR) ); \ -}) -#elif defined(CONFIG_M528x) -/* - * The MCF528x has a bit (SOFTRST) in memory (Reset Control Register RCR), - * that when set, resets the MCF528x. - */ -#define HARD_RESET_NOW() \ -({ \ - unsigned char volatile *reset; \ - asm("move.w #0x2700, %sr"); \ - reset = ((volatile unsigned char *)(MCF_IPSBAR + 0x110000)); \ - while(1) \ - *reset |= (0x01 << 7);\ -}) -#elif defined(CONFIG_M523x) -#define HARD_RESET_NOW() ({ \ - asm(" \ - movew #0x2700, %sr; \ - movel #0x01000000, %sp; \ - moveal #0x40110000, %a0; \ - moveb #0x80, (%a0); \ - "); \ -}) -#elif defined(CONFIG_M520x) - /* - * The MCF5208 has a bit (SOFTRST) in memory (Reset Control Register - * RCR), that when set, resets the MCF5208. - */ -#define HARD_RESET_NOW() \ -({ \ - unsigned char volatile *reset; \ - asm("move.w #0x2700, %sr"); \ - reset = ((volatile unsigned char *)(MCF_IPSBAR + 0xA0000)); \ - while(1) \ - *reset |= 0x80; \ -}) -#else -#define HARD_RESET_NOW() ({ \ - asm(" \ - movew #0x2700, %sr; \ - moveal #0x4, %a0; \ - moveal (%a0), %a0; \ - jmp (%a0); \ - "); \ -}) -#endif -#endif #define arch_align_stack(x) (x) diff --git a/arch/m68knommu/kernel/entry.S b/arch/m68knommu/kernel/entry.S index f4782d2dce8f..f56faa5c9cd9 100644 --- a/arch/m68knommu/kernel/entry.S +++ b/arch/m68knommu/kernel/entry.S @@ -26,7 +26,6 @@ #include <linux/sys.h> #include <linux/linkage.h> -#include <asm/thread_info.h> #include <asm/errno.h> #include <asm/setup.h> #include <asm/segment.h> diff --git a/arch/m68knommu/kernel/irq.c b/arch/m68knommu/kernel/irq.c index 56e0f4c55a67..3e56f60882b5 100644 --- a/arch/m68knommu/kernel/irq.c +++ b/arch/m68knommu/kernel/irq.c @@ -34,27 +34,6 @@ 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; diff --git a/arch/m68knommu/lib/checksum.c b/arch/m68knommu/lib/checksum.c index 269d83bfbbe1..8bf012aec81c 100644 --- a/arch/m68knommu/lib/checksum.c +++ b/arch/m68knommu/lib/checksum.c @@ -127,15 +127,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 */ diff --git a/arch/m68knommu/platform/5206/config.c b/arch/m68knommu/platform/5206/config.c index 53a5920c2b71..f6f79874e9af 100644 --- a/arch/m68knommu/platform/5206/config.c +++ b/arch/m68knommu/platform/5206/config.c @@ -12,7 +12,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> @@ -21,10 +20,6 @@ /***************************************************************************/ -void coldfire_reset(void); - -/***************************************************************************/ - static struct mcf_platform_uart m5206_uart_platform[] = { { .mapbase = MCF_MBAR + MCFUART_BASE1, @@ -109,10 +104,21 @@ void mcf_settimericr(unsigned int timer, unsigned int level) /***************************************************************************/ +void m5206_cpu_reset(void) +{ + local_irq_disable(); + /* Set watchdog to soft reset, and enabled */ + __raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR); + for (;;) + /* wait for watchdog to timeout */; +} + +/***************************************************************************/ + void __init config_BSP(char *commandp, int size) { mcf_setimr(MCFSIM_IMR_MASKALL); - mach_reset = coldfire_reset; + mach_reset = m5206_cpu_reset; } /***************************************************************************/ diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c index db902540bf2c..65887799db81 100644 --- a/arch/m68knommu/platform/5206e/config.c +++ b/arch/m68knommu/platform/5206e/config.c @@ -11,7 +11,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> @@ -21,10 +20,6 @@ /***************************************************************************/ -void coldfire_reset(void); - -/***************************************************************************/ - static struct mcf_platform_uart m5206e_uart_platform[] = { { .mapbase = MCF_MBAR + MCFUART_BASE1, @@ -109,6 +104,17 @@ void mcf_settimericr(unsigned int timer, unsigned int level) /***************************************************************************/ +void m5206e_cpu_reset(void) +{ + local_irq_disable(); + /* Set watchdog to soft reset, and enabled */ + __raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR); + for (;;) + /* wait for watchdog to timeout */; +} + +/***************************************************************************/ + void __init config_BSP(char *commandp, int size) { mcf_setimr(MCFSIM_IMR_MASKALL); @@ -119,7 +125,7 @@ void __init config_BSP(char *commandp, int size) commandp[size-1] = 0; #endif /* CONFIG_NETtel */ - mach_reset = coldfire_reset; + mach_reset = m5206e_cpu_reset; } /***************************************************************************/ diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68knommu/platform/520x/config.c index 855fc6a79d72..92614de42cd3 100644 --- a/arch/m68knommu/platform/520x/config.c +++ b/arch/m68knommu/platform/520x/config.c @@ -14,7 +14,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> @@ -23,10 +22,6 @@ /***************************************************************************/ -void coldfire_reset(void); - -/***************************************************************************/ - static struct mcf_platform_uart m520x_uart_platform[] = { { .mapbase = MCF_MBAR + MCFUART_BASE1, @@ -86,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); @@ -136,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); @@ -158,20 +134,17 @@ static void __init m520x_fec_init(void) /***************************************************************************/ -/* - * Program the vector to be an auto-vectored. - */ - -void mcf_autovector(unsigned int vec) +static void m520x_cpu_reset(void) { - /* Everything is auto-vectored on the 520x devices */ + local_irq_disable(); + __raw_writeb(MCF_RCR_SWRESET, MCF_RCR); } /***************************************************************************/ void __init config_BSP(char *commandp, int size) { - mach_reset = coldfire_reset; + mach_reset = m520x_cpu_reset; m520x_uarts_init(); m520x_fec_init(); } diff --git a/arch/m68knommu/platform/523x/config.c b/arch/m68knommu/platform/523x/config.c index 74133f27b30c..00f08d2e43b0 100644 --- a/arch/m68knommu/platform/523x/config.c +++ b/arch/m68knommu/platform/523x/config.c @@ -15,7 +15,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> @@ -24,10 +23,6 @@ /***************************************************************************/ -void coldfire_reset(void); - -/***************************************************************************/ - static struct mcf_platform_uart m523x_uart_platform[] = { { .mapbase = MCF_MBAR + MCFUART_BASE1, @@ -87,73 +82,17 @@ 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; -} - -/***************************************************************************/ - -void mcf_autovector(unsigned int vec) +static void m523x_cpu_reset(void) { - /* Everything is auto-vectored on the 523x */ + local_irq_disable(); + __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR); } /***************************************************************************/ void __init config_BSP(char *commandp, int size) { - mcf_disableall(); - mach_reset = coldfire_reset; - m523x_uarts_init(); - m523x_fec_init(); + mach_reset = m523x_cpu_reset; } /***************************************************************************/ diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c index 9eab19d01eb1..93d998825925 100644 --- a/arch/m68knommu/platform/5249/config.c +++ b/arch/m68knommu/platform/5249/config.c @@ -11,7 +11,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> @@ -20,10 +19,6 @@ /***************************************************************************/ -void coldfire_reset(void); - -/***************************************************************************/ - static struct mcf_platform_uart m5249_uart_platform[] = { { .mapbase = MCF_MBAR + MCFUART_BASE1, @@ -106,10 +101,21 @@ void mcf_settimericr(unsigned int timer, unsigned int level) /***************************************************************************/ +void m5249_cpu_reset(void) +{ + local_irq_disable(); + /* Set watchdog to soft reset, and enabled */ + __raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR); + for (;;) + /* wait for watchdog to timeout */; +} + +/***************************************************************************/ + void __init config_BSP(char *commandp, int size) { mcf_setimr(MCFSIM_IMR_MASKALL); - mach_reset = coldfire_reset; + mach_reset = m5249_cpu_reset; } /***************************************************************************/ diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c index e049245f4092..5f95fcde05fd 100644 --- a/arch/m68knommu/platform/5272/config.c +++ b/arch/m68knommu/platform/5272/config.c @@ -12,7 +12,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> @@ -21,8 +20,6 @@ /***************************************************************************/ -void coldfire_reset(void); - extern unsigned int mcf_timervector; extern unsigned int mcf_profilevector; extern unsigned int mcf_timerlevel; @@ -170,6 +167,19 @@ void mcf_settimericr(int timer, int level) /***************************************************************************/ +static void m5272_cpu_reset(void) +{ + local_irq_disable(); + /* Set watchdog to reset, and enabled */ + __raw_writew(0, MCF_MBAR + MCFSIM_WIRR); + __raw_writew(1, MCF_MBAR + MCFSIM_WRRR); + __raw_writew(0, MCF_MBAR + MCFSIM_WCR); + for (;;) + /* wait for watchdog to timeout */; +} + +/***************************************************************************/ + void __init config_BSP(char *commandp, int size) { #if defined (CONFIG_MOD5272) @@ -194,7 +204,7 @@ void __init config_BSP(char *commandp, int size) mcf_timervector = 69; mcf_profilevector = 70; - mach_reset = coldfire_reset; + mach_reset = m5272_cpu_reset; } /***************************************************************************/ diff --git a/arch/m68knommu/platform/527x/config.c b/arch/m68knommu/platform/527x/config.c index 428b15922ef5..fa51be172830 100644 --- a/arch/m68knommu/platform/527x/config.c +++ b/arch/m68knommu/platform/527x/config.c @@ -15,7 +15,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> @@ -24,10 +23,6 @@ /***************************************************************************/ -void coldfire_reset(void); - -/***************************************************************************/ - static struct mcf_platform_uart m527x_uart_platform[] = { { .mapbase = MCF_MBAR + MCFUART_BASE1, @@ -121,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 */ @@ -162,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); @@ -200,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); @@ -212,25 +174,17 @@ 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) +static void m527x_cpu_reset(void) { - /* Everything is auto-vectored on the 5272 */ + local_irq_disable(); + __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR); } /***************************************************************************/ void __init config_BSP(char *commandp, int size) { - mcf_disableall(); - mach_reset = coldfire_reset; + mach_reset = m527x_cpu_reset; m527x_uarts_init(); m527x_fec_init(); } diff --git a/arch/m68knommu/platform/528x/config.c b/arch/m68knommu/platform/528x/config.c index bee526f4d1af..6e608d1836f1 100644 --- a/arch/m68knommu/platform/528x/config.c +++ b/arch/m68knommu/platform/528x/config.c @@ -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,24 +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 - -/***************************************************************************/ - -void coldfire_reset(void); - /***************************************************************************/ static struct mcf_platform_uart m528x_uart_platform[] = { @@ -95,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); @@ -133,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); @@ -156,17 +122,10 @@ 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) +static void m528x_cpu_reset(void) { - /* Everything is auto-vectored on the 5272 */ + local_irq_disable(); + __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR); } /***************************************************************************/ @@ -200,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 @@ -214,6 +171,7 @@ void __init config_BSP(char *commandp, int size) static int __init init_BSP(void) { + mach_reset = m528x_cpu_reset; m528x_uarts_init(); m528x_fec_init(); platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices)); diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c index 44803bf70a6e..39da9e9ff674 100644 --- a/arch/m68knommu/platform/5307/config.c +++ b/arch/m68knommu/platform/5307/config.c @@ -12,7 +12,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> @@ -22,8 +21,6 @@ /***************************************************************************/ -void coldfire_reset(void); - extern unsigned int mcf_timervector; extern unsigned int mcf_profilevector; extern unsigned int mcf_timerlevel; @@ -119,6 +116,17 @@ void mcf_settimericr(unsigned int timer, unsigned int level) /***************************************************************************/ +void m5307_cpu_reset(void) +{ + local_irq_disable(); + /* Set watchdog to soft reset, and enabled */ + __raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR); + for (;;) + /* wait for watchdog to timeout */; +} + +/***************************************************************************/ + void __init config_BSP(char *commandp, int size) { mcf_setimr(MCFSIM_IMR_MASKALL); @@ -134,7 +142,7 @@ void __init config_BSP(char *commandp, int size) mcf_timerlevel = 6; #endif - mach_reset = coldfire_reset; + mach_reset = m5307_cpu_reset; #ifdef CONFIG_BDM_DISABLE /* diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68knommu/platform/532x/config.c index 591f2f801134..47e4573c328e 100644 --- a/arch/m68knommu/platform/532x/config.c +++ b/arch/m68knommu/platform/532x/config.c @@ -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,8 +30,6 @@ /***************************************************************************/ -void coldfire_reset(void); - extern unsigned int mcf_timervector; extern unsigned int mcf_profilevector; extern unsigned int mcf_timerlevel; @@ -100,18 +97,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; } } @@ -127,14 +117,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); @@ -146,28 +128,20 @@ 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); - } } /***************************************************************************/ -void __init config_BSP(char *commandp, int size) +static void m532x_cpu_reset(void) { - mcf_setimr(MCFSIM_IMR_MASKALL); + local_irq_disable(); + __raw_writeb(MCF_RCR_SWRESET, MCF_RCR); +} + +/***************************************************************************/ +void __init config_BSP(char *commandp, int size) +{ #if !defined(CONFIG_BOOTPARAM) /* Copy command line from FLASH to local buffer... */ memcpy(commandp, (char *) 0x4000, 4); @@ -181,7 +155,7 @@ void __init config_BSP(char *commandp, int size) mcf_timervector = 64+32; mcf_profilevector = 64+33; - mach_reset = coldfire_reset; + mach_reset = m532x_cpu_reset; #ifdef CONFIG_BDM_DISABLE /* diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c index 0ee8c1a200c8..b41d942bf8d0 100644 --- a/arch/m68knommu/platform/5407/config.c +++ b/arch/m68knommu/platform/5407/config.c @@ -12,7 +12,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> @@ -21,8 +20,6 @@ /***************************************************************************/ -void coldfire_reset(void); - extern unsigned int mcf_timervector; extern unsigned int mcf_profilevector; extern unsigned int mcf_timerlevel; @@ -110,6 +107,17 @@ void mcf_settimericr(unsigned int timer, unsigned int level) /***************************************************************************/ +void m5407_cpu_reset(void) +{ + local_irq_disable(); + /* set watchdog to soft reset, and enabled */ + __raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR); + for (;;) + /* wait for watchdog to timeout */; +} + +/***************************************************************************/ + void __init config_BSP(char *commandp, int size) { mcf_setimr(MCFSIM_IMR_MASKALL); @@ -121,7 +129,7 @@ void __init config_BSP(char *commandp, int size) mcf_timerlevel = 6; #endif - mach_reset = coldfire_reset; + mach_reset = m5407_cpu_reset; } /***************************************************************************/ diff --git a/arch/m68knommu/platform/68328/ints.c b/arch/m68knommu/platform/68328/ints.c index 72e56d554f4f..dab623389a01 100644 --- a/arch/m68knommu/platform/68328/ints.c +++ b/arch/m68knommu/platform/68328/ints.c @@ -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; + } } diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c index c36781157e09..1143f77caca4 100644 --- a/arch/m68knommu/platform/68360/ints.c +++ b/arch/m68knommu/platform/68360/ints.c @@ -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; + } } diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile index 1bcb9372353f..85be019f378b 100644 --- a/arch/m68knommu/platform/coldfire/Makefile +++ b/arch/m68knommu/platform/coldfire/Makefile @@ -15,16 +15,16 @@ 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_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_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 intc.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 extra-y := head.o diff --git a/arch/m68knommu/platform/coldfire/intc-2.c b/arch/m68knommu/platform/coldfire/intc-2.c new file mode 100644 index 000000000000..5598c8b8661f --- /dev/null +++ b/arch/m68knommu/platform/coldfire/intc-2.c @@ -0,0 +1,93 @@ +/* + * 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; + } +} + diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68knommu/platform/coldfire/intc-simr.c new file mode 100644 index 000000000000..1b01e79c2f63 --- /dev/null +++ b/arch/m68knommu/platform/coldfire/intc-simr.c @@ -0,0 +1,78 @@ +/* + * 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); + } +} + diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c new file mode 100644 index 000000000000..c81ab6e5cf26 --- /dev/null +++ b/arch/m68knommu/platform/coldfire/intc.c @@ -0,0 +1,55 @@ +/* + * intc.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/traps.h> +#include <asm/coldfire.h> +#include <asm/mcfsim.h> + +static void intc_irq_mask(unsigned int irq) +{ +} + +static void intc_irq_unmask(unsigned int 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(); + + 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); + } +} + diff --git a/arch/m68knommu/platform/coldfire/pit.c b/arch/m68knommu/platform/coldfire/pit.c index 61b96211f8ff..d8720ee34510 100644 --- a/arch/m68knommu/platform/coldfire/pit.c +++ b/arch/m68knommu/platform/coldfire/pit.c @@ -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); } diff --git a/arch/m68knommu/platform/coldfire/vectors.c b/arch/m68knommu/platform/coldfire/vectors.c index 6cf894620234..a21d3f870b7a 100644 --- a/arch/m68knommu/platform/coldfire/vectors.c +++ b/arch/m68knommu/platform/coldfire/vectors.c @@ -1,7 +1,7 @@ /***************************************************************************/ /* - * 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,27 +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 */ -} - -/***************************************************************************/ - -void coldfire_reset(void) -{ - HARD_RESET_NOW(); -} - -/***************************************************************************/ |