summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/asm-arm/arch-ebsa285/time.h4
-rw-r--r--include/asm-arm/arch-rpc/ide.h2
-rw-r--r--include/asm-arm/arch-rpc/serial.h2
-rw-r--r--include/asm-arm/arch-rpc/uncompress.h24
-rw-r--r--include/asm-arm/arch-sa1100/irqs.h2
-rw-r--r--include/asm-arm/arch-sa1100/time.h2
-rw-r--r--include/asm-arm/ecard.h29
-rw-r--r--include/asm-arm/glue.h118
-rw-r--r--include/asm-arm/hardirq.h12
-rw-r--r--include/asm-arm/hardware/sa1111.h14
-rw-r--r--include/asm-arm/ide.h1
-rw-r--r--include/asm-arm/numnodes.h17
-rw-r--r--include/asm-arm/page.h64
-rw-r--r--include/asm-arm/pci.h4
-rw-r--r--include/asm-arm/pgalloc.h3
-rw-r--r--include/asm-arm/pgtable.h1
-rw-r--r--include/asm-arm/proc-armo/system.h2
-rw-r--r--include/asm-arm/proc-armv/pgalloc.h1
-rw-r--r--include/asm-arm/proc-armv/tlbflush.h230
-rw-r--r--include/asm-arm/processor.h26
-rw-r--r--include/asm-arm/procinfo.h2
-rw-r--r--include/asm-arm/tlb.h77
22 files changed, 412 insertions, 225 deletions
diff --git a/include/asm-arm/arch-ebsa285/time.h b/include/asm-arm/arch-ebsa285/time.h
index 7b40c671daad..a500b9c08b8b 100644
--- a/include/asm-arm/arch-ebsa285/time.h
+++ b/include/asm-arm/arch-ebsa285/time.h
@@ -62,7 +62,7 @@ static unsigned long isa_gettimeoffset(void)
count_p = count;
- count = (((mSEC_10_from_14/6)-1) - count) * tick;
+ count = (((mSEC_10_from_14/6)-1) - count) * (tick_nsec / 1000);
count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6);
return count;
@@ -182,7 +182,7 @@ static unsigned long timer1_gettimeoffset (void)
{
unsigned long value = LATCH - *CSR_TIMER1_VALUE;
- return (tick * value) / LATCH;
+ return ((tick_nsec / 1000) * value) / LATCH;
}
static void timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
diff --git a/include/asm-arm/arch-rpc/ide.h b/include/asm-arm/arch-rpc/ide.h
index aaf49b1be75c..15fecab1f7b8 100644
--- a/include/asm-arm/arch-rpc/ide.h
+++ b/include/asm-arm/arch-rpc/ide.h
@@ -44,5 +44,5 @@ ide_init_default_hwifs(void)
ide_init_hwif_ports(&hw, 0x1f0, 0x3f6, NULL);
hw.irq = IRQ_HARDDISK;
- ide_register_hw(&hw);
+ ide_register_hw(&hw, NULL);
}
diff --git a/include/asm-arm/arch-rpc/serial.h b/include/asm-arm/arch-rpc/serial.h
index 1497fc6fec8c..2f12e6da9bf6 100644
--- a/include/asm-arm/arch-rpc/serial.h
+++ b/include/asm-arm/arch-rpc/serial.h
@@ -29,7 +29,7 @@
/* UART CLK PORT IRQ FLAGS */
#define STD_SERIAL_PORT_DEFNS \
{ 0, BASE_BAUD, 0x3F8, 10, STD_COM_FLAGS }, /* ttyS0 */ \
- { 0, BASE_BAUD, 0x2F8, 10, STD_COM_FLAGS }, /* ttyS1 */ \
+ { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS1 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS2 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS3 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS4 */ \
diff --git a/include/asm-arm/arch-rpc/uncompress.h b/include/asm-arm/arch-rpc/uncompress.h
index dde1bfc7af20..4a3036dad1f2 100644
--- a/include/asm-arm/arch-rpc/uncompress.h
+++ b/include/asm-arm/arch-rpc/uncompress.h
@@ -56,7 +56,7 @@ static const unsigned long palette_4[16] = {
#define palette_setpixel(p) *(unsigned long *)(IO_START+0x00400000) = 0x10000000|((p) & 255)
#define palette_write(v) *(unsigned long *)(IO_START+0x00400000) = 0x00000000|((v) & 0x00ffffff)
-extern struct param_struct params;
+static struct param_struct *params = (struct param_struct *)PARAMS_PHYS;
#ifndef STANDALONE_DEBUG
/*
@@ -64,13 +64,13 @@ extern struct param_struct params;
*/
static void puts(const char *s)
{
- extern void ll_write_char(char *, unsigned long);
+ extern void ll_write_char(char *, char c, char white);
int x,y;
unsigned char c;
char *ptr;
- x = params.video_x;
- y = params.video_y;
+ x = params->video_x;
+ y = params->video_y;
while ( ( c = *(unsigned char *)s++ ) != '\0' ) {
if ( c == '\n' ) {
@@ -79,8 +79,8 @@ static void puts(const char *s)
y--;
}
} else {
- ptr = VIDMEM + ((y*video_num_columns*params.bytes_per_char_v+x)*bytes_per_char_h);
- ll_write_char(ptr, c|(white<<16));
+ ptr = VIDMEM + ((y*video_num_columns*params->bytes_per_char_v+x)*bytes_per_char_h);
+ ll_write_char(ptr, c, white);
if ( ++x >= video_num_columns ) {
x = 0;
if ( ++y >= video_num_lines ) {
@@ -90,8 +90,8 @@ static void puts(const char *s)
}
}
- params.video_x = x;
- params.video_y = y;
+ params->video_x = x;
+ params->video_y = y;
}
static void error(char *x);
@@ -103,9 +103,9 @@ static void arch_decomp_setup(void)
{
int i;
- video_num_lines = params.video_num_rows;
- video_num_columns = params.video_num_cols;
- bytes_per_char_h = params.bytes_per_char_h;
+ video_num_lines = params->video_num_rows;
+ video_num_columns = params->video_num_cols;
+ bytes_per_char_h = params->bytes_per_char_h;
video_size_row = video_num_columns * bytes_per_char_h;
if (bytes_per_char_h == 4)
for (i = 0; i < 256; i++)
@@ -140,7 +140,7 @@ static void arch_decomp_setup(void)
white = 7;
}
- if (params.nr_pages * params.page_size < 4096*1024) error("<4M of mem\n");
+ if (params->nr_pages * params->page_size < 4096*1024) error("<4M of mem\n");
}
#endif
diff --git a/include/asm-arm/arch-sa1100/irqs.h b/include/asm-arm/arch-sa1100/irqs.h
index 66e4f596c739..4d906d33a78e 100644
--- a/include/asm-arm/arch-sa1100/irqs.h
+++ b/include/asm-arm/arch-sa1100/irqs.h
@@ -109,7 +109,7 @@
#define AUDRDD (IRQ_BOARD_END + 41)
#define AUDSTO (IRQ_BOARD_END + 42)
#define IRQ_USBPWR (IRQ_BOARD_END + 43)
-#define IRQ_NHCIM (IRQ_BOARD_END + 44)
+#define IRQ_HCIM (IRQ_BOARD_END + 44)
#define IRQ_HCIBUFFACC (IRQ_BOARD_END + 45)
#define IRQ_HCIRMTWKP (IRQ_BOARD_END + 46)
#define IRQ_NHCIMFCIR (IRQ_BOARD_END + 47)
diff --git a/include/asm-arm/arch-sa1100/time.h b/include/asm-arm/arch-sa1100/time.h
index 5e459a32e8f8..c52eb9588c3c 100644
--- a/include/asm-arm/arch-sa1100/time.h
+++ b/include/asm-arm/arch-sa1100/time.h
@@ -58,7 +58,7 @@ static unsigned long sa1100_gettimeoffset (void)
elapsed = LATCH - ticks_to_match;
/* Now convert them to usec */
- usec = (unsigned long)(elapsed*tick)/LATCH;
+ usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
return usec;
}
diff --git a/include/asm-arm/ecard.h b/include/asm-arm/ecard.h
index fa0adbaeb12d..7c719a206399 100644
--- a/include/asm-arm/ecard.h
+++ b/include/asm-arm/ecard.h
@@ -95,9 +95,10 @@ typedef enum { /* Speed for ECARD_IOC space */
ECARD_SYNC = 3
} card_speed_t;
-typedef struct { /* Card ID structure */
- unsigned short manufacturer;
- unsigned short product;
+typedef struct ecard_id { /* Card ID structure */
+ unsigned short manufacturer;
+ unsigned short product;
+ void *data;
} card_ids;
struct in_ecid { /* Packed card ID information */
@@ -132,6 +133,8 @@ typedef struct { /* Card handler routines */
struct expansion_card {
struct expansion_card *next;
+ struct device dev;
+
/* Public data */
volatile unsigned char *irqaddr; /* address of IRQ register */
volatile unsigned char *fiqaddr; /* address of FIQ register */
@@ -248,4 +251,24 @@ struct ex_chunk_dir {
#endif
+extern struct bus_type ecard_bus_type;
+
+#define ECARD_DEV(_d) container_of((_d), struct expansion_card, dev)
+
+struct ecard_driver {
+ int (*probe)(struct expansion_card *, const struct ecard_id *id);
+ void (*remove)(struct expansion_card *);
+ const struct ecard_id *id_table;
+ unsigned int id;
+ struct device_driver drv;
+};
+
+#define ECARD_DRV(_d) container_of((_d), struct ecard_driver, drv)
+
+#define ecard_set_drvdata(ec,data) dev_set_drvdata(&(ec)->dev, (data))
+#define ecard_get_drvdata(ec) dev_get_drvdata(&(ec)->dev)
+
+int ecard_register_driver(struct ecard_driver *);
+void ecard_remove_driver(struct ecard_driver *);
+
#endif
diff --git a/include/asm-arm/glue.h b/include/asm-arm/glue.h
index 84b5d77c7562..a29d70176c75 100644
--- a/include/asm-arm/glue.h
+++ b/include/asm-arm/glue.h
@@ -27,59 +27,6 @@
/*
- * MMU TLB Model
- * =============
- *
- * We have the following to choose from:
- * v3 - ARMv3
- * v4 - ARMv4 without write buffer
- * v4wb - ARMv4 with write buffer without I TLB flush entry instruction
- * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction
- */
-#undef _TLB
-#undef MULTI_TLB
-
-#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
-# ifdef _TLB
-# define MULTI_TLB 1
-# else
-# define _TLB v3
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM720T)
-# ifdef _TLB
-# define MULTI_TLB 1
-# else
-# define _TLB v4
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
- defined(CONFIG_CPU_ARM926T) || defined(CONFIG_CPU_ARM1020) || \
- defined(CONFIG_CPU_XSCALE)
-# ifdef _TLB
-# define MULTI_TLB 1
-# else
-# define _TLB v4wbi
-# endif
-#endif
-
-#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
-# ifdef _TLB
-# define MULTI_TLB 1
-# else
-# define _TLB v4wb
-# endif
-#endif
-
-#ifndef _TLB
-#error Unknown TLB model
-#endif
-
-
-
-/*
* Data Abort Model
* ================
*
@@ -156,69 +103,4 @@
#error Unknown data abort handler type
#endif
-
-/*
- * User Space Model
- * ================
- *
- * This section selects the correct set of functions for dealing with
- * page-based copying and clearing for user space for the particular
- * processor(s) we're building for.
- *
- * We have the following to choose from:
- * v3 - ARMv3
- * v4wt - ARMv4 with writethrough cache, without minicache
- * v4wb - ARMv4 with writeback cache, without minicache
- * v4_mc - ARMv4 with minicache
- * xscale - Xscale
- */
-#undef _USER
-#undef MULTI_USER
-
-#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
-# ifdef _USER
-# define MULTI_USER 1
-# else
-# define _USER v3
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM720T)
-# ifdef _USER
-# define MULTI_USER 1
-# else
-# define _USER v4wt
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
- defined(CONFIG_CPU_ARM926T) || defined(CONFIG_CPU_SA110) || \
- defined(CONFIG_CPU_ARM1020)
-# ifdef _USER
-# define MULTI_USER 1
-# else
-# define _USER v4wb
-# endif
-#endif
-
-#if defined(CONFIG_CPU_SA1100)
-# ifdef _USER
-# define MULTI_USER 1
-# else
-# define _USER v4_mc
-# endif
-#endif
-
-#if defined(CONFIG_CPU_XSCALE)
-# ifdef _USER
-# define MULTI_USER 1
-# else
-# define _USER xscale_mc
-# endif
-#endif
-
-#ifndef _USER
-#error Unknown user operations model
-#endif
-
#endif
diff --git a/include/asm-arm/hardirq.h b/include/asm-arm/hardirq.h
index 0e6a5492e1e4..3f164e01f7a1 100644
--- a/include/asm-arm/hardirq.h
+++ b/include/asm-arm/hardirq.h
@@ -69,10 +69,18 @@ typedef struct {
#define irq_enter() (preempt_count() += HARDIRQ_OFFSET)
+#ifdef CONFIG_PREEMPT
+# define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked())
+# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
+#else
+# define in_atomic() (preempt_count() != 0)
+# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
+#endif
+
#ifndef CONFIG_SMP
#define irq_exit() \
do { \
- preempt_count() -= HARDIRQ_OFFSET; \
+ preempt_count() -= IRQ_EXIT_OFFSET; \
if (!in_interrupt() && softirq_pending(smp_processor_id())) \
__asm__("bl%? __do_softirq": : : "lr");/* out of line */\
preempt_enable_no_resched(); \
@@ -80,7 +88,7 @@ typedef struct {
#define synchronize_irq(irq) barrier()
#else
-#error SMP not supported
+extern void synchronize_irq(unsigned int irq);
#endif
#endif /* __ASM_HARDIRQ_H */
diff --git a/include/asm-arm/hardware/sa1111.h b/include/asm-arm/hardware/sa1111.h
index 311e4832eb2f..30e1f8141633 100644
--- a/include/asm-arm/hardware/sa1111.h
+++ b/include/asm-arm/hardware/sa1111.h
@@ -64,10 +64,6 @@
#define SA1111_SMCR 0x0004
#define SA1111_SKID 0x0008
-#define SBI_SKCR __CCREG(SA1111_SKCR)
-#define SBI_SMCR __CCREG(SA1111_SMCR)
-#define SBI_SKID __CCREG(SA1111_SKID)
-
#define SKCR_PLL_BYPASS (1<<0)
#define SKCR_RCLKEN (1<<1)
#define SKCR_SLEEP (1<<2)
@@ -131,16 +127,6 @@
#define SA1111_SKPEN1 0x021c
#define SA1111_SKPWM1 0x0220
-#define SKPCR __CCREG(SA1111_SKPCR)
-#define SKCDR __CCREG(SA1111_SKCDR)
-#define SKAUD __CCREG(SA1111_SKAUD)
-#define SKPMC __CCREG(SA1111_SKPMC)
-#define SKPTC __CCREG(SA1111_SKPTC)
-#define SKPEN0 __CCREG(SA1111_SKPEN0)
-#define SKPWM0 __CCREG(SA1111_SKPWM0)
-#define SKPEN1 __CCREG(SA1111_SKPEN1)
-#define SKPWM1 __CCREG(SA1111_SKPWM1)
-
#define SKPCR_UCLKEN (1<<0)
#define SKPCR_ACCLKEN (1<<1)
#define SKPCR_I2SCLKEN (1<<2)
diff --git a/include/asm-arm/ide.h b/include/asm-arm/ide.h
index 3b9c4c18c6af..e872974aa009 100644
--- a/include/asm-arm/ide.h
+++ b/include/asm-arm/ide.h
@@ -36,7 +36,6 @@
* The following are not needed for the non-m68k ports
*/
#define ide_ack_intr(hwif) (1)
-#define ide_fix_driveid(id) do {} while (0)
#define ide_release_lock(lock) do {} while (0)
#define ide_get_lock(lock, hdlr, data) do {} while (0)
diff --git a/include/asm-arm/numnodes.h b/include/asm-arm/numnodes.h
new file mode 100644
index 000000000000..4c12812f73dc
--- /dev/null
+++ b/include/asm-arm/numnodes.h
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-arm/numnodes.h
+ *
+ * Copyright (C) 2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARM_NUMNODES_H
+#define __ASM_ARM_NUMNODES_H
+
+#include <asm/memory.h>
+
+#define MAX_NUMNODES NR_NODES
+
+#endif
diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h
index 84b1f5970586..0b1a26ed991d 100644
--- a/include/asm-arm/page.h
+++ b/include/asm-arm/page.h
@@ -8,6 +8,70 @@
#include <asm/glue.h>
+/*
+ * User Space Model
+ * ================
+ *
+ * This section selects the correct set of functions for dealing with
+ * page-based copying and clearing for user space for the particular
+ * processor(s) we're building for.
+ *
+ * We have the following to choose from:
+ * v3 - ARMv3
+ * v4wt - ARMv4 with writethrough cache, without minicache
+ * v4wb - ARMv4 with writeback cache, without minicache
+ * v4_mc - ARMv4 with minicache
+ * xscale - Xscale
+ */
+#undef _USER
+#undef MULTI_USER
+
+#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER v3
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM720T)
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER v4wt
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
+ defined(CONFIG_CPU_ARM926T) || defined(CONFIG_CPU_SA110) || \
+ defined(CONFIG_CPU_ARM1020)
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER v4wb
+# endif
+#endif
+
+#if defined(CONFIG_CPU_SA1100)
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER v4_mc
+# endif
+#endif
+
+#if defined(CONFIG_CPU_XSCALE)
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER xscale_mc
+# endif
+#endif
+
+#ifndef _USER
+#error Unknown user operations model
+#endif
+
struct cpu_user_fns {
void (*cpu_clear_user_page)(void *p, unsigned long user);
void (*cpu_copy_user_page)(void *to, const void *from,
diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h
index 3a7310558dd2..cd074e0daf51 100644
--- a/include/asm-arm/pci.h
+++ b/include/asm-arm/pci.h
@@ -248,6 +248,10 @@ void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
#endif
+#define HAVE_PCI_MMAP
+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine);
+
#endif /* __KERNEL__ */
#endif
diff --git a/include/asm-arm/pgalloc.h b/include/asm-arm/pgalloc.h
index f0e2c9f5393d..81a7eccf2991 100644
--- a/include/asm-arm/pgalloc.h
+++ b/include/asm-arm/pgalloc.h
@@ -11,9 +11,6 @@
#define _ASMARM_PGALLOC_H
#include <asm/processor.h>
-#include <asm/cacheflush.h>
-#include <asm/tlbflush.h>
-
#include <asm/proc/pgalloc.h>
/*
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index ca5bef29d81b..da98e2ee55b8 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -12,6 +12,7 @@
#include <linux/config.h>
#include <asm/memory.h>
+#include <asm/proc-fns.h>
#include <asm/arch/vmalloc.h>
/*
diff --git a/include/asm-arm/proc-armo/system.h b/include/asm-arm/proc-armo/system.h
index 23f2b96cb2d0..9e46e58f56e4 100644
--- a/include/asm-arm/proc-armo/system.h
+++ b/include/asm-arm/proc-armo/system.h
@@ -10,8 +10,6 @@
#ifndef __ASM_PROC_SYSTEM_H
#define __ASM_PROC_SYSTEM_H
-#include <asm/proc-fns.h>
-
#define vectors_base() (0)
static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
diff --git a/include/asm-arm/proc-armv/pgalloc.h b/include/asm-arm/proc-armv/pgalloc.h
index 99546c6fc1c8..53e760417601 100644
--- a/include/asm-arm/proc-armv/pgalloc.h
+++ b/include/asm-arm/proc-armv/pgalloc.h
@@ -5,6 +5,7 @@
*
* Page table allocation/freeing primitives for 32-bit ARM processors.
*/
+#include <asm/cacheflush.h>
#include "pgtable.h"
/*
diff --git a/include/asm-arm/proc-armv/tlbflush.h b/include/asm-arm/proc-armv/tlbflush.h
index d465e954ae13..fd758b2e90f2 100644
--- a/include/asm-arm/proc-armv/tlbflush.h
+++ b/include/asm-arm/proc-armv/tlbflush.h
@@ -7,6 +7,113 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/config.h>
+#include <asm/glue.h>
+
+#define TLB_V3_PAGE (1 << 0)
+#define TLB_V4_U_PAGE (1 << 1)
+#define TLB_V4_D_PAGE (1 << 2)
+#define TLB_V4_I_PAGE (1 << 3)
+
+#define TLB_V3_FULL (1 << 8)
+#define TLB_V4_U_FULL (1 << 9)
+#define TLB_V4_D_FULL (1 << 10)
+#define TLB_V4_I_FULL (1 << 11)
+
+#define TLB_WB (1 << 31)
+
+/*
+ * MMU TLB Model
+ * =============
+ *
+ * We have the following to choose from:
+ * v3 - ARMv3
+ * v4 - ARMv4 without write buffer
+ * v4wb - ARMv4 with write buffer without I TLB flush entry instruction
+ * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction
+ */
+#undef _TLB
+#undef MULTI_TLB
+
+#define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE)
+
+#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v3
+# endif
+#endif
+
+#define v4_tlb_flags (TLB_V4_U_FULL | TLB_V4_U_PAGE)
+
+#if defined(CONFIG_CPU_ARM720T)
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v4
+# endif
+#endif
+
+#define v4wbi_tlb_flags (TLB_WB | \
+ TLB_V4_I_FULL | TLB_V4_D_FULL | \
+ TLB_V4_I_PAGE | TLB_V4_D_PAGE)
+
+#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
+ defined(CONFIG_CPU_ARM926T) || defined(CONFIG_CPU_ARM1020) || \
+ defined(CONFIG_CPU_XSCALE)
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v4wbi
+# endif
+#endif
+
+#define v4wb_tlb_flags (TLB_WB | \
+ TLB_V4_I_FULL | TLB_V4_D_FULL | \
+ TLB_V4_D_PAGE)
+
+#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v4wb
+# endif
+#endif
+
+#ifndef _TLB
+#error Unknown TLB model
+#endif
+
+#ifndef __ASSEMBLY__
+
+struct cpu_tlb_fns {
+ void (*flush_user_range)(unsigned long, unsigned long, struct vm_area_struct *);
+ void (*flush_kern_range)(unsigned long, unsigned long);
+ unsigned long tlb_flags;
+};
+
+/*
+ * Select the calling method
+ */
+#ifdef MULTI_TLB
+
+extern struct cpu_tlb_fns cpu_tlb;
+
+#define __cpu_flush_user_tlb_range cpu_tlb.flush_user_range
+#define __cpu_flush_kern_tlb_range cpu_tlb.flush_kern_range
+#define __cpu_tlb_flags cpu_tlb.tlb_flags
+
+#else
+
+#define __cpu_flush_user_tlb_range __glue(_TLB,_flush_user_tlb_range)
+#define __cpu_flush_kern_tlb_range __glue(_TLB,_flush_kern_tlb_range)
+#define __cpu_tlb_flags __glue(_TLB,_tlb_flags)
+
+extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
+extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long);
+
+#endif
/*
* TLB Management
@@ -51,56 +158,94 @@
* - kaddr - Kernel virtual memory address
*/
-struct cpu_tlb_fns {
- void (*flush_kern_all)(void);
- void (*flush_user_mm)(struct mm_struct *);
- void (*flush_user_range)(unsigned long, unsigned long, struct vm_area_struct *);
- void (*flush_user_page)(unsigned long, struct vm_area_struct *);
- void (*flush_kern_range)(unsigned long, unsigned long);
- void (*flush_kern_page)(unsigned long);
-};
+#define tlb_flag(f) (__cpu_tlb_flags & (f))
-/*
- * Convert calls to our calling convention.
- */
-#define flush_tlb_all() __cpu_flush_kern_tlb_all()
-#define flush_tlb_mm(mm) __cpu_flush_user_tlb_mm(mm)
-#define flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma)
-#define flush_tlb_page(vma,vaddr) __cpu_flush_user_tlb_page(vaddr,vma)
-#define flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e)
-#define flush_tlb_kernel_page(kaddr) __cpu_flush_kern_tlb_page(kaddr)
+static inline void flush_tlb_all(void)
+{
+ const int zero = 0;
-/*
- * Now select the calling method
- */
-#ifdef MULTI_TLB
+ if (tlb_flag(TLB_WB))
+ asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
-extern struct cpu_tlb_fns cpu_tlb;
+ if (tlb_flag(TLB_V3_FULL))
+ asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero));
+ if (tlb_flag(TLB_V4_U_FULL))
+ asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero));
+ if (tlb_flag(TLB_V4_D_FULL))
+ asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero));
+ if (tlb_flag(TLB_V4_I_FULL))
+ asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+}
-#define __cpu_flush_kern_tlb_all cpu_tlb.flush_kern_all
-#define __cpu_flush_user_tlb_mm cpu_tlb.flush_user_mm
-#define __cpu_flush_user_tlb_range cpu_tlb.flush_user_range
-#define __cpu_flush_user_tlb_page cpu_tlb.flush_user_page
-#define __cpu_flush_kern_tlb_range cpu_tlb.flush_kern_range
-#define __cpu_flush_kern_tlb_page cpu_tlb.flush_kern_page
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+ const int zero = 0;
-#else
+ if (tlb_flag(TLB_WB))
+ asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
-#define __cpu_flush_kern_tlb_all __glue(_TLB,_flush_kern_tlb_all)
-#define __cpu_flush_user_tlb_mm __glue(_TLB,_flush_user_tlb_mm)
-#define __cpu_flush_user_tlb_range __glue(_TLB,_flush_user_tlb_range)
-#define __cpu_flush_user_tlb_page __glue(_TLB,_flush_user_tlb_page)
-#define __cpu_flush_kern_tlb_range __glue(_TLB,_flush_kern_tlb_range)
-#define __cpu_flush_kern_tlb_page __glue(_TLB,_flush_kern_tlb_page)
+ if (mm == current->active_mm) {
+ if (tlb_flag(TLB_V3_FULL))
+ asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (zero));
+ if (tlb_flag(TLB_V4_U_FULL))
+ asm("mcr%? p15, 0, %0, c8, c7, 0" : : "r" (zero));
+ if (tlb_flag(TLB_V4_D_FULL))
+ asm("mcr%? p15, 0, %0, c8, c6, 0" : : "r" (zero));
+ if (tlb_flag(TLB_V4_I_FULL))
+ asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+ }
+}
-extern void __cpu_flush_kern_tlb_all(void);
-extern void __cpu_flush_user_tlb_mm(struct mm_struct *);
-extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
-extern void __cpu_flush_user_tlb_page(unsigned long, struct vm_area_struct *);
-extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long);
-extern void __cpu_flush_kern_tlb_page(unsigned long);
+static inline void
+flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+{
+ const int zero = 0;
-#endif
+ uaddr &= PAGE_MASK;
+
+ if (tlb_flag(TLB_WB))
+ asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+
+ if (vma->vm_mm == current->active_mm) {
+ if (tlb_flag(TLB_V3_PAGE))
+ asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (uaddr));
+ if (tlb_flag(TLB_V4_U_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (uaddr));
+ if (tlb_flag(TLB_V4_D_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (uaddr));
+ if (tlb_flag(TLB_V4_I_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr));
+ if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
+ asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+ }
+}
+
+static inline void flush_tlb_kernel_page(unsigned long kaddr)
+{
+ const int zero = 0;
+
+ kaddr &= PAGE_MASK;
+
+ if (tlb_flag(TLB_WB))
+ asm("mcr%? p15, 0, %0, c7, c10, 4" : : "r" (zero));
+
+ if (tlb_flag(TLB_V3_PAGE))
+ asm("mcr%? p15, 0, %0, c6, c0, 0" : : "r" (kaddr));
+ if (tlb_flag(TLB_V4_U_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c7, 1" : : "r" (kaddr));
+ if (tlb_flag(TLB_V4_D_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c6, 1" : : "r" (kaddr));
+ if (tlb_flag(TLB_V4_I_PAGE))
+ asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (kaddr));
+ if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
+ asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
+}
+
+/*
+ * Convert calls to our calling convention.
+ */
+#define flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma)
+#define flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e)
/*
* if PG_dcache_dirty is set for the page, we need to ensure that any
@@ -123,3 +268,4 @@ extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte
#define memc_update_addr(mm,pte,log) do { } while (0)
#define memc_clear(mm,physaddr) do { } while (0)
+#endif
diff --git a/include/asm-arm/processor.h b/include/asm-arm/processor.h
index 7f3bed11ebd1..b13e4e54282c 100644
--- a/include/asm-arm/processor.h
+++ b/include/asm-arm/processor.h
@@ -28,22 +28,30 @@
#include <asm/procinfo.h>
#include <asm/arch/memory.h>
#include <asm/proc/processor.h>
+#include <asm/types.h>
+
+union debug_insn {
+ u32 arm;
+ u16 thumb;
+};
+
+struct debug_entry {
+ u32 address;
+ union debug_insn insn;
+};
struct debug_info {
- int nsaved;
- struct {
- unsigned long address;
- unsigned long insn;
- } bp[2];
+ int nsaved;
+ struct debug_entry bp[2];
};
struct thread_struct {
/* fault info */
- unsigned long address;
- unsigned long trap_no;
- unsigned long error_code;
+ unsigned long address;
+ unsigned long trap_no;
+ unsigned long error_code;
/* debugging */
- struct debug_info debug;
+ struct debug_info debug;
};
#define INIT_THREAD { }
diff --git a/include/asm-arm/procinfo.h b/include/asm-arm/procinfo.h
index c143ffa712de..fced718b32be 100644
--- a/include/asm-arm/procinfo.h
+++ b/include/asm-arm/procinfo.h
@@ -12,8 +12,6 @@
#ifndef __ASSEMBLY__
-#include <asm/proc-fns.h>
-
struct cpu_tlb_fns;
struct cpu_user_fns;
struct processor;
diff --git a/include/asm-arm/tlb.h b/include/asm-arm/tlb.h
index 318357c01183..3aa4ee0feb67 100644
--- a/include/asm-arm/tlb.h
+++ b/include/asm-arm/tlb.h
@@ -1,21 +1,76 @@
+/*
+ * linux/include/asm-arm/tlb.h
+ *
+ * Copyright (C) 2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Experimentation shows that on a StrongARM, it appears to be faster
+ * to use the "invalidate whole tlb" rather than "invalidate single
+ * tlb" for this.
+ *
+ * This appears true for both the process fork+exit case, as well as
+ * the munmap-large-area case.
+ */
#ifndef __ASMARM_TLB_H
#define __ASMARM_TLB_H
-#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
-#define tlb_flush(tlb) \
- flush_tlb_mm((tlb)->mm)
-#define tlb_start_vma(tlb,vma) \
- flush_cache_range(vma, vma->vm_start, vma->vm_end)
-#define tlb_end_vma(tlb,vma) \
- flush_tlb_range(vma, vma->vm_start, vma->vm_end)
+/*
+ * TLB handling. This allows us to remove pages from the page
+ * tables, and efficiently handle the TLB issues.
+ */
+typedef struct free_pte_ctx {
+ struct mm_struct *mm;
+ unsigned int freed;
-#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
+ unsigned int flushes;
+ unsigned int avoided_flushes;
+} mmu_gather_t;
-#include <asm-generic/tlb.h>
+extern mmu_gather_t mmu_gathers[NR_CPUS];
-#define __pmd_free_tlb(tlb, pmd) pmd_free(pmd)
-#define __pte_free_tlb(tlb, pte) pte_free(pte)
+static inline mmu_gather_t *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+{
+ int cpu = smp_processor_id();
+ mmu_gather_t *tlb = &mmu_gathers[cpu];
+
+ tlb->mm = mm;
+ tlb->freed = 0;
+
+ return tlb;
+}
+
+static inline void tlb_finish_mmu(mmu_gather_t *tlb, unsigned long start, unsigned long end)
+{
+ struct mm_struct *mm = tlb->mm;
+ unsigned long freed = tlb->freed;
+ int rss = mm->rss;
+
+ if (rss < freed)
+ freed = rss;
+ mm->rss = rss - freed;
+
+ if (freed) {
+ flush_tlb_mm(mm);
+ tlb->flushes++;
+ } else {
+ tlb->avoided_flushes++;
+ }
+
+ /* keep the page table cache within bounds */
+ check_pgt_cache();
+}
+
+#define tlb_remove_tlb_entry(tlb,ptep,address) do { } while (0)
+#define tlb_start_vma(tlb,vma) do { } while (0)
+#define tlb_end_vma(tlb,vma) do { } while (0)
+
+#define tlb_remove_page(tlb,page) free_page_and_swap_cache(page)
+#define pte_free_tlb(tlb,ptep) pte_free(ptep)
+#define pmd_free_tlb(tlb,pmdp) pmd_free(pmdp)
#endif