Commit 8218f1ac authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-isdn.bkbits.net/linux-2.5.make

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 7a569667 0c686811
...@@ -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
...@@ -33,9 +33,9 @@ static void inline flush_all (void) ...@@ -33,9 +33,9 @@ static void inline flush_all (void)
* P4/Xeon Thermal transition interrupt handler * P4/Xeon Thermal transition interrupt handler
*/ */
#ifdef CONFIG_X86_LOCAL_APIC
static void intel_thermal_interrupt(struct pt_regs *regs) static void intel_thermal_interrupt(struct pt_regs *regs)
{ {
#ifdef CONFIG_X86_LOCAL_APIC
u32 l, h; u32 l, h;
unsigned int cpu = smp_processor_id(); unsigned int cpu = smp_processor_id();
...@@ -48,8 +48,8 @@ static void intel_thermal_interrupt(struct pt_regs *regs) ...@@ -48,8 +48,8 @@ static void intel_thermal_interrupt(struct pt_regs *regs)
} else { } else {
printk(KERN_INFO "CPU#%d: Temperature/speed normal\n", cpu); printk(KERN_INFO "CPU#%d: Temperature/speed normal\n", cpu);
} }
#endif
} }
#endif
static void unexpected_thermal_interrupt(struct pt_regs *regs) static void unexpected_thermal_interrupt(struct pt_regs *regs)
{ {
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/mc146818rtc.h> #include <linux/mc146818rtc.h>
#include <linux/compiler.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/smp.h> #include <asm/smp.h>
...@@ -183,6 +184,86 @@ static void clear_IO_APIC (void) ...@@ -183,6 +184,86 @@ static void clear_IO_APIC (void)
clear_IO_APIC_pin(apic, pin); clear_IO_APIC_pin(apic, pin);
} }
static void set_ioapic_affinity (unsigned int irq, unsigned long mask)
{
unsigned long flags;
/*
* Only the first 8 bits are valid.
*/
mask = mask << 24;
spin_lock_irqsave(&ioapic_lock, flags);
__DO_ACTION(1, = mask, )
spin_unlock_irqrestore(&ioapic_lock, flags);
}
#if CONFIG_SMP
typedef struct {
unsigned int cpu;
unsigned long timestamp;
} ____cacheline_aligned irq_balance_t;
static irq_balance_t irq_balance[NR_IRQS] __cacheline_aligned
= { [ 0 ... NR_IRQS-1 ] = { 1, 0 } };
extern unsigned long irq_affinity [NR_IRQS];
#endif
#define IDLE_ENOUGH(cpu,now) \
(idle_cpu(cpu) && ((now) - irq_stat[(cpu)].idle_timestamp > 1))
#define IRQ_ALLOWED(cpu,allowed_mask) \
((1 << cpu) & (allowed_mask))
static unsigned long move(int curr_cpu, unsigned long allowed_mask, unsigned long now, int direction)
{
int search_idle = 1;
int cpu = curr_cpu;
goto inside;
do {
if (unlikely(cpu == curr_cpu))
search_idle = 0;
inside:
if (direction == 1) {
cpu++;
if (cpu >= smp_num_cpus)
cpu = 0;
} else {
cpu--;
if (cpu == -1)
cpu = smp_num_cpus-1;
}
} while (!IRQ_ALLOWED(cpu,allowed_mask) ||
(search_idle && !IDLE_ENOUGH(cpu,now)));
return cpu;
}
static inline void balance_irq(int irq)
{
#if CONFIG_SMP
irq_balance_t *entry = irq_balance + irq;
unsigned long now = jiffies;
if (unlikely(entry->timestamp != now)) {
unsigned long allowed_mask;
int random_number;
rdtscl(random_number);
random_number &= 1;
allowed_mask = cpu_online_map & irq_affinity[irq];
entry->timestamp = now;
entry->cpu = move(entry->cpu, allowed_mask, now, random_number);
set_ioapic_affinity(irq, 1 << entry->cpu);
}
#endif
}
/* /*
* support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
* specific CPU-side IRQs. * specific CPU-side IRQs.
...@@ -672,8 +753,7 @@ void __init setup_IO_APIC_irqs(void) ...@@ -672,8 +753,7 @@ void __init setup_IO_APIC_irqs(void)
} }
/* /*
* Set up the 8259A-master output pin as broadcast to all * Set up the 8259A-master output pin:
* CPUs.
*/ */
void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector) void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector)
{ {
...@@ -1193,6 +1273,7 @@ static unsigned int startup_edge_ioapic_irq(unsigned int irq) ...@@ -1193,6 +1273,7 @@ static unsigned int startup_edge_ioapic_irq(unsigned int irq)
*/ */
static void ack_edge_ioapic_irq(unsigned int irq) static void ack_edge_ioapic_irq(unsigned int irq)
{ {
balance_irq(irq);
if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED)) if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
== (IRQ_PENDING | IRQ_DISABLED)) == (IRQ_PENDING | IRQ_DISABLED))
mask_IO_APIC_irq(irq); mask_IO_APIC_irq(irq);
...@@ -1232,6 +1313,7 @@ static void end_level_ioapic_irq (unsigned int irq) ...@@ -1232,6 +1313,7 @@ static void end_level_ioapic_irq (unsigned int irq)
unsigned long v; unsigned long v;
int i; int i;
balance_irq(irq);
/* /*
* It appears there is an erratum which affects at least version 0x11 * It appears there is an erratum which affects at least version 0x11
* of I/O APIC (that's the 82093AA and cores integrated into various * of I/O APIC (that's the 82093AA and cores integrated into various
...@@ -1288,19 +1370,6 @@ static void end_level_ioapic_irq (unsigned int irq) ...@@ -1288,19 +1370,6 @@ static void end_level_ioapic_irq (unsigned int irq)
static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ } static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ }
static void set_ioapic_affinity (unsigned int irq, unsigned long mask)
{
unsigned long flags;
/*
* Only the first 8 bits are valid.
*/
mask = mask << 24;
spin_lock_irqsave(&ioapic_lock, flags);
__DO_ACTION(1, = mask, )
spin_unlock_irqrestore(&ioapic_lock, flags);
}
/* /*
* Level and edge triggered IO-APIC interrupts need different handling, * Level and edge triggered IO-APIC interrupts need different handling,
* so we use two separate IRQ descriptors. Edge triggered IRQs can be * so we use two separate IRQ descriptors. Edge triggered IRQs can be
......
...@@ -1073,7 +1073,7 @@ static unsigned int parse_hex_value (const char *buffer, ...@@ -1073,7 +1073,7 @@ static unsigned int parse_hex_value (const char *buffer,
static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
static int irq_affinity_read_proc (char *page, char **start, off_t off, static int irq_affinity_read_proc (char *page, char **start, off_t off,
int count, int *eof, void *data) int count, int *eof, void *data)
{ {
......
...@@ -142,6 +142,7 @@ void cpu_idle (void) ...@@ -142,6 +142,7 @@ void cpu_idle (void)
void (*idle)(void) = pm_idle; void (*idle)(void) = pm_idle;
if (!idle) if (!idle)
idle = default_idle; idle = default_idle;
irq_stat[smp_processor_id()].idle_timestamp = jiffies;
while (!need_resched()) while (!need_resched())
idle(); idle();
schedule(); schedule();
......
...@@ -753,9 +753,17 @@ CONFIG_BLK_DEV_IDE_TCQ ...@@ -753,9 +753,17 @@ CONFIG_BLK_DEV_IDE_TCQ
If you have such a drive, say Y here. If you have such a drive, say Y here.
CONFIG_BLK_DEV_IDE_TCQ_DEFAULT CONFIG_BLK_DEV_IDE_TCQ_FULL
Enabled tagged command queueing unconditionally on drives that report When a command completes from the drive, the SERVICE bit is checked to
support for it. see if other queued commands are ready to be started. Doing this
immediately after a command completes has a tendency to 'starve' the
device hardware queue, since we risk emptying the queue completely
before starting any new commands. This shows up during stressing the
drive as a /\/\/\/\ queue size balance, where we could instead try and
maintain a minimum queue size and get a /---------\ graph instead.
Saying Y here will attempt to always keep the queue full when possible
at the cost of possibly increasing command turn-around latency.
Generally say Y here. Generally say Y here.
...@@ -766,6 +774,18 @@ CONFIG_BLK_DEV_IDE_TCQ_DEPTH ...@@ -766,6 +774,18 @@ CONFIG_BLK_DEV_IDE_TCQ_DEPTH
You probably just want the default of 32 here. If you enter an invalid You probably just want the default of 32 here. If you enter an invalid
number, the default value will be used. number, the default value will be used.
CONFIG_BLK_DEV_IDE_TCQ_DEFAULT
Enabled tagged command queueing unconditionally on drives that report
support for it. Regardless of the chosen value here, tagging can be
controlled at run time:
echo "using_tcq:32" > /proc/ide/hdX/settings
where any value between 1-32 selects chosen queue depth and enables
TCQ, and 0 disables it.
Generally say Y here.
CONFIG_BLK_DEV_IT8172 CONFIG_BLK_DEV_IT8172
Say Y here to support the on-board IDE controller on the Integrated Say Y here to support the on-board IDE controller on the Integrated
Technology Express, Inc. ITE8172 SBC. Vendor page at Technology Express, Inc. ITE8172 SBC. Vendor page at
......
...@@ -48,10 +48,11 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then ...@@ -48,10 +48,11 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
dep_bool ' Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO dep_bool ' Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO
define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' ATA tagged command queueing' CONFIG_BLK_DEV_IDE_TCQ $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' ATA tagged command queueing' CONFIG_BLK_DEV_IDE_TCQ $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' TCQ on by default' CONFIG_BLK_DEV_IDE_TCQ_DEFAULT $CONFIG_BLK_DEV_IDE_TCQ dep_bool ' Attempt to keep queue full' CONFIG_BLK_DEV_IDE_TCQ_FULL $CONFIG_BLK_DEV_IDE_TCQ
if [ $CONFIG_BLK_DEV_IDE_TCQ_DEFAULT != "n" ]; then dep_bool ' TCQ on by default' CONFIG_BLK_DEV_IDE_TCQ_DEFAULT $CONFIG_BLK_DEV_IDE_TCQ
int ' Default queue depth' CONFIG_BLK_DEV_IDE_TCQ_DEPTH 32 if [ "$CONFIG_BLK_DEV_IDE_TCQ" != "n" ]; then
fi int ' Default queue depth' CONFIG_BLK_DEV_IDE_TCQ_DEPTH 8
fi
dep_bool ' ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL dep_bool ' ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL
dep_bool ' Good-Bad DMA Model-Firmware (WIP)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_IDEDMA_PCI_WIP dep_bool ' Good-Bad DMA Model-Firmware (WIP)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_IDEDMA_PCI_WIP
dep_bool ' AEC62XX chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' AEC62XX chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI
......
This diff is collapsed.
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
memory, though. */ memory, though. */
#ifndef VERBOSE_IDE_CD_ERRORS #ifndef VERBOSE_IDE_CD_ERRORS
#define VERBOSE_IDE_CD_ERRORS 1 # define VERBOSE_IDE_CD_ERRORS 1
#endif #endif
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
this will give you a slightly smaller kernel. */ this will give you a slightly smaller kernel. */
#ifndef STANDARD_ATAPI #ifndef STANDARD_ATAPI
#define STANDARD_ATAPI 0 # define STANDARD_ATAPI 0
#endif #endif
...@@ -32,14 +32,14 @@ ...@@ -32,14 +32,14 @@
This is apparently needed for supermount. */ This is apparently needed for supermount. */
#ifndef NO_DOOR_LOCKING #ifndef NO_DOOR_LOCKING
#define NO_DOOR_LOCKING 0 # define NO_DOOR_LOCKING 0
#endif #endif
/************************************************************************/ /************************************************************************/
#define SECTOR_BITS 9 #define SECTOR_BITS 9
#ifndef SECTOR_SIZE #ifndef SECTOR_SIZE
#define SECTOR_SIZE (1 << SECTOR_BITS) # define SECTOR_SIZE (1 << SECTOR_BITS)
#endif #endif
#define SECTORS_PER_FRAME (CD_FRAMESIZE >> SECTOR_BITS) #define SECTORS_PER_FRAME (CD_FRAMESIZE >> SECTOR_BITS)
#define SECTOR_BUFFER_SIZE (CD_FRAMESIZE * 32) #define SECTOR_BUFFER_SIZE (CD_FRAMESIZE * 32)
...@@ -50,12 +50,6 @@ ...@@ -50,12 +50,6 @@
#define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b))
/* special command codes for strategy routine. */
#define PACKET_COMMAND 4315
#define REQUEST_SENSE_COMMAND 4316
#define RESET_DRIVE_COMMAND 4317
/* Configuration flags. These describe the capabilities of the drive. /* Configuration flags. These describe the capabilities of the drive.
They generally do not change after initialization, unless we learn They generally do not change after initialization, unless we learn
more about the drive from stuff failing. */ more about the drive from stuff failing. */
...@@ -90,7 +84,6 @@ struct ide_cd_config_flags { ...@@ -90,7 +84,6 @@ struct ide_cd_config_flags {
}; };
#define CDROM_CONFIG_FLAGS(drive) (&(((struct cdrom_info *)(drive->driver_data))->config_flags)) #define CDROM_CONFIG_FLAGS(drive) (&(((struct cdrom_info *)(drive->driver_data))->config_flags))
/* State flags. These give information about the current state of the /* State flags. These give information about the current state of the
drive, and will change during normal operation. */ drive, and will change during normal operation. */
struct ide_cd_state_flags { struct ide_cd_state_flags {
...@@ -111,24 +104,23 @@ struct packet_command { ...@@ -111,24 +104,23 @@ struct packet_command {
int quiet; int quiet;
int timeout; int timeout;
struct request_sense *sense; struct request_sense *sense;
unsigned char c[12];
}; };
/* Structure of a MSF cdrom address. */ /* Structure of a MSF cdrom address. */
struct atapi_msf { struct atapi_msf {
byte reserved; u8 __reserved;
byte minute; u8 minute;
byte second; u8 second;
byte frame; u8 frame;
}; } __attribute__((packed));
/* Space to hold the disk TOC. */ /* Space to hold the disk TOC. */
#define MAX_TRACKS 99 #define MAX_TRACKS 99
struct atapi_toc_header { struct atapi_toc_header {
unsigned short toc_length; u16 toc_length;
byte first_track; u8 first_track;
byte last_track; u8 last_track;
}; } __attribute__((packed));
struct atapi_toc_entry { struct atapi_toc_entry {
byte reserved1; byte reserved1;
...@@ -162,17 +154,17 @@ struct atapi_toc { ...@@ -162,17 +154,17 @@ struct atapi_toc {
/* This structure is annoyingly close to, but not identical with, /* This structure is annoyingly close to, but not identical with,
the cdrom_subchnl structure from cdrom.h. */ the cdrom_subchnl structure from cdrom.h. */
struct atapi_cdrom_subchnl { struct atapi_cdrom_subchnl {
u_char acdsc_reserved; u8 acdsc_reserved;
u_char acdsc_audiostatus; u8 acdsc_audiostatus;
u_short acdsc_length; u16 acdsc_length;
u_char acdsc_format; u8 acdsc_format;
#if defined(__BIG_ENDIAN_BITFIELD) #if defined(__BIG_ENDIAN_BITFIELD)
u_char acdsc_ctrl: 4; u8 acdsc_ctrl: 4;
u_char acdsc_adr: 4; u8 acdsc_adr: 4;
#elif defined(__LITTLE_ENDIAN_BITFIELD) #elif defined(__LITTLE_ENDIAN_BITFIELD)
u_char acdsc_adr: 4; u8 acdsc_adr: 4;
u_char acdsc_ctrl: 4; u8 acdsc_ctrl: 4;
#else #else
#error "Please fix <asm/byteorder.h>" #error "Please fix <asm/byteorder.h>"
#endif #endif
......
...@@ -107,10 +107,7 @@ static u8 get_command(ide_drive_t *drive, int cmd) ...@@ -107,10 +107,7 @@ static u8 get_command(ide_drive_t *drive, int cmd)
* 48-bit commands are pretty sanely laid out * 48-bit commands are pretty sanely laid out
*/ */
if (lba48bit) { if (lba48bit) {
if (cmd == READ) command = cmd == READ ? WIN_READ_EXT : WIN_WRITE_EXT;
command = WIN_READ_EXT;
else
command = WIN_WRITE_EXT;
if (drive->using_dma) { if (drive->using_dma) {
command++; /* WIN_*DMA_EXT */ command++; /* WIN_*DMA_EXT */
...@@ -118,31 +115,33 @@ static u8 get_command(ide_drive_t *drive, int cmd) ...@@ -118,31 +115,33 @@ static u8 get_command(ide_drive_t *drive, int cmd)
command++; /* WIN_*DMA_QUEUED_EXT */ command++; /* WIN_*DMA_QUEUED_EXT */
} else if (drive->mult_count) } else if (drive->mult_count)
command += 5; /* WIN_MULT*_EXT */ command += 5; /* WIN_MULT*_EXT */
} else {
/* return command;
* 28-bit commands seem not to be, though... }
*/
if (cmd == READ) { /*
if (drive->using_dma) { * 28-bit commands seem not to be, though...
if (drive->using_tcq) */
command = WIN_READDMA_QUEUED; if (cmd == READ) {
else if (drive->using_dma) {
command = WIN_READDMA; if (drive->using_tcq)
} else if (drive->mult_count) command = WIN_READDMA_QUEUED;
command = WIN_MULTREAD;
else else
command = WIN_READ; command = WIN_READDMA;
} else { } else if (drive->mult_count)
if (drive->using_dma) { command = WIN_MULTREAD;
if (drive->using_tcq) else
command = WIN_WRITEDMA_QUEUED; command = WIN_READ;
else } else {
command = WIN_WRITEDMA; if (drive->using_dma) {
} else if (drive->mult_count) if (drive->using_tcq)
command = WIN_MULTWRITE; command = WIN_WRITEDMA_QUEUED;
else else
command = WIN_WRITE; command = WIN_WRITEDMA;
} } else if (drive->mult_count)
command = WIN_MULTWRITE;
else
command = WIN_WRITE;
} }
return command; return command;
...@@ -895,24 +894,24 @@ static int proc_idedisk_read_tcq ...@@ -895,24 +894,24 @@ static int proc_idedisk_read_tcq
__set_bit(i, &tag_mask); __set_bit(i, &tag_mask);
len += sprintf(out+len, "%d, ", i); len += sprintf(out+len, "%d, ", i);
if (ar->ar_time > max_jif) if (cur_jif - ar->ar_time > max_jif)
max_jif = ar->ar_time; max_jif = cur_jif - ar->ar_time;
cmds++; cmds++;
} }
len += sprintf(out+len, "]\n"); len += sprintf(out+len, "]\n");
len += sprintf(out+len, "Queue:\t\t\treleased [ %d ] - started [ %d ]\n", drive->tcq->immed_rel, drive->tcq->immed_comp);
if (drive->tcq->queued != cmds) if (drive->tcq->queued != cmds)
len += sprintf(out+len, "pending request and queue count mismatch (%d)\n", cmds); len += sprintf(out+len, "pending request and queue count mismatch (counted: %d)\n", cmds);
if (tag_mask != drive->tcq->tag_mask) if (tag_mask != drive->tcq->tag_mask)
len += sprintf(out+len, "tag masks differ (counted %lx != %lx\n", tag_mask, drive->tcq->tag_mask); len += sprintf(out+len, "tag masks differ (counted %lx != %lx\n", tag_mask, drive->tcq->tag_mask);
len += sprintf(out+len, "DMA status:\t\t%srunning\n", test_bit(IDE_DMA, &HWGROUP(drive)->flags) ? "" : "not "); len += sprintf(out+len, "DMA status:\t\t%srunning\n", test_bit(IDE_DMA, &HWGROUP(drive)->flags) ? "" : "not ");
if (max_jif) len += sprintf(out+len, "Oldest command:\t\t%lu jiffies\n", max_jif);
len += sprintf(out+len, "Oldest command:\t\t%lu\n", cur_jif - max_jif); len += sprintf(out+len, "Oldest command ever:\t%lu\n", drive->tcq->oldest_command);
len += sprintf(out+len, "immed rel %d, immed comp %d\n", drive->tcq->immed_rel, drive->tcq->immed_comp);
drive->tcq->max_last_depth = 0; drive->tcq->max_last_depth = 0;
...@@ -1017,8 +1016,10 @@ static int set_using_tcq(ide_drive_t *drive, int arg) ...@@ -1017,8 +1016,10 @@ static int set_using_tcq(ide_drive_t *drive, int arg)
return -EPERM; return -EPERM;
if (!drive->channel->dmaproc) if (!drive->channel->dmaproc)
return -EPERM; return -EPERM;
if (arg == drive->queue_depth && drive->using_tcq)
return 0;
drive->using_tcq = arg; drive->queue_depth = arg ? arg : 1;
if (drive->channel->dmaproc(arg ? ide_dma_queued_on : ide_dma_queued_off, drive)) if (drive->channel->dmaproc(arg ? ide_dma_queued_on : ide_dma_queued_off, drive))
return -EIO; return -EIO;
......
...@@ -610,9 +610,6 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) ...@@ -610,9 +610,6 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
case ide_dma_check: case ide_dma_check:
return config_drive_for_dma (drive); return config_drive_for_dma (drive);
case ide_dma_begin: case ide_dma_begin:
#ifdef DEBUG
printk("ide_dma_begin: from %p\n", __builtin_return_address(0));
#endif
if (test_and_set_bit(IDE_DMA, &HWGROUP(drive)->flags)) if (test_and_set_bit(IDE_DMA, &HWGROUP(drive)->flags))
BUG(); BUG();
/* Note that this is done *after* the cmd has /* Note that this is done *after* the cmd has
...@@ -634,14 +631,13 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) ...@@ -634,14 +631,13 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
case ide_dma_read: case ide_dma_read:
reading = 1 << 3; reading = 1 << 3;
case ide_dma_write: case ide_dma_write:
ar = HWGROUP(drive)->rq->special; ar = IDE_CUR_AR(drive);
if (ide_start_dma(hwif, drive, func)) if (ide_start_dma(hwif, drive, func))
return 1; return 1;
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return 0; return 0;
BUG_ON(HWGROUP(drive)->handler); BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */
if ((ar->ar_rq->flags & REQ_DRIVE_TASKFILE) && if ((ar->ar_rq->flags & REQ_DRIVE_TASKFILE) &&
...@@ -655,20 +651,13 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) ...@@ -655,20 +651,13 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
} }
return hwif->dmaproc(ide_dma_begin, drive); return hwif->dmaproc(ide_dma_begin, drive);
case ide_dma_end: /* returns 1 on error, 0 otherwise */ case ide_dma_end: /* returns 1 on error, 0 otherwise */
#ifdef DEBUG if (!test_and_clear_bit(IDE_DMA, &HWGROUP(drive)->flags))
printk("ide_dma_end: from %p\n", __builtin_return_address(0)); BUG();
#endif
if (!test_and_clear_bit(IDE_DMA, &HWGROUP(drive)->flags)) {
printk("ide_dma_end: dma not going? %p\n", __builtin_return_address(0));
return 1;
}
drive->waiting_for_dma = 0; drive->waiting_for_dma = 0;
outb(inb(dma_base)&~1, dma_base); /* stop DMA */ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
dma_stat = inb(dma_base+2); /* get DMA status */ dma_stat = inb(dma_base+2); /* get DMA status */
outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
ide_destroy_dmatable(drive); /* purge DMA mappings */ ide_destroy_dmatable(drive); /* purge DMA mappings */
if (drive->tcq)
IDE_SET_CUR_TAG(drive, -1);
return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; /* verify good DMA status */ return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; /* verify good DMA status */
case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */ case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
dma_stat = inb(dma_base+2); dma_stat = inb(dma_base+2);
......
...@@ -192,19 +192,16 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ...@@ -192,19 +192,16 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
/* /*
* it's an ata drive, build command list * it's an ata drive, build command list
*/ */
#ifndef CONFIG_BLK_DEV_IDE_TCQ
drive->queue_depth = 1; drive->queue_depth = 1;
#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEPTH
drive->queue_depth = CONFIG_BLK_DEV_IDE_TCQ_DEPTH;
#else #else
# ifndef CONFIG_BLK_DEV_IDE_TCQ_DEPTH
# define CONFIG_BLK_DEV_IDE_TCQ_DEPTH 1
# endif
drive->queue_depth = drive->id->queue_depth + 1; drive->queue_depth = drive->id->queue_depth + 1;
if (drive->queue_depth > CONFIG_BLK_DEV_IDE_TCQ_DEPTH) #endif
drive->queue_depth = CONFIG_BLK_DEV_IDE_TCQ_DEPTH;
if (drive->queue_depth < 1 || drive->queue_depth > IDE_MAX_TAG) if (drive->queue_depth < 1 || drive->queue_depth > IDE_MAX_TAG)
drive->queue_depth = IDE_MAX_TAG; drive->queue_depth = IDE_MAX_TAG;
#endif
if (ide_build_commandlist(drive)) if (ide_init_commandlist(drive))
goto err_misc; goto err_misc;
return; return;
......
...@@ -980,7 +980,7 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -980,7 +980,7 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
/* FIXME: Do we really have to zero out the buffer? /* FIXME: Do we really have to zero out the buffer?
*/ */
memset(argbuf, 0, 4 + SECTOR_WORDS * 4 * vals[3]); memset(argbuf, 4, SECTOR_WORDS * 4 * vals[3]);
ide_init_drive_cmd(&rq); ide_init_drive_cmd(&rq);
rq.buffer = argbuf; rq.buffer = argbuf;
memcpy(argbuf, vals, 4); memcpy(argbuf, vals, 4);
......
This diff is collapsed.
This diff is collapsed.
...@@ -648,6 +648,12 @@ ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigne ...@@ -648,6 +648,12 @@ ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigne
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr)); memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
/* The four drives on the two logical (one physical) interfaces
are distinguished by writing the drive number (0-3) to the
Feature register.
FIXME: Is promise_selectproc now redundant??
*/
taskfile.feature = (drive->channel->unit << 1) + drive->select.b.unit;
taskfile.sector_count = rq->nr_sectors; taskfile.sector_count = rq->nr_sectors;
taskfile.sector_number = block; taskfile.sector_number = block;
taskfile.low_cylinder = (block>>=8); taskfile.low_cylinder = (block>>=8);
......
...@@ -1704,8 +1704,8 @@ cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -1704,8 +1704,8 @@ cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
* Use MCLK from BIOS. FIXME: what about hotplug? * Use MCLK from BIOS. FIXME: what about hotplug?
*/ */
#ifndef __arm__ #ifndef __arm__
cfb->mclk_mult = cyber2000_grphr(MCLK_MULT, cfb); cfb->mclk_mult = cyber2000_grphr(EXT_MCLK_MULT, cfb);
cfb->mclk_div = cyber2000_grphr(MCLK_DIV, cfb); cfb->mclk_div = cyber2000_grphr(EXT_MCLK_DIV, cfb);
#else #else
/* /*
* MCLK on the NetWinder and the Shark is fixed at 75MHz * MCLK on the NetWinder and the Shark is fixed at 75MHz
......
...@@ -2365,7 +2365,7 @@ int __init neofb_setup (char *options) ...@@ -2365,7 +2365,7 @@ int __init neofb_setup (char *options)
if (!options || !*options) if (!options || !*options)
return 0; return 0;
for (this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) while ((this_opt = strsep(&options,",")) != NULL)
{ {
if (!*this_opt) continue; if (!*this_opt) continue;
......
...@@ -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) \
......
...@@ -95,30 +95,25 @@ pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int di ...@@ -95,30 +95,25 @@ pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int di
/* nothing to do */ /* nothing to do */
} }
/* Whether pci_unmap_{single,page} is a nop depends upon the /*
* Whether pci_unmap_{single,page} is a nop depends upon the
* configuration. * configuration.
*/ */
#ifdef CONFIG_SA1111 #ifdef CONFIG_PCI
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME;
dma_addr_t ADDR_NAME; #define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME;
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \ #define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME)
__u32 LEN_NAME; #define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL))
#define pci_unmap_addr(PTR, ADDR_NAME) \ #define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
((PTR)->ADDR_NAME) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \ #else
(((PTR)->ADDR_NAME) = (VAL))
#define pci_unmap_len(PTR, LEN_NAME) \
((PTR)->LEN_NAME)
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
(((PTR)->LEN_NAME) = (VAL))
#else /* !(CONFIG_SA1111) */
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) #define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
#define pci_unmap_addr(PTR, ADDR_NAME) (0) #define pci_unmap_addr(PTR, ADDR_NAME) (0)
#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0) #define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
#define pci_unmap_len(PTR, LEN_NAME) (0) #define pci_unmap_len(PTR, LEN_NAME) (0)
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
#endif /* CONFIG_SA1111 */ #endif /* CONFIG_PCI */
/* Map a set of buffers described by scatterlist in streaming /* Map a set of buffers described by scatterlist in streaming
* mode for DMA. This is the scather-gather version of the * mode for DMA. This is the scather-gather version of the
......
...@@ -12,6 +12,7 @@ typedef struct { ...@@ -12,6 +12,7 @@ typedef struct {
unsigned int __local_bh_count; unsigned int __local_bh_count;
unsigned int __syscall_count; unsigned int __syscall_count;
struct task_struct * __ksoftirqd_task; /* waitqueue is too large */ struct task_struct * __ksoftirqd_task; /* waitqueue is too large */
unsigned long idle_timestamp;
unsigned int __nmi_count; /* arch dependent */ unsigned int __nmi_count; /* arch dependent */
} ____cacheline_aligned irq_cpustat_t; } ____cacheline_aligned irq_cpustat_t;
......
...@@ -273,19 +273,22 @@ typedef union { ...@@ -273,19 +273,22 @@ typedef union {
} b; } b;
} special_t; } special_t;
#define IDE_MAX_TAG 32 /* spec says 32 max */ #define IDE_MAX_TAG (32) /* spec says 32 max */
#define IDE_INACTIVE_TAG (-1)
struct ata_request; struct ata_request;
typedef struct ide_tag_info_s { typedef struct ide_tag_info_s {
unsigned long tag_mask; /* next tag bit mask */ unsigned long tag_mask; /* next tag bit mask */
struct ata_request *ar[IDE_MAX_TAG]; /* in-progress requests */ struct ata_request *ar[IDE_MAX_TAG]; /* in-progress requests */
int active_tag; /* current active tag */ int active_tag; /* current active tag */
int queued; /* current depth */ int queued; /* current depth */
/* /*
* stats -> * stats ->
*/ */
int max_depth; /* max depth ever */ int max_depth; /* max depth ever */
int max_last_depth; /* max since last check */ int max_last_depth; /* max since last check */
/* /*
...@@ -295,14 +298,19 @@ typedef struct ide_tag_info_s { ...@@ -295,14 +298,19 @@ typedef struct ide_tag_info_s {
*/ */
int immed_rel; int immed_rel;
int immed_comp; int immed_comp;
unsigned long oldest_command;
} ide_tag_info_t; } ide_tag_info_t;
#define IDE_GET_AR(drive, tag) ((drive)->tcq->ar[(tag)]) #define IDE_GET_AR(drive, tag) ((drive)->tcq->ar[(tag)])
#define IDE_CUR_TAG(drive) (IDE_GET_AR((drive), (drive)->tcq->active_tag)) #define IDE_CUR_TAG(drive) (IDE_GET_AR((drive), (drive)->tcq->active_tag))
#define IDE_SET_CUR_TAG(drive, tag) ((drive)->tcq->active_tag = (tag)) #define IDE_SET_CUR_TAG(drive, tag) \
do { \
((drive)->tcq->active_tag = (tag)); \
if ((tag) == IDE_INACTIVE_TAG) \
HWGROUP((drive))->rq = NULL; \
} while (0);
#define IDE_CUR_AR(drive) \ #define IDE_CUR_AR(drive) (HWGROUP((drive))->rq->special)
((drive)->using_tcq ? IDE_CUR_TAG((drive)) : HWGROUP((drive))->rq->special)
struct ide_settings_s; struct ide_settings_s;
...@@ -359,6 +367,7 @@ typedef struct ide_drive_s { ...@@ -359,6 +367,7 @@ typedef struct ide_drive_s {
unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */ unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */
unsigned remap_0_to_1 : 2; /* 0=remap if ezdrive, 1=remap, 2=noremap */ unsigned remap_0_to_1 : 2; /* 0=remap if ezdrive, 1=remap, 2=noremap */
unsigned ata_flash : 1; /* 1=present, 0=default */ unsigned ata_flash : 1; /* 1=present, 0=default */
unsigned service_pending: 1;
unsigned addressing; /* : 2; 0=28-bit, 1=48-bit, 2=64-bit */ unsigned addressing; /* : 2; 0=28-bit, 1=48-bit, 2=64-bit */
byte scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */ byte scsi; /* 0=default, 1=skip current ide-subdriver for ide-scsi emulation */
select_t select; /* basic drive/head select reg value */ select_t select; /* basic drive/head select reg value */
...@@ -546,7 +555,7 @@ extern void ide_unregister(struct ata_channel *hwif); ...@@ -546,7 +555,7 @@ extern void ide_unregister(struct ata_channel *hwif);
typedef enum { typedef enum {
ide_stopped, /* no drive operation was started */ ide_stopped, /* no drive operation was started */
ide_started, /* a drive operation was started, and a handler was set */ ide_started, /* a drive operation was started, and a handler was set */
ide_released /* started and released bus */ ide_released, /* started, handler set, bus released */
} ide_startstop_t; } ide_startstop_t;
/* /*
...@@ -980,6 +989,11 @@ extern void revalidate_drives(void); ...@@ -980,6 +989,11 @@ extern void revalidate_drives(void);
#define ATA_AR_SETUP 2 #define ATA_AR_SETUP 2
#define ATA_AR_RETURN 4 #define ATA_AR_RETURN 4
/*
* if turn-around time is longer than this, halve queue depth
*/
#define ATA_AR_MAX_TURNAROUND (3 * HZ)
#define list_ata_entry(entry) list_entry((entry), struct ata_request, ar_queue) #define list_ata_entry(entry) list_entry((entry), struct ata_request, ar_queue)
static inline void ata_ar_init(ide_drive_t *drive, struct ata_request *ar) static inline void ata_ar_init(ide_drive_t *drive, struct ata_request *ar)
...@@ -1026,7 +1040,7 @@ static inline void ata_ar_put(ide_drive_t *drive, struct ata_request *ar) ...@@ -1026,7 +1040,7 @@ static inline void ata_ar_put(ide_drive_t *drive, struct ata_request *ar)
ar->ar_rq = NULL; ar->ar_rq = NULL;
} }
extern inline int ide_get_tag(ide_drive_t *drive) static inline int ide_get_tag(ide_drive_t *drive)
{ {
int tag = ffz(drive->tcq->tag_mask); int tag = ffz(drive->tcq->tag_mask);
...@@ -1043,12 +1057,28 @@ extern inline int ide_get_tag(ide_drive_t *drive) ...@@ -1043,12 +1057,28 @@ extern inline int ide_get_tag(ide_drive_t *drive)
} }
#ifdef CONFIG_BLK_DEV_IDE_TCQ #ifdef CONFIG_BLK_DEV_IDE_TCQ
# define ide_pending_commands(drive) ((drive)->using_tcq && (drive)->tcq->queued) static inline int ide_pending_commands(ide_drive_t *drive)
{
if (!drive->tcq)
return 0;
return drive->tcq->queued;
}
static inline int ide_can_queue(ide_drive_t *drive)
{
if (!drive->tcq)
return 1;
return drive->tcq->queued < drive->queue_depth;
}
#else #else
# define ide_pending_commands(drive) 0 #define ide_pending_commands(drive) (0)
#define ide_can_queue(drive) (1)
#endif #endif
int ide_build_commandlist(ide_drive_t *); int ide_build_commandlist(ide_drive_t *);
int ide_init_commandlist(ide_drive_t *);
void ide_teardown_commandlist(ide_drive_t *); void ide_teardown_commandlist(ide_drive_t *);
int ide_tcq_dmaproc(ide_dma_action_t, ide_drive_t *); int ide_tcq_dmaproc(ide_dma_action_t, ide_drive_t *);
ide_startstop_t ide_start_tag(ide_dma_action_t, ide_drive_t *, struct ata_request *); ide_startstop_t ide_start_tag(ide_dma_action_t, ide_drive_t *, struct ata_request *);
......
...@@ -272,6 +272,10 @@ static void __init smp_init(void) ...@@ -272,6 +272,10 @@ static void __init smp_init(void)
#define smp_init() do { } while (0) #define smp_init() do { } while (0)
#endif #endif
static inline void setup_per_cpu_areas(void)
{
}
#else #else
#ifdef __GENERIC_PER_CPU #ifdef __GENERIC_PER_CPU
...@@ -296,10 +300,6 @@ static void __init setup_per_cpu_areas(void) ...@@ -296,10 +300,6 @@ static void __init setup_per_cpu_areas(void)
memcpy(ptr, __per_cpu_start, size); memcpy(ptr, __per_cpu_start, size);
} }
} }
#else
static inline void setup_per_cpu_areas(void)
{
}
#endif /* !__GENERIC_PER_CPU */ #endif /* !__GENERIC_PER_CPU */
/* Called by boot processor to activate the rest. */ /* Called by boot processor to activate the rest. */
......
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