Commit 66bc4a6f authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu: (53 commits)
  m68knommu: Make PAGE_SIZE available to assembly files.
  m68knommu: fix ColdFire definition of CLOCK_TICK_RATE
  m68knommu: set multi-function pins for ethernet when enabled
  m68knommu: remove special interrupt handling code for ne2k support
  m68knommu: relax IO_SPACE_LIMIT setting
  m68knommu: remove ColdFire direct interrupt register access
  m68knommu: create a speciailized ColdFire 5272 interrupt controller
  m68knommu: add support for second interrupt controller of ColdFire 5249
  m68knommu: clean up old ColdFire timer irq setup
  m68knommu: map ColdFire interrupts to correct masking bits
  m68knommu: clean up ColdFire 532x CPU timer setup
  m68knommu: simplify ColdFire "timers" clock initialization
  m68knommu: support code to mask external interrupts on old ColdFire CPU's
  m68knommu: merge old ColdFire interrupt controller masking macros
  m68knommu: remove duplicate ColdFire mcf_autovector() code
  m68knommu: move ColdFire INTC definitions to new include file
  m68knommu: mask off all interrupts in ColdFire intc-simr controller
  m68knommu: remove timer device interrupt setup for ColdFire 532x
  m68knommu: remove interrupt masking from ColdFire pit timer
  m68knommu: remove unecessary interrupt level setting in ColdFire 520x setup
  ...
