Commit c662921a authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 007427b9 bf3abfa9
This diff is collapsed.
This diff is collapsed.
......@@ -286,3 +286,5 @@ EXPORT_SYMBOL(set_dma_page);
EXPORT_SYMBOL(get_dma_residue);
EXPORT_SYMBOL(set_dma_sg);
EXPORT_SYMBOL(set_dma_speed);
EXPORT_SYMBOL(dma_spin_lock);
......@@ -16,6 +16,7 @@
#include <linux/config.h>
#include "entry-header.S"
#include <asm/thread_info.h>
#include <asm/glue.h>
#ifdef IOC_BASE
......@@ -681,12 +682,12 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE
/*
* This routine must not corrupt r9
*/
#ifdef MULTI_CPU
#ifdef MULTI_ABORT
ldr r4, .LCprocfns @ pass r0, r3 to
mov lr, pc @ processor code
ldr pc, [r4] @ call processor specific code
#else
bl cpu_data_abort
bl CPU_ABORT_HANDLER
#endif
msr cpsr_c, r9
mov r2, sp
......@@ -799,7 +800,7 @@ __pabt_svc: sub sp, sp, #S_FRAME_SIZE
.LCirq: .word __temp_irq
.LCund: .word __temp_und
.LCabt: .word __temp_abt
#ifdef MULTI_CPU
#ifdef MULTI_ABORT
.LCprocfns: .word SYMBOL_NAME(processor)
#endif
.LCfp: .word SYMBOL_NAME(fp_enter)
......@@ -823,12 +824,12 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
alignment_trap r7, r7, __temp_abt
zero_fp
mov r0, r2 @ remove once everyones in sync
#ifdef MULTI_CPU
#ifdef MULTI_ABORT
ldr r4, .LCprocfns @ pass r0, r3 to
mov lr, pc @ processor code
ldr pc, [r4] @ call processor specific code
#else
bl cpu_data_abort
bl CPU_ABORT_HANDLER
#endif
set_cpsr_c r2, #MODE_SVC @ Enable interrupts
mov r2, sp
......
......@@ -76,6 +76,9 @@ struct processor processor;
#ifdef MULTI_TLB
struct cpu_tlb_fns cpu_tlb;
#endif
#ifdef MULTI_USER
struct cpu_user_fns cpu_user;
#endif
unsigned char aux_device_present;
char elf_platform[ELF_PLATFORM_SIZE];
......@@ -248,6 +251,9 @@ static void __init setup_processor(void)
#ifdef MULTI_TLB
cpu_tlb = *list->tlb;
#endif
#ifdef MULTI_USER
cpu_user = *list->user;
#endif
printk("Processor: %s %s revision %d\n",
proc_info.manufacturer, proc_info.cpu_name,
......
......@@ -113,7 +113,6 @@ static int __init integrator_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
extern void pci_v3_init(void *);
struct hw_pci integrator_pci __initdata = {
mem_offset: 0x40000000,
swizzle: integrator_swizzle,
map_irq: integrator_map_irq,
setup: pci_v3_setup,
......
......@@ -435,7 +435,7 @@ static int __init pci_v3_setup_resources(struct resource **resource)
resource[1] = &non_mem;
resource[2] = &pre_mem;
return 0;
return 1;
}
/*
......@@ -529,8 +529,10 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
{
int ret = 0;
if (nr == 0)
if (nr == 0) {
sys->mem_offset = 0x40000000;
ret = pci_v3_setup_resources(sys->resource);
}
return ret;
}
......@@ -634,7 +636,6 @@ void __init pci_v3_preinit(void)
void __init pci_v3_postinit(void)
{
unsigned int pci_cmd;
int ret;
pci_cmd = PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
......
......@@ -47,23 +47,44 @@ static u_long iq80310_read_timer (void)
u_long b0, b1, b2, b3, val;
b0 = *la0; b1 = *la1; b2 = *la2; b3 = *la3;
b0 = (((b0 & 0x20) >> 1) | (b0 & 0x1f));
b1 = (((b1 & 0x20) >> 1) | (b1 & 0x1f));
b2 = (((b2 & 0x20) >> 1) | (b2 & 0x1f));
b0 = (((b0 & 0x40) >> 1) | (b0 & 0x1f));
b1 = (((b1 & 0x40) >> 1) | (b1 & 0x1f));
b2 = (((b2 & 0x40) >> 1) | (b2 & 0x1f));
b3 = (b3 & 0x0f);
val = ((b0 << 0) | (b1 << 6) | (b2 << 12) | (b3 << 18));
return val;
}
/* IRQs are disabled before entering here from do_gettimeofday() */
/*
* IRQs are disabled before entering here from do_gettimeofday().
* Note that the counter may wrap. When it does, 'elapsed' will
* be small, but we will have a pending interrupt.
*/
static unsigned long iq80310_gettimeoffset (void)
{
unsigned long elapsed, usec;
unsigned long elapsed, usec, tmp1;
unsigned int stat1, stat2;
/* We need elapsed timer ticks since last interrupt */
stat1 = *(volatile u8 *)IQ80310_INT_STAT;
elapsed = iq80310_read_timer();
stat2 = *(volatile u8 *)IQ80310_INT_STAT;
/*
* If an interrupt was pending before we read the timer,
* we've already wrapped. Factor this into the time.
* If an interrupt was pending after we read the timer,
* it may have wrapped between checking the interrupt
* status and reading the timer. Re-read the timer to
* be sure its value is after the wrap.
*/
if (stat1 & 1)
elapsed += LATCH;
else if (stat2 & 1)
elapsed = LATCH + iq80310_read_timer();
/* Now convert them to usec */
/*
* Now convert them to usec.
*/
usec = (unsigned long)(elapsed*tick)/LATCH;
return usec;
......@@ -92,9 +113,7 @@ static void iq80310_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*
* -DS
*/
irq_exit(smp_processor_id(), irq);
do_timer(regs);
irq_enter(smp_processor_id(), irq);
}
extern unsigned long (*gettimeoffset)(void);
......@@ -116,4 +135,3 @@ void __init time_init(void)
*timer_en |= 2;
*timer_en |= 1;
}
......@@ -14,69 +14,105 @@ obj-y := generic.o irq.o dma.o
obj-m :=
obj-n :=
obj- :=
led-y := leds.o
export-objs := assabet.o dma.o flexanet.o freebird.o generic.o h3600.o \
huw_webpanel.o irq.o pcipool.o sa1111.o sa1111-pcibuf.o \
yopy.o usb_ctl.o usb_recv.o usb_send.o
export-objs := dma.o generic.o irq.o pcipool.o sa1111.o sa1111-pcibuf.o \
usb_ctl.o usb_recv.o usb_send.o pm.o
# This needs to be cleaned up. We probably need to have SA1100
# and SA1110 config symbols.
#
# We link the CPU support next, so that RAM timings can be tuned.
ifeq ($(CONFIG_CPU_FREQ),y)
obj-$(CONFIG_SA1100_ASSABET) += cpu-sa1110.o
obj-$(CONFIG_SA1100_CERF) += cpu-sa1110.o
obj-$(CONFIG_SA1100_PT_SYSTEM3) += cpu-sa1110.o
obj-$(CONFIG_SA1100_LART) += cpu-sa1100.o
obj-$(CONFIG_SA1100_ASSABET) += cpu-sa1110.o
obj-$(CONFIG_SA1100_CERF) += cpu-sa1110.o
obj-$(CONFIG_SA1100_LART) += cpu-sa1100.o
obj-$(CONFIG_SA1100_PT_SYSTEM3) += cpu-sa1110.o
endif
# Next, the SA1111 stuff.
obj-$(CONFIG_SA1111) += sa1111.o
obj-$(CONFIG_USB_OHCI_SA1111) += sa1111-pcibuf.o pcipool.o
obj-$(CONFIG_SA1111) += sa1111.o
obj-$(CONFIG_USB_OHCI_SA1111) += sa1111-pcibuf.o pcipool.o
# Specific board support
obj-$(CONFIG_SA1100_ADSBITSY) += adsbitsy.o
obj-$(CONFIG_SA1100_ASSABET) += assabet.o
obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o
obj-$(CONFIG_SA1100_BRUTUS) += brutus.o
obj-$(CONFIG_SA1100_CERF) += cerf.o
obj-$(CONFIG_SA1100_EMPEG) += empeg.o
obj-$(CONFIG_SA1100_FLEXANET) += flexanet.o
obj-$(CONFIG_SA1100_FREEBIRD) += freebird.o
obj-$(CONFIG_SA1100_GRAPHICSCLIENT) += graphicsclient.o
obj-$(CONFIG_SA1100_GRAPHICSMASTER) += graphicsmaster.o
obj-$(CONFIG_SA1100_H3600) += h3600.o
obj-$(CONFIG_SA1100_HUW_WEBPANEL) += huw_webpanel.o
obj-$(CONFIG_SA1100_ITSY) += itsy.o
obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o
obj-$(CONFIG_SA1100_LART) += lart.o
obj-$(CONFIG_SA1100_NANOENGINE) += nanoengine.o
obj-$(CONFIG_SA1100_OMNIMETER) += omnimeter.o
obj-$(CONFIG_SA1100_PANGOLIN) += pangolin.o
obj-$(CONFIG_SA1100_PFS168) += pfs168.o
obj-$(CONFIG_SA1100_PLEB) += pleb.o
obj-$(CONFIG_SA1100_SHANNON) += shannon.o
obj-$(CONFIG_SA1100_SHERMAN) += sherman.o
obj-$(CONFIG_SA1100_PT_SYSTEM3) += system3.o
obj-$(CONFIG_SA1100_SIMPAD) += simpad.o
obj-$(CONFIG_SA1100_VICTOR) += victor.o
obj-$(CONFIG_SA1100_XP860) += xp860.o
obj-$(CONFIG_SA1100_YOPY) += yopy.o
obj-$(CONFIG_SA1100_ADSBITSY) += adsbitsy.o
led-$(CONFIG_SA1100_ADSBITSY) += leds-adsbitsy.o
obj-$(CONFIG_SA1100_ASSABET) += assabet.o
export-objs += assabet.o
led-$(CONFIG_SA1100_ASSABET) += leds-assabet.o
obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o
obj-$(CONFIG_SA1100_BADGE4) += badge4.o
export-objs += badge4.o
obj-$(CONFIG_SA1100_BRUTUS) += brutus.o
led-$(CONFIG_SA1100_BRUTUS) += leds-brutus.o
obj-$(CONFIG_SA1100_CERF) += cerf.o
led-$(CONFIG_SA1100_CERF) += leds-cerf.o
obj-$(CONFIG_SA1100_EMPEG) += empeg.o
obj-$(CONFIG_SA1100_FLEXANET) += flexanet.o
export-objs += flexanet.o
led-$(CONFIG_SA1100_FLEXANET) += leds-flexanet.o
obj-$(CONFIG_SA1100_FREEBIRD) += freebird.o
export-objs += freebird.o
obj-$(CONFIG_SA1100_GRAPHICSCLIENT) += graphicsclient.o
led-$(CONFIG_SA1100_GRAPHICSCLIENT) += leds-graphicsclient.o
obj-$(CONFIG_SA1100_GRAPHICSMASTER) += graphicsmaster.o
led-$(CONFIG_SA1100_GRAPHICSMASTER) += leds-graphicsmaster.o
obj-$(CONFIG_SA1100_H3600) += h3600.o
export-objs += h3600.o
obj-$(CONFIG_SA1100_HUW_WEBPANEL) += huw_webpanel.o
export-objs += huw_webpanel.o
obj-$(CONFIG_SA1100_ITSY) += itsy.o
obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o
obj-$(CONFIG_SA1100_LART) += lart.o
led-$(CONFIG_SA1100_LART) += leds-lart.o
obj-$(CONFIG_SA1100_NANOENGINE) += nanoengine.o
obj-$(CONFIG_SA1100_OMNIMETER) += omnimeter.o
obj-$(CONFIG_SA1100_PANGOLIN) += pangolin.o
obj-$(CONFIG_SA1100_PFS168) += pfs168.o
led-$(CONFIG_SA1100_PFS168) += leds-pfs168.o
obj-$(CONFIG_SA1100_PLEB) += pleb.o
obj-$(CONFIG_SA1100_PT_SYSTEM3) += system3.o
led-$(CONFIG_SA1100_PT_SYSTEM3) += leds-system3.o
obj-$(CONFIG_SA1100_SHANNON) += shannon.o
obj-$(CONFIG_SA1100_SHERMAN) += sherman.o
obj-$(CONFIG_SA1100_SIMPAD) += simpad.o
led-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o
obj-$(CONFIG_SA1100_STORK) += stork.o
export-objs += stork.o
obj-$(CONFIG_SA1100_VICTOR) += victor.o
obj-$(CONFIG_SA1100_XP860) += xp860.o
obj-$(CONFIG_SA1100_YOPY) += yopy.o
export-objs += yopy.o
# LEDs support
leds-y := leds.o
leds-$(CONFIG_SA1100_ADSBITSY) += leds-adsbitsy.o
leds-$(CONFIG_SA1100_ASSABET) += leds-assabet.o
leds-$(CONFIG_SA1100_BRUTUS) += leds-brutus.o
leds-$(CONFIG_SA1100_CERF) += leds-cerf.o
leds-$(CONFIG_SA1100_FLEXANET) += leds-flexanet.o
leds-$(CONFIG_SA1100_GRAPHICSCLIENT) += leds-graphicsclient.o
leds-$(CONFIG_SA1100_GRAPHICSMASTER) += leds-graphicsmaster.o
leds-$(CONFIG_SA1100_LART) += leds-lart.o
leds-$(CONFIG_SA1100_PFS168) += leds-pfs168.o
leds-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o
leds-$(CONFIG_SA1100_PT_SYSTEM3) += leds-system3.o
obj-$(CONFIG_LEDS) += $(leds-y)
obj-$(CONFIG_LEDS) += $(led-y)
# SA1110 USB client support
list-multi += sa1100usb_core.o
......
......@@ -3,7 +3,7 @@
*
* Copyright (C) 2001 Russell King
*
* $Id: cpu-sa1110.c,v 1.6 2001/10/22 11:53:47 rmk Exp $
* $Id: cpu-sa1110.c,v 1.8 2002/01/09 17:13:27 rmk Exp $
*
* 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
......@@ -69,13 +69,23 @@ static struct sdram_params tc59sm716_cl3_params __initdata = {
};
static struct sdram_params samsung_k4s641632d_tc75 __initdata = {
rows: 14,
tck: 9,
trcd: 27,
trp: 20,
twr: 9,
refresh: 64000,
cas_latency: 3,
rows: 14,
tck: 9,
trcd: 27,
trp: 20,
twr: 9,
refresh: 64000,
cas_latency: 3,
};
static struct sdram_params samsung_km416s4030ct __initdata = {
rows: 13,
tck: 8,
trcd: 24, /* 3 CLKs */
trp: 24, /* 3 CLKs */
twr: 16, /* Trdl: 2 CLKs */
refresh: 64000,
cas_latency: 3,
};
static struct sdram_params sdram_params;
......@@ -273,6 +283,8 @@ static int __init sa1110_clk_init(void)
if (machine_is_pt_system3())
sdram = &samsung_k4s641632d_tc75;
if (machine_is_h3100())
sdram = &samsung_km416s4030ct;
if (sdram) {
printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d"
......
......@@ -20,6 +20,7 @@
* in the platform specific files.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/slab.h>
......@@ -27,6 +28,7 @@
#include <linux/interrupt.h>
#include <linux/sysctl.h>
#include <linux/errno.h>
#include <linux/cpufreq.h>
#include <asm/hardware.h>
#include <asm/memory.h>
......@@ -210,3 +212,5 @@ static int __init pm_init(void)
__initcall(pm_init);
#endif
EXPORT_SYMBOL(pm_do_suspend);
......@@ -99,10 +99,9 @@ extern void convert_to_tag_list(struct param_struct *params, int mem_init);
*/
static struct map_desc system3_io_desc[] __initdata = {
/* virtual physical length domain r w c b */
{ 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
{ 0xf3000000, PT_CPLD_BASE, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* System Registers */
{ 0xf4000000, PT_SA1111_BASE, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA-1111 */
/* virtual physical length domain r w c b */
{ 0xf3000000, PT_CPLD_BASE, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* System Registers */
{ 0xf4000000, PT_SA1111_BASE, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA-1111 */
LAST_DESC
};
......
#include <linux/linkage.h>
#include <asm/assembler.h>
/*
* Function: armv4_early_abort
* Function: v4_early_abort
*
* Params : r2 = address of aborted instruction
* : r3 = saved SPSR
......@@ -18,7 +18,7 @@
* picture. Unfortunately, this does happen. We live with it.
*/
.align 5
ENTRY(armv4_early_abort)
ENTRY(v4_early_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
ldr r3, [r2] @ read aborted ARM instruction
......
#include <linux/linkage.h>
#include <asm/assembler.h>
/*
* Function: armv4t_early_abort
* Function: v4t_early_abort
*
* Params : r2 = address of aborted instruction
* : r3 = saved SPSR
......@@ -18,7 +18,7 @@
* picture. Unfortunately, this does happen. We live with it.
*/
.align 5
ENTRY(armv4t_early_abort)
ENTRY(v4t_early_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
tst r3, #PSR_T_BIT
......
#include <linux/linkage.h>
#include <asm/assembler.h>
/*
* Function: armv5ej_early_abort
* Function: v5ej_early_abort
*
* Params : r2 = address of aborted instruction
* : r3 = saved SPSR
......@@ -18,7 +18,7 @@
* picture. Unfortunately, this does happen. We live with it.
*/
.align 5
ENTRY(armv5ej_early_abort)
ENTRY(v5ej_early_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
tst r3, #PSR_J_BIT
......
#include <linux/linkage.h>
#include <asm/assembler.h>
/*
* Function: armv4t_late_abort
* Function: v4t_late_abort
*
* Params : r2 = address of aborted instruction
* : r3 = saved SPSR
......@@ -17,7 +17,7 @@
* abort here if the I-TLB and D-TLB aren't seeing the same
* picture. Unfortunately, this does happen. We live with it.
*/
ENTRY(armv4t_late_abort)
ENTRY(v4t_late_abort)
tst r3, #PSR_T_BIT @ check for thumb mode
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
......
......@@ -20,7 +20,7 @@
*
* FIXME: do we need to handle cache stuff...
*/
ENTRY(armv3_copy_user_page)
ENTRY(v3_copy_user_page)
stmfd sp!, {r4, lr} @ 2
mov r2, #PAGE_SZ/64 @ 1
ldmia r1!, {r3, r4, ip, lr} @ 4+1
......@@ -42,7 +42,7 @@ ENTRY(armv3_copy_user_page)
*
* FIXME: do we need to handle cache stuff...
*/
ENTRY(armv3_clear_user_page)
ENTRY(v3_clear_user_page)
str lr, [sp, #-4]!
mov r1, #PAGE_SZ/64 @ 1
mov r2, #0 @ 1
......@@ -57,3 +57,8 @@ ENTRY(armv3_clear_user_page)
bne 1b @ 1
ldr pc, [sp], #4
.section ".text.init", #alloc, #execinstr
ENTRY(v3_user_fns)
.long v3_clear_user_page
.long v3_copy_user_page
......@@ -26,7 +26,7 @@
* instruction. If your processor does not supply this, you have to write your
* own copy_user_page that does the right thing.
*/
ENTRY(armv4_copy_user_page)
ENTRY(v4_copy_user_page)
stmfd sp!, {r4, lr} @ 2
mov r2, #PAGE_SZ/64 @ 1
ldmia r1!, {r3, r4, ip, lr} @ 4
......@@ -51,7 +51,7 @@ ENTRY(armv4_copy_user_page)
*
* Same story as above.
*/
ENTRY(armv4_clear_user_page)
ENTRY(v4_clear_user_page)
str lr, [sp, #-4]!
mov r1, #PAGE_SZ/64 @ 1
mov r2, #0 @ 1
......@@ -68,3 +68,10 @@ ENTRY(armv4_clear_user_page)
bne 1b @ 1
mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB
ldr pc, [sp], #4
.section ".text.init", #alloc, #execinstr
ENTRY(v4_user_fns)
.long v4_clear_user_page
.long v4_copy_user_page
......@@ -26,7 +26,7 @@
* instruction. If your processor does not supply this, you have to write your
* own copy_user_page that does the right thing.
*/
ENTRY(armv4_mc_copy_user_page)
ENTRY(v4_mc_copy_user_page)
stmfd sp!, {r4, lr} @ 2
mov r4, r0
mov r0, r1
......@@ -53,7 +53,7 @@ ENTRY(armv4_mc_copy_user_page)
*
* Same story as above.
*/
ENTRY(armv4_mc_clear_user_page)
ENTRY(v4_mc_clear_user_page)
str lr, [sp, #-4]!
mov r1, #PAGE_SZ/64 @ 1
mov r2, #0 @ 1
......@@ -69,3 +69,10 @@ ENTRY(armv4_mc_clear_user_page)
subs r1, r1, #1 @ 1
bne 1b @ 1
ldr pc, [sp], #4
.section ".text.init", #alloc, #execinstr
ENTRY(v4_mc_user_fns)
.long v4_mc_clear_user_page
.long v4_mc_copy_user_page
......@@ -32,7 +32,7 @@
* page. We rely on the mini-cache being smaller than one page, so we'll
* cycle through the complete cache anyway.
*/
ENTRY(armv5te_copy_user_page)
ENTRY(v5te_mc_copy_user_page)
stmfd sp!, {r4, r5, lr}
mov r5, r0
mov r0, r1
......@@ -62,7 +62,7 @@ ENTRY(armv5te_copy_user_page)
* r0 = destination
* r1 = virtual user address of ultimate destination page
*/
ENTRY(armv5te_clear_user_page)
ENTRY(v5te_mc_clear_user_page)
str lr, [sp, #-4]!
mov r1, #PAGE_SZ/32
mov r2, #0
......@@ -77,3 +77,9 @@ ENTRY(armv5te_clear_user_page)
subs r1, r1, #1
bne 1b
ldr pc, [sp], #4
.section ".text.init", #alloc, #execinstr
ENTRY(v5te_mc_user_fns)
.long v5te_mc_clear_user_page
.long v5te_mc_copy_user_page
......@@ -181,7 +181,7 @@ static void adjust_pte(struct vm_area_struct *vma, unsigned long address)
static void
make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page)
{
struct vm_area_struct *mpnt;
struct list_head *l;
struct mm_struct *mm = vma->vm_mm;
unsigned long pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
int aliases = 0;
......@@ -191,10 +191,12 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page)
* space, then we need to handle them specially to maintain
* cache coherency.
*/
for (mpnt = page->mapping->i_mmap_shared; mpnt;
mpnt = mpnt->vm_next_share) {
list_for_each(l, &page->mapping->i_mmap_shared) {
struct vm_area_struct *mpnt;
unsigned long off;
mpnt = list_entry(l, struct vm_area_struct, shared);
/*
* If this VMA is not in our MM, we can ignore it.
* Note that we intentionally don't mask out the VMA
......
/*
* linux/arch/arm/mm/init.c
*
* Copyright (C) 1995-2000 Russell King
* Copyright (C) 1995-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
......@@ -46,7 +46,7 @@
#define TABLE_OFFSET 0
#endif
#define TABLE_SIZE ((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *))
#define TABLE_SIZE ((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(pte_t))
static unsigned long totalram_pages;
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
......@@ -319,7 +319,7 @@ static __init void reserve_node_zero(unsigned int bootmap_pfn, unsigned int boot
* and can only be in node 0.
*/
reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
PTRS_PER_PGD * sizeof(void *));
PTRS_PER_PGD * sizeof(pgd_t));
#endif
/*
* And don't forget to reserve the allocator bitmap,
......
/*
* linux/arch/arm/mm/mm-armv.c
*
* Copyright (C) 1998-2000 Russell King
* Copyright (C) 1998-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
......@@ -82,9 +82,6 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
init_pgd = pgd_offset_k(0);
if (vectors_base() == 0) {
init_pmd = pmd_offset(init_pgd, 0);
init_pte = pte_offset(init_pmd, 0);
/*
* This lock is here just to satisfy pmd_alloc and pte_lock
*/
......@@ -172,11 +169,14 @@ void free_pgd_slow(pgd_t *pgd)
static inline void
alloc_init_section(unsigned long virt, unsigned long phys, int prot)
{
pmd_t pmd;
pmd_t *pmdp, pmd;
pmd_val(pmd) = phys | prot;
pmdp = pmd_offset(pgd_offset_k(virt), virt);
if (virt & (1 << PMD_SHIFT))
pmdp++;
set_pmd(pmd_offset(pgd_offset_k(virt), virt), pmd);
pmd_val(pmd) = phys | prot;
set_pmd(pmdp, pmd);
}
/*
......@@ -189,18 +189,19 @@ alloc_init_section(unsigned long virt, unsigned long phys, int prot)
static inline void
alloc_init_page(unsigned long virt, unsigned long phys, int domain, int prot)
{
pmd_t *pmdp;
pmd_t *pmdp, pmd;
pte_t *ptep;
pmdp = pmd_offset(pgd_offset_k(virt), virt);
if (pmd_none(*pmdp)) {
pte_t *ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
sizeof(pte_t));
ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
sizeof(pte_t));
ptep += PTRS_PER_PTE;
set_pmd(pmdp, __mk_pmd(ptep, PMD_TYPE_TABLE | PMD_DOMAIN(domain)));
pmd_val(pmd) = __pa(ptep) | PMD_TYPE_TABLE | PMD_DOMAIN(domain);
set_pmd(pmdp, pmd);
pmd_val(pmd) += 256 * sizeof(pte_t);
set_pmd(pmdp + 1, pmd);
}
ptep = pte_offset_kernel(pmdp, virt);
......@@ -266,11 +267,11 @@ static void __init create_mapping(struct map_desc *md)
length -= PAGE_SIZE;
}
while (length >= PGDIR_SIZE) {
while (length >= (PGDIR_SIZE / 2)) {
alloc_init_section(virt, virt + off, prot_sect);
virt += PGDIR_SIZE;
length -= PGDIR_SIZE;
virt += (PGDIR_SIZE / 2);
length -= (PGDIR_SIZE / 2);
}
while (length >= PAGE_SIZE) {
......@@ -463,41 +464,3 @@ void __init create_memmap_holes(struct meminfo *mi)
for (node = 0; node < numnodes; node++)
free_unused_memmap_node(node, mi);
}
/*
* PTE table allocation cache.
*
* This is a move away from our custom 2K page allocator. We now use the
* slab cache to keep track of these objects.
*
* With this, it is questionable as to whether the PGT cache gains us
* anything. We may be better off dropping the PTE stuff from our PGT
* cache implementation.
*/
kmem_cache_t *pte_cache;
/*
* The constructor gets called for each object within the cache when the
* cache page is created. Note that if slab tries to misalign the blocks,
* we BUG() loudly.
*/
static void pte_cache_ctor(void *pte, kmem_cache_t *cache, unsigned long flags)
{
unsigned long block = (unsigned long)pte;
if (block & 2047)
BUG();
memzero(pte, 2 * PTRS_PER_PTE * sizeof(pte_t));
cpu_cache_clean_invalidate_range(block, block +
PTRS_PER_PTE * sizeof(pte_t), 0);
}
void __init pgtable_cache_init(void)
{
pte_cache = kmem_cache_create("pte-cache",
2 * PTRS_PER_PTE * sizeof(pte_t), 0, 0,
pte_cache_ctor, NULL);
if (!pte_cache)
BUG();
}
......@@ -499,7 +499,9 @@ ENTRY(cpu_arm1020_set_pmd)
*/
.align 5
ENTRY(cpu_arm1020_set_pte)
str r1, [r0], #-1024 @ linux version
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version
eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
......@@ -608,7 +610,7 @@ __arm1020_setup:
*/
.type arm1020_processor_functions, #object
arm1020_processor_functions:
.word armv4t_early_abort
.word v4t_early_abort
.word cpu_arm1020_check_bugs
.word cpu_arm1020_proc_init
.word cpu_arm1020_proc_fin
......@@ -635,10 +637,6 @@ arm1020_processor_functions:
.word cpu_arm1020_set_pmd
.word cpu_arm1020_set_pte
/* misc */
.word armv4_clear_user_page
.word armv4_copy_user_page
.size arm1020_processor_functions, . - arm1020_processor_functions
.type cpu_arm1020_info, #object
......@@ -672,4 +670,5 @@ __arm1020_proc_info:
.long cpu_arm1020_info
.long arm1020_processor_functions
.long v4wbi_tlb_fns
.long v4_user_fns
.size __arm1020_proc_info, . - __arm1020_proc_info
......@@ -342,6 +342,7 @@ arm3_elf_name: .asciz "v2"
.long cpu_arm2_info
.long SYMBOL_NAME(arm2_processor_functions)
.long 0
.long 0
.long 0x41560250
.long 0xfffffff0
......@@ -353,6 +354,7 @@ arm3_elf_name: .asciz "v2"
.long cpu_arm250_info
.long SYMBOL_NAME(arm250_processor_functions)
.long 0
.long 0
.long 0x41560300
.long 0xfffffff0
......@@ -364,3 +366,5 @@ arm3_elf_name: .asciz "v2"
.long cpu_arm3_info
.long SYMBOL_NAME(arm3_processor_functions)
.long 0
.long 0
......@@ -274,7 +274,9 @@ ENTRY(cpu_arm7_set_pmd)
.align 5
ENTRY(cpu_arm6_set_pte)
ENTRY(cpu_arm7_set_pte)
str r1, [r0], #-1024 @ linux version
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version
eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
......@@ -373,10 +375,6 @@ ENTRY(arm6_processor_functions)
.word cpu_arm6_set_pmd
.word cpu_arm6_set_pte
/* other */
.word armv3_clear_user_page
.word armv3_copy_user_page
.size arm6_processor_functions, . - arm6_processor_functions
/*
......@@ -412,10 +410,6 @@ ENTRY(arm7_processor_functions)
.word cpu_arm7_set_pmd
.word cpu_arm7_set_pte
/* other */
.word armv3_clear_user_page
.word armv3_copy_user_page
.size arm7_processor_functions, . - arm7_processor_functions
.type cpu_arm6_info, #object
......@@ -465,6 +459,7 @@ __arm6_proc_info:
.long cpu_arm6_info
.long arm6_processor_functions
.long v3_tlb_fns
.long v3_user_fns
.size __arm6_proc_info, . - __arm6_proc_info
.type __arm610_proc_info, #object
......@@ -479,6 +474,7 @@ __arm610_proc_info:
.long cpu_arm610_info
.long arm6_processor_functions
.long v3_tlb_fns
.long v3_user_fns
.size __arm610_proc_info, . - __arm610_proc_info
.type __arm7_proc_info, #object
......@@ -493,6 +489,7 @@ __arm7_proc_info:
.long cpu_arm7_info
.long arm7_processor_functions
.long v3_tlb_fns
.long v3_user_fns
.size __arm7_proc_info, . - __arm7_proc_info
.type __arm710_proc_info, #object
......@@ -507,4 +504,5 @@ __arm710_proc_info:
.long cpu_arm710_info
.long arm7_processor_functions
.long v3_tlb_fns
.long v3_user_fns
.size __arm710_proc_info, . - __arm710_proc_info
......@@ -136,7 +136,9 @@ ENTRY(cpu_arm720_set_pmd)
*/
.align 5
ENTRY(cpu_arm720_set_pte)
str r1, [r0], #-1024 @ linux version
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version
eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
......@@ -199,7 +201,7 @@ __arm720_setup: mov r0, #0
*/
.type arm720_processor_functions, #object
ENTRY(arm720_processor_functions)
.word armv4t_late_abort
.word v4t_late_abort
.word cpu_arm720_check_bugs
.word cpu_arm720_proc_init
.word cpu_arm720_proc_fin
......@@ -226,10 +228,6 @@ ENTRY(arm720_processor_functions)
.word cpu_arm720_set_pmd
.word cpu_arm720_set_pte
/* misc */
.word armv4_clear_user_page
.word armv4_copy_user_page
.size arm720_processor_functions, . - arm720_processor_functions
.type cpu_arm720_info, #object
......@@ -265,4 +263,5 @@ __arm720_proc_info:
.long cpu_arm720_info @ info
.long arm720_processor_functions
.long v4_tlb_fns
.long v4_user_fns
.size __arm720_proc_info, . - __arm720_proc_info
......@@ -420,7 +420,9 @@ ENTRY(cpu_arm920_set_pmd)
*/
.align 5
ENTRY(cpu_arm920_set_pte)
str r1, [r0], #-1024 @ linux version
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version
eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
......@@ -511,7 +513,7 @@ __arm920_setup:
*/
.type arm920_processor_functions, #object
arm920_processor_functions:
.word armv4t_early_abort
.word v4t_early_abort
.word cpu_arm920_check_bugs
.word cpu_arm920_proc_init
.word cpu_arm920_proc_fin
......@@ -538,10 +540,6 @@ arm920_processor_functions:
.word cpu_arm920_set_pmd
.word cpu_arm920_set_pte
/* misc */
.word armv4_clear_user_page
.word armv4_copy_user_page
.size arm920_processor_functions, . - arm920_processor_functions
.type cpu_arm920_info, #object
......@@ -575,4 +573,5 @@ __arm920_proc_info:
.long cpu_arm920_info
.long arm920_processor_functions
.long v4wbi_tlb_fns
.long v4_user_fns
.size __arm920_proc_info, . - __arm920_proc_info
......@@ -421,7 +421,9 @@ ENTRY(cpu_arm922_set_pmd)
*/
.align 5
ENTRY(cpu_arm922_set_pte)
str r1, [r0], #-1024 @ linux version
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version
eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
......@@ -512,7 +514,7 @@ __arm922_setup:
*/
.type arm922_processor_functions, #object
arm922_processor_functions:
.word armv4t_early_abort
.word v4t_early_abort
.word cpu_arm922_check_bugs
.word cpu_arm922_proc_init
.word cpu_arm922_proc_fin
......@@ -539,10 +541,6 @@ arm922_processor_functions:
.word cpu_arm922_set_pmd
.word cpu_arm922_set_pte
/* misc */
.word armv4_clear_user_page
.word armv4_copy_user_page
.size arm922_processor_functions, . - arm922_processor_functions
.type cpu_arm922_info, #object
......@@ -576,4 +574,5 @@ __arm922_proc_info:
.long cpu_arm922_info
.long arm922_processor_functions
.long v4wbi_tlb_fns
.long v4_user_fns
.size __arm922_proc_info, . - __arm922_proc_info
......@@ -443,7 +443,9 @@ ENTRY(cpu_arm926_set_pmd)
*/
.align 5
ENTRY(cpu_arm926_set_pte)
str r1, [r0], #-1024 @ linux version
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version
eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
......@@ -549,7 +551,7 @@ __arm926_setup:
*/
.type arm926_processor_functions, #object
arm926_processor_functions:
.word armv5ej_early_abort
.word v5ej_early_abort
.word cpu_arm926_check_bugs
.word cpu_arm926_proc_init
.word cpu_arm926_proc_fin
......@@ -576,10 +578,6 @@ arm926_processor_functions:
.word cpu_arm926_set_pmd
.word cpu_arm926_set_pte
/* misc */
.word armv4_clear_user_page
.word armv4_copy_user_page
.size arm926_processor_functions, . - arm926_processor_functions
.type cpu_arm926_info, #object
......@@ -613,4 +611,5 @@ __arm926_proc_info:
.long cpu_arm926_info
.long arm926_processor_functions
.long v4wbi_tlb_fns
.long v4_user_fns
.size __arm926_proc_info, . - __arm926_proc_info
/*
* linux/arch/arm/mm/proc-sa110.S
*
* Copyright (C) 1997-2000 Russell King
* Copyright (C) 1997-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
......@@ -468,7 +468,9 @@ ENTRY(cpu_sa1100_set_pmd)
.align 5
ENTRY(cpu_sa110_set_pte)
ENTRY(cpu_sa1100_set_pte)
str r1, [r0], #-1024 @ linux version
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version
eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
......@@ -538,7 +540,7 @@ __setup_common:
.type sa110_processor_functions, #object
ENTRY(sa110_processor_functions)
.word armv4_early_abort
.word v4_early_abort
.word cpu_sa110_check_bugs
.word cpu_sa110_proc_init
.word cpu_sa110_proc_fin
......@@ -565,10 +567,6 @@ ENTRY(sa110_processor_functions)
.word cpu_sa110_set_pmd
.word cpu_sa110_set_pte
/* misc */
.word armv4_clear_user_page
.word armv4_copy_user_page
.size sa110_processor_functions, . - sa110_processor_functions
.type cpu_sa110_info, #object
......@@ -610,10 +608,6 @@ ENTRY(sa1100_processor_functions)
.word cpu_sa1100_set_pmd
.word cpu_sa1100_set_pte
/* misc */
.word armv4_mc_clear_user_page
.word armv4_mc_copy_user_page
.size sa1100_processor_functions, . - sa1100_processor_functions
cpu_sa1100_info:
......@@ -651,6 +645,7 @@ __sa110_proc_info:
.long cpu_sa110_info
.long sa110_processor_functions
.long v4wb_tlb_fns
.long v4_user_fns
.size __sa110_proc_info, . - __sa110_proc_info
.type __sa1100_proc_info,#object
......@@ -665,6 +660,7 @@ __sa1100_proc_info:
.long cpu_sa1100_info
.long sa1100_processor_functions
.long v4wb_tlb_fns
.long v4_mc_user_fns
.size __sa1100_proc_info, . - __sa1100_proc_info
.type __sa1110_proc_info,#object
......@@ -679,4 +675,5 @@ __sa1110_proc_info:
.long cpu_sa1110_info
.long sa1100_processor_functions
.long v4wb_tlb_fns
.long v4_mc_user_fns
.size __sa1110_proc_info, . - __sa1110_proc_info
......@@ -602,7 +602,9 @@ ENTRY(cpu_xscale_set_pmd)
*/
.align 5
ENTRY(cpu_xscale_set_pte)
str r1, [r0], #-1024 @ linux version
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version
bic r2, r1, #0xff0
orr r2, r2, #PTE_TYPE_EXT @ extended page
......@@ -695,7 +697,7 @@ __xscale_setup:
.type xscale_processor_functions, #object
ENTRY(xscale_processor_functions)
.word armv4t_early_abort
.word v4t_early_abort
.word cpu_xscale_check_bugs
.word cpu_xscale_proc_init
.word cpu_xscale_proc_fin
......@@ -722,10 +724,6 @@ ENTRY(xscale_processor_functions)
.word cpu_xscale_set_pmd
.word cpu_xscale_set_pte
/* misc */
.word armv5te_clear_user_page
.word armv5te_copy_user_page
.size xscale_processor_functions, . - xscale_processor_functions
.type cpu_80200_info, #object
......@@ -765,6 +763,7 @@ __80200_proc_info:
.long cpu_80200_info
.long xscale_processor_functions
.long v4wbi_tlb_fns
.long v5te_mc_user_fns
.size __80200_proc_info, . - __80200_proc_info
.type __pxa250_proc_info,#object
......@@ -779,6 +778,7 @@ __pxa250_proc_info:
.long cpu_pxa250_info
.long xscale_processor_functions
.long v4wbi_tlb_fns
.long v5te_mc_user_fns
.size __cotulla_proc_info, . - __cotulla_proc_info
.size __pxa250_proc_info, . - __pxa250_proc_info
......@@ -14,6 +14,9 @@
*/
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/miscdevice.h>
#include <linux/rtc.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
......@@ -21,15 +24,19 @@
#include <asm/io.h>
#include <asm/hardware/ioc.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include "pcf8583.h"
extern unsigned long
mktime(unsigned int year, unsigned int mon, unsigned int day,
unsigned int hour, unsigned int min, unsigned int sec);
extern int (*set_rtc)(void);
static struct i2c_client *rtc_client;
static const unsigned char days_in_mon[] =
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static unsigned int rtc_epoch = 1900;
#define CMOS_CHECKSUM (63)
#define CMOS_YEAR (64 + 128)
static inline int rtc_command(int cmd, void *data)
{
......@@ -44,12 +51,10 @@ static inline int rtc_command(int cmd, void *data)
/*
* Read the current RTC time and date, and update xtime.
*/
static void get_rtc_time(void)
static void get_rtc_time(struct rtc_tm *rtctm, unsigned int *year)
{
unsigned char ctrl;
unsigned char year;
struct rtc_tm rtctm;
struct mem rtcmem = { 0xc0, 1, &year };
unsigned char ctrl, yr[2];
struct mem rtcmem = { CMOS_YEAR, sizeof(yr), yr };
/*
* Ensure that the RTC is running.
......@@ -73,22 +78,53 @@ static void get_rtc_time(void)
if (rtc_command(MEM_READ, &rtcmem))
return;
if (rtc_command(RTC_GETDATETIME, &rtctm))
if (rtc_command(RTC_GETDATETIME, rtctm))
return;
if (year < 70)
year += 100;
*year = yr[1] * 100 + yr[0];
}
static int set_rtc_time(struct rtc_tm *rtctm, unsigned int year)
{
unsigned char yr[2], leap, chk;
struct mem cmos_year = { CMOS_YEAR, sizeof(yr), yr };
struct mem cmos_check = { CMOS_CHECKSUM, 1, &chk };
int ret;
leap = (!(year % 4) && (year % 100)) || !(year % 400);
if (rtctm->mon > 12 || rtctm->mday == 0)
return -EINVAL;
if (rtctm->mday > (days_in_mon[rtctm->mon] + (rtctm->mon == 2 && leap)))
return -EINVAL;
if (rtctm->hours >= 24 || rtctm->mins >= 60 || rtctm->secs >= 60)
return -EINVAL;
xtime.tv_usec = rtctm.cs * 10000;
xtime.tv_sec = mktime(1900 + year, rtctm.mon, rtctm.mday,
rtctm.hours, rtctm.mins, rtctm.secs);
ret = rtc_command(RTC_SETDATETIME, rtctm);
if (ret == 0) {
rtc_command(MEM_READ, &cmos_check);
rtc_command(MEM_READ, &cmos_year);
chk -= yr[1] + yr[0];
yr[1] = year / 100;
yr[0] = year % 100;
chk += yr[1] + yr[0];
rtc_command(MEM_WRITE, &cmos_year);
rtc_command(MEM_WRITE, &cmos_check);
}
return ret;
}
/*
* Set the RTC time only. Note that
* we do not touch the date.
*/
static int set_rtc_time(void)
static int k_set_rtc_time(void)
{
struct rtc_tm new_rtctm, old_rtctm;
unsigned long nowtime = xtime.tv_sec;
......@@ -110,13 +146,70 @@ static int set_rtc_time(void)
* [ rtc: 1/1/2000 23:58:00, real 2/1/2000 00:01:00,
* rtc gets set to 1/1/2000 00:01:00 ]
*/
if ((old_rtctm.hours == 23 && old_rtctm.mins == 59) ||
(new_rtctm.hours == 23 && new_rtctm.mins == 59))
if ((old_rtctm.hours == 23 && old_rtctm.mins == 59) ||
(new_rtctm.hours == 23 && new_rtctm.mins == 59))
return 1;
return rtc_command(RTC_SETTIME, &new_rtctm);
}
static int rtc_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
unsigned int year;
struct rtc_time rtctm;
struct rtc_tm rtc_raw;
switch (cmd) {
case RTC_ALM_READ:
case RTC_ALM_SET:
break;
case RTC_RD_TIME:
get_rtc_time(&rtc_raw, &year);
rtctm.tm_sec = rtc_raw.secs;
rtctm.tm_min = rtc_raw.mins;
rtctm.tm_hour = rtc_raw.hours;
rtctm.tm_mday = rtc_raw.mday;
rtctm.tm_mon = rtc_raw.mon - 1; /* month starts at 0 */
rtctm.tm_year = year - 1900; /* starts at 1900 */
return copy_to_user((void *)arg, &rtctm, sizeof(rtctm))
? -EFAULT : 0;
case RTC_SET_TIME:
if (!capable(CAP_SYS_TIME))
return -EACCES;
if (copy_from_user(&rtctm, (void *)arg, sizeof(rtctm)))
return -EFAULT;
rtc_raw.secs = rtctm.tm_sec;
rtc_raw.mins = rtctm.tm_min;
rtc_raw.hours = rtctm.tm_hour;
rtc_raw.mday = rtctm.tm_mday;
rtc_raw.mon = rtctm.tm_mon + 1;
rtc_raw.year_off = 2;
year = rtctm.tm_year + 1900;
return set_rtc_time(&rtc_raw, year);
break;
case RTC_EPOCH_READ:
return put_user(rtc_epoch, (unsigned long *)arg);
}
return -EINVAL;
}
static struct file_operations rtc_fops = {
ioctl: rtc_ioctl,
};
static struct miscdevice rtc_dev = {
minor: RTC_MINOR,
name: "rtc",
fops: &rtc_fops,
};
/* IOC / IOMD i2c driver */
#define FORCE_ONES 0xdc
#define SCL 0x02
......@@ -184,9 +277,16 @@ static int ioc_client_reg(struct i2c_client *client)
{
if (client->id == I2C_DRIVERID_PCF8583 &&
client->addr == 0x50) {
struct rtc_tm rtctm;
unsigned int year;
rtc_client = client;
get_rtc_time();
set_rtc = set_rtc_time;
get_rtc_time(&rtctm, &year);
xtime.tv_usec = rtctm.cs * 10000;
xtime.tv_sec = mktime(year, rtctm.mon, rtctm.mday,
rtctm.hours, rtctm.mins, rtctm.secs);
set_rtc = k_set_rtc_time;
}
return 0;
......@@ -212,9 +312,16 @@ static struct i2c_adapter ioc_ops = {
static int __init i2c_ioc_init(void)
{
int ret;
force_ones = FORCE_ONES | SCL | SDA;
return i2c_bit_add_bus(&ioc_ops);
ret = i2c_bit_add_bus(&ioc_ops);
if (ret >= 0)
misc_register(&rtc_dev);
return ret;
}
__initcall(i2c_ioc_init);
......@@ -20,7 +20,4 @@
#define MY_PORT_ADDRESS(port,cardaddr) \
((cardaddr) + 0x200 - (port) * 0x100)
#define INIT serial_card_atomwide_init
#define EXIT serial_card_atomwide_exit
#include "serial-card.c"
......@@ -29,6 +29,7 @@
#include <linux/types.h>
#include <linux/serial.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <asm/ecard.h>
......@@ -38,95 +39,84 @@
#define NUM_SERIALS MY_NUMPORTS * MAX_ECARDS
#endif
#ifdef MODULE
static int __serial_ports[NUM_SERIALS];
static int __serial_pcount;
static int __serial_addr[NUM_SERIALS];
static int serial_ports[NUM_SERIALS];
static int serial_pcount;
static int serial_addr[NUM_SERIALS];
static struct expansion_card *expcard[MAX_ECARDS];
#define ADD_ECARD(ec,card) expcard[(card)] = (ec)
#define ADD_PORT(port,addr) \
do { \
__serial_ports[__serial_pcount] = (port); \
__serial_addr[__serial_pcount] = (addr); \
__serial_pcount += 1; \
} while (0)
#else
#define ADD_ECARD(ec,card)
#define ADD_PORT(port,addr)
#endif
static const card_ids serial_cids[] = { MY_CARD_LIST, { 0xffff, 0xffff } };
static inline int serial_register_onedev (unsigned long port, int irq)
{
struct serial_struct req;
struct serial_struct req;
memset(&req, 0, sizeof(req));
req.baud_base = MY_BAUD_BASE;
req.irq = irq;
req.port = port;
req.flags = 0;
memset(&req, 0, sizeof(req));
req.baud_base = MY_BAUD_BASE;
req.irq = irq;
req.port = port;
req.flags = 0;
return register_serial(&req);
return register_serial(&req);
}
static int __init INIT (void)
static int __init serial_card_init(void)
{
int card = 0;
ecard_startfind ();
do {
struct expansion_card *ec;
unsigned long cardaddr;
int port;
ec = ecard_find (0, serial_cids);
if (!ec)
break;
cardaddr = MY_BASE_ADDRESS(ec);
for (port = 0; port < MY_NUMPORTS; port ++) {
unsigned long address;
int line;
address = MY_PORT_ADDRESS(port, cardaddr);
line = serial_register_onedev (address, ec->irq);
if (line < 0)
break;
ADD_PORT(line, address);
}
if (port) {
ecard_claim (ec);
ADD_ECARD(ec, card);
} else
break;
} while (++card < MAX_ECARDS);
return card ? 0 : -ENODEV;
int card = 0;
ecard_startfind ();
do {
struct expansion_card *ec;
unsigned long cardaddr;
int port;
ec = ecard_find (0, serial_cids);
if (!ec)
break;
cardaddr = MY_BASE_ADDRESS(ec);
for (port = 0; port < MY_NUMPORTS; port ++) {
unsigned long address;
int line;
address = MY_PORT_ADDRESS(port, cardaddr);
line = serial_register_onedev (address, ec->irq);
if (line < 0)
break;
serial_ports[serial_pcount] = line;
serial_addr[serial_pcount] = address;
serial_pcount += 1;
}
if (port) {
ecard_claim (ec);
expcard[card] = ec;
} else
break;
} while (++card < MAX_ECARDS);
return card ? 0 : -ENODEV;
}
static void __exit EXIT (void)
static void __exit serial_card_exit(void)
{
#ifdef MODULE
int i;
int i;
for (i = 0; i < __serial_pcount; i++) {
unregister_serial(__serial_ports[i]);
release_region(__serial_addr[i], 8);
}
for (i = 0; i < serial_pcount; i++) {
unregister_serial(serial_ports[i]);
release_region(serial_addr[i], 8);
}
for (i = 0; i < MAX_ECARDS; i++)
if (expcard[i])
ecard_release (expcard[i]);
#endif
for (i = 0; i < MAX_ECARDS; i++)
if (expcard[i])
ecard_release (expcard[i]);
}
EXPORT_NO_SYMBOLS;
MODULE_AUTHOR("Russell King");
MODULE_LICENSE("GPL");
module_init(INIT);
module_exit(EXIT);
module_init(serial_card_init);
module_exit(serial_card_exit);
......@@ -18,7 +18,4 @@
#define MY_PORT_ADDRESS(port,cardaddress) \
((cardaddress) + (port) * 8)
#define INIT serial_card_dualsp_init
#define EXIT serial_card_dualsp_exit
#include "serial-card.c"
......@@ -718,7 +718,7 @@ dropping:{
/*
* Don't print this message too many times...
*/
if (jiffies - last_warned > 30 * HZ) {
if (time_after(jiffies, last_warned + 10 * HZ)) {
last_warned = jiffies;
printk("%s: memory squeeze, dropping packet.\n", dev->name);
}
......
/*
* linux/drivers/acorn/net/etherh.c
*
* Copyright (C) 2000 Russell King
* Copyright (C) 2000-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
......@@ -23,6 +23,7 @@
* 12-10-1999 CK/TEW EtherM driver first release
* 21-12-2000 TTC EtherH/EtherM integration
* 25-12-2000 RMK 1.08 Clean integration of EtherM into this driver.
* 03-01-2002 RMK 1.09 Always enable IRQs if we're in the nic slot.
*/
#include <linux/module.h>
......@@ -64,13 +65,18 @@ static const card_ids __init etherh_cids[] = {
{ 0xffff, 0xffff }
};
struct etherh_priv {
unsigned int id;
unsigned int ctrl_port;
unsigned int ctrl;
};
MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("EtherH/EtherM driver");
MODULE_LICENSE("GPL");
static char version[] __initdata =
"EtherH/EtherM Driver (c) 2000 Russell King v1.08\n";
"EtherH/EtherM Driver (c) 2002 Russell King v1.09\n";
#define ETHERH500_DATAPORT 0x200 /* MEMC */
#define ETHERH500_NS8390 0x000 /* MEMC */
......@@ -97,18 +103,61 @@ static char version[] __initdata =
#define ETHERM_TX_START_PAGE 64
#define ETHERM_STOP_PAGE 127
/* --------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------ */
static inline void etherh_set_ctrl(struct etherh_priv *eh, unsigned int mask)
{
eh->ctrl |= mask;
outb(eh->ctrl, eh->ctrl_port);
}
static inline void etherh_clr_ctrl(struct etherh_priv *eh, unsigned int mask)
{
eh->ctrl &= ~mask;
outb(eh->ctrl, eh->ctrl_port);
}
static inline unsigned int etherh_get_stat(struct etherh_priv *eh)
{
return inb(eh->ctrl_port);
}
static void etherh_irq_enable(ecard_t *ec, int irqnr)
{
struct etherh_priv *eh = ec->irq_data;
etherh_set_ctrl(eh, ETHERH_CP_IE);
}
static void etherh_irq_disable(ecard_t *ec, int irqnr)
{
struct etherh_priv *eh = ec->irq_data;
etherh_clr_ctrl(eh, ETHERH_CP_IE);
}
static expansioncard_ops_t etherh_ops = {
irqenable: etherh_irq_enable,
irqdisable: etherh_irq_disable,
};
static void
etherh_setif(struct net_device *dev)
{
struct ei_device *ei_local = (struct ei_device *) dev->priv;
struct etherh_priv *eh = (struct etherh_priv *)dev->rmem_start;
unsigned long addr, flags;
save_flags_cli(flags);
local_irq_save(flags);
/* set the interface type */
switch (dev->mem_end) {
switch (eh->id) {
case PROD_I3_ETHERLAN600:
case PROD_I3_ETHERLAN600A:
addr = dev->base_addr + EN0_RCNTHI;
......@@ -124,14 +173,13 @@ etherh_setif(struct net_device *dev)
break;
case PROD_I3_ETHERLAN500:
addr = dev->rmem_start;
switch (dev->if_port) {
case IF_PORT_10BASE2:
outb(inb(addr) & ~ETHERH_CP_IF, addr);
etherh_clr_ctrl(eh, ETHERH_CP_IF);
break;
case IF_PORT_10BASET:
outb(inb(addr) | ETHERH_CP_IF, addr);
etherh_set_ctrl(eh, ETHERH_CP_IF);
break;
}
break;
......@@ -140,16 +188,17 @@ etherh_setif(struct net_device *dev)
break;
}
restore_flags(flags);
local_irq_restore(flags);
}
static int
etherh_getifstat(struct net_device *dev)
{
struct ei_device *ei_local = (struct ei_device *) dev->priv;
struct etherh_priv *eh = (struct etherh_priv *)dev->rmem_start;
int stat = 0;
switch (dev->mem_end) {
switch (eh->id) {
case PROD_I3_ETHERLAN600:
case PROD_I3_ETHERLAN600A:
switch (dev->if_port) {
......@@ -168,7 +217,7 @@ etherh_getifstat(struct net_device *dev)
stat = 1;
break;
case IF_PORT_10BASET:
stat = inb(dev->rmem_start) & ETHERH_CP_HEARTBEAT;
stat = etherh_get_stat(eh) & ETHERH_CP_HEARTBEAT;
break;
}
break;
......@@ -251,7 +300,13 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf
return;
}
ei_local->dmaing |= 1;
/*
* Make sure we have a round number of bytes if we're in word mode.
*/
if (count & 1 && ei_local->word16)
count++;
ei_local->dmaing = 1;
addr = dev->base_addr;
dma_addr = dev->mem_start;
......@@ -291,7 +346,7 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf
}
outb (ENISR_RDC, addr + EN0_ISR);
ei_local->dmaing &= ~1;
ei_local->dmaing = 0;
}
/*
......@@ -311,7 +366,7 @@ etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int
return;
}
ei_local->dmaing |= 1;
ei_local->dmaing = 1;
addr = dev->base_addr;
dma_addr = dev->mem_start;
......@@ -332,7 +387,7 @@ etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int
insb (dma_addr, buf, count);
outb (ENISR_RDC, addr + EN0_ISR);
ei_local->dmaing &= ~1;
ei_local->dmaing = 0;
}
/*
......@@ -351,7 +406,7 @@ etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_p
return;
}
ei_local->dmaing |= 1;
ei_local->dmaing = 1;
addr = dev->base_addr;
dma_addr = dev->mem_start;
......@@ -369,7 +424,7 @@ etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_p
insb (dma_addr, hdr, sizeof (*hdr));
outb (ENISR_RDC, addr + EN0_ISR);
ei_local->dmaing &= ~1;
ei_local->dmaing = 0;
}
/*
......@@ -427,23 +482,6 @@ etherh_close(struct net_device *dev)
return 0;
}
static void etherh_irq_enable(ecard_t *ec, int irqnr)
{
unsigned int ctrl_addr = (unsigned int)ec->irq_data;
outb(inb(ctrl_addr) | ETHERH_CP_IE, ctrl_addr);
}
static void etherh_irq_disable(ecard_t *ec, int irqnr)
{
unsigned int ctrl_addr = (unsigned int)ec->irq_data;
outb(inb(ctrl_addr) & ~ETHERH_CP_IE, ctrl_addr);
}
static expansioncard_ops_t etherh_ops = {
irqenable: etherh_irq_enable,
irqdisable: etherh_irq_disable,
};
/*
* Initialisation
*/
......@@ -506,6 +544,7 @@ static struct net_device * __init etherh_init_one(struct expansion_card *ec)
{
struct ei_device *ei_local;
struct net_device *dev;
struct etherh_priv *eh;
const char *dev_type;
int i, size;
......@@ -517,6 +556,10 @@ static struct net_device * __init etherh_init_one(struct expansion_card *ec)
if (!dev)
goto out;
eh = kmalloc(sizeof(struct etherh_priv), GFP_KERNEL);
if (!eh)
goto out_nopriv;
SET_MODULE_OWNER(dev);
dev->open = etherh_open;
......@@ -524,8 +567,15 @@ static struct net_device * __init etherh_init_one(struct expansion_card *ec)
dev->set_config = etherh_set_config;
dev->irq = ec->irq;
dev->base_addr = ecard_address(ec, ECARD_MEMC, 0);
dev->mem_end = ec->cid.product;
dev->rmem_start = (unsigned long)eh;
/*
* IRQ and control port handling
*/
ec->ops = &etherh_ops;
ec->irq_data = eh;
eh->ctrl = 0;
eh->id = ec->cid.product;
switch (ec->cid.product) {
case PROD_ANT_ETHERM:
......@@ -533,7 +583,7 @@ static struct net_device * __init etherh_init_one(struct expansion_card *ec)
goto free;
dev->base_addr += ETHERM_NS8390;
dev->mem_start = dev->base_addr + ETHERM_DATAPORT;
ec->irq_data = (void *)(dev->base_addr + ETHERM_CTRLPORT);
eh->ctrl_port = dev->base_addr + ETHERM_CTRLPORT;
break;
case PROD_I3_ETHERLAN500:
......@@ -541,8 +591,7 @@ static struct net_device * __init etherh_init_one(struct expansion_card *ec)
goto free;
dev->base_addr += ETHERH500_NS8390;
dev->mem_start = dev->base_addr + ETHERH500_DATAPORT;
dev->rmem_start = (unsigned long)
ec->irq_data = (void *)ecard_address (ec, ECARD_IOC, ECARD_FAST)
eh->ctrl_port = ecard_address (ec, ECARD_IOC, ECARD_FAST)
+ ETHERH500_CTRLPORT;
break;
......@@ -551,8 +600,8 @@ static struct net_device * __init etherh_init_one(struct expansion_card *ec)
if (etherh_addr(dev->dev_addr, ec))
goto free;
dev->base_addr += ETHERH600_NS8390;
dev->mem_start = dev->base_addr + ETHERH600_DATAPORT;
ec->irq_data = (void *)(dev->base_addr + ETHERH600_CTRLPORT);
dev->mem_start = dev->base_addr + ETHERH600_DATAPORT;
eh->ctrl_port = dev->base_addr + ETHERH600_CTRLPORT;
break;
default:
......@@ -571,6 +620,12 @@ static struct net_device * __init etherh_init_one(struct expansion_card *ec)
if (ethdev_init(dev))
goto release;
/*
* If we're in the NIC slot, make sure the IRQ is enabled
*/
if (dev->irq == 11)
etherh_set_ctrl(eh, ETHERH_CP_IE);
/*
* Unfortunately, ethdev_init eventually calls
* ether_setup, which re-writes dev->flags.
......@@ -636,6 +691,8 @@ static struct net_device * __init etherh_init_one(struct expansion_card *ec)
release:
release_region(dev->base_addr, 16);
free:
kfree(eh);
out_nopriv:
unregister_netdev(dev);
kfree(dev);
out:
......@@ -696,6 +753,7 @@ static void __exit etherh_exit(void)
}
if (e_card[i]) {
e_card[i]->ops = NULL;
kfree(e_card[i]->irq_data);
ecard_release(e_card[i]);
e_card[i] = NULL;
}
......
......@@ -2583,10 +2583,10 @@ int acornscsi_queuecmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
done(SCpnt);
return 0;
}
save_flags_cli(flags);
local_irq_save(flags);
if (host->scsi.phase == PHASE_IDLE)
acornscsi_kick(host);
restore_flags(flags);
local_irq_restore(flags);
}
return 0;
}
......
......@@ -2137,7 +2137,7 @@ int fas216_command(Scsi_Cmnd *SCpnt)
* However, we must re-enable interrupts, or else we'll be
* waiting forever.
*/
spin_unlock_irq(&io_request_lock);
spin_unlock_irq(info->host->host_lock);
while (!info->internal_done) {
/*
......@@ -2149,13 +2149,13 @@ int fas216_command(Scsi_Cmnd *SCpnt)
* to be some time (eg, disconnected).
*/
if (inb(REG_STAT(info)) & STAT_INT) {
spin_lock_irq(&io_request_lock);
spin_lock_irq(info->host->host_lock);
fas216_intr(info->host);
spin_unlock_irq(&io_request_lock);
spin_unlock_irq(info->host->host_lock);
}
}
spin_lock_irq(&io_request_lock);
spin_lock_irq(info->host->host_lock);
return SCpnt->result;
}
......@@ -2459,13 +2459,13 @@ int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
/*
* Ugly ugly ugly!
* We need to release the io_request_lock and enable
* We need to release the host_lock and enable
* IRQs if we sleep, but we must relock and disable
* IRQs after the sleep.
*/
spin_unlock_irq(&io_request_lock);
spin_unlock_irq(info->host->host_lock);
scsi_sleep(25*HZ/100);
spin_lock_irq(&io_request_lock);
spin_lock_irq(info->host->host_lock);
/*
* Release the SCSI reset.
......@@ -2628,9 +2628,9 @@ int fas216_init(struct Scsi_Host *instance)
/*
* scsi standard says wait 250ms
*/
spin_unlock_irq(&io_request_lock);
spin_unlock_irq(info->host->host_lock);
scsi_sleep(25*HZ/100);
spin_lock_irq(&io_request_lock);
spin_lock_irq(info->host->host_lock);
outb(info->scsi.cfg[0], REG_CNTL1(info));
inb(REG_INST(info));
......
......@@ -82,6 +82,68 @@ static struct pcmcia_low_level *pcmcia_low_level;
static struct timer_list poll_timer;
static struct tq_struct sa1100_pcmcia_task;
/*
* sa1100_pcmcia_default_mecr_timing
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
*
* Calculate MECR clock wait states for given CPU clock
* speed and command wait state. This function can be over-
* written by a board specific version.
*
* The default is to simply calculate the BS values as specified in
* the INTEL SA1100 development manual
* "Expansion Memory (PCMCIA) Configuration Register (MECR)"
* that's section 10.2.5 in _my_ version of the manuial ;)
*/
static int sa1100_pcmcia_default_mecr_timing(unsigned int sock, unsigned int cpu_speed,
unsigned int cmd_time )
{
return sa1100_pcmcia_mecr_bs( cmd_time, cpu_speed );
}
/* sa1100_pcmcia_set_mecr()
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^
*
* set MECR value for socket <sock> based on this sockets
* io, mem and attribute space access speed.
* Call board specific BS value calculation to allow boards
* to tweak the BS values.
*/
static int sa1100_pcmcia_set_mecr( int sock )
{
struct sa1100_pcmcia_socket *skt;
u32 mecr;
int clock;
long flags;
unsigned int bs;
if ( sock<0 || sock>SA1100_PCMCIA_MAX_SOCK )
return -1;
skt = PCMCIA_SOCKET( sock );
local_irq_save(flags);
clock = cpufreq_get(0);
bs = pcmcia_low_level->socket_get_timing( sock, clock, skt->speed_io);
mecr = MECR;
MECR_FAST_SET(mecr, sock, 0);
MECR_BSIO_SET(mecr, sock, bs );
MECR_BSA_SET(mecr, sock, bs );
MECR_BSM_SET(mecr, sock, bs );
MECR = mecr;
local_irq_restore(flags);
DEBUG(4, "%s(): FAST%u %lx BSM%u %lx BSA%u %lx BSIO%u %lx\n",
__FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock),
sock, MECR_BSIO_GET(mecr, sock));
return 0;
}
/*
* sa1100_pcmcia_state_to_config
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -586,26 +648,10 @@ sa1100_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
}
if (map->flags & MAP_ACTIVE) {
unsigned int clock, speed = map->speed;
unsigned long mecr;
if ( map->speed == 0)
map->speed = SA1100_PCMCIA_IO_ACCESS;
if (speed == 0)
speed = SA1100_PCMCIA_IO_ACCESS;
clock = cpufreq_get(0);
mecr = MECR;
MECR_BSIO_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
skt->speed_io = speed;
DEBUG(4, "%s(): FAST%u %lx BSM%u %lx BSA%u %lx BSIO%u %lx\n",
__FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock),
sock, MECR_BSIO_GET(mecr, sock));
MECR = mecr;
sa1100_pcmcia_set_mecr( sock );
}
if (map->stop == 1)
......@@ -683,39 +729,19 @@ sa1100_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
}
if (map->flags & MAP_ACTIVE) {
unsigned int clock, speed = map->speed;
unsigned long mecr;
/*
* When clients issue RequestMap, the access speed is not always
* properly configured. Choose some sensible defaults.
*/
if (speed == 0) {
if (skt->cs_state.Vcc == 33)
speed = SA1100_PCMCIA_3V_MEM_ACCESS;
else
speed = SA1100_PCMCIA_5V_MEM_ACCESS;
}
clock = cpufreq_get(0);
/* Fixme: MECR is not pre-empt safe. */
mecr = MECR;
if (map->flags & MAP_ATTRIB) {
MECR_BSA_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
skt->speed_attr = speed;
} else {
MECR_BSM_SET(mecr, sock, sa1100_pcmcia_mecr_bs(speed, clock));
skt->speed_mem = speed;
}
/*
* When clients issue RequestMap, the access speed is not always
* properly configured. Choose some sensible defaults.
*/
if (map->speed == 0) {
if (skt->cs_state.Vcc == 33)
map->speed = SA1100_PCMCIA_3V_MEM_ACCESS;
else
map->speed = SA1100_PCMCIA_5V_MEM_ACCESS;
}
sa1100_pcmcia_set_mecr( sock );
DEBUG(4, "%s(): FAST%u %lx BSM%u %lx BSA%u %lx BSIO%u %lx\n",
__FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock),
sock, MECR_BSIO_GET(mecr, sock));
MECR = mecr;
}
start = (map->flags & MAP_ATTRIB) ? skt->phys_attr : skt->phys_mem;
......@@ -857,20 +883,10 @@ static struct pccard_operations sa1100_pcmcia_operations = {
static void sa1100_pcmcia_update_mecr(unsigned int clock)
{
unsigned int sock;
unsigned long mecr = MECR;
for(sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock){
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
MECR_BSIO_SET(mecr, sock,
sa1100_pcmcia_mecr_bs(skt->speed_io, clock));
MECR_BSA_SET(mecr, sock,
sa1100_pcmcia_mecr_bs(skt->speed_attr, clock));
MECR_BSM_SET(mecr, sock,
sa1100_pcmcia_mecr_bs(skt->speed_mem, clock));
for (sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock) {
sa1100_pcmcia_set_mecr( sock );
}
MECR = mecr;
}
/* sa1100_pcmcia_notifier()
......@@ -929,8 +945,7 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
struct pcmcia_init pcmcia_init;
struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
struct pcmcia_state_array state_array;
unsigned int i, clock;
unsigned long mecr;
unsigned int i;
int ret;
/*
......@@ -941,6 +956,13 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
pcmcia_low_level = ops;
/*
* set default MECR calculation if the board specific
* code did not specify one...
*/
if (!pcmcia_low_level->socket_get_timing)
pcmcia_low_level->socket_get_timing = sa1100_pcmcia_default_mecr_timing;
pcmcia_init.handler = sa1100_pcmcia_interrupt;
ret = ops->init(&pcmcia_init);
if (ret < 0) {
......@@ -967,10 +989,6 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
* We initialize the MECR to default values here, because we are
* not guaranteed to see a SetIOMap operation at runtime.
*/
mecr = 0;
clock = cpufreq_get(0);
for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
struct pcmcia_irq_info irq_info;
......@@ -1000,13 +1018,9 @@ int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
goto out_err;
}
MECR_FAST_SET(mecr, i, 0);
MECR_BSIO_SET(mecr, i, sa1100_pcmcia_mecr_bs(skt->speed_io, clock));
MECR_BSA_SET(mecr, i, sa1100_pcmcia_mecr_bs(skt->speed_attr, clock));
MECR_BSM_SET(mecr, i, sa1100_pcmcia_mecr_bs(skt->speed_mem, clock));
sa1100_pcmcia_set_mecr( i );
}
MECR = mecr;
/* Only advertise as many sockets as we can detect */
ret = register_ss_entry(sa1100_pcmcia_socket_count,
......
......@@ -69,6 +69,12 @@ struct pcmcia_low_level {
* Disable card status IRQs and PCMCIA bus on suspend.
*/
int (*socket_suspend)(int sock);
/*
* Calculate MECR timing clock wait states
*/
int (*socket_get_timing)(unsigned int sock, unsigned int cpu_speed,
unsigned int cmd_time );
};
extern int sa1100_register_pcmcia(struct pcmcia_low_level *);
......
......@@ -17,29 +17,34 @@
* will stop our MCLK signal (which provides the clock for the glue
* logic, and therefore the timer interrupt).
*
* Instead, we spin, waiting for either hlt_counter or need_resched()
* to be set. If we have been spinning for 2cs, then we drop the
* core clock down to the memory clock.
* Instead, we spin, polling the IRQ_STAT register for the occurrence
* of any interrupt with core clock down to the memory clock.
*/
static void arch_idle(void)
{
unsigned long start_idle;
const char *irq_stat = (char *)0xff000000;
long flags;
start_idle = jiffies;
if (!hlt_counter)
return;
do {
if (need_resched() || hlt_counter)
goto slow_out;
} while (time_before(jiffies, start_idle + HZ/50));
cpu_do_idle(IDLE_CLOCK_SLOW);
while (!need_resched() && !hlt_counter) {
/* do nothing slowly */
}
cpu_do_idle(IDLE_CLOCK_FAST);
slow_out:
/* disable interrupts */
cli();
/* check need_resched here to avoid races */
if (need_resched()) {
sti();
return;
}
/* disable clock switching */
asm volatile ("mcr%? p15, 0, ip, c15, c2, 2");
/* wait for an interrupt to occur */
while (!*irq_stat);
/* enable clock switching */
asm volatile ("mcr%? p15, 0, ip, c15, c1, 2");
/* allow the interrupt to happen */
sti();
} while (!need_resched());
}
#define arch_reset(mode) cpu_reset(0x80000000)
......
......@@ -107,18 +107,12 @@ extern struct processor {
*/
void (*set_pte)(pte_t *ptep, pte_t pte);
} pgtable;
struct { /* other */
void (*clear_user_page)(void *page, unsigned long u_addr);
void (*copy_user_page)(void *to, void *from, unsigned long u_addr);
} misc;
} processor;
extern const struct processor arm6_processor_functions;
extern const struct processor arm7_processor_functions;
extern const struct processor sa110_processor_functions;
#define cpu_data_abort(pc) processor._data_abort(pc)
#define cpu_check_bugs() processor._check_bugs()
#define cpu_proc_init() processor._proc_init()
#define cpu_proc_fin() processor._proc_fin()
......@@ -141,9 +135,6 @@ extern const struct processor sa110_processor_functions;
#define cpu_set_pmd(pmdp, pmd) processor.pgtable.set_pmd(pmdp, pmd)
#define cpu_set_pte(ptep, pte) processor.pgtable.set_pte(ptep, pte)
#define cpu_copy_user_page(to,from,uaddr) processor.misc.copy_user_page(to,from,uaddr)
#define cpu_clear_user_page(page,uaddr) processor.misc.clear_user_page(page,uaddr)
#define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))
#define cpu_get_pgd() \
......
......@@ -22,7 +22,6 @@
* function pointers for this lot. Otherwise, we can optimise the
* table away.
*/
#define cpu_data_abort __cpu_fn(CPU_ABRT,_abort)
#define cpu_check_bugs __cpu_fn(CPU_NAME,_check_bugs)
#define cpu_proc_init __cpu_fn(CPU_NAME,_proc_init)
#define cpu_proc_fin __cpu_fn(CPU_NAME,_proc_fin)
......@@ -40,8 +39,6 @@
#define cpu_set_pgd __cpu_fn(CPU_NAME,_set_pgd)
#define cpu_set_pmd __cpu_fn(CPU_NAME,_set_pmd)
#define cpu_set_pte __cpu_fn(CPU_NAME,_set_pte)
#define cpu_copy_user_page __cpu_fn(MMU_ARCH,_copy_user_page)
#define cpu_clear_user_page __cpu_fn(MMU_ARCH,_clear_user_page)
#ifndef __ASSEMBLY__
......@@ -74,9 +71,6 @@ extern void cpu_set_pgd(unsigned long pgd_phys);
extern void cpu_set_pmd(pmd_t *pmdp, pmd_t pmd);
extern void cpu_set_pte(pte_t *ptep, pte_t pte);
extern void cpu_copy_user_page(void *to, void *from, unsigned long u_addr);
extern void cpu_clear_user_page(void *page, unsigned long u_addr);
extern volatile void cpu_reset(unsigned long addr);
#define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))
......
......@@ -24,14 +24,21 @@
#endif
#define __glue(name,fn) ____glue(name,fn)
/*
* Select MMU TLB handling.
*/
/*
* ARMv3 MMU
* 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
......@@ -40,9 +47,6 @@
# endif
#endif
/*
* ARMv4 MMU without write buffer
*/
#if defined(CONFIG_CPU_ARM720T)
# ifdef _TLB
# define MULTI_TLB 1
......@@ -51,9 +55,6 @@
# endif
#endif
/*
* ARMv4 MMU with write buffer, with invalidate I TLB entry instruction
*/
#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
defined(CONFIG_CPU_ARM926T) || defined(CONFIG_CPU_ARM1020) || \
defined(CONFIG_CPU_XSCALE)
......@@ -64,9 +65,6 @@
# endif
#endif
/*
* ARMv4 MMU with write buffer, without invalidate I TLB entry instruction
*/
#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
# ifdef _TLB
# define MULTI_TLB 1
......@@ -75,4 +73,134 @@
# endif
#endif
#ifndef _TLB
#error Unknown TLB model
#endif
/*
* Data Abort Model
* ================
*
* We have the following to choose from:
* arm6 - ARM6 style
* arm7 - ARM7 style
* v4_early - ARMv4 without Thumb early abort handler
* v4t_late - ARMv4 with Thumb late abort handler
* v4t_early - ARMv4 with Thumb early abort handler
* v5ej_early - ARMv5 with Thumb and Java early abort handler
*/
#undef CPU_ABORT_HANDLER
#undef MULTI_ABORT
#if defined(CONFIG_CPU_ARM610)
# ifdef CPU_ABORT_HANDLER
# define MULTI_ABORT 1
# else
# define CPU_ABORT_HANDLER cpu_arm6_data_abort
# endif
#endif
#if defined(CONFIG_CPU_ARM710)
# ifdef CPU_ABORT_HANDLER
# define MULTI_ABORT 1
# else
# define CPU_ABORT_HANDLER cpu_arm7_data_abort
# endif
#endif
#if defined(CONFIG_CPU_ARM720T)
# ifdef CPU_ABORT_HANDLER
# define MULTI_ABORT 1
# else
# define CPU_ABORT_HANDLER v4t_late_abort
# endif
#endif
#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100)
# ifdef CPU_ABORT_HANDLER
# define MULTI_ABORT 1
# else
# define CPU_ABORT_HANDLER v4_early_abort
# endif
#endif
#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
defined(CONFIG_CPU_ARM1020) || defined(CONFIG_CPU_XSCALE)
# ifdef CPU_ABORT_HANDLER
# define MULTI_ABORT 1
# else
# define CPU_ABORT_HANDLER v4t_early_abort
# endif
#endif
#if defined(CONFIG_CPU_ARM926T)
# ifdef CPU_ABORT_HANDLER
# define MULTI_ABORT 1
# else
# define CPU_ABORT_HANDLER v5ej_early_abort
# endif
#endif
#ifndef CPU_ABORT_HANDLER
#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
* v4 - ARMv4 without minicache
* v4_mc - ARMv4 with minicache
* v5te_mc - ARMv5TE with minicache
*/
#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) || 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 v4
# 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 v5te_mc
# endif
#endif
#ifndef _USER
#error Unknown user operations model
#endif
#endif
......@@ -19,12 +19,6 @@ struct hw_pci {
/* Setup bus resources */
void (*setup_resources)(struct resource **);
/*
* This is the offset of PCI memory base registers
* to physical memory.
*/
unsigned long mem_offset;
/* IRQ swizzle */
u8 (*swizzle)(struct pci_dev *dev, u8 *pin);
......
#ifndef _ASMARM_PAGE_H
#define _ASMARM_PAGE_H
#include <asm/proc/page.h>
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#include <linux/config.h>
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#define STRICT_MM_TYPECHECKS
#include <asm/glue.h>
#define clear_page(page) memzero((void *)(page), PAGE_SIZE)
extern void copy_page(void *to, void *from);
struct cpu_user_fns {
void (*cpu_clear_user_page)(void *p, unsigned long user);
void (*cpu_copy_user_page)(void *to, const void *from,
unsigned long user);
};
#ifdef MULTI_USER
extern struct cpu_user_fns cpu_user;
#define __cpu_clear_user_page cpu_user.cpu_clear_user_page
#define __cpu_copy_user_page cpu_user.cpu_copy_user_page
#else
#define __cpu_clear_user_page __glue(_USER,_clear_user_page)
#define __cpu_copy_user_page __glue(_USER,_copy_user_page)
extern void __cpu_clear_user_page(void *p, unsigned long user);
extern void __cpu_copy_user_page(void *to, const void *from,
unsigned long user);
#endif
#define clear_user_page(addr,vaddr) \
do { \
preempt_disable(); \
cpu_clear_user_page(addr, vaddr); \
__cpu_clear_user_page(addr, vaddr); \
preempt_enable(); \
} while (0)
#define copy_user_page(to,from,vaddr) \
do { \
preempt_disable(); \
cpu_copy_user_page(to, from, vaddr); \
__cpu_copy_user_page(to, from, vaddr); \
preempt_enable(); \
} while (0)
#define clear_page(page) memzero((void *)(page), PAGE_SIZE)
extern void copy_page(void *to, void *from);
#undef STRICT_MM_TYPECHECKS
#ifdef STRICT_MM_TYPECHECKS
/*
* These are used to make use of C type-checking..
*/
typedef struct { unsigned long pte; } pte_t;
typedef struct { unsigned long pmd; } pmd_t;
typedef struct { unsigned long pgd; } pgd_t;
typedef struct { unsigned long pgprot; } pgprot_t;
#define pte_val(x) ((x).pte)
#define pmd_val(x) ((x).pmd)
#define pgd_val(x) ((x).pgd)
#define pgprot_val(x) ((x).pgprot)
#define __pte(x) ((pte_t) { (x) } )
#define __pmd(x) ((pmd_t) { (x) } )
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
#else
......@@ -53,25 +71,29 @@ typedef struct { unsigned long pgprot; } pgprot_t;
*/
typedef unsigned long pte_t;
typedef unsigned long pmd_t;
typedef unsigned long pgd_t;
typedef unsigned long pgprot_t;
#define pte_val(x) (x)
#define pmd_val(x) (x)
#define pgd_val(x) (x)
#define pgprot_val(x) (x)
#define __pte(x) (x)
#define __pmd(x) (x)
#define __pgd(x) (x)
#define __pgprot(x) (x)
#endif
#endif /* STRICT_MM_TYPECHECKS */
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
#include <asm/proc/page.h>
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#ifdef CONFIG_DEBUG_BUGVERBOSE
......@@ -105,7 +127,6 @@ static inline int get_order(unsigned long size)
#endif /* !__ASSEMBLY__ */
#include <linux/config.h>
#include <asm/arch/memory.h>
#define __pa(x) __virt_to_phys((unsigned long)(x))
......@@ -120,6 +141,6 @@ static inline int get_order(unsigned long size)
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
#endif
#endif /* __KERNEL__ */
#endif
/*
* linux/include/asm-arm/pgtable.h
*
* Copyright (C) 2000-2001 Russell King
* Copyright (C) 2000-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
......@@ -19,7 +19,11 @@
* PGDIR_SHIFT determines what a third-level page table entry can map
*/
#define PMD_SHIFT 20
#ifdef CONFIG_CPU_32
#define PGDIR_SHIFT 21
#else
#define PGDIR_SHIFT 20
#endif
#define LIBRARY_TEXT_START 0x0c000000
......@@ -93,7 +97,6 @@ extern struct page *empty_zero_page;
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_present(pmd) (pmd_val(pmd))
#define pmd_clear(pmdp) set_pmd(pmdp, __pmd(0))
/*
* Permanent address of a page. We never have highmem, so this is trivial.
......@@ -106,18 +109,10 @@ extern struct page *empty_zero_page;
*/
static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
{
pte_t pte;
pte_val(pte) = physpage | pgprot_val(pgprot);
return pte;
return __pte(physpage | pgprot_val(pgprot));
}
#define mk_pte(page,pgprot) \
({ \
pte_t __pte; \
pte_val(__pte) = __pa(page_address(page)) + \
pgprot_val(pgprot); \
__pte; \
})
#define mk_pte(page,pgprot) mk_pte_phys(__pa(page_address(page)), pgprot)
/*
* The "pgd_xxx()" functions here are trivial for a folded two-level
......@@ -127,7 +122,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
#define pgd_none(pgd) (0)
#define pgd_bad(pgd) (0)
#define pgd_present(pgd) (1)
#define pgd_clear(pgdp)
#define pgd_clear(pgdp) do { } while (0)
#define page_pte_prot(page,prot) mk_pte(page, prot)
#define page_pte(page) mk_pte(page, __pgprot(0))
......@@ -147,15 +142,6 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
/* Find an entry in the third-level page table.. */
#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
#define pmd_page(dir) ((struct page *)__pmd_page(dir))
#define __pte_offset(dir, addr) ((pte_t *)__pmd_page(*(dir)) + __pte_index(addr))
#define pte_offset_kernel __pte_offset
#define pte_offset_map __pte_offset
#define pte_offset_map_nested __pte_offset
#define pte_unmap(pte) do { } while (0)
#define pte_unmap_nested(pte) do { } while (0)
#include <asm/proc/pgtable.h>
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
......@@ -182,8 +168,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
#include <asm-generic/pgtable.h>
extern void pgtable_cache_init(void);
/*
* remap a physical address `phys' of size `size' with page protection `prot'
* into virtual address `from'
......
/*
* linux/include/asm-arm/proc-armo/page.h
*
* Copyright (C) 1995, 1996 Russell King
* Copyright (C) 1995-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
......@@ -21,4 +21,20 @@
#define EXEC_PAGESIZE 32768
#ifndef __ASSEMBLY__
#ifdef STRICT_MM_TYPECHECKS
typedef struct { unsigned long pgd; } pgd_t;
#define pgd_val(x) ((x).pgd)
#else
typedef unsigned long pgd_t;
#define pgd_val(x) (x)
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ASM_PROC_PAGE_H */
/*
* linux/include/asm-arm/proc-armo/pgalloc.h
*
* Copyright (C) 2001 Russell King
* Copyright (C) 2001-2002 Russell King
*
* Page table allocation/freeing primitives for 26-bit ARM processors.
*/
/* unfortunately, this includes linux/mm.h and the rest of the universe. */
#include <linux/slab.h>
extern kmem_cache_t *pte_cache;
/*
* Allocate one PTE table.
*
* Note that we keep the processor copy of the PTE entries separate
* from the Linux copy. The processor copies are offset by -PTRS_PER_PTE
* words from the Linux copy.
*/
static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
static inline pte_t *
pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
{
return kmem_cache_alloc(pte_cache, GFP_KERNEL);
}
/*
* Free one PTE table.
*/
static inline void pte_free_slow(pte_t *pte)
static inline void pte_free_kernel(pte_t *pte)
{
if (pte)
kmem_cache_free(pte_cache, pte);
......@@ -39,9 +29,16 @@ static inline void pte_free_slow(pte_t *pte)
* If 'mm' is the init tasks mm, then we are doing a vmalloc, and we
* need to set stuff up correctly for it.
*/
#define pmd_populate(mm,pmdp,pte) \
do { \
set_pmd(pmdp, __mk_pmd(pte, _PAGE_TABLE)); \
} while (0)
static inline void
pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
{
set_pmd(pmdp, __mk_pmd(ptep, _PAGE_TABLE));
}
/*
* We use the old 2.5.5-rmk1 hack for this.
* This is not truely correct, but should be functional.
*/
#define pte_alloc_one(mm,addr) ((struct page *)pte_alloc_one_kernel(mm,addr))
#define pte_free(pte) pte_free_kernel((pte_t *)pte)
#define pmd_populate(mm,pmdp,ptep) pmd_populate_kernel(mm,pmdp,(pte_t *)ptep)
/*
* linux/include/asm-arm/proc-armo/pgtable.h
*
* Copyright (C) 1995-2001 Russell King
* Copyright (C) 1995-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
......@@ -32,6 +32,7 @@
#define pmd_bad(pmd) ((pmd_val(pmd) & 0xfc000002))
#define set_pmd(pmdp,pmd) ((*(pmdp)) = (pmd))
#define pmd_clear(pmdp) set_pmd(pmdp, __pmd(0))
static inline pmd_t __mk_pmd(pte_t *ptep, unsigned long prot)
{
......@@ -48,6 +49,12 @@ static inline unsigned long pmd_page(pmd_t pmd)
return __phys_to_virt(pmd_val(pmd) & ~_PAGE_TABLE);
}
#define pte_offset_kernel(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
#define pte_offset_map(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
#define pte_offset_map_nested(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
#define pte_unmap(pte) do { } while (0)
#define pte_unmap_nested(pte) do { } while (0)
#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
#define _PAGE_PRESENT 0x01
......@@ -89,11 +96,11 @@ static inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) &= ~_PAGE_NOT_USE
static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) &= ~_PAGE_CLEAN; return pte; }
static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) &= ~_PAGE_OLD; return pte; }
#define pte_alloc_kernel pte_alloc
/*
* We don't store cache state bits in the page table here.
*/
#define pgprot_noncached(prot) (prot)
extern void pgtable_cache_init(void);
#endif /* __ASM_PROC_PGTABLE_H */
/*
* linux/include/asm-arm/proc-armv/cache.h
*
* Copyright (C) 1999-2001 Russell King
* Copyright (C) 1999-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
......@@ -134,7 +134,8 @@ static __inline__ void flush_page_to_ram(struct page *page)
#define clean_dcache_range(_s,_e) cpu_dcache_clean_range((_s),(_e))
#define flush_dcache_range(_s,_e) cpu_cache_clean_invalidate_range((_s),(_e),0)
#define mapping_mapped(map) ((map)->i_mmap || (map)->i_mmap_shared)
#define mapping_mapped(map) (!list_empty(&(map)->i_mmap) || \
!list_empty(&(map)->i_mmap_shared))
/*
* flush_dcache_page is used when the kernel has written to the page
......@@ -204,7 +205,7 @@ static inline void flush_icache_page(struct vm_area_struct *vma, struct page *pa
* TLB Management
* ==============
*
* The arch/arm/mm/tlb-*.S files implement this methods.
* The arch/arm/mm/tlb-*.S files implement these methods.
*
* The TLB specific code is expected to perform whatever tests it
* needs to determine if it should invalidate the TLB for each
......
/*
* linux/include/asm-arm/proc-armv/page.h
*
* Copyright (C) 1995, 1996 Russell King
* Copyright (C) 1995-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
......@@ -15,4 +15,23 @@
#define EXEC_PAGESIZE 4096
#ifndef __ASSEMBLY__
#ifdef STRICT_MM_TYPECHECKS
typedef struct {
unsigned long pgd0;
unsigned long pgd1;
} pgd_t;
#define pgd_val(x) ((x).pgd0)
#else
typedef unsigned long pgd_t[2];
#define pgd_val(x) ((x)[0])
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ASM_PROC_PAGE_H */
/*
* linux/include/asm-arm/proc-armv/pgalloc.h
*
* Copyright (C) 2001 Russell King
* Copyright (C) 2001-2002 Russell King
*
* Page table allocation/freeing primitives for 32-bit ARM processors.
*/
/* unfortunately, this includes linux/mm.h and the rest of the universe. */
#include <linux/slab.h>
extern kmem_cache_t *pte_cache;
#include "pgtable.h"
/*
* Allocate one PTE table.
*
* Note that we keep the processor copy of the PTE entries separate
* from the Linux copy. The processor copies are offset by -PTRS_PER_PTE
* words from the Linux copy.
* This actually allocates two hardware PTE tables, but we wrap this up
* into one table thus:
*
* +------------+
* | h/w pt 0 |
* +------------+
* | h/w pt 1 |
* +------------+
* | Linux pt 0 |
* +------------+
* | Linux pt 1 |
* +------------+
*/
static inline pte_t *
pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
{
int count = 0;
pte_t *pte;
pte = kmem_cache_alloc(pte_cache, GFP_KERNEL);
if (pte)
do {
pte = (pte_t *)__get_free_page(GFP_KERNEL);
if (!pte) {
current->state = TASK_UNINTERRUPTIBLE;
schedule_timeout(HZ);
}
} while (!pte && (count++ < 10));
if (pte) {
clear_page(pte);
clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE);
pte += PTRS_PER_PTE;
}
return pte;
}
static inline struct page *
pte_alloc_one(struct mm_struct *mm, unsigned long addr)
{
pte_t *pte;
struct page *pte;
int count = 0;
pte = kmem_cache_alloc(pte_cache, GFP_KERNEL);
if (pte)
pte += PTRS_PER_PTE;
return (struct page *)pte;
do {
pte = alloc_pages(GFP_KERNEL, 0);
if (!pte) {
current->state = TASK_UNINTERRUPTIBLE;
schedule_timeout(HZ);
}
} while (!pte && (count++ < 10));
if (pte) {
void *page = page_address(pte);
clear_page(page);
clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
}
return pte;
}
/*
......@@ -47,34 +76,49 @@ static inline void pte_free_kernel(pte_t *pte)
{
if (pte) {
pte -= PTRS_PER_PTE;
kmem_cache_free(pte_cache, pte);
free_page((unsigned long)pte);
}
}
static inline void pte_free(struct page *pte)
{
pte_t *_pte = (pte_t *)pte;
if (pte) {
_pte -= PTRS_PER_PTE;
kmem_cache_free(pte_cache, _pte);
}
__free_page(pte);
}
/*
* Populate the pmdp entry with a pointer to the pte. This pmd is part
* of the mm address space.
*
* If 'mm' is the init tasks mm, then we are doing a vmalloc, and we
* need to set stuff up correctly for it.
* Ensure that we always set both PMD entries.
*/
#define pmd_populate_kernel(mm,pmdp,pte) \
do { \
BUG_ON(mm != &init_mm); \
set_pmd(pmdp, __mk_pmd(pte, _PAGE_KERNEL_TABLE));\
} while (0)
#define pmd_populate(mm,pmdp,pte) \
do { \
BUG_ON(mm == &init_mm); \
set_pmd(pmdp, __mk_pmd(pte, _PAGE_USER_TABLE)); \
} while (0)
static inline void
pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
{
unsigned long pte_ptr = (unsigned long)ptep;
pmd_t pmd;
BUG_ON(mm != &init_mm);
/*
* The pmd must be loaded with the physical
* address of the PTE table
*/
pte_ptr -= PTRS_PER_PTE * sizeof(void *);
pmd_val(pmd) = __pa(pte_ptr) | _PAGE_KERNEL_TABLE;
set_pmd(pmdp, pmd);
pmd_val(pmd) += 256 * sizeof(pte_t);
set_pmd(pmdp + 1, pmd);
}
static inline void
pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep)
{
pmd_t pmd;
BUG_ON(mm == &init_mm);
pmd_val(pmd) = __pa(page_address(ptep)) | _PAGE_USER_TABLE;
set_pmd(pmdp, pmd);
pmd_val(pmd) += 256 * sizeof(pte_t);
set_pmd(pmdp + 1, pmd);
}
/*
* linux/include/asm-arm/proc-armv/pgtable.h
*
* Copyright (C) 1995-2001 Russell King
* Copyright (C) 1995-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
......@@ -16,12 +16,17 @@
#define __ASM_PROC_PGTABLE_H
/*
* entries per page directory level: they are two-level, so
* we don't really have any PMD directory.
* We pull a couple of tricks here:
* 1. We wrap the PMD into the PGD.
* 2. We lie about the size of the PTE and PGD.
* Even though we have 256 PTE entries and 4096 PGD entries, we tell
* Linux that we actually have 512 PTE entries and 2048 PGD entries.
* Each "Linux" PGD entry is made up of two hardware PGD entries, and
* each PTE table is actually two hardware PTE tables.
*/
#define PTRS_PER_PTE 256
#define PTRS_PER_PTE 512
#define PTRS_PER_PMD 1
#define PTRS_PER_PGD 4096
#define PTRS_PER_PGD 2048
/*
* Hardware page table definitions.
......@@ -109,33 +114,30 @@
#define pmd_bad(pmd) (pmd_val(pmd) & 2)
#define set_pmd(pmdp,pmd) cpu_set_pmd(pmdp, pmd)
static inline pmd_t __mk_pmd(pte_t *ptep, unsigned long prot)
static inline void pmd_clear(pmd_t *pmdp)
{
unsigned long pte_ptr = (unsigned long)ptep;
pmd_t pmd;
pte_ptr -= PTRS_PER_PTE * sizeof(void *);
/*
* The pmd must be loaded with the physical
* address of the PTE table
*/
pmd_val(pmd) = __virt_to_phys(pte_ptr) | prot;
return pmd;
set_pmd(pmdp, __pmd(0));
set_pmd(pmdp + 1, __pmd(0));
}
static inline unsigned long __pmd_page(pmd_t pmd)
static inline pte_t *pmd_page_kernel(pmd_t pmd)
{
unsigned long ptr;
ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
ptr += PTRS_PER_PTE * sizeof(void *);
return __phys_to_virt(ptr);
return __va(ptr);
}
#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd)))
#define pte_offset_kernel(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
#define pte_offset_map(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
#define pte_offset_map_nested(dir,addr) (pmd_page_kernel(*(dir)) + __pte_index(addr))
#define pte_unmap(pte) do { } while (0)
#define pte_unmap_nested(pte) do { } while (0)
#define set_pte(ptep, pte) cpu_set_pte(ptep,pte)
/*
......@@ -183,6 +185,8 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
*/
#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE))
#define pgtable_cache_init() do { } while (0)
#endif /* __ASSEMBLY__ */
#endif /* __ASM_PROC_PGTABLE_H */
......@@ -28,8 +28,6 @@
/*
* CPU_NAME - the prefix for CPU related functions
* CPU_ABRT - the prefix for the CPU abort decoding function
* MMU_ARCH - the prefix for copy_user_page/clear_user_page
*/
#ifdef CONFIG_CPU_32
......@@ -40,8 +38,6 @@
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm6
# define CPU_ABRT cpu_arm6
# define MMU_ARCH armv3
# endif
# endif
# ifdef CONFIG_CPU_ARM710
......@@ -50,8 +46,6 @@
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm7
# define CPU_ABRT cpu_arm7
# define MMU_ARCH armv3
# endif
# endif
# ifdef CONFIG_CPU_ARM720T
......@@ -60,8 +54,6 @@
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm720
# define CPU_ABRT armv4t_late
# define MMU_ARCH armv4
# endif
# endif
# ifdef CONFIG_CPU_ARM920T
......@@ -70,8 +62,6 @@
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm920
# define CPU_ABRT armv4t_early
# define MMU_ARCH armv4
# endif
# endif
# ifdef CONFIG_CPU_ARM922T
......@@ -80,8 +70,6 @@
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm922
# define CPU_ABRT armv4t_early
# define MMU_ARCH armv4
# endif
# endif
# ifdef CONFIG_CPU_ARM926T
......@@ -90,8 +78,6 @@
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm926
# define CPU_ABRT armv5ej_early
# define MMU_ARCH armv4
# endif
# endif
# ifdef CONFIG_CPU_SA110
......@@ -100,8 +86,6 @@
# define MULTI_CPU
# else
# define CPU_NAME cpu_sa110
# define CPU_ABRT armv4_early
# define MMU_ARCH armv4
# endif
# endif
# ifdef CONFIG_CPU_SA1100
......@@ -110,8 +94,6 @@
# define MULTI_CPU
# else
# define CPU_NAME cpu_sa1100
# define CPU_ABRT armv4_early
# define MMU_ARCH armv4_mc
# endif
# endif
# ifdef CONFIG_CPU_ARM1020
......@@ -120,8 +102,6 @@
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm1020
# define CPU_ABRT armv4t_early
# define MMU_ARCH armv4
# endif
# endif
# ifdef CONFIG_CPU_XSCALE
......@@ -130,8 +110,6 @@
# define MULTI_CPU
# else
# define CPU_NAME cpu_xscale
# define CPU_ABRT armv4t_early
# define MMU_ARCH armv5te
# endif
# endif
#endif
......
......@@ -15,6 +15,7 @@
#include <asm/proc-fns.h>
struct cpu_tlb_fns;
struct cpu_user_fns;
struct processor;
struct proc_info_item {
......@@ -32,21 +33,22 @@ struct proc_info_item {
* arch/arm/mm/proc-*.S and arch/arm/kernel/head-armv.S
*/
struct proc_info_list {
unsigned int cpu_val;
unsigned int cpu_mask;
unsigned long __cpu_mmu_flags; /* used by head-armv.S */
unsigned long __cpu_flush; /* used by head-armv.S */
const char *arch_name;
const char *elf_name;
unsigned int elf_hwcap;
struct proc_info_item *info;
struct processor *proc;
struct cpu_tlb_fns *tlb;
unsigned int cpu_val;
unsigned int cpu_mask;
unsigned long __cpu_mmu_flags; /* used by head-armv.S */
unsigned long __cpu_flush; /* used by head-armv.S */
const char *arch_name;
const char *elf_name;
unsigned int elf_hwcap;
struct proc_info_item *info;
struct processor *proc;
struct cpu_tlb_fns *tlb;
struct cpu_user_fns *user;
};
#endif /* __ASSEMBLY__ */
#define PROC_INFO_SZ 40
#define PROC_INFO_SZ 44
#define HWCAP_SWP 1
#define HWCAP_HALF 2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment