Commit a5358dec authored by Russell King's avatar Russell King

Merge flint.arm.linux.org.uk:/usr/src/linux-bk-2.5/linux-2.5

into flint.arm.linux.org.uk:/usr/src/linux-bk-2.5/linux-2.5-rmk
parents 22e962f9 ac75d023
...@@ -206,26 +206,15 @@ LC0: .word __bss_start ...@@ -206,26 +206,15 @@ LC0: .word __bss_start
* r7 = architecture number * r7 = architecture number
* r8 = run-time address of "start" * r8 = run-time address of "start"
* On exit, * On exit,
* r0, r1, r2, r3, r8, r9 corrupted * r1, r2, r3, r8, r9, r12 corrupted
* This routine must preserve: * This routine must preserve:
* r4, r5, r6, r7 * r4, r5, r6, r7
*/ */
.align 5 .align 5
cache_on: ldr r1, proc_sa110_type cache_on: mov r3, #8 @ cache_on function
eor r1, r1, r6 b call_cache_fn
movs r1, r1, lsr #5 @ catch SA110 and SA1100
beq 1f __cache_on: sub r3, r4, #16384 @ Page directory size
ldr r1, proc_sa1110_type
eor r1, r1, r6
movs r1, r1, lsr #4
beq 1f
ldr r1, proc_xscale_type
eor r1, r1, r6
movs r1, r1, lsr #16
@ movne pc, lr
bne cache_off
1:
sub r3, r4, #16384 @ Page directory size
bic r3, r3, #0xff @ Align the pointer bic r3, r3, #0xff @ Align the pointer
bic r3, r3, #0x3f00 bic r3, r3, #0x3f00
/* /*
...@@ -277,8 +266,9 @@ cache_on: ldr r1, proc_sa110_type ...@@ -277,8 +266,9 @@ cache_on: ldr r1, proc_sa110_type
mov pc, lr mov pc, lr
/* /*
* This code is relocatable. It is relocated by the above code to the end * All code following this line is relocatable. It is relocated by
* of the kernel and executed there. During this time, we have no stacks. * the above code to the end of the decompressed kernel image and
* executed there. During this time, we have no stacks.
* *
* r0 = decompressed kernel length * r0 = decompressed kernel length
* r1-r3 = unused * r1-r3 = unused
...@@ -309,47 +299,101 @@ call_kernel: bl cache_clean_flush ...@@ -309,47 +299,101 @@ call_kernel: bl cache_clean_flush
mov pc, r4 @ call kernel mov pc, r4 @ call kernel
/* /*
* Here follow the relocatable cache support functions for * Here follow the relocatable cache support functions for the
* the various processors. * various processors. This is a generic hook for locating an
* entry and jumping to an instruction at the specified offset
* from the start of the block. Please note this is all position
* independent code.
*
* r1 = corrupted
* r2 = corrupted
* r3 = block offset
* r6 = CPU ID
* r12 = corrupted
*/
call_cache_fn: adr r12, proc_types
1: ldr r1, [r12, #0] @ get value
ldr r2, [r12, #4] @ get mask
eor r1, r1, r6 @ (real ^ match)
tst r1, r2 @ & mask
addeq pc, r12, r3 @ call cache function
add r12, r12, #4*5
b 1b
/*
* Table for cache operations. This is basically:
* - CPU ID match
* - CPU ID mask
* - 'cache on' method instruction
* - 'cache off' method instruction
* - 'cache flush' method instruction
*
* We match an entry using: ((real_id ^ match) & mask) == 0
*
* Writethrough caches generally only need 'on' and 'off'
* methods. Writeback caches _must_ have the flush method
* defined.
*/ */
.type proc_types,#object
proc_types:
.word 0x41560600 @ ARM6/610
.word 0xffffffe0
b __arm6_cache_off
b __arm6_cache_off
mov pc, lr
.type proc_sa110_type,#object .word 0x41007000 @ ARM7/710
proc_sa110_type: .word 0xfff8fe00
.word 0x4401a100 b __arm7_cache_off
.size proc_sa110_type, . - proc_sa110_type b __arm7_cache_off
mov pc, lr
.type proc_sa1110_type,#object .word 0x41807200 @ ARM720T (writethrough)
proc_sa1110_type: .word 0xffffff00
.word 0x6901b110 b __cache_on
.size proc_sa1110_type, . - proc_sa1110_type b __armv4_cache_off
mov pc, lr
.word 0x4401a100 @ sa110 / sa1100
.word 0xffffffe0
b __cache_on
b __armv4_cache_off
b __armv4_cache_flush
.word 0x6901b110 @ sa1110
.word 0xfffffff0
b __cache_on
b __armv4_cache_off
b __armv4_cache_flush
.word 0x69050000 @ xscale
.word 0xffff0000
b __cache_on
b __armv4_cache_off
b __armv4_cache_flush
.word 0 @ unrecognised type
.word 0
mov pc, lr
mov pc, lr
mov pc, lr
.size proc_types, . - proc_types
/* /*
* Turn off the Cache and MMU. ARMv3 does not support * Turn off the Cache and MMU. ARMv3 does not support
* reading the control register, but ARMv4 does. * reading the control register, but ARMv4 does.
* *
* On entry, r6 = processor ID * On entry, r6 = processor ID
* On exit, r0, r1 corrupted * On exit, r0, r1, r2, r3, r12 corrupted
* This routine must preserve: r4, r6, r7 * This routine must preserve: r4, r6, r7
*/ */
.align 5 .align 5
cache_off: cache_off: mov r3, #12 @ cache_off function
#ifdef CONFIG_CPU_ARM610 b call_cache_fn
eor r1, r6, #0x41000000
eor r1, r1, #0x00560000 __armv4_cache_off:
bic r1, r1, #0x0000001f
teq r1, #0x00000600
mov r0, #0x00000060 @ ARM6 control reg.
beq __armv3_cache_off
#endif
#ifdef CONFIG_CPU_ARM710
eor r1, r6, #0x41000000
bic r1, r1, #0x00070000
bic r1, r1, #0x000000ff
teq r1, #0x00007000 @ ARM7
teqne r1, #0x00007100 @ ARM710
mov r0, #0x00000070 @ ARM7 control reg.
beq __armv3_cache_off
#endif
mrc p15, 0, r0, c1, c0 mrc p15, 0, r0, c1, c0
bic r0, r0, #0x000d bic r0, r0, #0x000d
mcr p15, 0, r0, c1, c0 @ turn MMU and cache off mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
...@@ -358,6 +402,14 @@ cache_off: ...@@ -358,6 +402,14 @@ cache_off:
mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4 mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4
mov pc, lr mov pc, lr
__arm6_cache_off:
mov r0, #0x00000060 @ ARM6 control reg.
b __armv3_cache_off
__arm7_cache_off:
mov r0, #0x00000070 @ ARM7 control reg.
b __armv3_cache_off
__armv3_cache_off: __armv3_cache_off:
mcr p15, 0, r0, c1, c0 @ turn MMU and cache off mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
mov r0, #0 mov r0, #0
...@@ -371,25 +423,16 @@ __armv3_cache_off: ...@@ -371,25 +423,16 @@ __armv3_cache_off:
* On entry, * On entry,
* r6 = processor ID * r6 = processor ID
* On exit, * On exit,
* r1, r2, r12 corrupted * r1, r2, r3, r12 corrupted
* This routine must preserve: * This routine must preserve:
* r4, r6, r7 * r0, r4, r5, r6, r7
*/ */
.align 5 .align 5
cache_clean_flush: cache_clean_flush:
ldr r1, proc_sa110_type mov r3, #16
eor r1, r1, r6 b call_cache_fn
movs r1, r1, lsr #5 @ catch SA110 and SA1100
beq 1f __armv4_cache_flush:
ldr r1, proc_sa1110_type
eor r1, r1, r6
movs r1, r1, lsr #4
beq 1f
ldr r1, proc_xscale_type
eor r1, r1, r6
movs r1, r1, lsr #16
movne pc, lr
1:
bic r1, pc, #31 bic r1, pc, #31
add r2, r1, #65536 @ 2x the largest dcache size add r2, r1, #65536 @ 2x the largest dcache size
1: ldr r12, [r1], #32 @ s/w flush D cache 1: ldr r12, [r1], #32 @ s/w flush D cache
...@@ -400,12 +443,6 @@ cache_clean_flush: ...@@ -400,12 +443,6 @@ cache_clean_flush:
mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r1, c7, c10, 4 @ drain WB
mov pc, lr mov pc, lr
.type proc_xscale_type,#object
proc_xscale_type:
.word 0x69050000
.size proc_xscale_type, . - proc_xscale_type
/* /*
* Various debugging routines for printing hex characters and * Various debugging routines for printing hex characters and
* memory, which again must be relocatable. * memory, which again must be relocatable.
......
This diff is collapsed.
...@@ -68,6 +68,7 @@ extern void __umoddi3(void); ...@@ -68,6 +68,7 @@ extern void __umoddi3(void);
extern void __udivmoddi4(void); extern void __udivmoddi4(void);
extern void __udivsi3(void); extern void __udivsi3(void);
extern void __umodsi3(void); extern void __umodsi3(void);
extern void abort(void);
extern void ret_from_exception(void); extern void ret_from_exception(void);
extern void fpundefinstr(void); extern void fpundefinstr(void);
......
...@@ -426,6 +426,9 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) ...@@ -426,6 +426,9 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
pci_read_config_word(dev, PCI_COMMAND, &cmd); pci_read_config_word(dev, PCI_COMMAND, &cmd);
cmd |= features; cmd |= features;
pci_write_config_word(dev, PCI_COMMAND, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd);
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
SMP_CACHE_BYTES >> 2);
} }
/* /*
......
...@@ -31,14 +31,6 @@ ...@@ -31,14 +31,6 @@
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
/*
* Values for cpu_do_idle()
*/
#define IDLE_WAIT_SLOW 0
#define IDLE_WAIT_FAST 1
#define IDLE_CLOCK_SLOW 2
#define IDLE_CLOCK_FAST 3
extern const char *processor_modes[]; extern const char *processor_modes[];
extern void setup_mm_for_reboot(char mode); extern void setup_mm_for_reboot(char mode);
...@@ -77,6 +69,18 @@ __setup("hlt", hlt_setup); ...@@ -77,6 +69,18 @@ __setup("hlt", hlt_setup);
void (*pm_idle)(void); void (*pm_idle)(void);
void (*pm_power_off)(void); void (*pm_power_off)(void);
/*
* This is our default idle handler. We need to disable
* interrupts here to ensure we don't miss a wakeup call.
*/
static void default_idle(void)
{
__cli();
if (!need_resched() && !hlt_counter)
arch_idle();
__sti();
}
/* /*
* The idle thread. We try to conserve power, while trying to keep * The idle thread. We try to conserve power, while trying to keep
* overall latency low. The architecture specific idle is passed * overall latency low. The architecture specific idle is passed
...@@ -89,7 +93,7 @@ void cpu_idle(void) ...@@ -89,7 +93,7 @@ void cpu_idle(void)
while (1) { while (1) {
void (*idle)(void) = pm_idle; void (*idle)(void) = pm_idle;
if (!idle) if (!idle)
idle = arch_idle; idle = default_idle;
leds_event(led_idle_start); leds_event(led_idle_start);
while (!need_resched()) while (!need_resched())
idle(); idle();
......
...@@ -188,7 +188,7 @@ static inline void dump_cache(const char *prefix, unsigned int cache) ...@@ -188,7 +188,7 @@ static inline void dump_cache(const char *prefix, unsigned int cache)
{ {
unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0); unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
printk("%s size %dK associativity %d line length %d sets %d\n", printk("%s: %d bytes, associativity %d, %d byte lines, %d sets\n",
prefix, prefix,
mult << (8 + CACHE_SIZE(cache)), mult << (8 + CACHE_SIZE(cache)),
(mult << CACHE_ASSOC(cache)) >> 1, (mult << CACHE_ASSOC(cache)) >> 1,
......
...@@ -546,12 +546,14 @@ void abort(void) ...@@ -546,12 +546,14 @@ void abort(void)
void __init trap_init(void) void __init trap_init(void)
{ {
extern void __trap_init(void *); extern void __trap_init(unsigned long);
unsigned long base = vectors_base();
__trap_init((void *)vectors_base());
if (vectors_base() != 0) __trap_init(base);
printk(KERN_DEBUG "Relocating machine vectors to 0x%08x\n", flush_icache_range(base, base + PAGE_SIZE);
vectors_base()); if (base != 0)
printk(KERN_DEBUG "Relocating machine vectors to 0x%08lx\n",
base);
#ifdef CONFIG_CPU_32 #ifdef CONFIG_CPU_32
modify_domain(DOMAIN_USER, DOMAIN_CLIENT); modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
#endif #endif
......
...@@ -106,8 +106,10 @@ static struct irqaction irq_cascade = { handler: no_action, name: "cascade", }; ...@@ -106,8 +106,10 @@ static struct irqaction irq_cascade = { handler: no_action, name: "cascade", };
static struct resource pic1_resource = { "pic1", 0x20, 0x3f }; static struct resource pic1_resource = { "pic1", 0x20, 0x3f };
static struct resource pic2_resource = { "pic2", 0xa0, 0xbf }; static struct resource pic2_resource = { "pic2", 0xa0, 0xbf };
void __init isa_init_irq(unsigned int irq) void __init isa_init_irq(unsigned int host_irq)
{ {
unsigned int irq;
/* /*
* Setup, and then probe for an ISA PIC * Setup, and then probe for an ISA PIC
* If the PIC is not there, then we * If the PIC is not there, then we
...@@ -133,10 +135,10 @@ void __init isa_init_irq(unsigned int irq) ...@@ -133,10 +135,10 @@ void __init isa_init_irq(unsigned int irq)
outb(0xff, PIC_MASK_HI);/* mask all IRQs */ outb(0xff, PIC_MASK_HI);/* mask all IRQs */
} else { } else {
printk(KERN_INFO "IRQ: ISA PIC not found\n"); printk(KERN_INFO "IRQ: ISA PIC not found\n");
irq = -1; host_irq = (unsigned int)-1;
} }
if (irq != -1) { if (host_irq != (unsigned int)-1) {
for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) { for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) {
set_irq_chip(irq, &isa_lo_chip); set_irq_chip(irq, &isa_lo_chip);
set_irq_handler(irq, do_level_IRQ); set_irq_handler(irq, do_level_IRQ);
...@@ -153,7 +155,7 @@ void __init isa_init_irq(unsigned int irq) ...@@ -153,7 +155,7 @@ void __init isa_init_irq(unsigned int irq)
request_resource(&ioport_resource, &pic2_resource); request_resource(&ioport_resource, &pic2_resource);
setup_irq(IRQ_ISA_CASCADE, &irq_cascade); setup_irq(IRQ_ISA_CASCADE, &irq_cascade);
set_irq_chained_handler(irq, isa_irq_handler); set_irq_chained_handler(host_irq, isa_irq_handler);
/* /*
* On the NetWinder, don't automatically * On the NetWinder, don't automatically
......
...@@ -52,26 +52,10 @@ static int __init adsbitsy_init(void) ...@@ -52,26 +52,10 @@ static int __init adsbitsy_init(void)
/* /*
* Probe for SA1111. * Probe for SA1111.
*/ */
ret = sa1111_probe(0x18000000); ret = sa1111_init(NULL, 0x18000000, IRQ_GPIO0);
if (ret < 0) if (ret < 0)
return ret; return ret;
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/
sa1111_configure_smc(1,
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/* /*
* Enable PWM control for LCD * Enable PWM control for LCD
*/ */
...@@ -81,20 +65,6 @@ static int __init adsbitsy_init(void) ...@@ -81,20 +65,6 @@ static int __init adsbitsy_init(void)
SKPWM1 = 0x01; // Backlight SKPWM1 = 0x01; // Backlight
SKPEN1 = 1; SKPEN1 = 1;
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE);
sa1111_init_irq(IRQ_GPIO0);
return 0; return 0;
} }
......
...@@ -34,8 +34,6 @@ ...@@ -34,8 +34,6 @@
static int __init badge4_sa1111_init(void) static int __init badge4_sa1111_init(void)
{ {
int ret;
/* /*
* Ensure that the memory bus request/grant signals are setup, * Ensure that the memory bus request/grant signals are setup,
* and the grant is held in its inactive state * and the grant is held in its inactive state
...@@ -45,40 +43,7 @@ static int __init badge4_sa1111_init(void) ...@@ -45,40 +43,7 @@ static int __init badge4_sa1111_init(void)
/* /*
* Probe for SA1111. * Probe for SA1111.
*/ */
ret = sa1111_probe(BADGE4_SA1111_BASE); return sa1111_init(NULL, BADGE4_SA1111_BASE, BADGE4_IRQ_GPIO_SA1111);
if (ret < 0)
return ret;
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/
sa1111_configure_smc(1,
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
sa1111_init_irq(BADGE4_IRQ_GPIO_SA1111);
return 0;
} }
static int __init badge4_init(void) static int __init badge4_init(void)
......
...@@ -42,26 +42,10 @@ static int __init graphicsmaster_init(void) ...@@ -42,26 +42,10 @@ static int __init graphicsmaster_init(void)
/* /*
* Probe for SA1111. * Probe for SA1111.
*/ */
ret = sa1111_probe(0x18000000); ret = sa1111_init(NULL, 0x18000000, ADS_EXT_IRQ(0));
if (ret < 0) if (ret < 0)
return ret; return ret;
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/
sa1111_configure_smc(1,
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/* /*
* Enable PWM control for LCD * Enable PWM control for LCD
*/ */
...@@ -71,19 +55,6 @@ static int __init graphicsmaster_init(void) ...@@ -71,19 +55,6 @@ static int __init graphicsmaster_init(void)
SKPWM1 = 0x01; // Backlight SKPWM1 = 0x01; // Backlight
SKPEN1 = 1; SKPEN1 = 1;
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
sa1111_init_irq(ADS_EXT_IRQ(0));
return 0; return 0;
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/device.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -21,6 +22,10 @@ ...@@ -21,6 +22,10 @@
#include "sa1111.h" #include "sa1111.h"
static struct device neponset_device = {
name: "Neponset",
bus_id: "nep_bus",
};
/* /*
* Install handler for Neponset IRQ. Note that we have to loop here * Install handler for Neponset IRQ. Note that we have to loop here
...@@ -125,6 +130,10 @@ static int __init neponset_init(void) ...@@ -125,6 +130,10 @@ static int __init neponset_init(void)
return -ENODEV; return -ENODEV;
} }
ret = device_register(&neponset_device);
if (ret)
return ret;
neponset_init_irq(); neponset_init_irq();
/* /*
...@@ -139,45 +148,9 @@ static int __init neponset_init(void) ...@@ -139,45 +148,9 @@ static int __init neponset_init(void)
/* FIXME: setup MSC2 */ /* FIXME: setup MSC2 */
/* /*
* Probe for a SA1111. * Probe and initialise the SA1111.
*/
ret = sa1111_probe(0x40000000);
if (ret < 0)
return ret;
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/ */
sa1111_configure_smc(1, return sa1111_init(&neponset_device, 0x40000000, IRQ_NEPONSET_SA1111);
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
/*
* Initialise SA1111 IRQs
*/
sa1111_init_irq(IRQ_NEPONSET_SA1111);
return 0;
} }
__initcall(neponset_init); __initcall(neponset_init);
......
...@@ -35,40 +35,7 @@ static int __init pfs168_init(void) ...@@ -35,40 +35,7 @@ static int __init pfs168_init(void)
/* /*
* Probe for SA1111. * Probe for SA1111.
*/ */
ret = sa1111_probe(0x40000000); return sa1111_init(NULL, 0x40000000, IRQ_GPIO25);
if (ret < 0)
return ret;
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/
sa1111_configure_smc(1,
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
sa1111_init_irq(IRQ_GPIO25); /* SA1111 IRQ on GPIO 25 */
return 0;
} }
__initcall(pfs168_init); __initcall(pfs168_init);
......
...@@ -23,8 +23,11 @@ ...@@ -23,8 +23,11 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
...@@ -32,11 +35,9 @@ ...@@ -32,11 +35,9 @@
#include "sa1111.h" #include "sa1111.h"
struct resource sa1111_resource = { struct sa1111_device *sa1111;
name: "SA1111",
};
EXPORT_SYMBOL(sa1111_resource); EXPORT_SYMBOL(sa1111);
/* /*
* SA1111 interrupt support. Since clearing an IRQ while there are * SA1111 interrupt support. Since clearing an IRQ while there are
...@@ -65,6 +66,9 @@ sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) ...@@ -65,6 +66,9 @@ sa1111_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1) for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1)
if (stat1 & 1) if (stat1 & 1)
do_edge_IRQ(i, irq_desc + i, regs); do_edge_IRQ(i, irq_desc + i, regs);
/* For level-based interrupts */
desc->chip->unmask(irq);
} }
#define SA1111_IRQMASK_LO(x) (1 << (x - IRQ_SA1111_START)) #define SA1111_IRQMASK_LO(x) (1 << (x - IRQ_SA1111_START))
...@@ -198,7 +202,7 @@ static struct irqchip sa1111_high_chip = { ...@@ -198,7 +202,7 @@ static struct irqchip sa1111_high_chip = {
type: sa1111_type_highirq, type: sa1111_type_highirq,
}; };
void __init sa1111_init_irq(int irq_nr) static void __init sa1111_init_irq(int irq_nr)
{ {
unsigned int irq; unsigned int irq;
...@@ -239,6 +243,21 @@ void __init sa1111_init_irq(int irq_nr) ...@@ -239,6 +243,21 @@ void __init sa1111_init_irq(int irq_nr)
set_irq_chained_handler(irq_nr, sa1111_irq_handler); set_irq_chained_handler(irq_nr, sa1111_irq_handler);
} }
static int sa1111_suspend(struct device *dev, u32 state, u32 level)
{
return 0;
}
static int sa1111_resume(struct device *dev, u32 level)
{
return 0;
}
static struct device_driver sa1111_device_driver = {
suspend: sa1111_suspend,
resume: sa1111_resume,
};
/** /**
* sa1111_probe - probe for a single SA1111 chip. * sa1111_probe - probe for a single SA1111 chip.
* @phys_addr: physical address of device. * @phys_addr: physical address of device.
...@@ -251,38 +270,71 @@ void __init sa1111_init_irq(int irq_nr) ...@@ -251,38 +270,71 @@ void __init sa1111_init_irq(int irq_nr)
* %-EBUSY physical address already marked in-use. * %-EBUSY physical address already marked in-use.
* %0 successful. * %0 successful.
*/ */
int __init sa1111_probe(unsigned long phys_addr) static int __init
sa1111_probe(struct device *parent, unsigned long phys_addr)
{ {
struct sa1111_device *sa;
unsigned long id; unsigned long id;
int ret = -ENODEV; int ret = -ENODEV;
sa1111_resource.start = phys_addr; sa = kmalloc(sizeof(struct sa1111_device), GFP_KERNEL);
sa1111_resource.end = phys_addr + 0x2000; if (!sa)
return -ENOMEM;
memset(sa, 0, sizeof(struct sa1111_device));
if (request_resource(&iomem_resource, &sa1111_resource)) { sa->resource.name = "SA1111";
sa->resource.start = phys_addr;
sa->resource.end = phys_addr + 0x2000;
if (request_resource(&iomem_resource, &sa->resource)) {
ret = -EBUSY; ret = -EBUSY;
goto out; goto out;
} }
/* eventually ioremap... */
sa->base = (void *)0xf4000000;
if (!sa->base) {
ret = -ENOMEM;
goto release;
}
/* /*
* Probe for the chip. Only touch the SBI registers. * Probe for the chip. Only touch the SBI registers.
*/ */
id = SBI_SKID; id = readl(sa->base + SA1111_SKID);
if ((id & SKID_ID_MASK) != SKID_SA1111_ID) { if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id); printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id);
ret = -ENODEV; ret = -ENODEV;
goto release; goto unmap;
} }
/*
* We found the chip.
*/
strcpy(sa->dev.name, "SA1111");
sprintf(sa->dev.bus_id, "%8.8lx", phys_addr);
sa->dev.parent = parent;
sa->dev.driver = &sa1111_device_driver;
ret = device_register(&sa->dev);
if (ret)
printk("sa1111 device_register failed: %d\n", ret);
printk(KERN_INFO "SA1111 Microprocessor Companion Chip: " printk(KERN_INFO "SA1111 Microprocessor Companion Chip: "
"silicon revision %lx, metal revision %lx\n", "silicon revision %lx, metal revision %lx\n",
(id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK)); (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
sa1111 = sa;
return 0; return 0;
unmap:
// iounmap(sa->base);
release: release:
release_resource(&sa1111_resource); release_resource(&sa->resource);
out: out:
kfree(sa);
return ret; return ret;
} }
...@@ -302,7 +354,8 @@ int __init sa1111_probe(unsigned long phys_addr) ...@@ -302,7 +354,8 @@ int __init sa1111_probe(unsigned long phys_addr)
*/ */
void sa1111_wake(void) void sa1111_wake(void)
{ {
unsigned long flags; struct sa1111_device *sa = sa1111;
unsigned long flags, r;
local_irq_save(flags); local_irq_save(flags);
...@@ -317,8 +370,11 @@ void sa1111_wake(void) ...@@ -317,8 +370,11 @@ void sa1111_wake(void)
/* /*
* Turn VCO on, and disable PLL Bypass. * Turn VCO on, and disable PLL Bypass.
*/ */
SBI_SKCR &= ~SKCR_VCO_OFF; r = readl(sa->base + SA1111_SKCR);
SBI_SKCR |= SKCR_PLL_BYPASS | SKCR_OE_EN; r &= ~SKCR_VCO_OFF;
writel(r, sa->base + SA1111_SKCR);
r |= SKCR_PLL_BYPASS | SKCR_OE_EN;
writel(r, sa->base + SA1111_SKCR);
/* /*
* Wait lock time. SA1111 manual _doesn't_ * Wait lock time. SA1111 manual _doesn't_
...@@ -329,7 +385,8 @@ void sa1111_wake(void) ...@@ -329,7 +385,8 @@ void sa1111_wake(void)
/* /*
* Enable RCLK. We also ensure that RDYEN is set. * Enable RCLK. We also ensure that RDYEN is set.
*/ */
SBI_SKCR |= SKCR_RCLKEN | SKCR_RDYEN; r |= SKCR_RCLKEN | SKCR_RDYEN;
writel(r, sa->base + SA1111_SKCR);
/* /*
* Wait 14 RCLK cycles for the chip to finish coming out * Wait 14 RCLK cycles for the chip to finish coming out
...@@ -340,18 +397,26 @@ void sa1111_wake(void) ...@@ -340,18 +397,26 @@ void sa1111_wake(void)
/* /*
* Ensure all clocks are initially off. * Ensure all clocks are initially off.
*/ */
SKPCR = 0; writel(0, sa->base + SA1111_SKPCR);
local_irq_restore(flags); local_irq_restore(flags);
} }
void sa1111_doze(void) void sa1111_doze(void)
{ {
if (SKPCR & SKPCR_UCLKEN) { struct sa1111_device *sa = sa1111;
unsigned long flags;
local_irq_save(flags);
if (readl(sa->base + SA1111_SKPCR) & SKPCR_UCLKEN) {
local_irq_restore(flags);
printk("SA1111 doze mode refused\n"); printk("SA1111 doze mode refused\n");
return; return;
} }
SBI_SKCR &= ~SKCR_RCLKEN;
writel(readl(sa->base + SA1111_SKCR) & ~SKCR_RCLKEN, sa->base + SA1111_SKCR);
local_irq_restore(flags);
} }
/* /*
...@@ -359,12 +424,13 @@ void sa1111_doze(void) ...@@ -359,12 +424,13 @@ void sa1111_doze(void)
*/ */
void sa1111_configure_smc(int sdram, unsigned int drac, unsigned int cas_latency) void sa1111_configure_smc(int sdram, unsigned int drac, unsigned int cas_latency)
{ {
struct sa1111_device *sa = sa1111;
unsigned int smcr = SMCR_DTIM | SMCR_MBGE | FInsrt(drac, SMCR_DRAC); unsigned int smcr = SMCR_DTIM | SMCR_MBGE | FInsrt(drac, SMCR_DRAC);
if (cas_latency == 3) if (cas_latency == 3)
smcr |= SMCR_CLAT; smcr |= SMCR_CLAT;
SBI_SMCR = smcr; writel(smcr, sa->base + SA1111_SMCR);
} }
/* According to the "Intel StrongARM SA-1111 Microprocessor Companion /* According to the "Intel StrongARM SA-1111 Microprocessor Companion
...@@ -432,3 +498,46 @@ int sa1111_check_dma_bug(dma_addr_t addr) ...@@ -432,3 +498,46 @@ int sa1111_check_dma_bug(dma_addr_t addr)
} }
EXPORT_SYMBOL(sa1111_check_dma_bug); EXPORT_SYMBOL(sa1111_check_dma_bug);
int sa1111_init(struct device *parent, unsigned long phys, unsigned int irq)
{
int ret;
ret = sa1111_probe(parent, phys);
if (ret < 0)
return ret;
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/
sa1111_configure_smc(1,
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
/*
* Initialise SA1111 IRQs
*/
sa1111_init_irq(irq);
return 0;
}
/* /*
* linux/arch/arm/mach-sa1100/sa1111.h * linux/arch/arm/mach-sa1100/sa1111.h
*/ */
struct device;
/* /*
* Probe for a SA1111 chip. * Probe for a SA1111 chip.
*/ */
extern int sa1111_probe(unsigned long phys); extern int
sa1111_init(struct device *parent, unsigned long phys, unsigned int irq);
/* /*
* Wake up a SA1111 chip. * Wake up a SA1111 chip.
...@@ -16,9 +18,3 @@ extern void sa1111_wake(void); ...@@ -16,9 +18,3 @@ extern void sa1111_wake(void);
* Doze the SA1111 chip. * Doze the SA1111 chip.
*/ */
extern void sa1111_doze(void); extern void sa1111_doze(void);
/*
* Configure the SA1111 shared memory controller.
*/
extern void sa1111_configure_smc(int sdram, unsigned int drac, unsigned int cas_latency);
extern void sa1111_init_irq(int irq_nr);
...@@ -426,45 +426,12 @@ static int __init system3_init(void) ...@@ -426,45 +426,12 @@ static int __init system3_init(void)
/* /*
* Probe for a SA1111. * Probe for a SA1111.
*/ */
ret = sa1111_probe(PT_SA1111_BASE); ret = sa1111_init(NULL, PT_SA1111_BASE, IRQ_SYSTEM3_SA1111);
if (ret < 0) { if (ret < 0) {
printk( KERN_WARNING"PT Digital Board: no SA1111 found!\n" ); printk( KERN_WARNING"PT Digital Board: no SA1111 found!\n" );
goto DONE; goto DONE;
} }
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* don't corrupt the SDRAM. Note that this ungates the SA1111's
* MBGNT signal, so we must have called sa1110_mb_disable()
* beforehand.
*/
sa1111_configure_smc(1,
FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
/*
* We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position.
*/
SKPCR |= SKPCR_DCLKEN;
/*
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
/*
* Initialise SA1111 IRQs
*/
sa1111_init_irq(IRQ_SYSTEM3_SA1111);
#if defined( CONFIG_CPU_FREQ ) #if defined( CONFIG_CPU_FREQ )
ret = cpufreq_register_notifier(&system3_clkchg_block); ret = cpufreq_register_notifier(&system3_clkchg_block);
if ( ret != 0 ) { if ( ret != 0 ) {
......
...@@ -20,6 +20,8 @@ static int __init shark_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ...@@ -20,6 +20,8 @@ static int __init shark_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
else return 255; else return 255;
} }
extern void __init via82c505_preinit(void *sysdata);
struct hw_pci shark_pci __initdata = { struct hw_pci shark_pci __initdata = {
setup: via82c505_setup, setup: via82c505_setup,
swizzle: pci_std_swizzle, swizzle: pci_std_swizzle,
......
...@@ -28,7 +28,7 @@ ENTRY(v5ej_early_abort) ...@@ -28,7 +28,7 @@ ENTRY(v5ej_early_abort)
ldrneh r3, [r2] @ read aborted thumb instruction ldrneh r3, [r2] @ read aborted thumb instruction
ldreq r3, [r2] @ read aborted ARM instruction ldreq r3, [r2] @ read aborted ARM instruction
movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20 movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
tst r2, #1 << 20 @ L = 1 -> write tst r3, #1 << 20 @ L = 1 -> write
orreq r1, r1, #1 << 8 @ yes. orreq r1, r1, #1 << 8 @ yes.
1: mov pc, lr 1: mov pc, lr
......
...@@ -25,10 +25,12 @@ ...@@ -25,10 +25,12 @@
/* /*
* This allocates one page of cache-coherent memory space and returns * This allocates one page of cache-coherent memory space and returns
* both the virtual and a "dma" address to that space. It is not clear * both the virtual and a "dma" address to that space.
* whether this could be called from an interrupt context or not. For *
* now, we expressly forbid it, especially as some of the stuff we do * We should allow this function to be called from interrupt context.
* here is not interrupt context safe. * However, we call ioremap, which needs to fiddle around with various
* things (like the vmlist_lock, and allocating page tables). These
* things aren't interrupt safe (yet).
* *
* Note that this does *not* zero the allocated area! * Note that this does *not* zero the allocated area!
*/ */
...@@ -36,8 +38,9 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) ...@@ -36,8 +38,9 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
{ {
struct page *page, *end, *free; struct page *page, *end, *free;
unsigned long order; unsigned long order;
void *ret, *virt; void *ret;
/* FIXME */
if (in_interrupt()) if (in_interrupt())
BUG(); BUG();
...@@ -48,22 +51,22 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) ...@@ -48,22 +51,22 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
if (!page) if (!page)
goto no_page; goto no_page;
/* *dma_handle = page_to_bus(page);
* We could do with a page_to_phys and page_to_bus here. ret = __ioremap(page_to_phys(page), size, 0);
*/
virt = page_address(page);
*dma_handle = virt_to_bus(virt);
ret = __ioremap(virt_to_phys(virt), size, 0);
if (!ret) if (!ret)
goto no_remap; goto no_remap;
#if 0 /* ioremap_does_flush_cache_all */ #if 0 /* ioremap_does_flush_cache_all */
/* {
* we need to ensure that there are no cachelines in use, or void *virt = page_address(page);
* worse dirty in this area. Really, we don't need to do
* this since __ioremap does a flush_cache_all() anyway. --rmk /*
*/ * we need to ensure that there are no cachelines in use, or
invalidate_dcache_range(virt, virt + size); * worse dirty in this area. Really, we don't need to do
* this since __ioremap does a flush_cache_all() anyway. --rmk
*/
invalidate_dcache_range(virt, virt + size);
}
#endif #endif
/* /*
...@@ -72,7 +75,6 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) ...@@ -72,7 +75,6 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
* We also mark the pages in use as reserved so that * We also mark the pages in use as reserved so that
* remap_page_range works. * remap_page_range works.
*/ */
page = virt_to_page(virt);
free = page + (size >> PAGE_SHIFT); free = page + (size >> PAGE_SHIFT);
end = page + (1 << order); end = page + (1 << order);
...@@ -93,18 +95,12 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) ...@@ -93,18 +95,12 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handle) void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handle)
{ {
void *__ret; int gfp = GFP_KERNEL;
int __gfp = GFP_KERNEL;
#ifdef CONFIG_PCI if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
if ((hwdev) == NULL || gfp |= GFP_DMA;
(hwdev)->dma_mask != 0xffffffff)
#endif
__gfp |= GFP_DMA;
__ret = consistent_alloc(__gfp, (size), return consistent_alloc(gfp, size, handle);
(handle));
return __ret;
} }
/* /*
...@@ -114,19 +110,16 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handl ...@@ -114,19 +110,16 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handl
void consistent_free(void *vaddr, size_t size, dma_addr_t handle) void consistent_free(void *vaddr, size_t size, dma_addr_t handle)
{ {
struct page *page, *end; struct page *page, *end;
void *virt;
if (in_interrupt()) if (in_interrupt())
BUG(); BUG();
virt = bus_to_virt(handle);
/* /*
* More messing around with the MM internals. This is * More messing around with the MM internals. This is
* sick, but then so is remap_page_range(). * sick, but then so is remap_page_range().
*/ */
size = PAGE_ALIGN(size); size = PAGE_ALIGN(size);
page = virt_to_page(virt); page = virt_to_page(bus_to_virt(handle));
end = page + (size >> PAGE_SHIFT); end = page + (size >> PAGE_SHIFT);
for (; page < end; page++) for (; page < end; page++)
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# To add an entry into this database, please see Documentation/arm/README, # To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk # or contact rmk@arm.linux.org.uk
# #
# Last update: Sun Mar 24 11:48:10 2002 # Last update: Fri Mar 29 15:51:20 2002
# #
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
# #
...@@ -179,3 +179,4 @@ jornada56x ARCH_JORNADA56X JORNADA56X 167 ...@@ -179,3 +179,4 @@ jornada56x ARCH_JORNADA56X JORNADA56X 167
active SA1100_ACTIVE ACTIVE 168 active SA1100_ACTIVE ACTIVE 168
iq80321 ARCH_IQ80321 IQ80321 169 iq80321 ARCH_IQ80321 IQ80321 169
wid SA1100_WID WID 170 wid SA1100_WID WID 170
sabinal ARCH_SABINAL SABINAL 171
...@@ -11,8 +11,7 @@ ...@@ -11,8 +11,7 @@
static inline void arch_idle(void) static inline void arch_idle(void)
{ {
#if 0 #if 0
if (!hlt_counter) cpu_do_idle();
cpu_do_idle(0);
#endif #endif
} }
......
...@@ -15,8 +15,7 @@ ...@@ -15,8 +15,7 @@
#ifndef __ASM_ARCH_SYSTEM_H #ifndef __ASM_ARCH_SYSTEM_H
#define __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H
static inline void static inline void arch_idle(void)
arch_idle(void)
{ {
} }
......
...@@ -8,9 +8,8 @@ ...@@ -8,9 +8,8 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
static void arch_idle(void) static inline void arch_idle(void)
{ {
while (!need_resched() && !hlt_counter);
} }
static inline void arch_reset(char mode) static inline void arch_reset(char mode)
......
...@@ -7,11 +7,11 @@ ...@@ -7,11 +7,11 @@
#define __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H
#include <asm/hardware/iomd.h> #include <asm/hardware/iomd.h>
#include <asm/io.h>
static void arch_idle(void) static inline void arch_idle(void)
{ {
while (!need_resched() && !hlt_counter) iomd_writeb(0, IOMD_SUSMODE);
iomd_writeb(0, IOMD_SUSMODE);
} }
#define arch_reset(mode) \ #define arch_reset(mode) \
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <asm/hardware/clps7111.h> #include <asm/hardware/clps7111.h>
static void arch_idle(void) static inline void arch_idle(void)
{ {
clps_writel(1, HALT); clps_writel(1, HALT);
__asm__ __volatile__( __asm__ __volatile__(
......
...@@ -20,31 +20,18 @@ ...@@ -20,31 +20,18 @@
* Instead, we spin, polling the IRQ_STAT register for the occurrence * Instead, we spin, polling the IRQ_STAT register for the occurrence
* of any interrupt with core clock down to the memory clock. * of any interrupt with core clock down to the memory clock.
*/ */
static void arch_idle(void) static inline void arch_idle(void)
{ {
const char *irq_stat = (char *)0xff000000; const char *irq_stat = (char *)0xff000000;
long flags;
if (!hlt_counter) /* disable clock switching */
return; asm volatile ("mcr%? p15, 0, ip, c15, c2, 2");
do { /* wait for an interrupt to occur */
/* disable interrupts */ while (!*irq_stat);
cli();
/* check need_resched here to avoid races */ /* enable clock switching */
if (need_resched()) { asm volatile ("mcr%? p15, 0, ip, c15, c1, 2");
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) #define arch_reset(mode) cpu_reset(0x80000000)
......
...@@ -13,26 +13,9 @@ ...@@ -13,26 +13,9 @@
#include <asm/leds.h> #include <asm/leds.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
static void arch_idle(void) static inline void arch_idle(void)
{ {
unsigned long start_idle; cpu_do_idle();
start_idle = jiffies;
do {
if (need_resched() || hlt_counter)
goto slow_out;
cpu_do_idle(IDLE_WAIT_FAST);
} while (time_before(jiffies, start_idle + HZ/50));
cpu_do_idle(IDLE_CLOCK_SLOW);
while (!need_resched() && !hlt_counter) {
cpu_do_idle(IDLE_WAIT_SLOW);
}
cpu_do_idle(IDLE_CLOCK_FAST);
slow_out:
} }
static inline void arch_reset(char mode) static inline void arch_reset(char mode)
......
...@@ -24,13 +24,13 @@ ...@@ -24,13 +24,13 @@
#include <asm/arch/platform.h> #include <asm/arch/platform.h>
static void arch_idle(void) static inline void arch_idle(void)
{ {
/* /*
* This should do all the clock switching * This should do all the clock switching
* and wait for interrupt tricks * and wait for interrupt tricks
*/ */
cpu_do_idle(0); cpu_do_idle();
} }
extern __inline__ void arch_reset(char mode) extern __inline__ void arch_reset(char mode)
......
...@@ -23,13 +23,13 @@ ...@@ -23,13 +23,13 @@
#include <asm/arch/platform.h> #include <asm/arch/platform.h>
static void arch_idle(void) static inline void arch_idle(void)
{ {
/* /*
* This should do all the clock switching * This should do all the clock switching
* and wait for interrupt tricks * and wait for interrupt tricks
*/ */
cpu_do_idle(0); cpu_do_idle();
} }
static inline void arch_reset(char mode) static inline void arch_reset(char mode)
......
...@@ -10,10 +10,7 @@ ...@@ -10,10 +10,7 @@
static inline void arch_idle(void) static inline void arch_idle(void)
{ {
if (!hlt_counter) cpu_do_idle();
{
cpu_do_idle(0);
}
} }
......
...@@ -12,9 +12,8 @@ ...@@ -12,9 +12,8 @@
#ifndef __ASM_ARCH_SYSTEM_H #ifndef __ASM_ARCH_SYSTEM_H
#define __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H
static void arch_idle(void) static inline void arch_idle(void)
{ {
/* fixme: this needs to be cleaned up (converted from ASM code) --rmk */
*(unsigned long *)(IO_BASE + 0x50004) = 1; /* idle mode */ *(unsigned long *)(IO_BASE + 0x50004) = 1; /* idle mode */
} }
......
...@@ -14,10 +14,9 @@ ...@@ -14,10 +14,9 @@
#ifndef __ASM_ARCH_SYSTEM_H #ifndef __ASM_ARCH_SYSTEM_H
#define __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H
static void arch_idle(void) static inline void arch_idle(void)
{ {
while (!need_resched() && !hlt_counter) cpu_do_idle();
cpu_do_idle(IDLE_WAIT_SLOW);
} }
#define arch_reset(mode) do { } while (0) #define arch_reset(mode) do { } while (0)
......
...@@ -14,13 +14,7 @@ ...@@ -14,13 +14,7 @@
static inline void arch_idle(void) static inline void arch_idle(void)
{ {
if (!hlt_counter) { cpu_do_idle();
int flags;
local_irq_save(flags);
if(!need_resched())
cpu_do_idle(0);
local_irq_restore(flags);
}
} }
......
...@@ -11,26 +11,9 @@ ...@@ -11,26 +11,9 @@
#include <asm/hardware/iomd.h> #include <asm/hardware/iomd.h>
#include <asm/io.h> #include <asm/io.h>
static void arch_idle(void) static inline void arch_idle(void)
{ {
unsigned long start_idle; cpu_do_idle();
start_idle = jiffies;
do {
if (need_resched() || hlt_counter)
goto slow_out;
cpu_do_idle(IDLE_WAIT_FAST);
} while (time_before(jiffies, start_idle + HZ/50));
cpu_do_idle(IDLE_CLOCK_SLOW);
while (!need_resched() && !hlt_counter) {
cpu_do_idle(IDLE_WAIT_SLOW);
}
cpu_do_idle(IDLE_CLOCK_FAST);
slow_out:
} }
static inline void arch_reset(char mode) static inline void arch_reset(char mode)
......
...@@ -7,13 +7,7 @@ ...@@ -7,13 +7,7 @@
static inline void arch_idle(void) static inline void arch_idle(void)
{ {
if (!hlt_counter) { cpu_do_idle();
int flags;
local_irq_save(flags);
if (!need_resched())
cpu_do_idle(0);
local_irq_restore(flags);
}
} }
#ifdef CONFIG_SA1100_VICTOR #ifdef CONFIG_SA1100_VICTOR
......
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
#define __bus_to_virt__is_a_macro #define __bus_to_virt__is_a_macro
#define __bus_to_virt(x) __phys_to_virt(x) #define __bus_to_virt(x) __phys_to_virt(x)
#define isa_virt_to_bus virt_to_bus
#define PHYS_TO_NID(addr) (0) #define PHYS_TO_NID(addr) (0)
#endif #endif
...@@ -21,7 +21,7 @@ static void arch_reset(char mode) ...@@ -21,7 +21,7 @@ static void arch_reset(char mode)
} }
static void arch_idle(void) static inline void arch_idle(void)
{ {
} }
......
...@@ -6,26 +6,9 @@ ...@@ -6,26 +6,9 @@
#ifndef __ASM_ARCH_SYSTEM_H #ifndef __ASM_ARCH_SYSTEM_H
#define __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H
static void arch_idle(void) static inline void arch_idle(void)
{ {
unsigned long start_idle; cpu_do_idle();
start_idle = jiffies;
do {
if (need_resched() || hlt_counter)
goto slow_out;
cpu_do_idle(IDLE_WAIT_FAST);
} while (time_before(jiffies, start_idle + HZ/50));
cpu_do_idle(IDLE_CLOCK_SLOW);
while (!need_resched() && !hlt_counter) {
cpu_do_idle(IDLE_WAIT_SLOW);
}
cpu_do_idle(IDLE_CLOCK_FAST);
slow_out:
} }
#define arch_reset(mode) do { } while (0) #define arch_reset(mode) do { } while (0)
......
...@@ -40,7 +40,7 @@ extern const struct processor arm3_processor_functions; ...@@ -40,7 +40,7 @@ extern const struct processor arm3_processor_functions;
#define cpu_proc_init() processor._proc_init() #define cpu_proc_init() processor._proc_init()
#define cpu_proc_fin() processor._proc_fin() #define cpu_proc_fin() processor._proc_fin()
#define cpu_do_idle() do { } while (0) #define cpu_do_idle() do { } while (0)
#define cpu_switch_mm(pgd,tsk) processor._set_pgd(pgd) #define cpu_switch_mm(pgd,mm) processor._set_pgd(pgd)
#define cpu_xchg_1(x,ptr) processor._xchg_1(x,ptr) #define cpu_xchg_1(x,ptr) processor._xchg_1(x,ptr)
#define cpu_xchg_4(x,ptr) processor._xchg_4(x,ptr) #define cpu_xchg_4(x,ptr) processor._xchg_4(x,ptr)
......
...@@ -12,8 +12,7 @@ ...@@ -12,8 +12,7 @@
#include <asm/memory.h> #include <asm/memory.h>
#include <asm/page.h> #include <asm/page.h>
/* forward-declare task_struct */ struct mm_struct;
struct task_struct;
/* /*
* Don't change this structure - ASM code * Don't change this structure - ASM code
...@@ -43,7 +42,7 @@ extern struct processor { ...@@ -43,7 +42,7 @@ extern struct processor {
/* /*
* Idle the processor * Idle the processor
*/ */
int (*_do_idle)(int mode); int (*_do_idle)(void);
/* /*
* Processor architecture specific * Processor architecture specific
*/ */
...@@ -93,7 +92,7 @@ extern struct processor { ...@@ -93,7 +92,7 @@ extern struct processor {
/* /*
* Set the page table * Set the page table
*/ */
void (*set_pgd)(unsigned long pgd_phys); void (*set_pgd)(unsigned long pgd_phys, struct mm_struct *mm);
/* /*
* Set a PMD (handling IMP bit 4) * Set a PMD (handling IMP bit 4)
*/ */
...@@ -113,7 +112,7 @@ extern const struct processor sa110_processor_functions; ...@@ -113,7 +112,7 @@ extern const struct processor sa110_processor_functions;
#define cpu_proc_init() processor._proc_init() #define cpu_proc_init() processor._proc_init()
#define cpu_proc_fin() processor._proc_fin() #define cpu_proc_fin() processor._proc_fin()
#define cpu_reset(addr) processor.reset(addr) #define cpu_reset(addr) processor.reset(addr)
#define cpu_do_idle(mode) processor._do_idle(mode) #define cpu_do_idle() processor._do_idle()
#define cpu_cache_clean_invalidate_all() processor.cache.clean_invalidate_all() #define cpu_cache_clean_invalidate_all() processor.cache.clean_invalidate_all()
#define cpu_cache_clean_invalidate_range(s,e,f) processor.cache.clean_invalidate_range(s,e,f) #define cpu_cache_clean_invalidate_range(s,e,f) processor.cache.clean_invalidate_range(s,e,f)
...@@ -126,11 +125,11 @@ extern const struct processor sa110_processor_functions; ...@@ -126,11 +125,11 @@ extern const struct processor sa110_processor_functions;
#define cpu_icache_invalidate_range(s,e) processor.icache.invalidate_range(s,e) #define cpu_icache_invalidate_range(s,e) processor.icache.invalidate_range(s,e)
#define cpu_icache_invalidate_page(vp) processor.icache.invalidate_page(vp) #define cpu_icache_invalidate_page(vp) processor.icache.invalidate_page(vp)
#define cpu_set_pgd(pgd) processor.pgtable.set_pgd(pgd) #define cpu_set_pgd(pgd,mm) processor.pgtable.set_pgd(pgd,mm)
#define cpu_set_pmd(pmdp, pmd) processor.pgtable.set_pmd(pmdp, pmd) #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_set_pte(ptep, pte) processor.pgtable.set_pte(ptep, pte)
#define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd))) #define cpu_switch_mm(pgd,mm) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)),mm)
#define cpu_get_pgd() \ #define cpu_get_pgd() \
({ \ ({ \
......
...@@ -44,15 +44,14 @@ ...@@ -44,15 +44,14 @@
#include <asm/memory.h> #include <asm/memory.h>
#include <asm/page.h> #include <asm/page.h>
/* forward declare task_struct */ struct mm_struct;
struct task_struct;
/* declare all the functions as extern */ /* declare all the functions as extern */
extern void cpu_data_abort(unsigned long pc); extern void cpu_data_abort(unsigned long pc);
extern void cpu_check_bugs(void); extern void cpu_check_bugs(void);
extern void cpu_proc_init(void); extern void cpu_proc_init(void);
extern void cpu_proc_fin(void); extern void cpu_proc_fin(void);
extern int cpu_do_idle(int mode); extern int cpu_do_idle(void);
extern void cpu_cache_clean_invalidate_all(void); extern void cpu_cache_clean_invalidate_all(void);
extern void cpu_cache_clean_invalidate_range(unsigned long address, unsigned long end, int flags); extern void cpu_cache_clean_invalidate_range(unsigned long address, unsigned long end, int flags);
...@@ -65,13 +64,13 @@ extern void cpu_dcache_clean_entry(unsigned long address); ...@@ -65,13 +64,13 @@ extern void cpu_dcache_clean_entry(unsigned long address);
extern void cpu_icache_invalidate_range(unsigned long start, unsigned long end); extern void cpu_icache_invalidate_range(unsigned long start, unsigned long end);
extern void cpu_icache_invalidate_page(void *virt_page); extern void cpu_icache_invalidate_page(void *virt_page);
extern void cpu_set_pgd(unsigned long pgd_phys); extern void cpu_set_pgd(unsigned long pgd_phys, struct mm_struct *mm);
extern void cpu_set_pmd(pmd_t *pmdp, pmd_t pmd); 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_set_pte(pte_t *ptep, pte_t pte);
extern volatile void cpu_reset(unsigned long addr); extern volatile void cpu_reset(unsigned long addr);
#define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd))) #define cpu_switch_mm(pgd,mm) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)),mm)
#define cpu_get_pgd() \ #define cpu_get_pgd() \
({ \ ({ \
......
...@@ -26,9 +26,7 @@ ...@@ -26,9 +26,7 @@
#define SA1111_v2p( x ) ((x) - SA1111_VBASE + SA1111_BASE) #define SA1111_v2p( x ) ((x) - SA1111_VBASE + SA1111_BASE)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#define _SA1111(x) ((x) + sa1111->resource.start)
extern struct resource sa1111_resource;
#define _SA1111(x) ((x) + sa1111_resource.start)
#endif #endif
/* /*
...@@ -51,7 +49,8 @@ extern struct resource sa1111_resource; ...@@ -51,7 +49,8 @@ extern struct resource sa1111_resource;
*/ */
#define __CCREG(x) __REGP(SA1111_VBASE + (x)) #define __CCREG(x) __REGP(SA1111_VBASE + (x))
/* System Bus Interface (SBI) /*
* System Bus Interface (SBI)
* *
* Registers * Registers
* SKCR Control Register * SKCR Control Register
...@@ -127,28 +126,37 @@ extern struct resource sa1111_resource; ...@@ -127,28 +126,37 @@ extern struct resource sa1111_resource;
* SKPEN1 PWM1 Enable Register * SKPEN1 PWM1 Enable Register
* SKPWM1 PWM1 Clock Register * SKPWM1 PWM1 Clock Register
*/ */
#define SA1111_SKPCR 0x0200
#define _SKPCR _SA1111(0x0200) #define SA1111_SKCDR 0x0204
#define _SKCDR _SA1111(0x0204) #define SA1111_SKAUD 0x0208
#define _SKAUD _SA1111(0x0208) #define SA1111_SKPMC 0x020c
#define _SKPMC _SA1111(0x020c) #define SA1111_SKPTC 0x0210
#define _SKPTC _SA1111(0x0210) #define SA1111_SKPEN0 0x0214
#define _SKPEN0 _SA1111(0x0214) #define SA1111_SKPWN0 0x0218
#define _SKPWM0 _SA1111(0x0218) #define SA1111_SKPEN1 0x021c
#define _SKPEN1 _SA1111(0x021c) #define SA1111_SKPWM1 0x0220
#define _SKPWM1 _SA1111(0x0220)
#define _SKPCR _SA1111(SA1111_SKPCR)
#define _SKCDR _SA1111(SA1111_SKCDR)
#define _SKAUD _SA1111(SA1111_SKAUD)
#define _SKPMC _SA1111(SA1111_SKPMC)
#define _SKPTC _SA1111(SA1111_SKPTC)
#define _SKPEN0 _SA1111(SA1111_SKPEN0)
#define _SKPWM0 _SA1111(SA1111_SKPWM0)
#define _SKPEN1 _SA1111(SA1111_SKPEN1)
#define _SKPWM1 _SA1111(SA1111_SKPWM1)
#if LANGUAGE == C #if LANGUAGE == C
#define SKPCR __CCREG(0x0200) #define SKPCR __CCREG(SA1111_SKPCR)
#define SKCDR __CCREG(0x0204) #define SKCDR __CCREG(SA1111_SKCDR)
#define SKAUD __CCREG(0x0208) #define SKAUD __CCREG(SA1111_SKAUD)
#define SKPMC __CCREG(0x020c) #define SKPMC __CCREG(SA1111_SKPMC)
#define SKPTC __CCREG(0x0210) #define SKPTC __CCREG(SA1111_SKPTC)
#define SKPEN0 __CCREG(0x0214) #define SKPEN0 __CCREG(SA1111_SKPEN0)
#define SKPWM0 __CCREG(0x0218) #define SKPWM0 __CCREG(SA1111_SKPWM0)
#define SKPEN1 __CCREG(0x021c) #define SKPEN1 __CCREG(SA1111_SKPEN1)
#define SKPWM1 __CCREG(0x0220) #define SKPWM1 __CCREG(SA1111_SKPWM1)
#endif /* LANGUAGE == C */ #endif /* LANGUAGE == C */
...@@ -675,4 +683,12 @@ extern struct resource sa1111_resource; ...@@ -675,4 +683,12 @@ extern struct resource sa1111_resource;
#define PCSSR_S0_SLEEP (1<<0) #define PCSSR_S0_SLEEP (1<<0)
#define PCSSR_S1_SLEEP (1<<1) #define PCSSR_S1_SLEEP (1<<1)
struct sa1111_device {
struct device dev;
struct resource resource;
void *base;
};
extern struct sa1111_device *sa1111;
#endif /* _ASM_ARCH_SA1111 */ #endif /* _ASM_ARCH_SA1111 */
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/memory.h> #include <asm/memory.h>
...@@ -269,13 +270,22 @@ extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle); ...@@ -269,13 +270,22 @@ extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle);
extern void consistent_sync(void *vaddr, size_t size, int rw); extern void consistent_sync(void *vaddr, size_t size, int rw);
/* /*
* FIXME: I'm sure these will need to be changed for DISCONTIG * Change "struct page" to physical address.
*/ */
#ifdef CONFIG_DISCONTIG
#define page_to_phys(page) \
((((page) - page_zone(page)->zone_mem_map) << PAGE_SHIFT) \
+ page_zone(page)->zone_start_paddr)
#else
#define page_to_phys(page) \
(PHYS_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
#endif
/* /*
* Change "struct page" to physical address. * We should really eliminate virt_to_bus() here - it's depreciated.
*/ */
#define page_to_phys(page) (PHYS_OFFSET + ((page - mem_map) << PAGE_SHIFT)) #define page_to_bus(page) \
#define page_to_bus(page) (PHYS_OFFSET + ((page - mem_map) << PAGE_SHIFT)) (virt_to_bus(page_address(page)))
/* /*
* can the hardware map this into one segment or not, given no other * can the hardware map this into one segment or not, given no other
......
...@@ -43,7 +43,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, ...@@ -43,7 +43,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk, unsigned int cpu) struct task_struct *tsk, unsigned int cpu)
{ {
if (prev != next) if (prev != next)
cpu_switch_mm(next->pgd, tsk); cpu_switch_mm(next->pgd, next);
} }
#define activate_mm(prev, next) \ #define activate_mm(prev, next) \
......
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