parents 96c015b7 2985709d
#ifdef __uClinux__
#include "checksum_no.h"
#ifndef _M68K_CHECKSUM_H
#define _M68K_CHECKSUM_H
#include <linux/in6.h>
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
__wsum csum_partial(const void *buff, int len, __wsum sum);
/*
* the same as csum_partial, but copies from src while it
* checksums
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
extern __wsum csum_partial_copy_from_user(const void __user *src,
void *dst,
int len, __wsum sum,
int *csum_err);
extern __wsum csum_partial_copy_nocheck(const void *src,
void *dst, int len,
__wsum sum);
#ifdef CONFIG_COLDFIRE
/*
* The ColdFire cores don't support all the 68k instructions used
* in the optimized checksum code below. So it reverts back to using
* more standard C coded checksums. The fast checksum code is
* significantly larger than the optimized version, so it is not
* inlined here.
*/
__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
static inline __sum16 csum_fold(__wsum sum)
{
unsigned int tmp = (__force u32)sum;
tmp = (tmp & 0xffff) + (tmp >> 16);
tmp = (tmp & 0xffff) + (tmp >> 16);
return (__force __sum16)~tmp;
}
#else
#include "checksum_mm.h"
#endif
/*
* This is a version of ip_fast_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries.
*/
static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
{
unsigned int sum = 0;
unsigned long tmp;
__asm__ ("subqw #1,%2\n"
"1:\t"
"movel %1@+,%3\n\t"
"addxl %3,%0\n\t"
"dbra %2,1b\n\t"
"movel %0,%3\n\t"
"swap %3\n\t"
"addxw %3,%0\n\t"
"clrw %3\n\t"
"addxw %3,%0\n\t"
: "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp)
: "0" (sum), "1" (iph), "2" (ihl)
: "memory");
return (__force __sum16)~sum;
}
static inline __sum16 csum_fold(__wsum sum)
{
unsigned int tmp = (__force u32)sum;
__asm__("swap %1\n\t"
"addw %1, %0\n\t"
"clrw %1\n\t"
"addxw %1, %0"
: "=&d" (sum), "=&d" (tmp)
: "0" (sum), "1" (tmp));
return (__force __sum16)~sum;
}
#endif /* CONFIG_COLDFIRE */
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
__asm__ ("addl %2,%0\n\t"
"addxl %3,%0\n\t"
"addxl %4,%0\n\t"
"clrl %1\n\t"
"addxl %1,%0"
: "=&d" (sum), "=d" (saddr)
: "g" (daddr), "1" (saddr), "d" (len + proto),
"0" (sum));
return sum;
}
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
static inline __sum16 ip_compute_csum(const void *buff, int len)
{
return csum_fold (csum_partial(buff, len, 0));
}
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, unsigned short proto, __wsum sum)
{
register unsigned long tmp;
__asm__("addl %2@,%0\n\t"
"movel %2@(4),%1\n\t"
"addxl %1,%0\n\t"
"movel %2@(8),%1\n\t"
"addxl %1,%0\n\t"
"movel %2@(12),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@,%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(4),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(8),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(12),%1\n\t"
"addxl %1,%0\n\t"
"addxl %4,%0\n\t"
"clrl %1\n\t"
"addxl %1,%0"
: "=&d" (sum), "=&d" (tmp)
: "a" (saddr), "a" (daddr), "d" (len + proto),
"0" (sum));
return csum_fold(sum);
}
#endif /* _M68K_CHECKSUM_H */
#ifndef _M68K_CHECKSUM_H
#define _M68K_CHECKSUM_H
#include <linux/in6.h>
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
__wsum csum_partial(const void *buff, int len, __wsum sum);
/*
* the same as csum_partial, but copies from src while it
* checksums
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
extern __wsum csum_partial_copy_from_user(const void __user *src,
void *dst,
int len, __wsum sum,
int *csum_err);
extern __wsum csum_partial_copy_nocheck(const void *src,
void *dst, int len,
__wsum sum);
/*
* This is a version of ip_compute_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries.
*
*/
static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
{
unsigned int sum = 0;
unsigned long tmp;
__asm__ ("subqw #1,%2\n"
"1:\t"
"movel %1@+,%3\n\t"
"addxl %3,%0\n\t"
"dbra %2,1b\n\t"
"movel %0,%3\n\t"
"swap %3\n\t"
"addxw %3,%0\n\t"
"clrw %3\n\t"
"addxw %3,%0\n\t"
: "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp)
: "0" (sum), "1" (iph), "2" (ihl)
: "memory");
return (__force __sum16)~sum;
}
/*
* Fold a partial checksum
*/
static inline __sum16 csum_fold(__wsum sum)
{
unsigned int tmp = (__force u32)sum;
__asm__("swap %1\n\t"
"addw %1, %0\n\t"
"clrw %1\n\t"
"addxw %1, %0"
: "=&d" (sum), "=&d" (tmp)
: "0" (sum), "1" (tmp));
return (__force __sum16)~sum;
}
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
__asm__ ("addl %2,%0\n\t"
"addxl %3,%0\n\t"
"addxl %4,%0\n\t"
"clrl %1\n\t"
"addxl %1,%0"
: "=&d" (sum), "=d" (saddr)
: "g" (daddr), "1" (saddr), "d" (len + proto),
"0" (sum));
return sum;
}
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
static inline __sum16 ip_compute_csum(const void *buff, int len)
{
return csum_fold (csum_partial(buff, len, 0));
}
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, unsigned short proto, __wsum sum)
{
register unsigned long tmp;
__asm__("addl %2@,%0\n\t"
"movel %2@(4),%1\n\t"
"addxl %1,%0\n\t"
"movel %2@(8),%1\n\t"
"addxl %1,%0\n\t"
"movel %2@(12),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@,%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(4),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(8),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(12),%1\n\t"
"addxl %1,%0\n\t"
"addxl %4,%0\n\t"
"clrl %1\n\t"
"addxl %1,%0"
: "=&d" (sum), "=&d" (tmp)
: "a" (saddr), "a" (daddr), "d" (len + proto),
"0" (sum));
return csum_fold(sum);
}
#endif /* _M68K_CHECKSUM_H */
#ifndef _M68K_CHECKSUM_H
#define _M68K_CHECKSUM_H
#include <linux/in6.h>
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
__wsum csum_partial(const void *buff, int len, __wsum sum);
/*
* the same as csum_partial, but copies from src while it
* checksums
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
__wsum csum_partial_copy_nocheck(const void *src, void *dst,
int len, __wsum sum);
/*
* the same as csum_partial_copy, but copies from user space.
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
extern __wsum csum_partial_copy_from_user(const void __user *src,
void *dst, int len, __wsum sum, int *csum_err);
__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
/*
* Fold a partial checksum
*/
static inline __sum16 csum_fold(__wsum sum)
{
unsigned int tmp = (__force u32)sum;
#ifdef CONFIG_COLDFIRE
tmp = (tmp & 0xffff) + (tmp >> 16);
tmp = (tmp & 0xffff) + (tmp >> 16);
return (__force __sum16)~tmp;
#else
__asm__("swap %1\n\t"
"addw %1, %0\n\t"
"clrw %1\n\t"
"addxw %1, %0"
: "=&d" (sum), "=&d" (tmp)
: "0" (sum), "1" (sum));
return (__force __sum16)~sum;
#endif
}
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
__asm__ ("addl %1,%0\n\t"
"addxl %4,%0\n\t"
"addxl %5,%0\n\t"
"clrl %1\n\t"
"addxl %1,%0"
: "=&d" (sum), "=&d" (saddr)
: "0" (daddr), "1" (saddr), "d" (len + proto),
"d"(sum));
return sum;
}
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
}
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
extern __sum16 ip_compute_csum(const void *buff, int len);
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, unsigned short proto, __wsum sum)
{
register unsigned long tmp;
__asm__("addl %2@,%0\n\t"
"movel %2@(4),%1\n\t"
"addxl %1,%0\n\t"
"movel %2@(8),%1\n\t"
"addxl %1,%0\n\t"
"movel %2@(12),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@,%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(4),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(8),%1\n\t"
"addxl %1,%0\n\t"
"movel %3@(12),%1\n\t"
"addxl %1,%0\n\t"
"addxl %4,%0\n\t"
"clrl %1\n\t"
"addxl %1,%0"
: "=&d" (sum), "=&d" (tmp)
: "a" (saddr), "a" (daddr), "d" (len + proto),
"0" (sum));
return csum_fold(sum);
}
#endif /* _M68K_CHECKSUM_H */
#ifdef __uClinux__
#include "dma_no.h"
#ifndef _M68K_DMA_H
#define _M68K_DMA_H 1
#ifdef CONFIG_COLDFIRE
/*
* ColdFire DMA Model:
* ColdFire DMA supports two forms of DMA: Single and Dual address. Single
* address mode emits a source address, and expects that the device will either
* pick up the data (DMA READ) or source data (DMA WRITE). This implies that
* the device will place data on the correct byte(s) of the data bus, as the
* memory transactions are always 32 bits. This implies that only 32 bit
* devices will find single mode transfers useful. Dual address DMA mode
* performs two cycles: source read and destination write. ColdFire will
* align the data so that the device will always get the correct bytes, thus
* is useful for 8 and 16 bit devices. This is the mode that is supported
* below.
*
* AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000
* Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
*
* AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000
* Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
*
* APR/18/2002 : added proper support for MCF5272 DMA controller.
* Arthur Shipkowski (art@videon-central.com)
*/
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfdma.h>
/*
* Set number of channels of DMA on ColdFire for different implementations.
*/
#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \
defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
#define MAX_M68K_DMA_CHANNELS 4
#elif defined(CONFIG_M5272)
#define MAX_M68K_DMA_CHANNELS 1
#elif defined(CONFIG_M532x)
#define MAX_M68K_DMA_CHANNELS 0
#else
#include "dma_mm.h"
#define MAX_M68K_DMA_CHANNELS 2
#endif
extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
#if !defined(CONFIG_M5272)
#define DMA_MODE_WRITE_BIT 0x01 /* Memory/IO to IO/Memory select */
#define DMA_MODE_WORD_BIT 0x02 /* 8 or 16 bit transfers */
#define DMA_MODE_LONG_BIT 0x04 /* or 32 bit transfers */
#define DMA_MODE_SINGLE_BIT 0x08 /* single-address-mode */
/* I/O to memory, 8 bits, mode */
#define DMA_MODE_READ 0
/* memory to I/O, 8 bits, mode */
#define DMA_MODE_WRITE 1
/* I/O to memory, 16 bits, mode */
#define DMA_MODE_READ_WORD 2
/* memory to I/O, 16 bits, mode */
#define DMA_MODE_WRITE_WORD 3
/* I/O to memory, 32 bits, mode */
#define DMA_MODE_READ_LONG 4
/* memory to I/O, 32 bits, mode */
#define DMA_MODE_WRITE_LONG 5
/* I/O to memory, 8 bits, single-address-mode */
#define DMA_MODE_READ_SINGLE 8
/* memory to I/O, 8 bits, single-address-mode */
#define DMA_MODE_WRITE_SINGLE 9
/* I/O to memory, 16 bits, single-address-mode */
#define DMA_MODE_READ_WORD_SINGLE 10
/* memory to I/O, 16 bits, single-address-mode */
#define DMA_MODE_WRITE_WORD_SINGLE 11
/* I/O to memory, 32 bits, single-address-mode */
#define DMA_MODE_READ_LONG_SINGLE 12
/* memory to I/O, 32 bits, single-address-mode */
#define DMA_MODE_WRITE_LONG_SINGLE 13
#else /* CONFIG_M5272 is defined */
/* Source static-address mode */
#define DMA_MODE_SRC_SA_BIT 0x01
/* Two bits to select between all four modes */
#define DMA_MODE_SSIZE_MASK 0x06
/* Offset to shift bits in */
#define DMA_MODE_SSIZE_OFF 0x01
/* Destination static-address mode */
#define DMA_MODE_DES_SA_BIT 0x10
/* Two bits to select between all four modes */
#define DMA_MODE_DSIZE_MASK 0x60
/* Offset to shift bits in */
#define DMA_MODE_DSIZE_OFF 0x05
/* Size modifiers */
#define DMA_MODE_SIZE_LONG 0x00
#define DMA_MODE_SIZE_BYTE 0x01
#define DMA_MODE_SIZE_WORD 0x02
#define DMA_MODE_SIZE_LINE 0x03
/*
* Aliases to help speed quick ports; these may be suboptimal, however. They
* do not include the SINGLE mode modifiers since the MCF5272 does not have a
* mode where the device is in control of its addressing.
*/
/* I/O to memory, 8 bits, mode */
#define DMA_MODE_READ ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
/* memory to I/O, 8 bits, mode */
#define DMA_MODE_WRITE ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
/* I/O to memory, 16 bits, mode */
#define DMA_MODE_READ_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
/* memory to I/O, 16 bits, mode */
#define DMA_MODE_WRITE_WORD ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
/* I/O to memory, 32 bits, mode */
#define DMA_MODE_READ_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
/* memory to I/O, 32 bits, mode */
#define DMA_MODE_WRITE_LONG ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
#endif /* !defined(CONFIG_M5272) */
#if !defined(CONFIG_M5272)
/* enable/disable a specific DMA channel */
static __inline__ void enable_dma(unsigned int dmanr)
{
volatile unsigned short *dmawp;
#ifdef DMA_DEBUG
printk("enable_dma(dmanr=%d)\n", dmanr);
#endif
dmawp = (unsigned short *) dma_base_addr[dmanr];
dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT;
}
static __inline__ void disable_dma(unsigned int dmanr)
{
volatile unsigned short *dmawp;
volatile unsigned char *dmapb;
#ifdef DMA_DEBUG
printk("disable_dma(dmanr=%d)\n", dmanr);
#endif
dmawp = (unsigned short *) dma_base_addr[dmanr];
dmapb = (unsigned char *) dma_base_addr[dmanr];
/* Turn off external requests, and stop any DMA in progress */
dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT;
dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE;
}
/*
* Clear the 'DMA Pointer Flip Flop'.
* Write 0 for LSB/MSB, 1 for MSB/LSB access.
* Use this once to initialize the FF to a known state.
* After that, keep track of it. :-)
* --- In order to do that, the DMA routines below should ---