summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/Kconfig3
-rw-r--r--arch/alpha/include/asm/io.h8
-rw-r--r--arch/alpha/kernel/Makefile4
-rw-r--r--arch/alpha/kernel/irq.c31
-rw-r--r--arch/alpha/kernel/irq_alpha.c24
-rw-r--r--arch/alpha/kernel/irq_i8259.c26
-rw-r--r--arch/alpha/kernel/irq_pyxis.c27
-rw-r--r--arch/alpha/kernel/irq_srm.c27
-rw-r--r--arch/alpha/kernel/osf_sys.c3
-rw-r--r--arch/alpha/kernel/sys_alcor.c27
-rw-r--r--arch/alpha/kernel/sys_cabriolet.c28
-rw-r--r--arch/alpha/kernel/sys_dp264.c50
-rw-r--r--arch/alpha/kernel/sys_eb64p.c27
-rw-r--r--arch/alpha/kernel/sys_eiger.c27
-rw-r--r--arch/alpha/kernel/sys_jensen.c55
-rw-r--r--arch/alpha/kernel/sys_marvel.c50
-rw-r--r--arch/alpha/kernel/sys_mikasa.c27
-rw-r--r--arch/alpha/kernel/sys_noritake.c27
-rw-r--r--arch/alpha/kernel/sys_rawhide.c27
-rw-r--r--arch/alpha/kernel/sys_rx164.c27
-rw-r--r--arch/alpha/kernel/sys_sable.c28
-rw-r--r--arch/alpha/kernel/sys_takara.c27
-rw-r--r--arch/alpha/kernel/sys_titan.c31
-rw-r--r--arch/alpha/kernel/sys_wildfire.c42
-rw-r--r--arch/alpha/lib/Makefile4
-rw-r--r--arch/alpha/math-emu/Makefile2
-rw-r--r--arch/alpha/mm/Makefile2
-rw-r--r--arch/alpha/oprofile/Makefile2
-rw-r--r--arch/arm/mach-msm/board-qsd8x50.c4
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c17
-rw-r--r--arch/arm/mach-s5p6442/mach-smdk6442.c1
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6440.c1
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6450.c1
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkc110.c1
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c1
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkc210.c3
-rw-r--r--arch/arm/mach-s5pv310/mach-smdkv310.c3
-rw-r--r--arch/arm/plat-nomadik/include/plat/ste_dma40.h8
-rw-r--r--arch/arm/plat-omap/include/plat/onenand.h1
-rw-r--r--arch/m68k/include/asm/cacheflush_no.h95
-rw-r--r--arch/m68k/include/asm/coldfire.h2
-rw-r--r--arch/m68k/include/asm/entry_no.h59
-rw-r--r--arch/m68k/include/asm/gpio.h2
-rw-r--r--arch/m68k/include/asm/io_no.h1
-rw-r--r--arch/m68k/include/asm/m5206sim.h14
-rw-r--r--arch/m68k/include/asm/m520xsim.h17
-rw-r--r--arch/m68k/include/asm/m523xsim.h11
-rw-r--r--arch/m68k/include/asm/m5249sim.h10
-rw-r--r--arch/m68k/include/asm/m5272sim.h8
-rw-r--r--arch/m68k/include/asm/m527xsim.h10
-rw-r--r--arch/m68k/include/asm/m528xsim.h11
-rw-r--r--arch/m68k/include/asm/m52xxacr.h94
-rw-r--r--arch/m68k/include/asm/m5307sim.h43
-rw-r--r--arch/m68k/include/asm/m532xsim.h33
-rw-r--r--arch/m68k/include/asm/m53xxacr.h101
-rw-r--r--arch/m68k/include/asm/m5407sim.h42
-rw-r--r--arch/m68k/include/asm/m54xxacr.h97
-rw-r--r--arch/m68k/include/asm/m54xxgpt.h (renamed from arch/m68k/include/asm/m548xgpt.h)10
-rw-r--r--arch/m68k/include/asm/m54xxsim.h (renamed from arch/m68k/include/asm/m548xsim.h)23
-rw-r--r--arch/m68k/include/asm/mcfcache.h150
-rw-r--r--arch/m68k/include/asm/mcfsim.h4
-rw-r--r--arch/m68k/include/asm/mcfuart.h45
-rw-r--r--arch/m68k/include/asm/processor.h13
-rw-r--r--arch/m68knommu/Kconfig98
-rw-r--r--arch/m68knommu/Makefile14
-rw-r--r--arch/m68knommu/kernel/setup.c72
-rw-r--r--arch/m68knommu/mm/Makefile2
-rw-r--r--arch/m68knommu/mm/fault.c57
-rw-r--r--arch/m68knommu/mm/kmap.c9
-rw-r--r--arch/m68knommu/mm/memory.c33
-rw-r--r--arch/m68knommu/platform/54xx/Makefile (renamed from arch/m68knommu/platform/548x/Makefile)0
-rw-r--r--arch/m68knommu/platform/54xx/config.c (renamed from arch/m68knommu/platform/548x/config.c)32
-rw-r--r--arch/m68knommu/platform/68328/ints.c4
-rw-r--r--arch/m68knommu/platform/coldfire/Makefile4
-rw-r--r--arch/m68knommu/platform/coldfire/cache.c48
-rw-r--r--arch/m68knommu/platform/coldfire/entry.S56
-rw-r--r--arch/m68knommu/platform/coldfire/head.S26
-rw-r--r--arch/microblaze/include/asm/pgtable.h6
-rw-r--r--arch/microblaze/include/asm/tlb.h1
-rw-r--r--arch/microblaze/kernel/prom.c4
-rw-r--r--arch/mips/Kbuild.platforms1
-rw-r--r--arch/mips/Kconfig37
-rw-r--r--arch/mips/ath79/Kconfig50
-rw-r--r--arch/mips/ath79/Makefile28
-rw-r--r--arch/mips/ath79/Platform7
-rw-r--r--arch/mips/ath79/clock.c183
-rw-r--r--arch/mips/ath79/common.c97
-rw-r--r--arch/mips/ath79/common.h31
-rw-r--r--arch/mips/ath79/dev-ar913x-wmac.c60
-rw-r--r--arch/mips/ath79/dev-ar913x-wmac.h17
-rw-r--r--arch/mips/ath79/dev-common.c77
-rw-r--r--arch/mips/ath79/dev-common.h18
-rw-r--r--arch/mips/ath79/dev-gpio-buttons.c58
-rw-r--r--arch/mips/ath79/dev-gpio-buttons.h23
-rw-r--r--arch/mips/ath79/dev-leds-gpio.c56
-rw-r--r--arch/mips/ath79/dev-leds-gpio.h21
-rw-r--r--arch/mips/ath79/dev-spi.c38
-rw-r--r--arch/mips/ath79/dev-spi.h22
-rw-r--r--arch/mips/ath79/early_printk.c36
-rw-r--r--arch/mips/ath79/gpio.c197
-rw-r--r--arch/mips/ath79/irq.c187
-rw-r--r--arch/mips/ath79/mach-ap81.c98
-rw-r--r--arch/mips/ath79/mach-pb44.c118
-rw-r--r--arch/mips/ath79/machtypes.h23
-rw-r--r--arch/mips/ath79/prom.c57
-rw-r--r--arch/mips/ath79/setup.c206
-rw-r--r--arch/mips/configs/malta_defconfig3
-rw-r--r--arch/mips/include/asm/cache.h2
-rw-r--r--arch/mips/include/asm/cpu-info.h1
-rw-r--r--arch/mips/include/asm/inst.h14
-rw-r--r--arch/mips/include/asm/jump_label.h48
-rw-r--r--arch/mips/include/asm/mach-ath79/ar71xx_regs.h233
-rw-r--r--arch/mips/include/asm/mach-ath79/ath79.h96
-rw-r--r--arch/mips/include/asm/mach-ath79/ath79_spi_platform.h23
-rw-r--r--arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h56
-rw-r--r--arch/mips/include/asm/mach-ath79/gpio.h26
-rw-r--r--arch/mips/include/asm/mach-ath79/irq.h36
-rw-r--r--arch/mips/include/asm/mach-ath79/kernel-entry-init.h32
-rw-r--r--arch/mips/include/asm/mach-ath79/war.h25
-rw-r--r--arch/mips/include/asm/mips_machine.h54
-rw-r--r--arch/mips/include/asm/mmu_context.h8
-rw-r--r--arch/mips/include/asm/uasm.h7
-rw-r--r--arch/mips/kernel/Makefile3
-rw-r--r--arch/mips/kernel/cpu-probe.c2
-rw-r--r--arch/mips/kernel/jump_label.c54
-rw-r--r--arch/mips/kernel/mips_machine.c86
-rw-r--r--arch/mips/kernel/module.c5
-rw-r--r--arch/mips/kernel/proc.c9
-rw-r--r--arch/mips/kernel/prom.c6
-rw-r--r--arch/mips/kernel/setup.c2
-rw-r--r--arch/mips/kernel/traps.c2
-rw-r--r--arch/mips/kernel/vmlinux.lds.S7
-rw-r--r--arch/mips/mm/tlbex.c590
-rw-r--r--arch/mips/mm/uasm.c56
-rw-r--r--arch/mips/sibyte/common/sb_tbprof.c3
-rw-r--r--arch/mips/txx9/generic/pci.c7
-rw-r--r--arch/parisc/kernel/firmware.c13
-rw-r--r--arch/powerpc/kernel/perf_event.c1
-rw-r--r--arch/powerpc/kernel/prom.c4
-rw-r--r--arch/x86/include/asm/numa_32.h2
-rw-r--r--arch/x86/include/asm/numa_64.h1
-rw-r--r--arch/x86/kernel/irq_32.c7
-rw-r--r--arch/x86/mm/numa.c22
-rw-r--r--arch/x86/mm/numa_64.c24
-rw-r--r--arch/x86/mm/srat_32.c1
145 files changed, 4075 insertions, 1307 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 943fe6930f77..fc95ee1bcf6f 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -68,6 +68,9 @@ config GENERIC_IOMAP
bool
default n
+config GENERIC_HARDIRQS_NO__DO_IRQ
+ def_bool y
+
config GENERIC_HARDIRQS
bool
default y
diff --git a/arch/alpha/include/asm/io.h b/arch/alpha/include/asm/io.h
index eda9b909aa05..56ff96501350 100644
--- a/arch/alpha/include/asm/io.h
+++ b/arch/alpha/include/asm/io.h
@@ -37,8 +37,9 @@
*/
extern inline void __set_hae(unsigned long new_hae)
{
- unsigned long flags;
- local_irq_save(flags);
+ unsigned long flags = swpipl(IPL_MAX);
+
+ barrier();
alpha_mv.hae_cache = new_hae;
*alpha_mv.hae_register = new_hae;
@@ -46,7 +47,8 @@ extern inline void __set_hae(unsigned long new_hae)
/* Re-read to make sure it was written. */
new_hae = *alpha_mv.hae_register;
- local_irq_restore(flags);
+ setipl(flags);
+ barrier();
}
extern inline void set_hae(unsigned long new_hae)
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
index 1ee9b5b629b8..9bb7b858ed23 100644
--- a/arch/alpha/kernel/Makefile
+++ b/arch/alpha/kernel/Makefile
@@ -3,8 +3,8 @@
#
extra-y := head.o vmlinux.lds
-EXTRA_AFLAGS := $(KBUILD_CFLAGS)
-EXTRA_CFLAGS := -Werror -Wno-sign-compare
+asflags-y := $(KBUILD_CFLAGS)
+ccflags-y := -Werror -Wno-sign-compare
obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \
irq_alpha.o signal.o setup.o ptrace.o time.o \
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index fe912984d9b1..9ab234f48dd8 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -44,10 +44,11 @@ static char irq_user_affinity[NR_IRQS];
int irq_select_affinity(unsigned int irq)
{
+ struct irq_desc *desc = irq_to_desc[irq];
static int last_cpu;
int cpu = last_cpu + 1;
- if (!irq_desc[irq].chip->set_affinity || irq_user_affinity[irq])
+ if (!desc || !get_irq_desc_chip(desc)->set_affinity || irq_user_affinity[irq])
return 1;
while (!cpu_possible(cpu) ||
@@ -55,8 +56,8 @@ int irq_select_affinity(unsigned int irq)
cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);
last_cpu = cpu;
- cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
- irq_desc[irq].chip->set_affinity(irq, cpumask_of(cpu));
+ cpumask_copy(desc->affinity, cpumask_of(cpu));
+ get_irq_desc_chip(desc)->set_affinity(irq, cpumask_of(cpu));
return 0;
}
#endif /* CONFIG_SMP */
@@ -67,6 +68,7 @@ show_interrupts(struct seq_file *p, void *v)
int j;
int irq = *(loff_t *) v;
struct irqaction * action;
+ struct irq_desc *desc;
unsigned long flags;
#ifdef CONFIG_SMP
@@ -79,8 +81,13 @@ show_interrupts(struct seq_file *p, void *v)
#endif
if (irq < ACTUAL_NR_IRQS) {
- raw_spin_lock_irqsave(&irq_desc[irq].lock, flags);
- action = irq_desc[irq].action;
+ desc = irq_to_desc(irq);
+
+ if (!desc)
+ return 0;
+
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ action = desc->action;
if (!action)
goto unlock;
seq_printf(p, "%3d: ", irq);
@@ -90,7 +97,7 @@ show_interrupts(struct seq_file *p, void *v)
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
#endif
- seq_printf(p, " %14s", irq_desc[irq].chip->name);
+ seq_printf(p, " %14s", get_irq_desc_chip(desc)->name);
seq_printf(p, " %c%s",
(action->flags & IRQF_DISABLED)?'+':' ',
action->name);
@@ -103,7 +110,7 @@ show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n');
unlock:
- raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
} else if (irq == ACTUAL_NR_IRQS) {
#ifdef CONFIG_SMP
seq_puts(p, "IPI: ");
@@ -142,8 +149,10 @@ handle_irq(int irq)
* handled by some other CPU. (or is disabled)
*/
static unsigned int illegal_count=0;
+ struct irq_desc *desc = irq_to_desc(irq);
- if ((unsigned) irq > ACTUAL_NR_IRQS && illegal_count < MAX_ILLEGAL_IRQS ) {
+ if (!desc || ((unsigned) irq > ACTUAL_NR_IRQS &&
+ illegal_count < MAX_ILLEGAL_IRQS)) {
irq_err_count++;
illegal_count++;
printk(KERN_CRIT "device_interrupt: invalid interrupt %d\n",
@@ -151,14 +160,14 @@ handle_irq(int irq)
return;
}
- irq_enter();
/*
- * __do_IRQ() must be called with IPL_MAX. Note that we do not
+ * From here we must proceed with IPL_MAX. Note that we do not
* explicitly enable interrupts afterwards - some MILO PALcode
* (namely LX164 one) seems to have severe problems with RTI
* at IPL 0.
*/
local_irq_disable();
- __do_IRQ(irq);
+ irq_enter();
+ generic_handle_irq_desc(irq, desc);
irq_exit();
}
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
index 4c8bb374eb0a..2d0679b60939 100644
--- a/arch/alpha/kernel/irq_alpha.c
+++ b/arch/alpha/kernel/irq_alpha.c
@@ -219,31 +219,23 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr,
* processed by PALcode, and comes in via entInt vector 1.
*/
-static void rtc_enable_disable(unsigned int irq) { }
-static unsigned int rtc_startup(unsigned int irq) { return 0; }
-
struct irqaction timer_irqaction = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED,
.name = "timer",
};
-static struct irq_chip rtc_irq_type = {
- .name = "RTC",
- .startup = rtc_startup,
- .shutdown = rtc_enable_disable,
- .enable = rtc_enable_disable,
- .disable = rtc_enable_disable,
- .ack = rtc_enable_disable,
- .end = rtc_enable_disable,
-};
-
void __init
init_rtc_irq(void)
{
- irq_desc[RTC_IRQ].status = IRQ_DISABLED;
- irq_desc[RTC_IRQ].chip = &rtc_irq_type;
- setup_irq(RTC_IRQ, &timer_irqaction);
+ struct irq_desc *desc = irq_to_desc(RTC_IRQ);
+
+ if (desc) {
+ desc->status |= IRQ_DISABLED;
+ set_irq_chip_and_handler_name(RTC_IRQ, &no_irq_chip,
+ handle_simple_irq, "RTC");
+ setup_irq(RTC_IRQ, &timer_irqaction);
+ }
}
/* Dummy irqactions. */
diff --git a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c
index 83a9ac280890..956ea0ed1694 100644
--- a/arch/alpha/kernel/irq_i8259.c
+++ b/arch/alpha/kernel/irq_i8259.c
@@ -69,28 +69,11 @@ i8259a_mask_and_ack_irq(unsigned int irq)
spin_unlock(&i8259_irq_lock);
}
-unsigned int
-i8259a_startup_irq(unsigned int irq)
-{
- i8259a_enable_irq(irq);
- return 0; /* never anything pending */
-}
-
-void
-i8259a_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- i8259a_enable_irq(irq);
-}
-
struct irq_chip i8259a_irq_type = {
.name = "XT-PIC",
- .startup = i8259a_startup_irq,
- .shutdown = i8259a_disable_irq,
- .enable = i8259a_enable_irq,
- .disable = i8259a_disable_irq,
- .ack = i8259a_mask_and_ack_irq,
- .end = i8259a_end_irq,
+ .unmask = i8259a_enable_irq,
+ .mask = i8259a_disable_irq,
+ .mask_ack = i8259a_mask_and_ack_irq,
};
void __init
@@ -107,8 +90,7 @@ init_i8259a_irqs(void)
outb(0xff, 0xA1); /* mask all of 8259A-2 */
for (i = 0; i < 16; i++) {
- irq_desc[i].status = IRQ_DISABLED;
- irq_desc[i].chip = &i8259a_irq_type;
+ set_irq_chip_and_handler(i, &i8259a_irq_type, handle_level_irq);
}
setup_irq(2, &cascade);
diff --git a/arch/alpha/kernel/irq_pyxis.c b/arch/alpha/kernel/irq_pyxis.c
index 989ce46a0cf3..2863458c853e 100644
--- a/arch/alpha/kernel/irq_pyxis.c
+++ b/arch/alpha/kernel/irq_pyxis.c
@@ -40,20 +40,6 @@ pyxis_disable_irq(unsigned int irq)
pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16)));
}
-static unsigned int
-pyxis_startup_irq(unsigned int irq)
-{
- pyxis_enable_irq(irq);
- return 0;
-}
-
-static void
-pyxis_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- pyxis_enable_irq(irq);
-}
-
static void
pyxis_mask_and_ack_irq(unsigned int irq)
{
@@ -72,12 +58,9 @@ pyxis_mask_and_ack_irq(unsigned int irq)
static struct irq_chip pyxis_irq_type = {
.name = "PYXIS",
- .startup = pyxis_startup_irq,
- .shutdown = pyxis_disable_irq,
- .enable = pyxis_enable_irq,
- .disable = pyxis_disable_irq,
- .ack = pyxis_mask_and_ack_irq,
- .end = pyxis_end_irq,
+ .mask_ack = pyxis_mask_and_ack_irq,
+ .mask = pyxis_disable_irq,
+ .unmask = pyxis_enable_irq,
};
void
@@ -119,8 +102,8 @@ init_pyxis_irqs(unsigned long ignore_mask)
for (i = 16; i < 48; ++i) {
if ((ignore_mask >> i) & 1)
continue;
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = &pyxis_irq_type;
+ set_irq_chip_and_handler(i, &pyxis_irq_type, handle_level_irq);
+ irq_to_desc(i)->status |= IRQ_LEVEL;
}
setup_irq(16+7, &isa_cascade_irqaction);
diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c
index d63e93e1e8bf..0e57e828b413 100644
--- a/arch/alpha/kernel/irq_srm.c
+++ b/arch/alpha/kernel/irq_srm.c
@@ -33,29 +33,12 @@ srm_disable_irq(unsigned int irq)
spin_unlock(&srm_irq_lock);
}
-static unsigned int
-srm_startup_irq(unsigned int irq)
-{
- srm_enable_irq(irq);
- return 0;
-}
-
-static void
-srm_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- srm_enable_irq(irq);
-}
-
/* Handle interrupts from the SRM, assuming no additional weirdness. */
static struct irq_chip srm_irq_type = {
.name = "SRM",
- .startup = srm_startup_irq,
- .shutdown = srm_disable_irq,
- .enable = srm_enable_irq,
- .disable = srm_disable_irq,
- .ack = srm_disable_irq,
- .end = srm_end_irq,
+ .unmask = srm_enable_irq,
+ .mask = srm_disable_irq,
+ .mask_ack = srm_disable_irq,
};
void __init
@@ -68,8 +51,8 @@ init_srm_irqs(long max, unsigned long ignore_mask)
for (i = 16; i < max; ++i) {
if (i < 64 && ((ignore_mask >> i) & 1))
continue;
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = &srm_irq_type;
+ set_irq_chip_and_handler(i, &srm_irq_type, handle_level_irq);
+ irq_to_desc(i)->status |= IRQ_LEVEL;
}
}
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 547e8b84b2f7..fe698b5045e9 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -951,9 +951,6 @@ SYSCALL_DEFINE2(osf_utimes, const char __user *, filename,
return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL, 0);
}
-#define MAX_SELECT_SECONDS \
- ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
-
SYSCALL_DEFINE5(osf_select, int, n, fd_set __user *, inp, fd_set __user *, outp,
fd_set __user *, exp, struct timeval32 __user *, tvp)
{
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
index 20a30b8b9655..7bef61768236 100644
--- a/arch/alpha/kernel/sys_alcor.c
+++ b/arch/alpha/kernel/sys_alcor.c
@@ -65,13 +65,6 @@ alcor_mask_and_ack_irq(unsigned int irq)
*(vuip)GRU_INT_CLEAR = 0; mb();
}
-static unsigned int
-alcor_startup_irq(unsigned int irq)
-{
- alcor_enable_irq(irq);
- return 0;
-}
-
static void
alcor_isa_mask_and_ack_irq(unsigned int irq)
{
@@ -82,21 +75,11 @@ alcor_isa_mask_and_ack_irq(unsigned int irq)
*(vuip)GRU_INT_CLEAR = 0; mb();
}
-static void
-alcor_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- alcor_enable_irq(irq);
-}
-
static struct irq_chip alcor_irq_type = {
.name = "ALCOR",
- .startup = alcor_startup_irq,
- .shutdown = alcor_disable_irq,
- .enable = alcor_enable_irq,
- .disable = alcor_disable_irq,
- .ack = alcor_mask_and_ack_irq,
- .end = alcor_end_irq,
+ .unmask = alcor_enable_irq,
+ .mask = alcor_disable_irq,
+ .mask_ack = alcor_mask_and_ack_irq,
};
static void
@@ -142,8 +125,8 @@ alcor_init_irq(void)
on while IRQ probing. */
if (i >= 16+20 && i <= 16+30)
continue;
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = &alcor_irq_type;
+ set_irq_chip_and_handler(i, &alcor_irq_type, handle_level_irq);
+ irq_to_desc(i)->status |= IRQ_LEVEL;
}
i8259a_irq_type.ack = alcor_isa_mask_and_ack_irq;
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c
index 14c8898d19ec..b0c916493aea 100644
--- a/arch/alpha/kernel/sys_cabriolet.c
+++ b/arch/alpha/kernel/sys_cabriolet.c
@@ -57,28 +57,11 @@ cabriolet_disable_irq(unsigned int irq)
cabriolet_update_irq_hw(irq, cached_irq_mask |= 1UL << irq);
}
-static unsigned int
-cabriolet_startup_irq(unsigned int irq)
-{
- cabriolet_enable_irq(irq);
- return 0; /* never anything pending */
-}
-
-static void
-cabriolet_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- cabriolet_enable_irq(irq);
-}
-
static struct irq_chip cabriolet_irq_type = {
.name = "CABRIOLET",
- .startup = cabriolet_startup_irq,
- .shutdown = cabriolet_disable_irq,
- .enable = cabriolet_enable_irq,
- .disable = cabriolet_disable_irq,
- .ack = cabriolet_disable_irq,
- .end = cabriolet_end_irq,
+ .unmask = cabriolet_enable_irq,
+ .mask = cabriolet_disable_irq,
+ .mask_ack = cabriolet_disable_irq,
};
static void
@@ -122,8 +105,9 @@ common_init_irq(void (*srm_dev_int)(unsigned long v))
outb(0xff, 0x806);
for (i = 16; i < 35; ++i) {
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = &cabriolet_irq_type;
+ set_irq_chip_and_handler(i, &cabriolet_irq_type,
+ handle_level_irq);
+ irq_to_desc(i)->status |= IRQ_LEVEL;
}
}
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index 4026502ab707..edad5f759ccd 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -115,20 +115,6 @@ dp264_disable_irq(unsigned int irq)
spin_unlock(&dp264_irq_lock);
}
-static unsigned int
-dp264_startup_irq(unsigned int irq)
-{
- dp264_enable_irq(irq);
- return 0; /* never anything pending */
-}
-
-static void
-dp264_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- dp264_enable_irq(irq);
-}
-
static void
clipper_enable_irq(unsigned int irq)
{
@@ -147,20 +133,6 @@ clipper_disable_irq(unsigned int irq)
spin_unlock(&dp264_irq_lock);
}
-static unsigned int
-clipper_startup_irq(unsigned int irq)
-{
- clipper_enable_irq(irq);
- return 0; /* never anything pending */
-}
-
-static void
-clipper_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- clipper_enable_irq(irq);
-}
-
static void
cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
{
@@ -200,23 +172,17 @@ clipper_set_affinity(unsigned int irq, const struct cpumask *affinity)
static struct irq_chip dp264_irq_type = {
.name = "DP264",
- .startup = dp264_startup_irq,
- .shutdown = dp264_disable_irq,
- .enable = dp264_enable_irq,
- .disable = dp264_disable_irq,
- .ack = dp264_disable_irq,
- .end = dp264_end_irq,
+ .unmask = dp264_enable_irq,
+ .mask = dp264_disable_irq,
+ .mask_ack = dp264_disable_irq,
.set_affinity = dp264_set_affinity,
};
static struct irq_chip clipper_irq_type = {
.name = "CLIPPER",
- .startup = clipper_startup_irq,
- .shutdown = clipper_disable_irq,
- .enable = clipper_enable_irq,
- .disable = clipper_disable_irq,
- .ack = clipper_disable_irq,
- .end = clipper_end_irq,
+ .unmask = clipper_enable_irq,
+ .mask = clipper_disable_irq,
+ .mask_ack = clipper_disable_irq,
.set_affinity = clipper_set_affinity,
};
@@ -302,8 +268,8 @@ init_tsunami_irqs(struct irq_chip * ops, int imin, int imax)
{
long i;
for (i = imin; i <= imax; ++i) {
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = ops;
+ irq_to_desc(i)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(i, ops, handle_level_irq);
}
}
diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c
index df2090ce5e7f..ae5f29d127b0 100644
--- a/arch/alpha/kernel/sys_eb64p.c
+++ b/arch/alpha/kernel/sys_eb64p.c
@@ -55,28 +55,11 @@ eb64p_disable_irq(unsigned int irq)
eb64p_update_irq_hw(irq, cached_irq_mask |= 1 << irq);
}
-static unsigned int
-eb64p_startup_irq(unsigned int irq)
-{
- eb64p_enable_irq(irq);
- return 0; /* never anything pending */
-}
-
-static void
-eb64p_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- eb64p_enable_irq(irq);
-}
-
static struct irq_chip eb64p_irq_type = {
.name = "EB64P",
- .startup = eb64p_startup_irq,
- .shutdown = eb64p_disable_irq,
- .enable = eb64p_enable_irq,
- .disable = eb64p_disable_irq,
- .ack = eb64p_disable_irq,
- .end = eb64p_end_irq,
+ .unmask = eb64p_enable_irq,
+ .mask = eb64p_disable_irq,
+ .mask_ack = eb64p_disable_irq,
};
static void
@@ -135,8 +118,8 @@ eb64p_init_irq(void)
init_i8259a_irqs();
for (i = 16; i < 32; ++i) {
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = &eb64p_irq_type;
+ irq_to_desc(i)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(i, &eb64p_irq_type, handle_level_irq);
}
common_init_isa_dma();
diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c
index 3ca1dbcf4044..1121bc5c6c6c 100644
--- a/arch/alpha/kernel/sys_eiger.c
+++ b/arch/alpha/kernel/sys_eiger.c
@@ -66,28 +66,11 @@ eiger_disable_irq(unsigned int irq)
eiger_update_irq_hw(irq, mask);
}
-static unsigned int
-eiger_startup_irq(unsigned int irq)
-{
- eiger_enable_irq(irq);
- return 0; /* never anything pending */
-}
-
-static void
-eiger_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- eiger_enable_irq(irq);
-}
-
static struct irq_chip eiger_irq_type = {
.name = "EIGER",
- .startup = eiger_startup_irq,
- .shutdown = eiger_disable_irq,
- .enable = eiger_enable_irq,
- .disable = eiger_disable_irq,
- .ack = eiger_disable_irq,
- .end = eiger_end_irq,
+ .unmask = eiger_enable_irq,
+ .mask = eiger_disable_irq,
+ .mask_ack = eiger_disable_irq,
};
static void
@@ -153,8 +136,8 @@ eiger_init_irq(void)
init_i8259a_irqs();
for (i = 16; i < 128; ++i) {
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = &eiger_irq_type;
+ irq_to_desc(i)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(i, &eiger_irq_type, handle_level_irq);
}
}
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
index 7a7ae36fff91..34f55e03d331 100644
--- a/arch/alpha/kernel/sys_jensen.c
+++ b/arch/alpha/kernel/sys_jensen.c
@@ -62,30 +62,6 @@
* world.
*/
-static unsigned int
-jensen_local_startup(unsigned int irq)
-{
- /* the parport is really hw IRQ 1, silly Jensen. */
- if (irq == 7)
- i8259a_startup_irq(1);
- else
- /*
- * For all true local interrupts, set the flag that prevents
- * the IPL from being dropped during handler processing.
- */
- if (irq_desc[irq].action)
- irq_desc[irq].action->flags |= IRQF_DISABLED;
- return 0;
-}
-
-static void
-jensen_local_shutdown(unsigned int irq)
-{
- /* the parport is really hw IRQ 1, silly Jensen. */
- if (irq == 7)
- i8259a_disable_irq(1);
-}
-
static void
jensen_local_enable(unsigned int irq)
{
@@ -103,29 +79,18 @@ jensen_local_disable(unsigned int irq)
}
static void
-jensen_local_ack(unsigned int irq)
+jensen_local_mask_ack(unsigned int irq)
{
/* the parport is really hw IRQ 1, silly Jensen. */
if (irq == 7)
i8259a_mask_and_ack_irq(1);
}
-static void
-jensen_local_end(unsigned int irq)
-{
- /* the parport is really hw IRQ 1, silly Jensen. */
- if (irq == 7)
- i8259a_end_irq(1);
-}
-
static struct irq_chip jensen_local_irq_type = {
.name = "LOCAL",
- .startup = jensen_local_startup,
- .shutdown = jensen_local_shutdown,
- .enable = jensen_local_enable,
- .disable = jensen_local_disable,
- .ack = jensen_local_ack,
- .end = jensen_local_end,
+ .unmask = jensen_local_enable,
+ .mask = jensen_local_disable,
+ .mask_ack = jensen_local_mask_ack,
};
static void
@@ -158,7 +123,7 @@ jensen_device_interrupt(unsigned long vector)
}
/* If there is no handler yet... */
- if (irq_desc[irq].action == NULL) {
+ if (!irq_has_action(irq)) {
/* If it is a local interrupt that cannot be masked... */
if (vector >= 0x900)
{
@@ -206,11 +171,11 @@ jensen_init_irq(void)
{
init_i8259a_irqs();
- irq_desc[1].chip = &jensen_local_irq_type;
- irq_desc[4].chip = &jensen_local_irq_type;
- irq_desc[3].chip = &jensen_local_irq_type;
- irq_desc[7].chip = &jensen_local_irq_type;
- irq_desc[9].chip = &jensen_local_irq_type;
+ set_irq_chip_and_handler(1, &jensen_local_irq_type, handle_level_irq);
+ set_irq_chip_and_handler(4, &jensen_local_irq_type, handle_level_irq);
+ set_irq_chip_and_handler(3, &jensen_local_irq_type, handle_level_irq);
+ set_irq_chip_and_handler(7, &jensen_local_irq_type, handle_level_irq);
+ set_irq_chip_and_handler(9, &jensen_local_irq_type, handle_level_irq);
common_init_isa_dma();
}
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c
index 0bb3b5c4f693..2bfc9f1b1ddc 100644
--- a/arch/alpha/kernel/sys_marvel.c
+++ b/arch/alpha/kernel/sys_marvel.c
@@ -143,20 +143,6 @@ io7_disable_irq(unsigned int irq)
spin_unlock(&io7->irq_lock);
}
-static unsigned int
-io7_startup_irq(unsigned int irq)
-{
- io7_enable_irq(irq);
- return 0; /* never anything pending */
-}
-
-static void
-io7_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- io7_enable_irq(irq);
-}
-
static void
marvel_irq_noop(unsigned int irq)
{
@@ -171,32 +157,22 @@ marvel_irq_noop_return(unsigned int irq)
static struct irq_chip marvel_legacy_irq_type = {
.name = "LEGACY",
- .startup = marvel_irq_noop_return,
- .shutdown = marvel_irq_noop,
- .enable = marvel_irq_noop,
- .disable = marvel_irq_noop,
- .ack = marvel_irq_noop,
- .end = marvel_irq_noop,
+ .mask = marvel_irq_noop,
+ .unmask = marvel_irq_noop,
};
static struct irq_chip io7_lsi_irq_type = {
.name = "LSI",
- .startup = io7_startup_irq,
- .shutdown = io7_disable_irq,
- .enable = io7_enable_irq,
- .disable = io7_disable_irq,
- .ack = io7_disable_irq,
- .end = io7_end_irq,
+ .unmask = io7_enable_irq,
+ .mask = io7_disable_irq,
+ .mask_ack = io7_disable_irq,
};
static struct irq_chip io7_msi_irq_type = {
.name = "MSI",
- .startup = io7_startup_irq,
- .shutdown = io7_disable_irq,
- .enable = io7_enable_irq,
- .disable = io7_disable_irq,
+ .unmask = io7_enable_irq,
+ .mask = io7_disable_irq,
.ack = marvel_irq_noop,
- .end = io7_end_irq,
};
static void
@@ -304,8 +280,8 @@ init_io7_irqs(struct io7 *io7,
/* Set up the lsi irqs. */
for (i = 0; i < 128; ++i) {
- irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[base + i].chip = lsi_ops;
+ irq_to_desc(base + i)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(base + i, lsi_ops, handle_level_irq);
}
/* Disable the implemented irqs in hardware. */
@@ -318,8 +294,8 @@ init_io7_irqs(struct io7 *io7,
/* Set up the msi irqs. */
for (i = 128; i < (128 + 512); ++i) {
- irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[base + i].chip = msi_ops;
+ irq_to_desc(base + i)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(base + i, msi_ops, handle_level_irq);
}
for (i = 0; i < 16; ++i)
@@ -336,8 +312,8 @@ marvel_init_irq(void)
/* Reserve the legacy irqs. */
for (i = 0; i < 16; ++i) {
- irq_desc[i].status = IRQ_DISABLED;
- irq_desc[i].chip = &marvel_legacy_irq_type;
+ set_irq_chip_and_handler(i, &marvel_legacy_irq_type,
+ handle_level_irq);
}
/* Init the io7 irqs. */
diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c
index ee8865169811..bcc1639e8efb 100644
--- a/arch/alpha/kernel/sys_mikasa.c
+++ b/arch/alpha/kernel/sys_mikasa.c
@@ -54,28 +54,11 @@ mikasa_disable_irq(unsigned int irq)
mikasa_update_irq_hw(cached_irq_mask &= ~(1 << (irq - 16)));
}
-static unsigned int
-mikasa_startup_irq(unsigned int irq)
-{
- mikasa_enable_irq(irq);
- return 0;
-}
-
-static void
-mikasa_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- mikasa_enable_irq(irq);
-}
-
static struct irq_chip mikasa_irq_type = {
.name = "MIKASA",
- .startup = mikasa_startup_irq,
- .shutdown = mikasa_disable_irq,
- .enable = mikasa_enable_irq,
- .disable = mikasa_disable_irq,
- .ack = mikasa_disable_irq,
- .end = mikasa_end_irq,
+ .unmask = mikasa_enable_irq,
+ .mask = mikasa_disable_irq,
+ .mask_ack = mikasa_disable_irq,
};
static void
@@ -115,8 +98,8 @@ mikasa_init_irq(void)
mikasa_update_irq_hw(0);
for (i = 16; i < 32; ++i) {
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = &mikasa_irq_type;
+ irq_to_desc(i)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(i, &mikasa_irq_type, handle_level_irq);
}
init_i8259a_irqs();
diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c
index 86503fe73a88..e88f4ae1260e 100644
--- a/arch/alpha/kernel/sys_noritake.c
+++ b/arch/alpha/kernel/sys_noritake.c
@@ -59,28 +59,11 @@ noritake_disable_irq(unsigned int irq)
noritake_update_irq_hw(irq, cached_irq_mask &= ~(1 << (irq - 16)));
}
-static unsigned int
-noritake_startup_irq(unsigned int irq)
-{
- noritake_enable_irq(irq);
- return 0;
-}
-
-static void
-noritake_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- noritake_enable_irq(irq);
-}
-
static struct irq_chip noritake_irq_type = {
.name = "NORITAKE",
- .startup = noritake_startup_irq,
- .shutdown = noritake_disable_irq,
- .enable = noritake_enable_irq,
- .disable = noritake_disable_irq,
- .ack = noritake_disable_irq,
- .end = noritake_end_irq,
+ .unmask = noritake_enable_irq,
+ .mask = noritake_disable_irq,
+ .mask_ack = noritake_disable_irq,
};
static void
@@ -144,8 +127,8 @@ noritake_init_irq(void)
outw(0, 0x54c);
for (i = 16; i < 48; ++i) {
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = &noritake_irq_type;
+ irq_to_desc(i)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(i, &noritake_irq_type, handle_level_irq);
}
init_i8259a_irqs();
diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c
index 26c322bf89ee..6a51364dd1cc 100644
--- a/arch/alpha/kernel/sys_rawhide.c
+++ b/arch/alpha/kernel/sys_rawhide.c
@@ -121,28 +121,11 @@ rawhide_mask_and_ack_irq(unsigned int irq)
spin_unlock(&rawhide_irq_lock);
}
-static unsigned int
-rawhide_startup_irq(unsigned int irq)
-{
- rawhide_enable_irq(irq);
- return 0;
-}
-
-static void
-rawhide_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- rawhide_enable_irq(irq);
-}
-
static struct irq_chip rawhide_irq_type = {
.name = "RAWHIDE",
- .startup = rawhide_startup_irq,
- .shutdown = rawhide_disable_irq,
- .enable = rawhide_enable_irq,
- .disable = rawhide_disable_irq,
- .ack = rawhide_mask_and_ack_irq,
- .end = rawhide_end_irq,
+ .unmask = rawhide_enable_irq,
+ .mask = rawhide_disable_irq,
+ .mask_ack = rawhide_mask_and_ack_irq,
};
static void
@@ -194,8 +177,8 @@ rawhide_init_irq(void)
}
for (i = 16; i < 128; ++i) {
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = &rawhide_irq_type;
+ irq_to_desc(i)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(i, &rawhide_irq_type, handle_level_irq);
}
init_i8259a_irqs();
diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c
index be161129eab9..89e7e37ec84c 100644
--- a/arch/alpha/kernel/sys_rx164.c
+++ b/arch/alpha/kernel/sys_rx164.c
@@ -58,28 +58,11 @@ rx164_disable_irq(unsigned int irq)
rx164_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16)));
}
-static unsigned int
-rx164_startup_irq(unsigned int irq)
-{
- rx164_enable_irq(irq);
- return 0;
-}
-
-static void
-rx164_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- rx164_enable_irq(irq);
-}
-
static struct irq_chip rx164_irq_type = {
.name = "RX164",
- .startup = rx164_startup_irq,
- .shutdown = rx164_disable_irq,
- .enable = rx164_enable_irq,
- .disable = rx164_disable_irq,
- .ack = rx164_disable_irq,
- .end = rx164_end_irq,
+ .unmask = rx164_enable_irq,
+ .mask = rx164_disable_irq,
+ .mask_ack = rx164_disable_irq,
};
static void
@@ -116,8 +99,8 @@ rx164_init_irq(void)
rx164_update_irq_hw(0);
for (i = 16; i < 40; ++i) {
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = &rx164_irq_type;
+ irq_to_desc(i)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(i, &rx164_irq_type, handle_level_irq);
}
init_i8259a_irqs();
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
index b2abe27a23cf..5c4423d1b06c 100644
--- a/arch/alpha/kernel/sys_sable.c
+++ b/arch/alpha/kernel/sys_sable.c
@@ -474,20 +474,6 @@ sable_lynx_disable_irq(unsigned int irq)
#endif
}
-static unsigned int
-sable_lynx_startup_irq(unsigned int irq)
-{
- sable_lynx_enable_irq(irq);
- return 0;
-}
-
-static void
-sable_lynx_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- sable_lynx_enable_irq(irq);
-}
-
static void
sable_lynx_mask_and_ack_irq(unsigned int irq)
{
@@ -503,12 +489,9 @@ sable_lynx_mask_and_ack_irq(unsigned int irq)
static struct irq_chip sable_lynx_irq_type = {
.name = "SABLE/LYNX",
- .startup = sable_lynx_startup_irq,
- .shutdown = sable_lynx_disable_irq,
- .enable = sable_lynx_enable_irq,
- .disable = sable_lynx_disable_irq,
- .ack = sable_lynx_mask_and_ack_irq,
- .end = sable_lynx_end_irq,
+ .unmask = sable_lynx_enable_irq,
+ .mask = sable_lynx_disable_irq,
+ .mask_ack = sable_lynx_mask_and_ack_irq,
};
static void
@@ -535,8 +518,9 @@ sable_lynx_init_irq(int nr_of_irqs)
long i;
for (i = 0; i < nr_of_irqs; ++i) {
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = &sable_lynx_irq_type;
+ irq_to_desc(i)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(i, &sable_lynx_irq_type,
+ handle_level_irq);
}
common_init_isa_dma();
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c
index 4da596b6adbb..f8a1e8a862fb 100644
--- a/arch/alpha/kernel/sys_takara.c
+++ b/arch/alpha/kernel/sys_takara.c
@@ -60,28 +60,11 @@ takara_disable_irq(unsigned int irq)
takara_update_irq_hw(irq, mask);
}
-static unsigned int
-takara_startup_irq(unsigned int irq)
-{
- takara_enable_irq(irq);
- return 0; /* never anything pending */
-}
-
-static void
-takara_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- takara_enable_irq(irq);
-}
-
static struct irq_chip takara_irq_type = {
.name = "TAKARA",
- .startup = takara_startup_irq,
- .shutdown = takara_disable_irq,
- .enable = takara_enable_irq,
- .disable = takara_disable_irq,
- .ack = takara_disable_irq,
- .end = takara_end_irq,
+ .unmask = takara_enable_irq,
+ .mask = takara_disable_irq,
+ .mask_ack = takara_disable_irq,
};
static void
@@ -153,8 +136,8 @@ takara_init_irq(void)
takara_update_irq_hw(i, -1);
for (i = 16; i < 128; ++i) {
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = &takara_irq_type;
+ irq_to_desc(i)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(i, &takara_irq_type, handle_level_irq);
}
common_init_isa_dma();
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
index 9008d0f20c53..e02494bf5ef3 100644
--- a/arch/alpha/kernel/sys_titan.c
+++ b/arch/alpha/kernel/sys_titan.c
@@ -129,20 +129,6 @@ titan_disable_irq(unsigned int irq)
spin_unlock(&titan_irq_lock);
}
-static unsigned int
-titan_startup_irq(unsigned int irq)
-{
- titan_enable_irq(irq);
- return 0; /* never anything pending */
-}
-
-static void
-titan_end_irq(unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- titan_enable_irq(irq);
-}
-
static void
titan_cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
{
@@ -189,20 +175,17 @@ init_titan_irqs(struct irq_chip * ops, int imin, int imax)
{
long i;
for (i = imin; i <= imax; ++i) {
- irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i].chip = ops;
+ irq_to_desc(i)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(i, ops, handle_level_irq);
}
}
static struct irq_chip titan_irq_type = {
- .name = "TITAN",
- .startup = titan_startup_irq,
- .shutdown = titan_disable_irq,
- .enable = titan_enable_irq,
- .disable = titan_disable_irq,
- .ack = titan_disable_irq,
- .end = titan_end_irq,
- .set_affinity = titan_set_irq_affinity,
+ .name = "TITAN",
+ .unmask = titan_enable_irq,
+ .mask = titan_disable_irq,
+ .mask_ack = titan_disable_irq,
+ .set_affinity = titan_set_irq_affinity,
};
static irqreturn_t
diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c
index 62fd972e18ef..eec52594d410 100644
--- a/arch/alpha/kernel/sys_wildfire.c
+++ b/arch/alpha/kernel/sys_wildfire.c
@@ -139,32 +139,11 @@ wildfire_mask_and_ack_irq(unsigned int irq)
spin_unlock(&wildfire_irq_lock);
}
-static unsigned int
-wildfire_startup_irq(unsigned int irq)
-{
- wildfire_enable_irq(irq);
- return 0; /* never anything pending */
-}
-
-static void
-wildfire_end_irq(unsigned int irq)
-{
-#if 0
- if (!irq_desc[irq].action)
- printk("got irq %d\n", irq);
-#endif
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- wildfire_enable_irq(irq);
-}
-
static struct irq_chip wildfire_irq_type = {
.name = "WILDFIRE",
- .startup = wildfire_startup_irq,
- .shutdown = wildfire_disable_irq,
- .enable = wildfire_enable_irq,
- .disable = wildfire_disable_irq,
- .ack = wildfire_mask_and_ack_irq,
- .end = wildfire_end_irq,
+ .unmask = wildfire_enable_irq,
+ .mask = wildfire_disable_irq,
+ .mask_ack = wildfire_mask_and_ack_irq,
};
static void __init
@@ -198,15 +177,18 @@ wildfire_init_irq_per_pca(int qbbno, int pcano)
for (i = 0; i < 16; ++i) {
if (i == 2)
continue;
- irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i+irq_bias].chip = &wildfire_irq_type;
+ irq_to_desc(i+irq_bias)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(i+irq_bias, &wildfire_irq_type,
+ handle_level_irq);
}
- irq_desc[36+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[36+irq_bias].chip = &wildfire_irq_type;
+ irq_to_desc(36+irq_bias)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(36+irq_bias, &wildfire_irq_type,
+ handle_level_irq);
for (i = 40; i < 64; ++i) {
- irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL;
- irq_desc[i+irq_bias].chip = &wildfire_irq_type;
+ irq_to_desc(i+irq_bias)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(i+irq_bias, &wildfire_irq_type,
+ handle_level_irq);
}
setup_irq(32+irq_bias, &isa_enable);
diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile
index 9b72c59c95be..c0a83ab62b78 100644
--- a/arch/alpha/lib/Makefile
+++ b/arch/alpha/lib/Makefile
@@ -2,8 +2,8 @@
# Makefile for alpha-specific library files..
#
-EXTRA_AFLAGS := $(KBUILD_CFLAGS)
-EXTRA_CFLAGS := -Werror
+asflags-y := $(KBUILD_CFLAGS)
+ccflags-y := -Werror
# Many of these routines have implementations tuned for ev6.
# Choose them iff we're targeting ev6 specifically.
diff --git a/arch/alpha/math-emu/Makefile b/arch/alpha/math-emu/Makefile
index 359ef087e69e..7f4671995245 100644
--- a/arch/alpha/math-emu/Makefile
+++ b/arch/alpha/math-emu/Makefile
@@ -2,7 +2,7 @@
# Makefile for the FPU instruction emulation.
#
-EXTRA_CFLAGS := -w
+ccflags-y := -w
obj-$(CONFIG_MATHEMU) += math-emu.o
diff --git a/arch/alpha/mm/Makefile b/arch/alpha/mm/Makefile
index 09399c5386cb..c993d3f93cf6 100644
--- a/arch/alpha/mm/Makefile
+++ b/arch/alpha/mm/Makefile
@@ -2,7 +2,7 @@
# Makefile for the linux alpha-specific parts of the memory manager.
#
-EXTRA_CFLAGS := -Werror
+ccflags-y := -Werror
obj-y := init.o fault.o extable.o
diff --git a/arch/alpha/oprofile/Makefile b/arch/alpha/oprofile/Makefile
index 4aa56247bdc6..3473de751b03 100644
--- a/arch/alpha/oprofile/Makefile
+++ b/arch/alpha/oprofile/Makefile
@@ -1,4 +1,4 @@
-EXTRA_CFLAGS := -Werror -Wno-sign-compare
+ccflags-y := -Werror -Wno-sign-compare
obj-$(CONFIG_OPROFILE) += oprofile.o
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index 2e8391307f55..6dde8185205f 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -43,7 +43,7 @@ static const unsigned qsd8x50_surf_smc91x_gpio __initdata = 156;
* at run-time: they vary from board to board, and the true
* configuration won't be known until boot.
*/
-static struct resource smc91x_resources[] __initdata = {
+static struct resource smc91x_resources[] = {
[0] = {
.flags = IORESOURCE_MEM,
},
@@ -52,7 +52,7 @@ static struct resource smc91x_resources[] __initdata = {
},
};
-static struct platform_device smc91x_device __initdata = {
+static struct platform_device smc91x_device = {
.name = "smc91x",
.id = 0,
.num_resources = ARRAY_SIZE(smc91x_resources),
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index bd0495a9ac3b..22cc8c8df6cb 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -179,6 +179,22 @@ static struct omap_board_config_kernel ams_delta_config[] = {
{ OMAP_TAG_LCD, &ams_delta_lcd_config },
};
+static struct resource ams_delta_nand_resources[] = {
+ [0] = {
+ .start = OMAP1_MPUIO_BASE,
+ .end = OMAP1_MPUIO_BASE +
+ OMAP_MPUIO_IO_CNTL + sizeof(u32) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ams_delta_nand_device = {
+ .name = "ams-delta-nand",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ams_delta_nand_resources),
+ .resource = ams_delta_nand_resources,
+};
+
static struct resource ams_delta_kp_resources[] = {
[0] = {
.start = INT_KEYBOARD,
@@ -265,6 +281,7 @@ static struct omap1_cam_platform_data ams_delta_camera_platform_data = {
};
static struct platform_device *ams_delta_devices[] __initdata = {
+ &ams_delta_nand_device,
&ams_delta_kp_device,
&ams_delta_lcd_device,
&ams_delta_led_device,
diff --git a/arch/arm/mach-s5p6442/mach-smdk6442.c b/arch/arm/mach-s5p6442/mach-smdk6442.c
index e69f137b0a39..eaf6b9c489ff 100644
--- a/arch/arm/mach-s5p6442/mach-smdk6442.c
+++ b/arch/arm/mach-s5p6442/mach-smdk6442.c
@@ -68,6 +68,7 @@ static struct s3c2410_uartcfg smdk6442_uartcfgs[] __initdata = {
static struct platform_device *smdk6442_devices[] __initdata = {
&s3c_device_i2c0,
+ &samsung_asoc_dma,
&s5p6442_device_iis0,
&s3c_device_wdt,
};
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index e9802755daeb..e5beb84e2393 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -95,6 +95,7 @@ static struct platform_device *smdk6440_devices[] __initdata = {
&s3c_device_i2c1,
&s3c_device_ts,
&s3c_device_wdt,
+ &samsung_asoc_dma,
&s5p6440_device_iis,
};
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index b78f56292780..3a20de0a9264 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -113,6 +113,7 @@ static struct platform_device *smdk6450_devices[] __initdata = {
&s3c_device_i2c1,
&s3c_device_ts,
&s3c_device_wdt,
+ &samsung_asoc_dma,
&s5p6450_device_iis0,
/* s5p6450_device_spi0 will be added */
};
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
index bb20a14da100..ce11a02eabf3 100644
--- a/arch/arm/mach-s5pv210/mach-smdkc110.c
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -81,6 +81,7 @@ static struct s3c_ide_platdata smdkc110_ide_pdata __initdata = {
};
static struct platform_device *smdkc110_devices[] __initdata = {
+ &samsung_asoc_dma,
&s5pv210_device_iis0,
&s5pv210_device_ac97,
&s5pv210_device_spdif,
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index 88e45223c8af..bc9fdb52a020 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -225,6 +225,7 @@ static struct platform_device *smdkv210_devices[] __initdata = {
&s5pv210_device_ac97,
&s5pv210_device_iis0,
&s5pv210_device_spdif,
+ &samsung_asoc_dma,
&samsung_device_keypad,
&smdkv210_dm9000,
&smdkv210_lcd_lte480wv,
diff --git a/arch/arm/mach-s5pv310/mach-smdkc210.c b/arch/arm/mach-s5pv310/mach-smdkc210.c
index 2d49273c0a26..d9cab02e23ca 100644
--- a/arch/arm/mach-s5pv310/mach-smdkc210.c
+++ b/arch/arm/mach-s5pv310/mach-smdkc210.c
@@ -163,8 +163,9 @@ static struct platform_device *smdkc210_devices[] __initdata = {
&s5pv310_device_pd[PD_CAM],
&s5pv310_device_pd[PD_TV],
&s5pv310_device_pd[PD_GPS],
- &smdkc210_smsc911x,
&s5pv310_device_sysmmu,
+ &samsung_asoc_dma,
+ &smdkc210_smsc911x,
};
static void __init smdkc210_smsc911x_init(void)
diff --git a/arch/arm/mach-s5pv310/mach-smdkv310.c b/arch/arm/mach-s5pv310/mach-smdkv310.c
index 28680cf9a72c..b1cddbf3c616 100644
--- a/arch/arm/mach-s5pv310/mach-smdkv310.c
+++ b/arch/arm/mach-s5pv310/mach-smdkv310.c
@@ -163,8 +163,9 @@ static struct platform_device *smdkv310_devices[] __initdata = {
&s5pv310_device_pd[PD_CAM],
&s5pv310_device_pd[PD_TV],
&s5pv310_device_pd[PD_GPS],
- &smdkv310_smsc911x,
&s5pv310_device_sysmmu,
+ &samsung_asoc_dma,
+ &smdkv310_smsc911x,
};
static void __init smdkv310_smsc911x_init(void)
diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h
index 74b62f10d07f..4d6dd4c39b75 100644
--- a/arch/arm/plat-nomadik/include/plat/ste_dma40.h
+++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h
@@ -13,6 +13,14 @@
#include <linux/workqueue.h>
#include <linux/interrupt.h>
+/*
+ * Maxium size for a single dma descriptor
+ * Size is limited to 16 bits.
+ * Size is in the units of addr-widths (1,2,4,8 bytes)
+ * Larger transfers will be split up to multiple linked desc
+ */
+#define STEDMA40_MAX_SEG_SIZE 0xFFFF
+
/* dev types for memcpy */
#define STEDMA40_DEV_DST_MEMORY (-1)
#define STEDMA40_DEV_SRC_MEMORY (-1)
diff --git a/arch/arm/plat-omap/include/plat/onenand.h b/arch/arm/plat-omap/include/plat/onenand.h
index 72f433d7d827..affe87e9ece7 100644
--- a/arch/arm/plat-omap/include/plat/onenand.h
+++ b/arch/arm/plat-omap/include/plat/onenand.h
@@ -23,6 +23,7 @@ struct omap_onenand_platform_data {
int (*onenand_setup)(void __iomem *, int freq);
int dma_channel;
u8 flags;
+ u8 regulator_can_sleep;
};
#define ONENAND_MAX_PARTITIONS 8
diff --git a/arch/m68k/include/asm/cacheflush_no.h b/arch/m68k/include/asm/cacheflush_no.h
index 7085bd51668b..cb88aa96c4f1 100644
--- a/arch/m68k/include/asm/cacheflush_no.h
+++ b/arch/m68k/include/asm/cacheflush_no.h
@@ -2,21 +2,22 @@
#define _M68KNOMMU_CACHEFLUSH_H
/*
- * (C) Copyright 2000-2004, Greg Ungerer <gerg@snapgear.com>
+ * (C) Copyright 2000-2010, Greg Ungerer <gerg@snapgear.com>
*/
#include <linux/mm.h>
+#include <asm/mcfsim.h>
#define flush_cache_all() __flush_cache_all()
#define flush_cache_mm(mm) do { } while (0)
#define flush_cache_dup_mm(mm) do { } while (0)
-#define flush_cache_range(vma, start, end) __flush_cache_all()
+#define flush_cache_range(vma, start, end) do { } while (0)
#define flush_cache_page(vma, vmaddr) do { } while (0)
-#define flush_dcache_range(start,len) __flush_cache_all()
+#define flush_dcache_range(start, len) __flush_dcache_all()
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
#define flush_dcache_page(page) do { } while (0)
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
-#define flush_icache_range(start,len) __flush_cache_all()
+#define flush_icache_range(start, len) __flush_icache_all()
#define flush_icache_page(vma,pg) do { } while (0)
#define flush_icache_user_range(vma,pg,adr,len) do { } while (0)
#define flush_cache_vmap(start, end) do { } while (0)
@@ -27,66 +28,52 @@
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
memcpy(dst, src, len)
+void mcf_cache_push(void);
+
static inline void __flush_cache_all(void)
{
-#if defined(CONFIG_M5407) || defined(CONFIG_M548x)
- /*
- * Use cpushl to push and invalidate all cache lines.
- * Gas doesn't seem to know how to generate the ColdFire
- * cpushl instruction... Oh well, bit stuff it for now.
- */
- __asm__ __volatile__ (
- "nop\n\t"
- "clrl %%d0\n\t"
- "1:\n\t"
- "movel %%d0,%%a0\n\t"
- "2:\n\t"
- ".word 0xf468\n\t"
- "addl #0x10,%%a0\n\t"
- "cmpl #0x00000800,%%a0\n\t"
- "blt 2b\n\t"
- "addql #1,%%d0\n\t"
- "cmpil #4,%%d0\n\t"
- "bne 1b\n\t"
- "movel #0xb6088500,%%d0\n\t"
- "movec %%d0,%%CACR\n\t"
- : : : "d0", "a0" );
-#endif /* CONFIG_M5407 */
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x)
- __asm__ __volatile__ (
- "movel #0x81400100, %%d0\n\t"
- "movec %%d0, %%CACR\n\t"
- "nop\n\t"
- : : : "d0" );
-#endif /* CONFIG_M523x || CONFIG_M527x */
-#if defined(CONFIG_M528x)
- __asm__ __volatile__ (
- "movel #0x81000200, %%d0\n\t"
- "movec %%d0, %%CACR\n\t"
- "nop\n\t"
- : : : "d0" );
-#endif /* CONFIG_M528x */
-#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || defined(CONFIG_M5272)
+#ifdef CACHE_PUSH
+ mcf_cache_push();
+#endif
+#ifdef CACHE_INVALIDATE
__asm__ __volatile__ (
- "movel #0x81000100, %%d0\n\t"
+ "movel %0, %%d0\n\t"
"movec %%d0, %%CACR\n\t"
"nop\n\t"
- : : : "d0" );
-#endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */
-#ifdef CONFIG_M5249
+ : : "i" (CACHE_INVALIDATE) : "d0" );
+#endif
+}
+
+/*
+ * Some ColdFire parts implement separate instruction and data caches,
+ * on those we should just flush the appropriate cache. If we don't need
+ * to do any specific flushing then this will be optimized away.
+ */
+static inline void __flush_icache_all(void)
+{
+#ifdef CACHE_INVALIDATEI
__asm__ __volatile__ (
- "movel #0xa1000200, %%d0\n\t"
+ "movel %0, %%d0\n\t"
"movec %%d0, %%CACR\n\t"
"nop\n\t"
- : : : "d0" );
-#endif /* CONFIG_M5249 */
-#ifdef CONFIG_M532x
+ : : "i" (CACHE_INVALIDATEI) : "d0" );
+#endif
+}
+
+static inline void __flush_dcache_all(void)
+{
+#ifdef CACHE_PUSH
+ mcf_cache_push();
+#endif
+#ifdef CACHE_INVALIDATED
__asm__ __volatile__ (
- "movel #0x81000200, %%d0\n\t"
+ "movel %0, %%d0\n\t"
"movec %%d0, %%CACR\n\t"
"nop\n\t"
- : : : "d0" );
-#endif /* CONFIG_M532x */
+ : : "i" (CACHE_INVALIDATED) : "d0" );
+#else
+ /* Flush the wrtite buffer */
+ __asm__ __volatile__ ( "nop" );
+#endif
}
-
#endif /* _M68KNOMMU_CACHEFLUSH_H */
diff --git a/arch/m68k/include/asm/coldfire.h b/arch/m68k/include/asm/coldfire.h
index 3b0a34d0fe33..213028cbe110 100644
--- a/arch/m68k/include/asm/coldfire.h
+++ b/arch/m68k/include/asm/coldfire.h
@@ -32,7 +32,7 @@
*/
#define MCF_MBAR 0x10000000
#define MCF_MBAR2 0x80000000
-#if defined(CONFIG_M548x)
+#if defined(CONFIG_M54xx)
#define MCF_IPSBAR MCF_MBAR
#elif defined(CONFIG_M520x)
#define MCF_IPSBAR 0xFC000000
diff --git a/arch/m68k/include/asm/entry_no.h b/arch/m68k/include/asm/entry_no.h
index 26be277394f9..627d69bacc58 100644
--- a/arch/m68k/include/asm/entry_no.h
+++ b/arch/m68k/include/asm/entry_no.h
@@ -42,12 +42,16 @@
*/
#ifdef CONFIG_COLDFIRE
+#ifdef CONFIG_COLDFIRE_SW_A7
/*
- * This is made a little more tricky on the ColdFire. There is no
- * separate kernel and user stack pointers. Need to artificially
+ * This is made a little more tricky on older ColdFires. There is no
+ * separate supervisor and user stack pointers. Need to artificially
* construct a usp in software... When doing this we need to disable
- * interrupts, otherwise bad things could happen.
+ * interrupts, otherwise bad things will happen.
*/
+.globl sw_usp
+.globl sw_ksp
+
.macro SAVE_ALL
move #0x2700,%sr /* disable intrs */
btst #5,%sp@(2) /* from user? */
@@ -74,9 +78,7 @@
7:
.endm
-.macro RESTORE_ALL
- btst #5,%sp@(PT_SR) /* going user? */
- bnes 8f /* no, skip */
+.macro RESTORE_USER
move #0x2700,%sr /* disable intrs */
movel sw_usp,%a0 /* get usp */
movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */
@@ -91,19 +93,22 @@
subql #8,sw_usp /* set exception */
movel sw_usp,%sp /* restore usp */
rte
- 8:
- moveml %sp@,%d1-%d5/%a0-%a2
- lea %sp@(32),%sp /* space for 8 regs */
- movel %sp@+,%d0
- addql #4,%sp /* orig d0 */
- addl %sp@+,%sp /* stkadj */
- rte
.endm
+.macro RDUSP
+ movel sw_usp,%a2
+.endm
+
+.macro WRUSP
+ movel %a0,sw_usp
+.endm
+
+#else /* !CONFIG_COLDFIRE_SW_A7 */
/*
- * Quick exception save, use current stack only.
+ * Modern ColdFire parts have separate supervisor and user stack
+ * pointers. Simple load and restore macros for this case.
*/
-.macro SAVE_LOCAL
+.macro SAVE_ALL
move #0x2700,%sr /* disable intrs */
clrl %sp@- /* stkadj */
movel %d0,%sp@- /* orig d0 */
@@ -112,7 +117,7 @@
moveml %d1-%d5/%a0-%a2,%sp@
.endm
-.macro RESTORE_LOCAL
+.macro RESTORE_USER
moveml %sp@,%d1-%d5/%a0-%a2
lea %sp@(32),%sp /* space for 8 regs */
movel %sp@+,%d0
@@ -121,6 +126,18 @@
rte
.endm
+.macro RDUSP
+ /*move %usp,%a2*/
+ .word 0x4e6a
+.endm
+
+.macro WRUSP
+ /*move %a0,%usp*/
+ .word 0x4e60
+.endm
+
+#endif /* !CONFIG_COLDFIRE_SW_A7 */
+
.macro SAVE_SWITCH_STACK
lea %sp@(-24),%sp /* 6 regs */
moveml %a3-%a6/%d6-%d7,%sp@
@@ -131,14 +148,6 @@
lea %sp@(24),%sp /* 6 regs */
.endm
-/*
- * Software copy of the user and kernel stack pointers... Ugh...
- * Need these to get around ColdFire not having separate kernel
- * and user stack pointers.
- */
-.globl sw_usp
-.globl sw_ksp
-
#else /* !CONFIG_COLDFIRE */
/*
@@ -167,6 +176,6 @@
moveml %sp@+,%a3-%a6/%d6-%d7
.endm
-#endif /* !CONFIG_COLDFIRE */
+#endif /* !COLDFIRE_SW_A7 */
#endif /* __ASSEMBLY__ */
#endif /* __M68KNOMMU_ENTRY_H */
diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h
index 1b57adbafad5..c64c7b74cf86 100644
--- a/arch/m68k/include/asm/gpio.h
+++ b/arch/m68k/include/asm/gpio.h
@@ -37,7 +37,7 @@
#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M532x) || defined(CONFIG_M548x)
+ defined(CONFIG_M532x) || defined(CONFIG_M54xx)
/* These parts have GPIO organized by 8 bit ports */
diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h
index 6e2413e518cb..cf20f3097af6 100644
--- a/arch/m68k/include/asm/io_no.h
+++ b/arch/m68k/include/asm/io_no.h
@@ -145,7 +145,6 @@ static inline void io_insl(unsigned int addr, void *buf, int len)
#define IOMAP_WRITETHROUGH 3
extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
-extern void __iounmap(void *addr, unsigned long size);
static inline void *ioremap(unsigned long physaddr, unsigned long size)
{
diff --git a/arch/m68k/include/asm/m5206sim.h b/arch/m68k/include/asm/m5206sim.h
index 9c384e294af9..561b03b5ddf8 100644
--- a/arch/m68k/include/asm/m5206sim.h
+++ b/arch/m68k/include/asm/m5206sim.h
@@ -12,6 +12,10 @@
#define m5206sim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m5206)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
/*
* Define the 5206 SIM register set addresses.
@@ -88,6 +92,14 @@
#define MCFSIM_PADDR (MCF_MBAR + 0x1c5) /* Parallel Direction (r/w) */
#define MCFSIM_PADAT (MCF_MBAR + 0x1c9) /* Parallel Port Value (r/w) */
+#if defined(CONFIG_NETtel)
+#define MCFUART_BASE1 0x180 /* Base address of UART1 */
+#define MCFUART_BASE2 0x140 /* Base address of UART2 */
+#else
+#define MCFUART_BASE1 0x140 /* Base address of UART1 */
+#define MCFUART_BASE2 0x180 /* Base address of UART2 */
+#endif
+
/*
* Define system peripheral IRQ usage.
*/
@@ -95,7 +107,7 @@
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
/*
- * Generic GPIO
+ * Generic GPIO
*/
#define MCFGPIO_PIN_MAX 8
#define MCFGPIO_IRQ_VECBASE -1
diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h
index db824a4b136e..88ed8239fe4e 100644
--- a/arch/m68k/include/asm/m520xsim.h
+++ b/arch/m68k/include/asm/m520xsim.h
@@ -11,6 +11,11 @@
#define m520xsim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m520x)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
+
/*
* Define the 520x SIM register set addresses.
*/
@@ -54,6 +59,9 @@
#define MCFSIM_SDCS0 0x000a8110 /* SDRAM Chip Select 0 Configuration */
#define MCFSIM_SDCS1 0x000a8114 /* SDRAM Chip Select 1 Configuration */
+/*
+ * EPORT and GPIO registers.
+ */
#define MCFEPORT_EPDDR 0xFC088002
#define MCFEPORT_EPDR 0xFC088004
#define MCFEPORT_EPPDR 0xFC088005
@@ -97,6 +105,7 @@
#define MCFGPIO_PCLRR_UART 0xFC0A402A
#define MCFGPIO_PCLRR_FECH 0xFC0A402B
#define MCFGPIO_PCLRR_FECL 0xFC0A402C
+
/*
* Generic GPIO support
*/
@@ -109,7 +118,6 @@
#define MCFGPIO_PIN_MAX 80
#define MCFGPIO_IRQ_MAX 8
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
-/****************************************************************************/
#define MCF_GPIO_PAR_UART (0xA4036)
#define MCF_GPIO_PAR_FECI2C (0xA4033)
@@ -126,6 +134,13 @@
#define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 (0x04)
/*
+ * UART module.
+ */
+#define MCFUART_BASE1 0x60000 /* Base address of UART1 */
+#define MCFUART_BASE2 0x64000 /* Base address of UART2 */
+#define MCFUART_BASE3 0x68000 /* Base address of UART2 */
+
+/*
* Reset Controll Unit.
*/
#define MCF_RCR 0xFC0A0000
diff --git a/arch/m68k/include/asm/m523xsim.h b/arch/m68k/include/asm/m523xsim.h
index e8d06b24a48e..4ad7a00257a8 100644
--- a/arch/m68k/include/asm/m523xsim.h
+++ b/arch/m68k/include/asm/m523xsim.h
@@ -11,6 +11,10 @@
#define m523xsim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m523x)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
/*
* Define the 523x SIM register set addresses.
@@ -50,6 +54,13 @@
#define MCF_RCR_SWRESET 0x80 /* Software reset bit */
#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */
+/*
+ * UART module.
+ */
+#define MCFUART_BASE1 0x200 /* Base address of UART1 */
+#define MCFUART_BASE2 0x240 /* Base address of UART2 */
+#define MCFUART_BASE3 0x280 /* Base address of UART3 */
+
#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000)
#define MCFGPIO_PODR_DATAH (MCF_IPSBAR + 0x100001)
#define MCFGPIO_PODR_DATAL (MCF_IPSBAR + 0x100002)
diff --git a/arch/m68k/include/asm/m5249sim.h b/arch/m68k/include/asm/m5249sim.h
index 79b7b402f3c9..4908b118f2fd 100644
--- a/arch/m68k/include/asm/m5249sim.h
+++ b/arch/m68k/include/asm/m5249sim.h
@@ -11,6 +11,11 @@
#define m5249sim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m5249)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
+
/*
* Define the 5249 SIM register set addresses.
*/
@@ -56,6 +61,11 @@
#define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */
#define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */
+/*
+ * UART module.
+ */
+#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
+#define MCFUART_BASE2 0x200 /* Base address of UART2 */
/*
* Some symbol defines for the above...
diff --git a/arch/m68k/include/asm/m5272sim.h b/arch/m68k/include/asm/m5272sim.h
index df3332c2317d..b7cc50abc831 100644
--- a/arch/m68k/include/asm/m5272sim.h
+++ b/arch/m68k/include/asm/m5272sim.h
@@ -12,6 +12,11 @@
#define m5272sim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m5272)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
+
/*
* Define the 5272 SIM register set addresses.
*/
@@ -62,6 +67,9 @@
#define MCFSIM_DCMR1 0x5c /* DRAM 1 Mask reg (r/w) */
#define MCFSIM_DCCR1 0x63 /* DRAM 1 Control reg (r/w) */
+#define MCFUART_BASE1 0x100 /* Base address of UART1 */
+#define MCFUART_BASE2 0x140 /* Base address of UART2 */
+
#define MCFSIM_PACNT (MCF_MBAR + 0x80) /* Port A Control (r/w) */
#define MCFSIM_PADDR (MCF_MBAR + 0x84) /* Port A Direction (r/w) */
#define MCFSIM_PADAT (MCF_MBAR + 0x86) /* Port A Data (r/w) */
diff --git a/arch/m68k/include/asm/m527xsim.h b/arch/m68k/include/asm/m527xsim.h
index 1feb46f108ce..e8042e8bc003 100644
--- a/arch/m68k/include/asm/m527xsim.h
+++ b/arch/m68k/include/asm/m527xsim.h
@@ -11,6 +11,10 @@
#define m527xsim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m527x)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
/*
* Define the 5270/5271 SIM register set addresses.
@@ -55,6 +59,12 @@
#define MCFSIM_DMR1 0x5c /* SDRAM address mask 1 */
#endif
+/*
+ * UART module.
+ */
+#define MCFUART_BASE1 0x200 /* Base address of UART1 */
+#define MCFUART_BASE2 0x240 /* Base address of UART2 */
+#define MCFUART_BASE3 0x280 /* Base address of UART3 */
#ifdef CONFIG_M5271
#define MCFGPIO_PODR_ADDR (MCF_IPSBAR + 0x100000)
diff --git a/arch/m68k/include/asm/m528xsim.h b/arch/m68k/include/asm/m528xsim.h
index 891cbedad972..a6d2f4d9aaa0 100644
--- a/arch/m68k/include/asm/m528xsim.h
+++ b/arch/m68k/include/asm/m528xsim.h
@@ -11,6 +11,10 @@
#define m528xsim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m528x)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m52xxacr.h>
/*
* Define the 5280/5282 SIM register set addresses.
@@ -42,6 +46,13 @@
#define MCFSIM_DMR1 0x54 /* SDRAM address mask 1 */
/*
+ * UART module.
+ */
+#define MCFUART_BASE1 0x200 /* Base address of UART1 */
+#define MCFUART_BASE2 0x240 /* Base address of UART2 */
+#define MCFUART_BASE3 0x280 /* Base address of UART3 */
+
+/*
* GPIO registers
*/
#define MCFGPIO_PORTA (MCF_IPSBAR + 0x00100000)
diff --git a/arch/m68k/include/asm/m52xxacr.h b/arch/m68k/include/asm/m52xxacr.h
new file mode 100644
index 000000000000..abc391a9ae8d
--- /dev/null
+++ b/arch/m68k/include/asm/m52xxacr.h
@@ -0,0 +1,94 @@
+/****************************************************************************/
+
+/*
+ * m52xxacr.h -- ColdFire version 2 core cache support
+ *
+ * (C) Copyright 2010, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/****************************************************************************/
+#ifndef m52xxacr_h
+#define m52xxacr_h
+/****************************************************************************/
+
+/*
+ * All varients of the ColdFire using version 2 cores have a similar
+ * cache setup. Although not absolutely identical the cache register
+ * definitions are compatible for all of them. Mostly they support a
+ * configurable cache memory that can be instruction only, data only,
+ * or split instruction and data. The exception is the very old version 2
+ * core based parts, like the 5206(e), 5249 and 5272, which are instruction
+ * cache only. Cache size varies from 2k up to 16k.
+ */
+
+/*
+ * Define the Cache Control register flags.
+ */
+#define CACR_CENB 0x80000000 /* Enable cache */
+#define CACR_CDPI 0x10000000 /* Disable invalidation by CPUSHL */
+#define CACR_CFRZ 0x08000000 /* Cache freeze mode */
+#define CACR_CINV 0x01000000 /* Invalidate cache */
+#define CACR_DISI 0x00800000 /* Disable instruction cache */
+#define CACR_DISD 0x00400000 /* Disable data cache */
+#define CACR_INVI 0x00200000 /* Invalidate instruction cache */
+#define CACR_INVD 0x00100000 /* Invalidate data cache */
+#define CACR_CEIB 0x00000400 /* Non-cachable instruction burst */
+#define CACR_DCM 0x00000200 /* Default cache mode */
+#define CACR_DBWE 0x00000100 /* Buffered write enable */
+#define CACR_DWP 0x00000020 /* Write protection */
+#define CACR_EUSP 0x00000010 /* Enable separate user a7 */
+
+/*
+ * Define the Access Control register flags.
+ */
+#define ACR_BASE_POS 24 /* Address Base (upper 8 bits) */
+#define ACR_MASK_POS 16 /* Address Mask (next 8 bits) */
+#define ACR_ENABLE 0x00008000 /* Enable this ACR */
+#define ACR_USER 0x00000000 /* Allow only user accesses */
+#define ACR_SUPER 0x00002000 /* Allow supervisor access only */
+#define ACR_ANY 0x00004000 /* Allow any access type */
+#define ACR_CENB 0x00000000 /* Caching of region enabled */
+#define ACR_CDIS 0x00000040 /* Caching of region disabled */
+#define ACR_BWE 0x00000020 /* Write buffer enabled */
+#define ACR_WPROTECT 0x00000004 /* Write protect region */
+
+/*
+ * Set the cache controller settings we will use. On the cores that support
+ * a split cache configuration we allow all the combinations at Kconfig
+ * time. For those cores that only have an instruction cache we just set
+ * that as on.
+ */
+#if defined(CONFIG_CACHE_I)
+#define CACHE_TYPE (CACR_DISD + CACR_EUSP)
+#define CACHE_INVTYPEI 0
+#elif defined(CONFIG_CACHE_D)
+#define CACHE_TYPE (CACR_DISI + CACR_EUSP)
+#define CACHE_INVTYPED 0
+#elif defined(CONFIG_CACHE_BOTH)
+#define CACHE_TYPE CACR_EUSP
+#define CACHE_INVTYPEI CACR_INVI
+#define CACHE_INVTYPED CACR_INVD
+#else
+/* This is the instruction cache only devices (no split cache, no eusp) */
+#define CACHE_TYPE 0
+#define CACHE_INVTYPEI 0
+#endif
+
+#define CACHE_INIT (CACR_CINV + CACHE_TYPE)
+#define CACHE_MODE (CACR_CENB + CACHE_TYPE + CACR_DCM)
+
+#define CACHE_INVALIDATE (CACHE_MODE + CACR_CINV)
+#if defined(CACHE_INVTYPEI)
+#define CACHE_INVALIDATEI (CACHE_MODE + CACR_CINV + CACHE_INVTYPEI)
+#endif
+#if defined(CACHE_INVTYPED)
+#define CACHE_INVALIDATED (CACHE_MODE + CACR_CINV + CACHE_INVTYPED)
+#endif
+
+#define ACR0_MODE ((CONFIG_RAMBASE & 0xff000000) + \
+ (0x000f0000) + \
+ (ACR_ENABLE + ACR_ANY + ACR_CENB + ACR_BWE))
+#define ACR1_MODE 0
+
+/****************************************************************************/
+#endif /* m52xxsim_h */
diff --git a/arch/m68k/include/asm/m5307sim.h b/arch/m68k/include/asm/m5307sim.h
index c6830e5b54ce..0bf57397e7a9 100644
--- a/arch/m68k/include/asm/m5307sim.h
+++ b/arch/m68k/include/asm/m5307sim.h
@@ -14,6 +14,11 @@
#define m5307sim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m5307)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m53xxacr.h>
+
/*
* Define the 5307 SIM register set addresses.
*/
@@ -94,6 +99,17 @@
#define MCFSIM_PADAT (MCF_MBAR + 0x248)
/*
+ * UART module.
+ */
+#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
+#define MCFUART_BASE1 0x200 /* Base address of UART1 */
+#define MCFUART_BASE2 0x1c0 /* Base address of UART2 */
+#else
+#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
+#define MCFUART_BASE2 0x200 /* Base address of UART2 */
+#endif
+
+/*
* Generic GPIO support
*/
#define MCFGPIO_PIN_MAX 16
@@ -146,32 +162,5 @@
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
-/*
- * Define the Cache register flags.
- */
-#define CACR_EC (1<<31)
-#define CACR_ESB (1<<29)
-#define CACR_DPI (1<<28)
-#define CACR_HLCK (1<<27)
-#define CACR_CINVA (1<<24)
-#define CACR_DNFB (1<<10)
-#define CACR_DCM_WTHRU (0<<8)
-#define CACR_DCM_WBACK (1<<8)
-#define CACR_DCM_OFF_PRE (2<<8)
-#define CACR_DCM_OFF_IMP (3<<8)
-#define CACR_DW (1<<5)
-
-#define ACR_BASE_POS 24
-#define ACR_MASK_POS 16
-#define ACR_ENABLE (1<<15)
-#define ACR_USER (0<<13)
-#define ACR_SUPER (1<<13)
-#define ACR_ANY (2<<13)
-#define ACR_CM_WTHRU (0<<5)
-#define ACR_CM_WBACK (1<<5)
-#define ACR_CM_OFF_PRE (2<<5)
-#define ACR_CM_OFF_IMP (3<<5)
-#define ACR_WPROTECT (1<<2)
-
/****************************************************************************/
#endif /* m5307sim_h */
diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h
index c4bf1c81e3cf..e6470f8ca324 100644
--- a/arch/m68k/include/asm/m532xsim.h
+++ b/arch/m68k/include/asm/m532xsim.h
@@ -9,6 +9,11 @@
#define m532xsim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m532x)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m53xxacr.h>
+
#define MCF_REG32(x) (*(volatile unsigned long *)(x))
#define MCF_REG16(x) (*(volatile unsigned short *)(x))
#define MCF_REG08(x) (*(volatile unsigned char *)(x))
@@ -74,31 +79,11 @@
#define MCF_IRQ_PROFILER (64 + 33) /* Timer1 */
/*
- * Define the Cache register flags.
+ * UART module.
*/
-#define CACR_EC (1<<31)
-#define CACR_ESB (1<<29)
-#define CACR_DPI (1<<28)
-#define CACR_HLCK (1<<27)
-#define CACR_CINVA (1<<24)
-#define CACR_DNFB (1<<10)
-#define CACR_DCM_WTHRU (0<<8)
-#define CACR_DCM_WBACK (1<<8)
-#define CACR_DCM_OFF_PRE (2<<8)
-#define CACR_DCM_OFF_IMP (3<<8)
-#define CACR_DW (1<<5)
-
-#define ACR_BASE_POS 24
-#define ACR_MASK_POS 16
-#define ACR_ENABLE (1<<15)
-#define ACR_USER (0<<13)
-#define ACR_SUPER (1<<13)
-#define ACR_ANY (2<<13)
-#define ACR_CM_WTHRU (0<<5)
-#define ACR_CM_WBACK (1<<5)
-#define ACR_CM_OFF_PRE (2<<5)
-#define ACR_CM_OFF_IMP (3<<5)
-#define ACR_WPROTECT (1<<2)
+#define MCFUART_BASE1 0xFC060000 /* Base address of UART1 */
+#define MCFUART_BASE2 0xFC064000 /* Base address of UART2 */
+#define MCFUART_BASE3 0xFC068000 /* Base address of UART3 */
/*********************************************************************
*
diff --git a/arch/m68k/include/asm/m53xxacr.h b/arch/m68k/include/asm/m53xxacr.h
new file mode 100644
index 000000000000..cd952b0a8bd3
--- /dev/null
+++ b/arch/m68k/include/asm/m53xxacr.h
@@ -0,0 +1,101 @@
+/****************************************************************************/
+
+/*
+ * m53xxacr.h -- ColdFire version 3 core cache support
+ *
+ * (C) Copyright 2010, Greg Ungerer <gerg@snapgear.com>
+ */
+
+/****************************************************************************/
+#ifndef m53xxacr_h
+#define m53xxacr_h
+/****************************************************************************/
+
+/*
+ * All varients of the ColdFire using version 3 cores have a similar
+ * cache setup. They have a unified instruction and data cache, with
+ * configurable write-through or copy-back operation.
+ */
+
+/*
+ * Define the Cache Control register flags.
+ */
+#define CACR_EC 0x80000000 /* Enable cache */
+#define CACR_ESB 0x20000000 /* Enable store buffer */
+#define CACR_DPI 0x10000000 /* Disable invalidation by CPUSHL */
+#define CACR_HLCK 0x08000000 /* Half cache lock mode */
+#define CACR_CINVA 0x01000000 /* Invalidate cache */
+#define CACR_DNFB 0x00000400 /* Inhibited fill buffer */
+#define CACR_DCM_WT 0x00000000 /* Cacheable write-through */
+#define CACR_DCM_CB 0x00000100 /* Cacheable copy-back */
+#define CACR_DCM_PRE 0x00000200 /* Cache inhibited, precise */
+#define CACR_DCM_IMPRE 0x00000300 /* Cache inhibited, imprecise */
+#define CACR_WPROTECT 0x00000020 /* Write protect*/
+#define CACR_EUSP 0x00000010 /* Eanble separate user a7 */
+
+/*
+ * Define the Access Control register flags.
+ */
+#define ACR_BASE_POS 24 /* Address Base (upper 8 bits) */
+#define ACR_MASK_POS 16 /* Address Mask (next 8 bits) */
+#define ACR_ENABLE 0x00008000 /* Enable this ACR */
+#define ACR_USER 0x00000000 /* Allow only user accesses */
+#define ACR_SUPER 0x00002000 /* Allow supervisor access only */
+#define ACR_ANY 0x00004000 /* Allow any access type */
+#define ACR_CM_WT 0x00000000 /* Cacheable, write-through */
+#define ACR_CM_CB 0x00000020 /* Cacheable, copy-back */
+#define ACR_CM_PRE 0x00000040 /* Cache inhibited, precise */
+#define ACR_CM_IMPRE 0x00000060 /* Cache inhibited, imprecise */
+#define ACR_WPROTECT 0x00000004 /* Write protect region */
+
+/*
+ * Define the cache type and arrangement (needed for pushes).
+ */
+#if defined(CONFIG_M5307)
+#define CACHE_SIZE 0x2000 /* 8k of unified cache */
+#define ICACHE_SIZE CACHE_SIZE
+#define DCACHE_SIZE CACHE_SIZE
+#elif defined(CONFIG_M532x)
+#define CACHE_SIZE 0x4000 /* 32k of unified cache */
+#define ICACHE_SIZE CACHE_SIZE
+#define DCACHE_SIZE CACHE_SIZE
+#endif
+
+#define CACHE_LINE_SIZE 16 /* 16 byte line size */
+#define CACHE_WAYS 4 /* 4 ways - set associative */
+
+/*
+ * Set the cache controller settings we will use. This default in the
+ * CACR is cache inhibited, we use the ACR register to set cacheing
+ * enabled on the regions we want (eg RAM).
+ */
+#if defined(CONFIG_CACHE_COPYBACK)
+#define CACHE_TYPE ACR_CM_CB
+#define CACHE_PUSH
+#else
+#define CACHE_TYPE ACR_CM_WT
+#endif
+
+#ifdef CONFIG_COLDFIRE_SW_A7
+#define CACHE_MODE (CACR_EC + CACR_ESB + CACR_DCM_PRE)
+#else
+#define CACHE_MODE (CACR_EC + CACR_ESB + CACR_DCM_PRE + CACR_EUSP)
+#endif
+
+/*
+ * Unified cache means we will never need to flush for coherency of
+ * instruction fetch. We will need to flush to maintain memory/DMA
+ * coherency though in all cases. And for copyback caches we will need
+ * to push cached data as well.
+ */
+#define CACHE_INIT CACR_CINVA
+#define CACHE_INVALIDATE CACR_CINVA
+#define CACHE_INVALIDATED CACR_CINVA
+
+#define ACR0_MODE ((CONFIG_RAMBASE & 0xff000000) + \
+ (0x000f0000) + \
+ (ACR_ENABLE + ACR_ANY + CACHE_TYPE))
+#define ACR1_MODE 0
+
+/****************************************************************************/
+#endif /* m53xxsim_h */
diff --git a/arch/m68k/include/asm/m5407sim.h b/arch/m68k/include/asm/m5407sim.h
index c399abbf953c..75f5c28a551d 100644
--- a/arch/m68k/include/asm/m5407sim.h
+++ b/arch/m68k/include/asm/m5407sim.h
@@ -14,6 +14,11 @@
#define m5407sim_h
/****************************************************************************/
+#define CPU_NAME "COLDFIRE(m5407)"
+#define CPU_INSTR_PER_JIFFY 3
+
+#include <asm/m54xxacr.h>
+
/*
* Define the 5407 SIM register set addresses.
*/
@@ -73,6 +78,9 @@
#define MCFSIM_DACR1 0x110 /* DRAM 1 Addr and Ctrl (r/w) */
#define MCFSIM_DMR1 0x114 /* DRAM 1 Mask reg (r/w) */
+#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
+#define MCFUART_BASE2 0x200 /* Base address of UART2 */
+
#define MCFSIM_PADDR (MCF_MBAR + 0x244)
#define MCFSIM_PADAT (MCF_MBAR + 0x248)
@@ -117,39 +125,5 @@
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
-/*
- * Define the Cache register flags.
- */
-#define CACR_DEC 0x80000000 /* Enable data cache */
-#define CACR_DWP 0x40000000 /* Data write protection */
-#define CACR_DESB 0x20000000 /* Enable data store buffer */
-#define CACR_DDPI 0x10000000 /* Disable CPUSHL */
-#define CACR_DHCLK 0x08000000 /* Half data cache lock mode */
-#define CACR_DDCM_WT 0x00000000 /* Write through cache*/
-#define CACR_DDCM_CP 0x02000000 /* Copyback cache */
-#define CACR_DDCM_P 0x04000000 /* No cache, precise */
-#define CACR_DDCM_IMP 0x06000000 /* No cache, imprecise */
-#define CACR_DCINVA 0x01000000 /* Invalidate data cache */
-#define CACR_BEC 0x00080000 /* Enable branch cache */
-#define CACR_BCINVA 0x00040000 /* Invalidate branch cache */
-#define CACR_IEC 0x00008000 /* Enable instruction cache */
-#define CACR_DNFB 0x00002000 /* Inhibited fill buffer */
-#define CACR_IDPI 0x00001000 /* Disable CPUSHL */
-#define CACR_IHLCK 0x00000800 /* Intruction cache half lock */
-#define CACR_IDCM 0x00000400 /* Intruction cache inhibit */
-#define CACR_ICINVA 0x00000100 /* Invalidate instr cache */
-
-#define ACR_BASE_POS 24 /* Address Base */
-#define ACR_MASK_POS 16 /* Address Mask */
-#define ACR_ENABLE 0x00008000 /* Enable address */
-#define ACR_USER 0x00000000 /* User mode access only */
-#define ACR_SUPER 0x00002000 /* Supervisor mode only */
-#define ACR_ANY 0x00004000 /* Match any access mode */
-#define ACR_CM_WT 0x00000000 /* Write through mode */
-#define ACR_CM_CP 0x00000020 /* Copyback mode */
-#define ACR_CM_OFF_PRE 0x00000040 /* No cache, precise */
-#define ACR_CM_OFF_IMP 0x00000060 /* No cache, imprecise */
-#define ACR_WPROTECT 0x00000004 /* Write protect */
-
/****************************************************************************/
#endif /* m5407sim_h */
diff --git a/arch/m68k/include/asm/m54xxacr.h b/arch/m68k/include/asm/m54xxacr.h
new file mode 100644
index 000000000000..16a1835f9b2a
--- /dev/null
+++ b/arch/m68k/include/asm/m54xxacr.h
@@ -0,0 +1,97 @@
+/*
+ * Bit definitions for the MCF54xx ACR and CACR registers.
+ */
+
+#ifndef m54xxacr_h
+#define m54xxacr_h
+
+/*
+ * Define the Cache register flags.
+ */
+#define CACR_DEC 0x80000000 /* Enable data cache */
+#define CACR_DWP 0x40000000 /* Data write protection */
+#define CACR_DESB 0x20000000 /* Enable data store buffer */
+#define CACR_DDPI 0x10000000 /* Disable invalidation by CPUSHL */
+#define CACR_DHCLK 0x08000000 /* Half data cache lock mode */
+#define CACR_DDCM_WT 0x00000000 /* Write through cache*/
+#define CACR_DDCM_CP 0x02000000 /* Copyback cache */
+#define CACR_DDCM_P 0x04000000 /* No cache, precise */
+#define CACR_DDCM_IMP 0x06000000 /* No cache, imprecise */
+#define CACR_DCINVA 0x01000000 /* Invalidate data cache */
+#define CACR_BEC 0x00080000 /* Enable branch cache */
+#define CACR_BCINVA 0x00040000 /* Invalidate branch cache */
+#define CACR_IEC 0x00008000 /* Enable instruction cache */
+#define CACR_DNFB 0x00002000 /* Inhibited fill buffer */
+#define CACR_IDPI 0x00001000 /* Disable CPUSHL */
+#define CACR_IHLCK 0x00000800 /* Intruction cache half lock */
+#define CACR_IDCM 0x00000400 /* Intruction cache inhibit */
+#define CACR_ICINVA 0x00000100 /* Invalidate instr cache */
+#define CACR_EUSP 0x00000020 /* Enable separate user a7 */
+
+#define ACR_BASE_POS 24 /* Address Base */
+#define ACR_MASK_POS 16 /* Address Mask */
+#define ACR_ENABLE 0x00008000 /* Enable address */
+#define ACR_USER 0x00000000 /* User mode access only */
+#define ACR_SUPER 0x00002000 /* Supervisor mode only */
+#define ACR_ANY 0x00004000 /* Match any access mode */
+#define ACR_CM_WT 0x00000000 /* Write through mode */
+#define ACR_CM_CP 0x00000020 /* Copyback mode */
+#define ACR_CM_OFF_PRE 0x00000040 /* No cache, precise */
+#define ACR_CM_OFF_IMP 0x00000060 /* No cache, imprecise */
+#define ACR_CM 0x00000060 /* Cache mode mask */
+#define ACR_WPROTECT 0x00000004 /* Write protect */
+
+#if defined(CONFIG_M5407)
+
+#define ICACHE_SIZE 0x4000 /* instruction - 16k */
+#define DCACHE_SIZE 0x2000 /* data - 8k */
+
+#elif defined(CONFIG_M54xx)
+
+#define ICACHE_SIZE 0x8000 /* instruction - 32k */
+#define DCACHE_SIZE 0x8000 /* data - 32k */
+
+#endif
+
+#define CACHE_LINE_SIZE 0x0010 /* 16 bytes */
+#define CACHE_WAYS 4 /* 4 ways */
+
+/*
+ * Version 4 cores have a true harvard style separate instruction
+ * and data cache. Enable data and instruction caches, also enable write
+ * buffers and branch accelerator.
+ */
+/* attention : enabling CACR_DESB requires a "nop" to flush the store buffer */
+/* use '+' instead of '|' for assembler's sake */
+
+ /* Enable data cache */
+ /* Enable data store buffer */
+ /* outside ACRs : No cache, precise */
+ /* Enable instruction+branch caches */
+#if defined(CONFIG_M5407)
+#define CACHE_MODE (CACR_DEC+CACR_DESB+CACR_DDCM_P+CACR_BEC+CACR_IEC)
+#else
+#define CACHE_MODE (CACR_DEC+CACR_DESB+CACR_DDCM_P+CACR_BEC+CACR_IEC+CACR_EUSP)
+#endif
+#if defined(CONFIG_CACHE_COPYBACK)
+#define DATA_CACHE_MODE (ACR_ENABLE+ACR_ANY+ACR_CM_CP)
+#else
+#define DATA_CACHE_MODE (ACR_ENABLE+ACR_ANY+ACR_CM_WT)
+#endif
+#define INSN_CACHE_MODE (ACR_ENABLE+ACR_ANY)
+
+#define CACHE_INIT (CACR_DCINVA+CACR_BCINVA+CACR_ICINVA)
+#define CACHE_INVALIDATE (CACHE_MODE+CACR_DCINVA+CACR_BCINVA+CACR_ICINVA)
+#define CACHE_INVALIDATEI (CACHE_MODE+CACR_BCINVA+CACR_ICINVA)
+#define CACHE_INVALIDATED (CACHE_MODE+CACR_DCINVA)
+#define ACR0_MODE (0x000f0000+DATA_CACHE_MODE)
+#define ACR1_MODE 0
+#define ACR2_MODE (0x000f0000+INSN_CACHE_MODE)
+#define ACR3_MODE 0
+
+#if ((DATA_CACHE_MODE & ACR_CM) == ACR_CM_CP)
+/* Copyback cache mode must push dirty cache lines first */
+#define CACHE_PUSH
+#endif
+
+#endif /* m54xxacr_h */
diff --git a/arch/m68k/include/asm/m548xgpt.h b/arch/m68k/include/asm/m54xxgpt.h
index 33b2eef90f0a..df75dd87ae7a 100644
--- a/arch/m68k/include/asm/m548xgpt.h
+++ b/arch/m68k/include/asm/m54xxgpt.h
@@ -1,13 +1,13 @@
/*
- * File: m548xgpt.h
- * Purpose: Register and bit definitions for the MCF548X
+ * File: m54xxgpt.h
+ * Purpose: Register and bit definitions for the MCF54XX
*
* Notes:
*
*/
-#ifndef m548xgpt_h
-#define m548xgpt_h
+#ifndef m54xxgpt_h
+#define m54xxgpt_h
/*********************************************************************
*
@@ -87,4 +87,4 @@
/********************************************************************/
-#endif /* m548xgpt_h */
+#endif /* m54xxgpt_h */
diff --git a/arch/m68k/include/asm/m548xsim.h b/arch/m68k/include/asm/m54xxsim.h
index 149135ef30d2..462ae5328441 100644
--- a/arch/m68k/include/asm/m548xsim.h
+++ b/arch/m68k/include/asm/m54xxsim.h
@@ -1,11 +1,16 @@
/*
- * m548xsim.h -- ColdFire 547x/548x System Integration Unit support.
+ * m54xxsim.h -- ColdFire 547x/548x System Integration Unit support.
*/
-#ifndef m548xsim_h
-#define m548xsim_h
+#ifndef m54xxsim_h
+#define m54xxsim_h
-#define MCFINT_VECBASE 64
+#define CPU_NAME "COLDFIRE(m54xx)"
+#define CPU_INSTR_PER_JIFFY 2
+
+#include <asm/m54xxacr.h>
+
+#define MCFINT_VECBASE 64
/*
* Interrupt Controller Registers
@@ -22,6 +27,14 @@
#define MCFINTC_ICR0 0x40 /* Base ICR register */
/*
+ * UART module.
+ */
+#define MCFUART_BASE1 0x8600 /* Base address of UART1 */
+#define MCFUART_BASE2 0x8700 /* Base address of UART2 */
+#define MCFUART_BASE3 0x8800 /* Base address of UART3 */
+#define MCFUART_BASE4 0x8900 /* Base address of UART4 */
+
+/*
* Define system peripheral IRQ usage.
*/
#define MCF_IRQ_TIMER (64 + 54) /* Slice Timer 0 */
@@ -52,4 +65,4 @@
#define MCF_PAR_PSC_RTS_RTS (0x30)
#define MCF_PAR_PSC_CANRX (0x40)
-#endif /* m548xsim_h */
+#endif /* m54xxsim_h */
diff --git a/arch/m68k/include/asm/mcfcache.h b/arch/m68k/include/asm/mcfcache.h
deleted file mode 100644
index f49dfc09f70a..000000000000
--- a/arch/m68k/include/asm/mcfcache.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/****************************************************************************/
-
-/*
- * mcfcache.h -- ColdFire CPU cache support code
- *
- * (C) Copyright 2004, Greg Ungerer <gerg@snapgear.com>
- */
-
-/****************************************************************************/
-#ifndef __M68KNOMMU_MCFCACHE_H
-#define __M68KNOMMU_MCFCACHE_H
-/****************************************************************************/
-
-
-/*
- * The different ColdFire families have different cache arrangments.
- * Everything from a small instruction only cache, to configurable
- * data and/or instruction cache, to unified instruction/data, to
- * harvard style separate instruction and data caches.
- */
-
-#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || defined(CONFIG_M5272)
-/*
- * Simple version 2 core cache. These have instruction cache only,
- * we just need to invalidate it and enable it.
- */
-.macro CACHE_ENABLE
- movel #0x01000000,%d0 /* invalidate cache cmd */
- movec %d0,%CACR /* do invalidate cache */
- movel #0x80000100,%d0 /* setup cache mask */
- movec %d0,%CACR /* enable cache */
-.endm
-#endif /* CONFIG_M5206 || CONFIG_M5206e || CONFIG_M5272 */
-
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x)
-/*
- * New version 2 cores have a configurable split cache arrangement.
- * For now I am just enabling instruction cache - but ultimately I
- * think a split instruction/data cache would be better.
- */
-.macro CACHE_ENABLE
- movel #0x01400000,%d0
- movec %d0,%CACR /* invalidate cache */
- nop
- movel #0x0000c000,%d0 /* set SDRAM cached only */
- movec %d0,%ACR0
- movel #0x00000000,%d0 /* no other regions cached */
- movec %d0,%ACR1
- movel #0x80400100,%d0 /* configure cache */
- movec %d0,%CACR /* enable cache */
- nop
-.endm
-#endif /* CONFIG_M523x || CONFIG_M527x */
-
-#if defined(CONFIG_M528x)
-.macro CACHE_ENABLE
- nop
- movel #0x01000000, %d0
- movec %d0, %CACR /* Invalidate cache */
- nop
- movel #0x0000c020, %d0 /* Set SDRAM cached only */
- movec %d0, %ACR0
- movel #0x00000000, %d0 /* No other regions cached */
- movec %d0, %ACR1
- movel #0x80000200, %d0 /* Setup cache mask */
- movec %d0, %CACR /* Enable cache */
- nop
-.endm
-#endif /* CONFIG_M528x */
-
-#if defined(CONFIG_M5249) || defined(CONFIG_M5307)
-/*
- * The version 3 core cache. Oddly enough the version 2 core 5249
- * has the same SDRAM and cache setup as the version 3 cores.
- * This is a single unified instruction/data cache.
- */
-.macro CACHE_ENABLE
- movel #0x01000000,%d0 /* invalidate whole cache */
- movec %d0,%CACR
- nop
-#if defined(DEBUGGER_COMPATIBLE_CACHE) || defined(CONFIG_SECUREEDGEMP3)
- movel #0x0000c000,%d0 /* set SDRAM cached (write-thru) */
-#else
- movel #0x0000c020,%d0 /* set SDRAM cached (copyback) */
-#endif
- movec %d0,%ACR0
- movel #0x00000000,%d0 /* no other regions cached */
- movec %d0,%ACR1
- movel #0xa0000200,%d0 /* enable cache */
- movec %d0,%CACR
- nop
-.endm
-#endif /* CONFIG_M5249 || CONFIG_M5307 */
-
-#if defined(CONFIG_M532x)
-.macro CACHE_ENABLE
- movel #0x01000000,%d0 /* invalidate cache cmd */
- movec %d0,%CACR /* do invalidate cache */
- nop
- movel #0x4001C000,%d0 /* set SDRAM cached (write-thru) */
- movec %d0,%ACR0
- movel #0x00000000,%d0 /* no other regions cached */
- movec %d0,%ACR1
- movel #0x80000200,%d0 /* setup cache mask */
- movec %d0,%CACR /* enable cache */
- nop
-.endm
-#endif /* CONFIG_M532x */
-
-#if defined(CONFIG_M5407) || defined(CONFIG_M548x)
-/*
- * Version 4 cores have a true harvard style separate instruction
- * and data cache. Invalidate and enable cache, also enable write
- * buffers and branch accelerator.
- */
-.macro CACHE_ENABLE
- movel #0x01040100,%d0 /* invalidate whole cache */
- movec %d0,%CACR
- nop
- movel #0x000fc000,%d0 /* set SDRAM cached only */
- movec %d0, %ACR0
- movel #0x00000000,%d0 /* no other regions cached */
- movec %d0, %ACR1
- movel #0x000fc000,%d0 /* set SDRAM cached only */
- movec %d0, %ACR2
- movel #0x00000000,%d0 /* no other regions cached */
- movec %d0, %ACR3
- movel #0xb6088400,%d0 /* enable caches */
- movec %d0,%CACR
- nop
-.endm
-#endif /* CONFIG_M5407 */
-
-#if defined(CONFIG_M520x)
-.macro CACHE_ENABLE
- move.l #0x01000000,%d0 /* invalidate whole cache */
- movec %d0,%CACR
- nop
- move.l #0x0000c000,%d0 /* set SDRAM cached (write-thru) */
- movec %d0,%ACR0
- move.l #0x00000000,%d0 /* no other regions cached */
- movec %d0,%ACR1
- move.l #0x80400000,%d0 /* enable 8K instruction cache */
- movec %d0,%CACR
- nop
-.endm
-#endif /* CONFIG_M520x */
-
-/****************************************************************************/
-#endif /* __M68KNOMMU_MCFCACHE_H */
diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h
index 6901fd68165b..ebd0304054ad 100644
--- a/arch/m68k/include/asm/mcfsim.h
+++ b/arch/m68k/include/asm/mcfsim.h
@@ -41,8 +41,8 @@
#elif defined(CONFIG_M5407)
#include <asm/m5407sim.h>
#include <asm/mcfintc.h>
-#elif defined(CONFIG_M548x)
-#include <asm/m548xsim.h>
+#elif defined(CONFIG_M54xx)
+#include <asm/m54xxsim.h>
#endif
/****************************************************************************/
diff --git a/arch/m68k/include/asm/mcfuart.h b/arch/m68k/include/asm/mcfuart.h
index db72e2b889ca..2abedff0a694 100644
--- a/arch/m68k/include/asm/mcfuart.h
+++ b/arch/m68k/include/asm/mcfuart.h
@@ -12,49 +12,6 @@
#define mcfuart_h
/****************************************************************************/
-/*
- * Define the base address of the UARTS within the MBAR address
- * space.
- */
-#if defined(CONFIG_M5272)
-#define MCFUART_BASE1 0x100 /* Base address of UART1 */
-#define MCFUART_BASE2 0x140 /* Base address of UART2 */
-#elif defined(CONFIG_M5206) || defined(CONFIG_M5206e)
-#if defined(CONFIG_NETtel)
-#define MCFUART_BASE1 0x180 /* Base address of UART1 */
-#define MCFUART_BASE2 0x140 /* Base address of UART2 */
-#else
-#define MCFUART_BASE1 0x140 /* Base address of UART1 */
-#define MCFUART_BASE2 0x180 /* Base address of UART2 */
-#endif
-#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
-#define MCFUART_BASE1 0x200 /* Base address of UART1 */
-#define MCFUART_BASE2 0x240 /* Base address of UART2 */
-#define MCFUART_BASE3 0x280 /* Base address of UART3 */
-#elif defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407)
-#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
-#define MCFUART_BASE1 0x200 /* Base address of UART1 */
-#define MCFUART_BASE2 0x1c0 /* Base address of UART2 */
-#else
-#define MCFUART_BASE1 0x1c0 /* Base address of UART1 */
-#define MCFUART_BASE2 0x200 /* Base address of UART2 */
-#endif
-#elif defined(CONFIG_M520x)
-#define MCFUART_BASE1 0x60000 /* Base address of UART1 */
-#define MCFUART_BASE2 0x64000 /* Base address of UART2 */
-#define MCFUART_BASE3 0x68000 /* Base address of UART2 */
-#elif defined(CONFIG_M532x)
-#define MCFUART_BASE1 0xfc060000 /* Base address of UART1 */
-#define MCFUART_BASE2 0xfc064000 /* Base address of UART2 */
-#define MCFUART_BASE3 0xfc068000 /* Base address of UART3 */
-#elif defined(CONFIG_M548x)
-#define MCFUART_BASE1 0x8600 /* on M548x */
-#define MCFUART_BASE2 0x8700 /* on M548x */
-#define MCFUART_BASE3 0x8800 /* on M548x */
-#define MCFUART_BASE4 0x8900 /* on M548x */
-#endif
-
-
#include <linux/serial_core.h>
#include <linux/platform_device.h>
@@ -217,7 +174,7 @@ struct mcf_platform_uart {
#define MCFUART_URF_RXS 0xc0 /* Receiver status */
#endif
-#if defined(CONFIG_M548x)
+#if defined(CONFIG_M54xx)
#define MCFUART_TXFIFOSIZE 512
#elif defined(CONFIG_M5272)
#define MCFUART_TXFIFOSIZE 25
diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h
index 7a6a7590cc02..278c69bad57a 100644
--- a/arch/m68k/include/asm/processor.h
+++ b/arch/m68k/include/asm/processor.h
@@ -20,23 +20,26 @@
static inline unsigned long rdusp(void)
{
-#ifdef CONFIG_COLDFIRE
+#ifdef CONFIG_COLDFIRE_SW_A7
extern unsigned int sw_usp;
return sw_usp;
#else
- unsigned long usp;
- __asm__ __volatile__("move %/usp,%0" : "=a" (usp));
+ register unsigned long usp __asm__("a0");
+ /* move %usp,%a0 */
+ __asm__ __volatile__(".word 0x4e68" : "=a" (usp));
return usp;
#endif
}
static inline void wrusp(unsigned long usp)
{
-#ifdef CONFIG_COLDFIRE
+#ifdef CONFIG_COLDFIRE_SW_A7
extern unsigned int sw_usp;
sw_usp = usp;
#else
- __asm__ __volatile__("move %0,%/usp" : : "a" (usp));
+ register unsigned long a0 __asm__("a0") = usp;
+ /* move %a0,%usp */
+ __asm__ __volatile__(".word 0x4e60" : : "a" (a0) );
#endif
}
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index fa9f746cf4ae..704e7b92334c 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -75,6 +75,16 @@ config GENERIC_CLOCKEVENTS
config NO_IOPORT
def_bool y
+config COLDFIRE_SW_A7
+ bool
+ default n
+
+config HAVE_CACHE_SPLIT
+ bool
+
+config HAVE_CACHE_CB
+ bool
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
@@ -107,69 +117,90 @@ config M68360
config M5206
bool "MCF5206"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5206 processor support.
config M5206e
bool "MCF5206e"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5206e processor support.
config M520x
bool "MCF520x"
select GENERIC_CLOCKEVENTS
+ select HAVE_CACHE_SPLIT
help
Freescale Coldfire 5207/5208 processor support.
config M523x
bool "MCF523x"
select GENERIC_CLOCKEVENTS
+ select HAVE_CACHE_SPLIT
help
Freescale Coldfire 5230/1/2/4/5 processor support
config M5249
bool "MCF5249"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5249 processor support.
config M5271
bool "MCF5271"
+ select HAVE_CACHE_SPLIT
help
Freescale (Motorola) ColdFire 5270/5271 processor support.
config M5272
bool "MCF5272"
+ select COLDFIRE_SW_A7
help
Motorola ColdFire 5272 processor support.
config M5275
bool "MCF5275"
+ select HAVE_CACHE_SPLIT
help
Freescale (Motorola) ColdFire 5274/5275 processor support.
config M528x
bool "MCF528x"
select GENERIC_CLOCKEVENTS
+ select HAVE_CACHE_SPLIT
help
Motorola ColdFire 5280/5282 processor support.
config M5307
bool "MCF5307"
+ select COLDFIRE_SW_A7
+ select HAVE_CACHE_CB
help
Motorola ColdFire 5307 processor support.
config M532x
bool "MCF532x"
+ select HAVE_CACHE_CB
help
Freescale (Motorola) ColdFire 532x processor support.
config M5407
bool "MCF5407"
+ select COLDFIRE_SW_A7
+ select HAVE_CACHE_CB
help
Motorola ColdFire 5407 processor support.
+config M547x
+ bool "MCF547x"
+ select HAVE_CACHE_CB
+ help
+ Freescale ColdFire 5470/5471/5472/5473/5474/5475 processor support.
+
config M548x
bool "MCF548x"
+ select HAVE_CACHE_CB
help
Freescale ColdFire 5480/5481/5482/5483/5484/5485 processor support.
@@ -181,9 +212,14 @@ config M527x
select GENERIC_CLOCKEVENTS
default y
+config M54xx
+ bool
+ depends on (M548x || M547x)
+ default y
+
config COLDFIRE
bool
- depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407 || M548x)
+ depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407 || M54xx)
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
default y
@@ -230,6 +266,46 @@ config OLDMASK
Build support for the older revision ColdFire 5307 silicon.
Specifically this is the 1H55J mask revision.
+if HAVE_CACHE_SPLIT
+choice
+ prompt "Split Cache Configuration"
+ default CACHE_I
+
+config CACHE_I
+ bool "Instruction"
+ help
+ Use all of the ColdFire CPU cache memory as an instruction cache.
+
+config CACHE_D
+ bool "Data"
+ help
+ Use all of the ColdFire CPU cache memory as a data cache.
+
+config CACHE_BOTH
+ bool "Both"
+ help
+ Split the ColdFire CPU cache, and use half as an instruction cache
+ and half as a data cache.
+endchoice
+endif
+
+if HAVE_CACHE_CB
+choice
+ prompt "Data cache mode"
+ default CACHE_WRITETHRU
+
+config CACHE_WRITETHRU
+ bool "Write-through"
+ help
+ The ColdFire CPU cache is set into Write-through mode.
+
+config CACHE_COPYBACK
+ bool "Copy-back"
+ help
+ The ColdFire CPU cache is set into Copy-back mode.
+endchoice
+endif
+
comment "Platform"
config PILOT3
@@ -245,16 +321,16 @@ config XCOPILOT_BUGS
Support the bugs of Xcopilot.
config UC5272
- bool 'Arcturus Networks uC5272 dimm board support'
- depends on M5272
- help
- Support for the Arcturus Networks uC5272 dimm board.
+ bool 'Arcturus Networks uC5272 dimm board support'
+ depends on M5272
+ help
+ Support for the Arcturus Networks uC5272 dimm board.
config UC5282
- bool "Arcturus Networks uC5282 board support"
- depends on M528x
- help
- Support for the Arcturus Networks uC5282 dimm board.
+ bool "Arcturus Networks uC5282 board support"
+ depends on M528x
+ help
+ Support for the Arcturus Networks uC5282 dimm board.
config UCSIMM
bool "uCsimm module support"
@@ -279,7 +355,7 @@ config DIRECT_IO_ACCESS
depends on (UCSIMM || UCDIMM || DRAGEN2)
help
Disable the CPU internal registers protection in user mode,
- to allow a user application to read/write them.
+ to allow a user application to read/write them.
config INIT_LCD
bool "Initialize LCD"
@@ -517,7 +593,7 @@ config EMAC_INC
depends on (SOM5282EM)
config SNEHA
- bool
+ bool
default y
depends on CPU16B
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
index 026ef16fa68e..589613fed31d 100644
--- a/arch/m68knommu/Makefile
+++ b/arch/m68knommu/Makefile
@@ -25,7 +25,7 @@ platform-$(CONFIG_M528x) := 528x
platform-$(CONFIG_M5307) := 5307
platform-$(CONFIG_M532x) := 532x
platform-$(CONFIG_M5407) := 5407
-platform-$(CONFIG_M548x) := 548x
+platform-$(CONFIG_M54xx) := 54xx
PLATFORM := $(platform-y)
board-$(CONFIG_PILOT) := pilot
@@ -74,7 +74,7 @@ cpuclass-$(CONFIG_M528x) := coldfire
cpuclass-$(CONFIG_M5307) := coldfire
cpuclass-$(CONFIG_M532x) := coldfire
cpuclass-$(CONFIG_M5407) := coldfire
-cpuclass-$(CONFIG_M548x) := coldfire
+cpuclass-$(CONFIG_M54xx) := coldfire
cpuclass-$(CONFIG_M68328) := 68328
cpuclass-$(CONFIG_M68EZ328) := 68328
cpuclass-$(CONFIG_M68VZ328) := 68328
@@ -91,18 +91,18 @@ export PLATFORM BOARD MODEL CPUCLASS
# Some CFLAG additions based on specific CPU type.
#
cflags-$(CONFIG_M5206) := $(call cc-option,-mcpu=5206,-m5200)
-cflags-$(CONFIG_M5206e) := $(call cc-option,-m5206e,-m5200)
+cflags-$(CONFIG_M5206e) := $(call cc-option,-mcpu=5206e,-m5200)
cflags-$(CONFIG_M520x) := $(call cc-option,-mcpu=5208,-m5200)
cflags-$(CONFIG_M523x) := $(call cc-option,-mcpu=523x,-m5307)
cflags-$(CONFIG_M5249) := $(call cc-option,-mcpu=5249,-m5200)
cflags-$(CONFIG_M5271) := $(call cc-option,-mcpu=5271,-m5307)
cflags-$(CONFIG_M5272) := $(call cc-option,-mcpu=5272,-m5307)
cflags-$(CONFIG_M5275) := $(call cc-option,-mcpu=5275,-m5307)
-cflags-$(CONFIG_M528x) := $(call cc-option,-m528x,-m5307)
-cflags-$(CONFIG_M5307) := $(call cc-option,-m5307,-m5200)
+cflags-$(CONFIG_M528x) := $(call cc-option,-mcpu=528x,-m5307)
+cflags-$(CONFIG_M5307) := $(call cc-option,-mcpu=5307,-m5200)
cflags-$(CONFIG_M532x) := $(call cc-option,-mcpu=532x,-m5307)
-cflags-$(CONFIG_M5407) := $(call cc-option,-m5407,-m5200)
-cflags-$(CONFIG_M548x) := $(call cc-option,-m5407,-m5200)
+cflags-$(CONFIG_M5407) := $(call cc-option,-mcpu=5407,-m5200)
+cflags-$(CONFIG_M54xx) := $(call cc-option,-mcpu=5475,-m5200)
cflags-$(CONFIG_M68328) := -m68000
cflags-$(CONFIG_M68EZ328) := -m68000
cflags-$(CONFIG_M68VZ328) := -m68000
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index c684adf5dc40..16b2de7f5101 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -55,55 +55,29 @@ void (*mach_halt)(void);
void (*mach_power_off)(void);
#ifdef CONFIG_M68328
- #define CPU "MC68328"
+#define CPU_NAME "MC68328"
#endif
#ifdef CONFIG_M68EZ328
- #define CPU "MC68EZ328"
+#define CPU_NAME "MC68EZ328"
#endif
#ifdef CONFIG_M68VZ328
- #define CPU "MC68VZ328"
+#define CPU_NAME "MC68VZ328"
#endif
#ifdef CONFIG_M68360
- #define CPU "MC68360"
+#define CPU_NAME "MC68360"
#endif
-#if defined(CONFIG_M5206)
- #define CPU "COLDFIRE(m5206)"
+#ifndef CPU_NAME
+#define CPU_NAME "UNKNOWN"
#endif
-#if defined(CONFIG_M5206e)
- #define CPU "COLDFIRE(m5206e)"
-#endif
-#if defined(CONFIG_M520x)
- #define CPU "COLDFIRE(m520x)"
-#endif
-#if defined(CONFIG_M523x)
- #define CPU "COLDFIRE(m523x)"
-#endif
-#if defined(CONFIG_M5249)
- #define CPU "COLDFIRE(m5249)"
-#endif
-#if defined(CONFIG_M5271)
- #define CPU "COLDFIRE(m5270/5271)"
-#endif
-#if defined(CONFIG_M5272)
- #define CPU "COLDFIRE(m5272)"
-#endif
-#if defined(CONFIG_M5275)
- #define CPU "COLDFIRE(m5274/5275)"
-#endif
-#if defined(CONFIG_M528x)
- #define CPU "COLDFIRE(m5280/5282)"
-#endif
-#if defined(CONFIG_M5307)
- #define CPU "COLDFIRE(m5307)"
-#endif
-#if defined(CONFIG_M532x)
- #define CPU "COLDFIRE(m532x)"
-#endif
-#if defined(CONFIG_M5407)
- #define CPU "COLDFIRE(m5407)"
-#endif
-#ifndef CPU
- #define CPU "UNKNOWN"
+
+/*
+ * Different cores have different instruction execution timings.
+ * The old/traditional 68000 cores are basically all the same, at 16.
+ * The ColdFire cores vary a little, their values are defined in their
+ * headers. We default to the standard 68000 value here.
+ */
+#ifndef CPU_INSTR_PER_JIFFY
+#define CPU_INSTR_PER_JIFFY 16
#endif
extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
@@ -208,7 +182,7 @@ void __init setup_arch(char **cmdline_p)
command_line[sizeof(command_line) - 1] = 0;
#endif /* CONFIG_UBOOT */
- printk(KERN_INFO "\x0F\r\n\nuClinux/" CPU "\n");
+ printk(KERN_INFO "\x0F\r\n\nuClinux/" CPU_NAME "\n");
#ifdef CONFIG_UCDIMM
printk(KERN_INFO "uCdimm by Lineo, Inc. <www.lineo.com>\n");
@@ -257,11 +231,6 @@ void __init setup_arch(char **cmdline_p)
memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
boot_command_line[COMMAND_LINE_SIZE-1] = 0;
-#ifdef DEBUG
- if (strlen(*cmdline_p))
- printk(KERN_DEBUG "Command line: '%s'\n", *cmdline_p);
-#endif
-
#if defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &dummy_con;
#endif
@@ -303,15 +272,10 @@ static int show_cpuinfo(struct seq_file *m, void *v)
char *cpu, *mmu, *fpu;
u_long clockfreq;
- cpu = CPU;
+ cpu = CPU_NAME;
mmu = "none";
fpu = "none";
-
-#ifdef CONFIG_COLDFIRE
- clockfreq = (loops_per_jiffy * HZ) * 3;
-#else
- clockfreq = (loops_per_jiffy * HZ) * 16;
-#endif
+ clockfreq = (loops_per_jiffy * HZ) * CPU_INSTR_PER_JIFFY;
seq_printf(m, "CPU:\t\t%s\n"
"MMU:\t\t%s\n"
diff --git a/arch/m68knommu/mm/Makefile b/arch/m68knommu/mm/Makefile
index fc91f254f51b..b54ab6b4b523 100644
--- a/arch/m68knommu/mm/Makefile
+++ b/arch/m68knommu/mm/Makefile
@@ -2,4 +2,4 @@
# Makefile for the linux m68knommu specific parts of the memory manager.
#
-obj-y += init.o fault.o memory.o kmap.o
+obj-y += init.o kmap.o
diff --git a/arch/m68knommu/mm/fault.c b/arch/m68knommu/mm/fault.c
deleted file mode 100644
index bc05cf74d9c0..000000000000
--- a/arch/m68knommu/mm/fault.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * linux/arch/m68knommu/mm/fault.c
- *
- * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
- * Copyright (C) 2000 Lineo, Inc. (www.lineo.com)
- *
- * Based on:
- *
- * linux/arch/m68k/mm/fault.c
- *
- * Copyright (C) 1995 Hamish Macdonald
- */
-
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/ptrace.h>
-
-#include <asm/system.h>
-#include <asm/pgtable.h>
-
-extern void die_if_kernel(char *, struct pt_regs *, long);
-
-/*
- * This routine handles page faults. It determines the problem, and
- * then passes it off to one of the appropriate routines.
- *
- * error_code:
- * bit 0 == 0 means no page found, 1 means protection fault
- * bit 1 == 0 means read, 1 means write
- *
- * If this routine detects a bad access, it returns 1, otherwise it
- * returns 0.
- */
-asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
- unsigned long error_code)
-{
-#ifdef DEBUG
- printk(KERN_DEBUG "regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld\n",
- regs->sr, regs->pc, address, error_code);
-#endif
-
- /*
- * Oops. The kernel tried to access some bad page. We'll have to
- * terminate things with extreme prejudice.
- */
- if ((unsigned long) address < PAGE_SIZE)
- printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
- else
- printk(KERN_ALERT "Unable to handle kernel access");
- printk(KERN_ALERT " at virtual address %08lx\n", address);
- die_if_kernel("Oops", regs, error_code);
- do_exit(SIGKILL);
-
- return 1;
-}
-
diff --git a/arch/m68knommu/mm/kmap.c b/arch/m68knommu/mm/kmap.c
index 902c1dfda9e5..ece8d5ad4e6c 100644
--- a/arch/m68knommu/mm/kmap.c
+++ b/arch/m68knommu/mm/kmap.c
@@ -36,15 +36,6 @@ void iounmap(void *addr)
}
/*
- * __iounmap unmaps nearly everything, so be careful
- * it doesn't free currently pointer/page tables anymore but it
- * wans't used anyway and might be added later.
- */
-void __iounmap(void *addr, unsigned long size)
-{
-}
-
-/*
* Set new cache mode for some kernel address space.
* The caller must push data for that range itself, if such data may already
* be in the cache.
diff --git a/arch/m68knommu/mm/memory.c b/arch/m68knommu/mm/memory.c
deleted file mode 100644
index 8f7949e786d4..000000000000
--- a/arch/m68knommu/mm/memory.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * linux/arch/m68knommu/mm/memory.c
- *
- * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
- * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
- *
- * Based on:
- *
- * linux/arch/m68k/mm/memory.c
- *
- * Copyright (C) 1995 Hamish Macdonald
- */
-
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/types.h>
-
-#include <asm/segment.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-
-/*
- * Map some physical address range into the kernel address space.
- */
-
-unsigned long kernel_map(unsigned long paddr, unsigned long size,
- int nocacheflag, unsigned long *memavailp )
-{
- return paddr;
-}
-
diff --git a/arch/m68knommu/platform/548x/Makefile b/arch/m68knommu/platform/54xx/Makefile
index e6035e7a2d3f..e6035e7a2d3f 100644
--- a/arch/m68knommu/platform/548x/Makefile
+++ b/arch/m68knommu/platform/54xx/Makefile
diff --git a/arch/m68knommu/platform/548x/config.c b/arch/m68knommu/platform/54xx/config.c
index 9888846bd1cf..78130984db95 100644
--- a/arch/m68knommu/platform/548x/config.c
+++ b/arch/m68knommu/platform/54xx/config.c
@@ -1,7 +1,7 @@
/***************************************************************************/
/*
- * linux/arch/m68knommu/platform/548x/config.c
+ * linux/arch/m68knommu/platform/54xx/config.c
*
* Copyright (C) 2010, Philippe De Muyter <phdm@macqel.be>
*/
@@ -15,13 +15,13 @@
#include <linux/io.h>
#include <asm/machdep.h>
#include <asm/coldfire.h>
-#include <asm/m548xsim.h>
+#include <asm/m54xxsim.h>
#include <asm/mcfuart.h>
-#include <asm/m548xgpt.h>
+#include <asm/m54xxgpt.h>
/***************************************************************************/
-static struct mcf_platform_uart m548x_uart_platform[] = {
+static struct mcf_platform_uart m54xx_uart_platform[] = {
{
.mapbase = MCF_MBAR + MCFUART_BASE1,
.irq = 64 + 35,
@@ -40,20 +40,20 @@ static struct mcf_platform_uart m548x_uart_platform[] = {
},
};
-static struct platform_device m548x_uart = {
+static struct platform_device m54xx_uart = {
.name = "mcfuart",
.id = 0,
- .dev.platform_data = m548x_uart_platform,
+ .dev.platform_data = m54xx_uart_platform,
};
-static struct platform_device *m548x_devices[] __initdata = {
- &m548x_uart,
+static struct platform_device *m54xx_devices[] __initdata = {
+ &m54xx_uart,
};
/***************************************************************************/
-static void __init m548x_uart_init_line(int line, int irq)
+static void __init m54xx_uart_init_line(int line, int irq)
{
int rts_cts;
@@ -72,18 +72,18 @@ static void __init m548x_uart_init_line(int line, int irq)
MCF_MBAR + MCF_PAR_PSC(line));
}
-static void __init m548x_uarts_init(void)
+static void __init m54xx_uarts_init(void)
{
- const int nrlines = ARRAY_SIZE(m548x_uart_platform);
+ const int nrlines = ARRAY_SIZE(m54xx_uart_platform);
int line;
for (line = 0; (line < nrlines); line++)
- m548x_uart_init_line(line, m548x_uart_platform[line].irq);
+ m54xx_uart_init_line(line, m54xx_uart_platform[line].irq);
}
/***************************************************************************/
-static void mcf548x_reset(void)
+static void mcf54xx_reset(void)
{
/* disable interrupts and enable the watchdog */
asm("movew #0x2700, %sr\n");
@@ -97,8 +97,8 @@ static void mcf548x_reset(void)
void __init config_BSP(char *commandp, int size)
{
- mach_reset = mcf548x_reset;
- m548x_uarts_init();
+ mach_reset = mcf54xx_reset;
+ m54xx_uarts_init();
}
/***************************************************************************/
@@ -106,7 +106,7 @@ void __init config_BSP(char *commandp, int size)
static int __init init_BSP(void)
{
- platform_add_devices(m548x_devices, ARRAY_SIZE(m548x_devices));
+ platform_add_devices(m54xx_devices, ARRAY_SIZE(m54xx_devices));
return 0;
}
diff --git a/arch/m68knommu/platform/68328/ints.c b/arch/m68knommu/platform/68328/ints.c
index 865852806a17..2a3af193ccd3 100644
--- a/arch/m68knommu/platform/68328/ints.c
+++ b/arch/m68knommu/platform/68328/ints.c
@@ -179,8 +179,8 @@ void __init init_IRQ(void)
IMR = ~0;
for (i = 0; (i < NR_IRQS); i++) {
- set_irq_chip(irq, &intc_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ set_irq_chip(i, &intc_irq_chip);
+ set_irq_handler(i, handle_level_irq);
}
}
diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile
index 45f501fa4525..a8967baabd72 100644
--- a/arch/m68knommu/platform/coldfire/Makefile
+++ b/arch/m68knommu/platform/coldfire/Makefile
@@ -14,7 +14,7 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
-obj-$(CONFIG_COLDFIRE) += clk.o dma.o entry.o vectors.o
+obj-$(CONFIG_COLDFIRE) += cache.o clk.o dma.o entry.o vectors.o
obj-$(CONFIG_M5206) += timers.o intc.o
obj-$(CONFIG_M5206e) += timers.o intc.o
obj-$(CONFIG_M520x) += pit.o intc-simr.o
@@ -26,7 +26,7 @@ obj-$(CONFIG_M528x) += pit.o intc-2.o
obj-$(CONFIG_M5307) += timers.o intc.o
obj-$(CONFIG_M532x) += timers.o intc-simr.o
obj-$(CONFIG_M5407) += timers.o intc.o
-obj-$(CONFIG_M548x) += sltimers.o intc-2.o
+obj-$(CONFIG_M54xx) += sltimers.o intc-2.o
obj-y += pinmux.o gpio.o
extra-y := head.o
diff --git a/arch/m68knommu/platform/coldfire/cache.c b/arch/m68knommu/platform/coldfire/cache.c
new file mode 100644
index 000000000000..235d3c4f4f0f
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/cache.c
@@ -0,0 +1,48 @@
+/***************************************************************************/
+
+/*
+ * cache.c -- general ColdFire Cache maintainence code
+ *
+ * Copyright (C) 2010, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/***************************************************************************/
+#ifdef CACHE_PUSH
+/***************************************************************************/
+
+/*
+ * Use cpushl to push all dirty cache lines back to memory.
+ * Older versions of GAS don't seem to know how to generate the
+ * ColdFire cpushl instruction... Oh well, bit stuff it for now.
+ */
+
+void mcf_cache_push(void)
+{
+ __asm__ __volatile__ (
+ "clrl %%d0\n\t"
+ "1:\n\t"
+ "movel %%d0,%%a0\n\t"
+ "2:\n\t"
+ ".word 0xf468\n\t"
+ "addl %0,%%a0\n\t"
+ "cmpl %1,%%a0\n\t"
+ "blt 2b\n\t"
+ "addql #1,%%d0\n\t"
+ "cmpil %2,%%d0\n\t"
+ "bne 1b\n\t"
+ : /* No output */
+ : "i" (CACHE_LINE_SIZE),
+ "i" (DCACHE_SIZE / CACHE_WAYS),
+ "i" (CACHE_WAYS)
+ : "d0", "a0" );
+}
+
+/***************************************************************************/
+#endif /* CACHE_PUSH */
+/***************************************************************************/
diff --git a/arch/m68knommu/platform/coldfire/entry.S b/arch/m68knommu/platform/coldfire/entry.S
index e1debc8285ef..4ddfc3da70d8 100644
--- a/arch/m68knommu/platform/coldfire/entry.S
+++ b/arch/m68knommu/platform/coldfire/entry.S
@@ -36,13 +36,16 @@
#include <asm/asm-offsets.h>
#include <asm/entry.h>
+#ifdef CONFIG_COLDFIRE_SW_A7
+/*
+ * Define software copies of the supervisor and user stack pointers.
+ */
.bss
-
sw_ksp:
.long 0
-
sw_usp:
.long 0
+#endif /* CONFIG_COLDFIRE_SW_A7 */
.text
@@ -51,7 +54,6 @@ sw_usp:
.globl ret_from_exception
.globl ret_from_signal
.globl sys_call_table
-.globl ret_from_interrupt
.globl inthandler
.globl fasthandler
@@ -140,20 +142,7 @@ Luser_return:
jne Lwork_to_do /* still work to do */
Lreturn:
- move #0x2700,%sr /* disable intrs */
- movel sw_usp,%a0 /* get usp */
- movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */
- movel %sp@(PT_OFF_FORMATVEC),%a0@- /* copy exception format/vector/sr */
- moveml %sp@,%d1-%d5/%a0-%a2
- lea %sp@(32),%sp /* space for 8 regs */
- movel %sp@+,%d0
- addql #4,%sp /* orig d0 */
- addl %sp@+,%sp /* stk adj */
- addql #8,%sp /* remove exception */
- movel %sp,sw_ksp /* save ksp */
- subql #8,sw_usp /* set exception */
- movel sw_usp,%sp /* restore usp */
- rte
+ RESTORE_USER
Lwork_to_do:
movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */
@@ -191,31 +180,7 @@ ENTRY(inthandler)
jbsr do_IRQ /* call high level irq handler */
lea %sp@(8),%sp /* pop args off stack */
- bra ret_from_interrupt /* this was fallthrough */
-
-/*
- * This is the fast interrupt handler (for certain hardware interrupt
- * sources). Unlike the normal interrupt handler it just uses the
- * current stack (doesn't care if it is user or kernel). It also
- * doesn't bother doing the bottom half handlers.
- */
-ENTRY(fasthandler)
- SAVE_LOCAL
-
- movew %sp@(PT_OFF_FORMATVEC),%d0
- andl #0x03fc,%d0 /* mask out vector only */
-
- movel %sp,%sp@- /* push regs arg */
- lsrl #2,%d0 /* calculate real vector # */
- movel %d0,%sp@- /* push vector number */
- jbsr do_IRQ /* call high level irq handler */
- lea %sp@(8),%sp /* pop args off stack */
-
- RESTORE_LOCAL
-
-ENTRY(ret_from_interrupt)
- /* the fasthandler is confusing me, haven't seen any user */
- jmp ret_from_exception
+ bra ret_from_exception
/*
* Beware - when entering resume, prev (the current task) is
@@ -226,9 +191,8 @@ ENTRY(ret_from_interrupt)
*/
ENTRY(resume)
movel %a0, %d1 /* get prev thread in d1 */
-
- movel sw_usp,%d0 /* save usp */
- movel %d0,%a0@(TASK_THREAD+THREAD_USP)
+ RDUSP
+ movel %a2,%a0@(TASK_THREAD+THREAD_USP)
SAVE_SWITCH_STACK
movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */
@@ -236,5 +200,5 @@ ENTRY(resume)
RESTORE_SWITCH_STACK
movel %a1@(TASK_THREAD+THREAD_USP),%a0 /* restore thread user stack */
- movel %a0, sw_usp
+ WRUSP
rts
diff --git a/arch/m68knommu/platform/coldfire/head.S b/arch/m68knommu/platform/coldfire/head.S
index 0b2d7c7adf79..d5977909ae5f 100644
--- a/arch/m68knommu/platform/coldfire/head.S
+++ b/arch/m68knommu/platform/coldfire/head.S
@@ -3,7 +3,7 @@
/*
* head.S -- common startup code for ColdFire CPUs.
*
- * (C) Copyright 1999-2006, Greg Ungerer <gerg@snapgear.com>.
+ * (C) Copyright 1999-2010, Greg Ungerer <gerg@snapgear.com>.
*/
/*****************************************************************************/
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <asm/asm-offsets.h>
#include <asm/coldfire.h>
-#include <asm/mcfcache.h>
#include <asm/mcfsim.h>
#include <asm/thread_info.h>
@@ -173,10 +172,27 @@ _start:
/*
* Now that we know what the memory is, lets enable cache
- * and get things moving. This is Coldfire CPU specific.
+ * and get things moving. This is Coldfire CPU specific. Not
+ * all version cores have identical cache register setup. But
+ * it is very similar. Define the exact settings in the headers
+ * then the code here is the same for all.
*/
- CACHE_ENABLE /* enable CPU cache */
-
+ movel #CACHE_INIT,%d0 /* invalidate whole cache */
+ movec %d0,%CACR
+ nop
+ movel #ACR0_MODE,%d0 /* set RAM region for caching */
+ movec %d0,%ACR0
+ movel #ACR1_MODE,%d0 /* anything else to cache? */
+ movec %d0,%ACR1
+#ifdef ACR2_MODE
+ movel #ACR2_MODE,%d0
+ movec %d0,%ACR2
+ movel #ACR3_MODE,%d0
+ movec %d0,%ACR3
+#endif
+ movel #CACHE_MODE,%d0 /* enable cache */
+ movec %d0,%CACR
+ nop
#ifdef CONFIG_ROMFS_FS
/*
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h
index cae268c22ba2..b23f68075879 100644
--- a/arch/microblaze/include/asm/pgtable.h
+++ b/arch/microblaze/include/asm/pgtable.h
@@ -444,8 +444,9 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
*ptep = pte;
}
-static inline int ptep_test_and_clear_young(struct mm_struct *mm,
- unsigned long addr, pte_t *ptep)
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
+ unsigned long address, pte_t *ptep)
{
return (pte_update(ptep, _PAGE_ACCESSED, 0) & _PAGE_ACCESSED) != 0;
}
@@ -457,6 +458,7 @@ static inline int ptep_test_and_clear_dirty(struct mm_struct *mm,
(_PAGE_DIRTY | _PAGE_HWWRITE), 0) & _PAGE_DIRTY) != 0;
}
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
diff --git a/arch/microblaze/include/asm/tlb.h b/arch/microblaze/include/asm/tlb.h
index e8abd4a0349c..8aa97817cc8c 100644
--- a/arch/microblaze/include/asm/tlb.h
+++ b/arch/microblaze/include/asm/tlb.h
@@ -13,6 +13,7 @@
#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+#include <linux/pagemap.h>
#include <asm-generic/tlb.h>
#ifdef CONFIG_MMU
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index c881393f07fd..bceaa5543e39 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -47,9 +47,9 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
memblock_add(base, size);
}
-u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
{
- return memblock_alloc(size, align);
+ return __va(memblock_alloc(size, align));
}
#ifdef CONFIG_EARLY_PRINTK
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index 78439b8a83c4..7ff9b5492041 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -2,6 +2,7 @@
platforms += alchemy
platforms += ar7
+platforms += ath79
platforms += bcm47xx
platforms += bcm63xx
platforms += cavium-octeon
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index f489ec30e071..548e6cc3bc28 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -21,6 +21,7 @@ config MIPS
select HAVE_DMA_API_DEBUG
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
+ select HAVE_ARCH_JUMP_LABEL
menu "Machine selection"
@@ -65,6 +66,22 @@ config AR7
Support for the Texas Instruments AR7 System-on-a-Chip
family: TNETD7100, 7200 and 7300.
+config ATH79
+ bool "Atheros AR71XX/AR724X/AR913X based boards"
+ select ARCH_REQUIRE_GPIOLIB
+ select BOOT_RAW
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select MIPS_MACHINE
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ help
+ Support for the Atheros AR71XX/AR724X/AR913X SoCs.
+
config BCM47XX
bool "Broadcom BCM47XX based boards"
select CEVT_R4K
@@ -717,6 +734,7 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
endchoice
source "arch/mips/alchemy/Kconfig"
+source "arch/mips/ath79/Kconfig"
source "arch/mips/bcm63xx/Kconfig"
source "arch/mips/jazz/Kconfig"
source "arch/mips/jz4740/Kconfig"
@@ -883,6 +901,9 @@ config MIPS_DISABLE_OBSOLETE_IDE
config SYNC_R4K
bool
+config MIPS_MACHINE
+ def_bool n
+
config NO_IOPORT
def_bool n
@@ -2400,4 +2421,20 @@ source "security/Kconfig"
source "crypto/Kconfig"
+menuconfig VIRTUALIZATION
+ bool "Virtualization"
+ default n
+ ---help---
+ Say Y here to get to see options for using your Linux host to run other
+ operating systems inside virtual machines (guests).
+ This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
+
+if VIRTUALIZATION
+
+source drivers/virtio/Kconfig
+
+endif # VIRTUALIZATION
+
source "lib/Kconfig"
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
new file mode 100644
index 000000000000..b05828260f7f
--- /dev/null
+++ b/arch/mips/ath79/Kconfig
@@ -0,0 +1,50 @@
+if ATH79
+
+menu "Atheros AR71XX/AR724X/AR913X machine selection"
+
+config ATH79_MACH_AP81
+ bool "Atheros AP81 reference board"
+ select SOC_AR913X
+ select ATH79_DEV_AR913X_WMAC
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_SPI
+ help
+ Say 'Y' here if you want your kernel to support the
+ Atheros AP81 reference board.
+
+config ATH79_MACH_PB44
+ bool "Atheros PB44 reference board"
+ select SOC_AR71XX
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_SPI
+ help
+ Say 'Y' here if you want your kernel to support the
+ Atheros PB44 reference board.
+
+endmenu
+
+config SOC_AR71XX
+ def_bool n
+
+config SOC_AR724X
+ def_bool n
+
+config SOC_AR913X
+ def_bool n
+
+config ATH79_DEV_AR913X_WMAC
+ depends on SOC_AR913X
+ def_bool n
+
+config ATH79_DEV_GPIO_BUTTONS
+ def_bool n
+
+config ATH79_DEV_LEDS_GPIO
+ def_bool n
+
+config ATH79_DEV_SPI
+ def_bool n
+
+endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
new file mode 100644
index 000000000000..c33d4653007c
--- /dev/null
+++ b/arch/mips/ath79/Makefile
@@ -0,0 +1,28 @@
+#
+# Makefile for the Atheros AR71XX/AR724X/AR913X specific parts of the kernel
+#
+# Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+# Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 as published
+# by the Free Software Foundation.
+
+obj-y := prom.o setup.o irq.o common.o clock.o gpio.o
+
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+
+#
+# Devices
+#
+obj-y += dev-common.o
+obj-$(CONFIG_ATH79_DEV_AR913X_WMAC) += dev-ar913x-wmac.o
+obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o
+obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o
+obj-$(CONFIG_ATH79_DEV_SPI) += dev-spi.o
+
+#
+# Machines
+#
+obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o
+obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o
diff --git a/arch/mips/ath79/Platform b/arch/mips/ath79/Platform
new file mode 100644
index 000000000000..2bd663647d27
--- /dev/null
+++ b/arch/mips/ath79/Platform
@@ -0,0 +1,7 @@
+#
+# Atheros AR71xx/AR724x/AR913x
+#
+
+platform-$(CONFIG_ATH79) += ath79/
+cflags-$(CONFIG_ATH79) += -I$(srctree)/arch/mips/include/asm/mach-ath79
+load-$(CONFIG_ATH79) = 0xffffffff80060000
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
new file mode 100644
index 000000000000..680bde99a26c
--- /dev/null
+++ b/arch/mips/ath79/clock.c
@@ -0,0 +1,183 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common routines
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+
+#define AR71XX_BASE_FREQ 40000000
+#define AR724X_BASE_FREQ 5000000
+#define AR913X_BASE_FREQ 5000000
+
+struct clk {
+ unsigned long rate;
+};
+
+static struct clk ath79_ref_clk;
+static struct clk ath79_cpu_clk;
+static struct clk ath79_ddr_clk;
+static struct clk ath79_ahb_clk;
+static struct clk ath79_wdt_clk;
+static struct clk ath79_uart_clk;
+
+static void __init ar71xx_clocks_init(void)
+{
+ u32 pll;
+ u32 freq;
+ u32 div;
+
+ ath79_ref_clk.rate = AR71XX_BASE_FREQ;
+
+ pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
+
+ div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
+ freq = div * ath79_ref_clk.rate;
+
+ div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
+ ath79_cpu_clk.rate = freq / div;
+
+ div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
+ ath79_ddr_clk.rate = freq / div;
+
+ div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
+ ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
+
+ ath79_wdt_clk.rate = ath79_ahb_clk.rate;
+ ath79_uart_clk.rate = ath79_ahb_clk.rate;
+}
+
+static void __init ar724x_clocks_init(void)
+{
+ u32 pll;
+ u32 freq;
+ u32 div;
+
+ ath79_ref_clk.rate = AR724X_BASE_FREQ;
+ pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
+
+ div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK);
+ freq = div * ath79_ref_clk.rate;
+
+ div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
+ freq *= div;
+
+ ath79_cpu_clk.rate = freq;
+
+ div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
+ ath79_ddr_clk.rate = freq / div;
+
+ div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
+ ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
+
+ ath79_wdt_clk.rate = ath79_ahb_clk.rate;
+ ath79_uart_clk.rate = ath79_ahb_clk.rate;
+}
+
+static void __init ar913x_clocks_init(void)
+{
+ u32 pll;
+ u32 freq;
+ u32 div;
+
+ ath79_ref_clk.rate = AR913X_BASE_FREQ;
+ pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG);
+
+ div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK);
+ freq = div * ath79_ref_clk.rate;
+
+ ath79_cpu_clk.rate = freq;
+
+ div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1;
+ ath79_ddr_clk.rate = freq / div;
+
+ div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2;
+ ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
+
+ ath79_wdt_clk.rate = ath79_ahb_clk.rate;
+ ath79_uart_clk.rate = ath79_ahb_clk.rate;
+}
+
+void __init ath79_clocks_init(void)
+{
+ if (soc_is_ar71xx())
+ ar71xx_clocks_init();
+ else if (soc_is_ar724x())
+ ar724x_clocks_init();
+ else if (soc_is_ar913x())
+ ar913x_clocks_init();
+ else
+ BUG();
+
+ pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, "
+ "Ref:%lu.%03luMHz",
+ ath79_cpu_clk.rate / 1000000,
+ (ath79_cpu_clk.rate / 1000) % 1000,
+ ath79_ddr_clk.rate / 1000000,
+ (ath79_ddr_clk.rate / 1000) % 1000,
+ ath79_ahb_clk.rate / 1000000,
+ (ath79_ahb_clk.rate / 1000) % 1000,
+ ath79_ref_clk.rate / 1000000,
+ (ath79_ref_clk.rate / 1000) % 1000);
+}
+
+/*
+ * Linux clock API
+ */
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ if (!strcmp(id, "ref"))
+ return &ath79_ref_clk;
+
+ if (!strcmp(id, "cpu"))
+ return &ath79_cpu_clk;
+
+ if (!strcmp(id, "ddr"))
+ return &ath79_ddr_clk;
+
+ if (!strcmp(id, "ahb"))
+ return &ath79_ahb_clk;
+
+ if (!strcmp(id, "wdt"))
+ return &ath79_wdt_clk;
+
+ if (!strcmp(id, "uart"))
+ return &ath79_uart_clk;
+
+ return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get);
+
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c
new file mode 100644
index 000000000000..58f60e722a03
--- /dev/null
+++ b/arch/mips/ath79/common.c
@@ -0,0 +1,97 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common routines
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+
+static DEFINE_SPINLOCK(ath79_device_reset_lock);
+
+u32 ath79_cpu_freq;
+EXPORT_SYMBOL_GPL(ath79_cpu_freq);
+
+u32 ath79_ahb_freq;
+EXPORT_SYMBOL_GPL(ath79_ahb_freq);
+
+u32 ath79_ddr_freq;
+EXPORT_SYMBOL_GPL(ath79_ddr_freq);
+
+enum ath79_soc_type ath79_soc;
+
+void __iomem *ath79_pll_base;
+void __iomem *ath79_reset_base;
+EXPORT_SYMBOL_GPL(ath79_reset_base);
+void __iomem *ath79_ddr_base;
+
+void ath79_ddr_wb_flush(u32 reg)
+{
+ void __iomem *flush_reg = ath79_ddr_base + reg;
+
+ /* Flush the DDR write buffer. */
+ __raw_writel(0x1, flush_reg);
+ while (__raw_readl(flush_reg) & 0x1)
+ ;
+
+ /* It must be run twice. */
+ __raw_writel(0x1, flush_reg);
+ while (__raw_readl(flush_reg) & 0x1)
+ ;
+}
+EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush);
+
+void ath79_device_reset_set(u32 mask)
+{
+ unsigned long flags;
+ u32 reg;
+ u32 t;
+
+ if (soc_is_ar71xx())
+ reg = AR71XX_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar724x())
+ reg = AR724X_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar913x())
+ reg = AR913X_RESET_REG_RESET_MODULE;
+ else
+ BUG();
+
+ spin_lock_irqsave(&ath79_device_reset_lock, flags);
+ t = ath79_reset_rr(reg);
+ ath79_reset_wr(reg, t | mask);
+ spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
+}
+EXPORT_SYMBOL_GPL(ath79_device_reset_set);
+
+void ath79_device_reset_clear(u32 mask)
+{
+ unsigned long flags;
+ u32 reg;
+ u32 t;
+
+ if (soc_is_ar71xx())
+ reg = AR71XX_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar724x())
+ reg = AR724X_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar913x())
+ reg = AR913X_RESET_REG_RESET_MODULE;
+ else
+ BUG();
+
+ spin_lock_irqsave(&ath79_device_reset_lock, flags);
+ t = ath79_reset_rr(reg);
+ ath79_reset_wr(reg, t & ~mask);
+ spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
+}
+EXPORT_SYMBOL_GPL(ath79_device_reset_clear);
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h
new file mode 100644
index 000000000000..561906c2345e
--- /dev/null
+++ b/arch/mips/ath79/common.h
@@ -0,0 +1,31 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common definitions
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __ATH79_COMMON_H
+#define __ATH79_COMMON_H
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#define ATH79_MEM_SIZE_MIN (2 * 1024 * 1024)
+#define ATH79_MEM_SIZE_MAX (128 * 1024 * 1024)
+
+void ath79_clocks_init(void);
+void ath79_ddr_wb_flush(unsigned int reg);
+
+void ath79_gpio_function_enable(u32 mask);
+void ath79_gpio_function_disable(u32 mask);
+void ath79_gpio_function_setup(u32 set, u32 clear);
+void ath79_gpio_init(void);
+
+#endif /* __ATH79_COMMON_H */
diff --git a/arch/mips/ath79/dev-ar913x-wmac.c b/arch/mips/ath79/dev-ar913x-wmac.c
new file mode 100644
index 000000000000..48f425a5ba28
--- /dev/null
+++ b/arch/mips/ath79/dev-ar913x-wmac.c
@@ -0,0 +1,60 @@
+/*
+ * Atheros AR913X SoC built-in WMAC device support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/ath9k_platform.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "dev-ar913x-wmac.h"
+
+static struct ath9k_platform_data ar913x_wmac_data;
+
+static struct resource ar913x_wmac_resources[] = {
+ {
+ .start = AR913X_WMAC_BASE,
+ .end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = ATH79_CPU_IRQ_IP2,
+ .end = ATH79_CPU_IRQ_IP2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ar913x_wmac_device = {
+ .name = "ath9k",
+ .id = -1,
+ .resource = ar913x_wmac_resources,
+ .num_resources = ARRAY_SIZE(ar913x_wmac_resources),
+ .dev = {
+ .platform_data = &ar913x_wmac_data,
+ },
+};
+
+void __init ath79_register_ar913x_wmac(u8 *cal_data)
+{
+ if (cal_data)
+ memcpy(ar913x_wmac_data.eeprom_data, cal_data,
+ sizeof(ar913x_wmac_data.eeprom_data));
+
+ /* reset the WMAC */
+ ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
+ mdelay(10);
+
+ platform_device_register(&ar913x_wmac_device);
+}
diff --git a/arch/mips/ath79/dev-ar913x-wmac.h b/arch/mips/ath79/dev-ar913x-wmac.h
new file mode 100644
index 000000000000..579d562bbda8
--- /dev/null
+++ b/arch/mips/ath79/dev-ar913x-wmac.h
@@ -0,0 +1,17 @@
+/*
+ * Atheros AR913X SoC built-in WMAC device support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_AR913X_WMAC_H
+#define _ATH79_DEV_AR913X_WMAC_H
+
+void ath79_register_ar913x_wmac(u8 *cal_data);
+
+#endif /* _ATH79_DEV_AR913X_WMAC_H */
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
new file mode 100644
index 000000000000..3b82e325bebf
--- /dev/null
+++ b/arch/mips/ath79/dev-common.c
@@ -0,0 +1,77 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common devices
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+#include "dev-common.h"
+
+static struct resource ath79_uart_resources[] = {
+ {
+ .start = AR71XX_UART_BASE,
+ .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
+static struct plat_serial8250_port ath79_uart_data[] = {
+ {
+ .mapbase = AR71XX_UART_BASE,
+ .irq = ATH79_MISC_IRQ_UART,
+ .flags = AR71XX_UART_FLAGS,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ }, {
+ /* terminating entry */
+ }
+};
+
+static struct platform_device ath79_uart_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .resource = ath79_uart_resources,
+ .num_resources = ARRAY_SIZE(ath79_uart_resources),
+ .dev = {
+ .platform_data = ath79_uart_data
+ },
+};
+
+void __init ath79_register_uart(void)
+{
+ struct clk *clk;
+
+ clk = clk_get(NULL, "uart");
+ if (IS_ERR(clk))
+ panic("unable to get UART clock, err=%ld", PTR_ERR(clk));
+
+ ath79_uart_data[0].uartclk = clk_get_rate(clk);
+ platform_device_register(&ath79_uart_device);
+}
+
+static struct platform_device ath79_wdt_device = {
+ .name = "ath79-wdt",
+ .id = -1,
+};
+
+void __init ath79_register_wdt(void)
+{
+ platform_device_register(&ath79_wdt_device);
+}
diff --git a/arch/mips/ath79/dev-common.h b/arch/mips/ath79/dev-common.h
new file mode 100644
index 000000000000..0f514e1affce
--- /dev/null
+++ b/arch/mips/ath79/dev-common.h
@@ -0,0 +1,18 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common devices
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_COMMON_H
+#define _ATH79_DEV_COMMON_H
+
+void ath79_register_uart(void);
+void ath79_register_wdt(void);
+
+#endif /* _ATH79_DEV_COMMON_H */
diff --git a/arch/mips/ath79/dev-gpio-buttons.c b/arch/mips/ath79/dev-gpio-buttons.c
new file mode 100644
index 000000000000..4b0168a11c01
--- /dev/null
+++ b/arch/mips/ath79/dev-gpio-buttons.c
@@ -0,0 +1,58 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X GPIO button support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "linux/init.h"
+#include "linux/slab.h"
+#include <linux/platform_device.h>
+
+#include "dev-gpio-buttons.h"
+
+void __init ath79_register_gpio_keys_polled(int id,
+ unsigned poll_interval,
+ unsigned nbuttons,
+ struct gpio_keys_button *buttons)
+{
+ struct platform_device *pdev;
+ struct gpio_keys_platform_data pdata;
+ struct gpio_keys_button *p;
+ int err;
+
+ p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return;
+
+ memcpy(p, buttons, nbuttons * sizeof(*p));
+
+ pdev = platform_device_alloc("gpio-keys-polled", id);
+ if (!pdev)
+ goto err_free_buttons;
+
+ memset(&pdata, 0, sizeof(pdata));
+ pdata.poll_interval = poll_interval;
+ pdata.nbuttons = nbuttons;
+ pdata.buttons = p;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto err_put_pdev;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_put_pdev;
+
+ return;
+
+err_put_pdev:
+ platform_device_put(pdev);
+
+err_free_buttons:
+ kfree(p);
+}
diff --git a/arch/mips/ath79/dev-gpio-buttons.h b/arch/mips/ath79/dev-gpio-buttons.h
new file mode 100644
index 000000000000..481847ac1cba
--- /dev/null
+++ b/arch/mips/ath79/dev-gpio-buttons.h
@@ -0,0 +1,23 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X GPIO button support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_GPIO_BUTTONS_H
+#define _ATH79_DEV_GPIO_BUTTONS_H
+
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+void ath79_register_gpio_keys_polled(int id,
+ unsigned poll_interval,
+ unsigned nbuttons,
+ struct gpio_keys_button *buttons);
+
+#endif /* _ATH79_DEV_GPIO_BUTTONS_H */
diff --git a/arch/mips/ath79/dev-leds-gpio.c b/arch/mips/ath79/dev-leds-gpio.c
new file mode 100644
index 000000000000..cdade68dcd17
--- /dev/null
+++ b/arch/mips/ath79/dev-leds-gpio.c
@@ -0,0 +1,56 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include "dev-leds-gpio.h"
+
+void __init ath79_register_leds_gpio(int id,
+ unsigned num_leds,
+ struct gpio_led *leds)
+{
+ struct platform_device *pdev;
+ struct gpio_led_platform_data pdata;
+ struct gpio_led *p;
+ int err;
+
+ p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return;
+
+ memcpy(p, leds, num_leds * sizeof(*p));
+
+ pdev = platform_device_alloc("leds-gpio", id);
+ if (!pdev)
+ goto err_free_leds;
+
+ memset(&pdata, 0, sizeof(pdata));
+ pdata.num_leds = num_leds;
+ pdata.leds = p;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto err_put_pdev;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_put_pdev;
+
+ return;
+
+err_put_pdev:
+ platform_device_put(pdev);
+
+err_free_leds:
+ kfree(p);
+}
diff --git a/arch/mips/ath79/dev-leds-gpio.h b/arch/mips/ath79/dev-leds-gpio.h
new file mode 100644
index 000000000000..6e5d8851ebcf
--- /dev/null
+++ b/arch/mips/ath79/dev-leds-gpio.h
@@ -0,0 +1,21 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_LEDS_GPIO_H
+#define _ATH79_DEV_LEDS_GPIO_H
+
+#include <linux/leds.h>
+
+void ath79_register_leds_gpio(int id,
+ unsigned num_leds,
+ struct gpio_led *leds);
+
+#endif /* _ATH79_DEV_LEDS_GPIO_H */
diff --git a/arch/mips/ath79/dev-spi.c b/arch/mips/ath79/dev-spi.c
new file mode 100644
index 000000000000..aa30163efbfd
--- /dev/null
+++ b/arch/mips/ath79/dev-spi.c
@@ -0,0 +1,38 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X SPI controller device
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "dev-spi.h"
+
+static struct resource ath79_spi_resources[] = {
+ {
+ .start = AR71XX_SPI_BASE,
+ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ath79_spi_device = {
+ .name = "ath79-spi",
+ .id = -1,
+ .resource = ath79_spi_resources,
+ .num_resources = ARRAY_SIZE(ath79_spi_resources),
+};
+
+void __init ath79_register_spi(struct ath79_spi_platform_data *pdata,
+ struct spi_board_info const *info,
+ unsigned n)
+{
+ spi_register_board_info(info, n);
+ ath79_spi_device.dev.platform_data = pdata;
+ platform_device_register(&ath79_spi_device);
+}
diff --git a/arch/mips/ath79/dev-spi.h b/arch/mips/ath79/dev-spi.h
new file mode 100644
index 000000000000..d732565ca736
--- /dev/null
+++ b/arch/mips/ath79/dev-spi.h
@@ -0,0 +1,22 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X SPI controller device
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_SPI_H
+#define _ATH79_DEV_SPI_H
+
+#include <linux/spi/spi.h>
+#include <asm/mach-ath79/ath79_spi_platform.h>
+
+void ath79_register_spi(struct ath79_spi_platform_data *pdata,
+ struct spi_board_info const *info,
+ unsigned n);
+
+#endif /* _ATH79_DEV_SPI_H */
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c
new file mode 100644
index 000000000000..7499b0e9df26
--- /dev/null
+++ b/arch/mips/ath79/early_printk.c
@@ -0,0 +1,36 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X SoC early printk support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/serial_reg.h>
+#include <asm/addrspace.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+static inline void prom_wait_thre(void __iomem *base)
+{
+ u32 lsr;
+
+ do {
+ lsr = __raw_readl(base + UART_LSR * 4);
+ if (lsr & UART_LSR_THRE)
+ break;
+ } while (1);
+}
+
+void prom_putchar(unsigned char ch)
+{
+ void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
+
+ prom_wait_thre(base);
+ __raw_writel(ch, base + UART_TX * 4);
+ prom_wait_thre(base);
+}
diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c
new file mode 100644
index 000000000000..a0c426b82123
--- /dev/null
+++ b/arch/mips/ath79/gpio.c
@@ -0,0 +1,197 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X GPIO API support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79.h>
+#include "common.h"
+
+static void __iomem *ath79_gpio_base;
+static unsigned long ath79_gpio_count;
+static DEFINE_SPINLOCK(ath79_gpio_lock);
+
+static void __ath79_gpio_set_value(unsigned gpio, int value)
+{
+ void __iomem *base = ath79_gpio_base;
+
+ if (value)
+ __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_SET);
+ else
+ __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_CLEAR);
+}
+
+static int __ath79_gpio_get_value(unsigned gpio)
+{
+ return (__raw_readl(ath79_gpio_base + AR71XX_GPIO_REG_IN) >> gpio) & 1;
+}
+
+static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+ return __ath79_gpio_get_value(offset);
+}
+
+static void ath79_gpio_set_value(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ __ath79_gpio_set_value(offset, value);
+}
+
+static int ath79_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
+ base + AR71XX_GPIO_REG_OE);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+
+ return 0;
+}
+
+static int ath79_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ if (value)
+ __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
+ else
+ __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
+ base + AR71XX_GPIO_REG_OE);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+
+ return 0;
+}
+
+static struct gpio_chip ath79_gpio_chip = {
+ .label = "ath79",
+ .get = ath79_gpio_get_value,
+ .set = ath79_gpio_set_value,
+ .direction_input = ath79_gpio_direction_input,
+ .direction_output = ath79_gpio_direction_output,
+ .base = 0,
+};
+
+void ath79_gpio_function_enable(u32 mask)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) | mask,
+ base + AR71XX_GPIO_REG_FUNC);
+ /* flush write */
+ __raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void ath79_gpio_function_disable(u32 mask)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~mask,
+ base + AR71XX_GPIO_REG_FUNC);
+ /* flush write */
+ __raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void ath79_gpio_function_setup(u32 set, u32 clear)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ __raw_writel((__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~clear) | set,
+ base + AR71XX_GPIO_REG_FUNC);
+ /* flush write */
+ __raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void __init ath79_gpio_init(void)
+{
+ int err;
+
+ if (soc_is_ar71xx())
+ ath79_gpio_count = AR71XX_GPIO_COUNT;
+ else if (soc_is_ar724x())
+ ath79_gpio_count = AR724X_GPIO_COUNT;
+ else if (soc_is_ar913x())
+ ath79_gpio_count = AR913X_GPIO_COUNT;
+ else
+ BUG();
+
+ ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
+ ath79_gpio_chip.ngpio = ath79_gpio_count;
+
+ err = gpiochip_add(&ath79_gpio_chip);
+ if (err)
+ panic("cannot add AR71xx GPIO chip, error=%d", err);
+}
+
+int gpio_get_value(unsigned gpio)
+{
+ if (gpio < ath79_gpio_count)
+ return __ath79_gpio_get_value(gpio);
+
+ return __gpio_get_value(gpio);
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+void gpio_set_value(unsigned gpio, int value)
+{
+ if (gpio < ath79_gpio_count)
+ __ath79_gpio_set_value(gpio, value);
+ else
+ __gpio_set_value(gpio, value);
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+int gpio_to_irq(unsigned gpio)
+{
+ /* FIXME */
+ return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+int irq_to_gpio(unsigned irq)
+{
+ /* FIXME */
+ return -EINVAL;
+}
+EXPORT_SYMBOL(irq_to_gpio);
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
new file mode 100644
index 000000000000..1bf7f719ba53
--- /dev/null
+++ b/arch/mips/ath79/irq.c
@@ -0,0 +1,187 @@
+/*
+ * Atheros AR71xx/AR724x/AR913x specific interrupt handling
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+
+static unsigned int ath79_ip2_flush_reg;
+static unsigned int ath79_ip3_flush_reg;
+
+static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ void __iomem *base = ath79_reset_base;
+ u32 pending;
+
+ pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
+ __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+ if (pending & MISC_INT_UART)
+ generic_handle_irq(ATH79_MISC_IRQ_UART);
+
+ else if (pending & MISC_INT_DMA)
+ generic_handle_irq(ATH79_MISC_IRQ_DMA);
+
+ else if (pending & MISC_INT_PERFC)
+ generic_handle_irq(ATH79_MISC_IRQ_PERFC);
+
+ else if (pending & MISC_INT_TIMER)
+ generic_handle_irq(ATH79_MISC_IRQ_TIMER);
+
+ else if (pending & MISC_INT_OHCI)
+ generic_handle_irq(ATH79_MISC_IRQ_OHCI);
+
+ else if (pending & MISC_INT_ERROR)
+ generic_handle_irq(ATH79_MISC_IRQ_ERROR);
+
+ else if (pending & MISC_INT_GPIO)
+ generic_handle_irq(ATH79_MISC_IRQ_GPIO);
+
+ else if (pending & MISC_INT_WDOG)
+ generic_handle_irq(ATH79_MISC_IRQ_WDOG);
+
+ else
+ spurious_interrupt();
+}
+
+static void ar71xx_misc_irq_unmask(unsigned int irq)
+{
+ void __iomem *base = ath79_reset_base;
+ u32 t;
+
+ irq -= ATH79_MISC_IRQ_BASE;
+
+ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+ __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+ /* flush write */
+ __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+}
+
+static void ar71xx_misc_irq_mask(unsigned int irq)
+{
+ void __iomem *base = ath79_reset_base;
+ u32 t;
+
+ irq -= ATH79_MISC_IRQ_BASE;
+
+ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+ /* flush write */
+ __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+}
+
+static void ar724x_misc_irq_ack(unsigned int irq)
+{
+ void __iomem *base = ath79_reset_base;
+ u32 t;
+
+ irq -= ATH79_MISC_IRQ_BASE;
+
+ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
+ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
+
+ /* flush write */
+ __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
+}
+
+static struct irq_chip ath79_misc_irq_chip = {
+ .name = "MISC",
+ .unmask = ar71xx_misc_irq_unmask,
+ .mask = ar71xx_misc_irq_mask,
+};
+
+static void __init ath79_misc_irq_init(void)
+{
+ void __iomem *base = ath79_reset_base;
+ int i;
+
+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
+
+ if (soc_is_ar71xx() || soc_is_ar913x())
+ ath79_misc_irq_chip.mask_ack = ar71xx_misc_irq_mask;
+ else if (soc_is_ar724x())
+ ath79_misc_irq_chip.ack = ar724x_misc_irq_ack;
+ else
+ BUG();
+
+ for (i = ATH79_MISC_IRQ_BASE;
+ i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ set_irq_chip_and_handler(i, &ath79_misc_irq_chip,
+ handle_level_irq);
+ }
+
+ set_irq_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned long pending;
+
+ pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+ if (pending & STATUSF_IP7)
+ do_IRQ(ATH79_CPU_IRQ_TIMER);
+
+ else if (pending & STATUSF_IP2) {
+ ath79_ddr_wb_flush(ath79_ip2_flush_reg);
+ do_IRQ(ATH79_CPU_IRQ_IP2);
+ }
+
+ else if (pending & STATUSF_IP4)
+ do_IRQ(ATH79_CPU_IRQ_GE0);
+
+ else if (pending & STATUSF_IP5)
+ do_IRQ(ATH79_CPU_IRQ_GE1);
+
+ else if (pending & STATUSF_IP3) {
+ ath79_ddr_wb_flush(ath79_ip3_flush_reg);
+ do_IRQ(ATH79_CPU_IRQ_USB);
+ }
+
+ else if (pending & STATUSF_IP6)
+ do_IRQ(ATH79_CPU_IRQ_MISC);
+
+ else
+ spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+ if (soc_is_ar71xx()) {
+ ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI;
+ ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB;
+ } else if (soc_is_ar724x()) {
+ ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE;
+ ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB;
+ } else if (soc_is_ar913x()) {
+ ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC;
+ ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB;
+ } else
+ BUG();
+
+ cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC;
+ mips_cpu_irq_init();
+ ath79_misc_irq_init();
+}
diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c
new file mode 100644
index 000000000000..eee4c121deb4
--- /dev/null
+++ b/arch/mips/ath79/mach-ap81.c
@@ -0,0 +1,98 @@
+/*
+ * Atheros AP81 board support
+ *
+ * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "machtypes.h"
+#include "dev-ar913x-wmac.h"
+#include "dev-gpio-buttons.h"
+#include "dev-leds-gpio.h"
+#include "dev-spi.h"
+
+#define AP81_GPIO_LED_STATUS 1
+#define AP81_GPIO_LED_AOSS 3
+#define AP81_GPIO_LED_WLAN 6
+#define AP81_GPIO_LED_POWER 14
+
+#define AP81_GPIO_BTN_SW4 12
+#define AP81_GPIO_BTN_SW1 21
+
+#define AP81_KEYS_POLL_INTERVAL 20 /* msecs */
+#define AP81_KEYS_DEBOUNCE_INTERVAL (3 * AP81_KEYS_POLL_INTERVAL)
+
+#define AP81_CAL_DATA_ADDR 0x1fff1000
+
+static struct gpio_led ap81_leds_gpio[] __initdata = {
+ {
+ .name = "ap81:green:status",
+ .gpio = AP81_GPIO_LED_STATUS,
+ .active_low = 1,
+ }, {
+ .name = "ap81:amber:aoss",
+ .gpio = AP81_GPIO_LED_AOSS,
+ .active_low = 1,
+ }, {
+ .name = "ap81:green:wlan",
+ .gpio = AP81_GPIO_LED_WLAN,
+ .active_low = 1,
+ }, {
+ .name = "ap81:green:power",
+ .gpio = AP81_GPIO_LED_POWER,
+ .active_low = 1,
+ }
+};
+
+static struct gpio_keys_button ap81_gpio_keys[] __initdata = {
+ {
+ .desc = "sw1",
+ .type = EV_KEY,
+ .code = BTN_0,
+ .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = AP81_GPIO_BTN_SW1,
+ .active_low = 1,
+ } , {
+ .desc = "sw4",
+ .type = EV_KEY,
+ .code = BTN_1,
+ .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = AP81_GPIO_BTN_SW4,
+ .active_low = 1,
+ }
+};
+
+static struct spi_board_info ap81_spi_info[] = {
+ {
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 25000000,
+ .modalias = "m25p64",
+ }
+};
+
+static struct ath79_spi_platform_data ap81_spi_data = {
+ .bus_num = 0,
+ .num_chipselect = 1,
+};
+
+static void __init ap81_setup(void)
+{
+ u8 *cal_data = (u8 *) KSEG1ADDR(AP81_CAL_DATA_ADDR);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
+ ap81_leds_gpio);
+ ath79_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(ap81_gpio_keys),
+ ap81_gpio_keys);
+ ath79_register_spi(&ap81_spi_data, ap81_spi_info,
+ ARRAY_SIZE(ap81_spi_info));
+ ath79_register_ar913x_wmac(cal_data);
+}
+
+MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board",
+ ap81_setup);
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
new file mode 100644
index 000000000000..ec7b7a135d53
--- /dev/null
+++ b/arch/mips/ath79/mach-pb44.c
@@ -0,0 +1,118 @@
+/*
+ * Atheros PB44 reference board support
+ *
+ * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/i2c/pcf857x.h>
+
+#include "machtypes.h"
+#include "dev-gpio-buttons.h"
+#include "dev-leds-gpio.h"
+#include "dev-spi.h"
+
+#define PB44_GPIO_I2C_SCL 0
+#define PB44_GPIO_I2C_SDA 1
+
+#define PB44_GPIO_EXP_BASE 16
+#define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + 6)
+#define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + 8)
+#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + 9)
+#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + 10)
+
+#define PB44_KEYS_POLL_INTERVAL 20 /* msecs */
+#define PB44_KEYS_DEBOUNCE_INTERVAL (3 * PB44_KEYS_POLL_INTERVAL)
+
+static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
+ .sda_pin = PB44_GPIO_I2C_SDA,
+ .scl_pin = PB44_GPIO_I2C_SCL,
+};
+
+static struct platform_device pb44_i2c_gpio_device = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &pb44_i2c_gpio_data,
+ }
+};
+
+static struct pcf857x_platform_data pb44_pcf857x_data = {
+ .gpio_base = PB44_GPIO_EXP_BASE,
+};
+
+static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("pcf8575", 0x20),
+ .platform_data = &pb44_pcf857x_data,
+ },
+};
+
+static struct gpio_led pb44_leds_gpio[] __initdata = {
+ {
+ .name = "pb44:amber:jump1",
+ .gpio = PB44_GPIO_LED_JUMP1,
+ .active_low = 1,
+ }, {
+ .name = "pb44:green:jump2",
+ .gpio = PB44_GPIO_LED_JUMP2,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_button pb44_gpio_keys[] __initdata = {
+ {
+ .desc = "soft_reset",
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = PB44_GPIO_SW_RESET,
+ .active_low = 1,
+ } , {
+ .desc = "jumpstart",
+ .type = EV_KEY,
+ .code = KEY_WPS_BUTTON,
+ .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = PB44_GPIO_SW_JUMP,
+ .active_low = 1,
+ }
+};
+
+static struct spi_board_info pb44_spi_info[] = {
+ {
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 25000000,
+ .modalias = "m25p64",
+ },
+};
+
+static struct ath79_spi_platform_data pb44_spi_data = {
+ .bus_num = 0,
+ .num_chipselect = 1,
+};
+
+static void __init pb44_init(void)
+{
+ i2c_register_board_info(0, pb44_i2c_board_info,
+ ARRAY_SIZE(pb44_i2c_board_info));
+ platform_device_register(&pb44_i2c_gpio_device);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
+ pb44_leds_gpio);
+ ath79_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(pb44_gpio_keys),
+ pb44_gpio_keys);
+ ath79_register_spi(&pb44_spi_data, pb44_spi_info,
+ ARRAY_SIZE(pb44_spi_info));
+}
+
+MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
+ pb44_init);
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
new file mode 100644
index 000000000000..3940fe470b2d
--- /dev/null
+++ b/arch/mips/ath79/machtypes.h
@@ -0,0 +1,23 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X machine type definitions
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_MACHTYPE_H
+#define _ATH79_MACHTYPE_H
+
+#include <asm/mips_machine.h>
+
+enum ath79_mach_type {
+ ATH79_MACH_GENERIC = 0,
+ ATH79_MACH_AP81, /* Atheros AP81 reference board */
+ ATH79_MACH_PB44, /* Atheros PB44 reference board */
+};
+
+#endif /* _ATH79_MACHTYPE_H */
diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c
new file mode 100644
index 000000000000..e9cbd7c2918f
--- /dev/null
+++ b/arch/mips/ath79/prom.c
@@ -0,0 +1,57 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X specific prom routines
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+
+#include "common.h"
+
+static inline int is_valid_ram_addr(void *addr)
+{
+ if (((u32) addr > KSEG0) &&
+ ((u32) addr < (KSEG0 + ATH79_MEM_SIZE_MAX)))
+ return 1;
+
+ if (((u32) addr > KSEG1) &&
+ ((u32) addr < (KSEG1 + ATH79_MEM_SIZE_MAX)))
+ return 1;
+
+ return 0;
+}
+
+static __init void ath79_prom_init_cmdline(int argc, char **argv)
+{
+ int i;
+
+ if (!is_valid_ram_addr(argv))
+ return;
+
+ for (i = 0; i < argc; i++)
+ if (is_valid_ram_addr(argv[i])) {
+ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
+ strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline));
+ }
+}
+
+void __init prom_init(void)
+{
+ ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1);
+}
+
+void __init prom_free_prom_memory(void)
+{
+ /* We do not have to prom memory to free */
+}
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
new file mode 100644
index 000000000000..159b42f106b0
--- /dev/null
+++ b/arch/mips/ath79/setup.c
@@ -0,0 +1,206 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X specific setup
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <asm/bootinfo.h>
+#include <asm/time.h> /* for mips_hpt_frequency */
+#include <asm/reboot.h> /* for _machine_{restart,halt} */
+#include <asm/mips_machine.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+#include "dev-common.h"
+#include "machtypes.h"
+
+#define ATH79_SYS_TYPE_LEN 64
+
+#define AR71XX_BASE_FREQ 40000000
+#define AR724X_BASE_FREQ 5000000
+#define AR913X_BASE_FREQ 5000000
+
+static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
+
+static void ath79_restart(char *command)
+{
+ ath79_device_reset_set(AR71XX_RESET_FULL_CHIP);
+ for (;;)
+ if (cpu_wait)
+ cpu_wait();
+}
+
+static void ath79_halt(void)
+{
+ while (1)
+ cpu_wait();
+}
+
+static void __init ath79_detect_mem_size(void)
+{
+ unsigned long size;
+
+ for (size = ATH79_MEM_SIZE_MIN; size < ATH79_MEM_SIZE_MAX;
+ size <<= 1) {
+ if (!memcmp(ath79_detect_mem_size,
+ ath79_detect_mem_size + size, 1024))
+ break;
+ }
+
+ add_memory_region(0, size, BOOT_MEM_RAM);
+}
+
+static void __init ath79_detect_sys_type(void)
+{
+ char *chip = "????";
+ u32 id;
+ u32 major;
+ u32 minor;
+ u32 rev = 0;
+
+ id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID);
+ major = id & REV_ID_MAJOR_MASK;
+
+ switch (major) {
+ case REV_ID_MAJOR_AR71XX:
+ minor = id & AR71XX_REV_ID_MINOR_MASK;
+ rev = id >> AR71XX_REV_ID_REVISION_SHIFT;
+ rev &= AR71XX_REV_ID_REVISION_MASK;
+ switch (minor) {
+ case AR71XX_REV_ID_MINOR_AR7130:
+ ath79_soc = ATH79_SOC_AR7130;
+ chip = "7130";
+ break;
+
+ case AR71XX_REV_ID_MINOR_AR7141:
+ ath79_soc = ATH79_SOC_AR7141;
+ chip = "7141";
+ break;
+
+ case AR71XX_REV_ID_MINOR_AR7161:
+ ath79_soc = ATH79_SOC_AR7161;
+ chip = "7161";
+ break;
+ }
+ break;
+
+ case REV_ID_MAJOR_AR7240:
+ ath79_soc = ATH79_SOC_AR7240;
+ chip = "7240";
+ rev = (id & AR724X_REV_ID_REVISION_MASK);
+ break;
+
+ case REV_ID_MAJOR_AR7241:
+ ath79_soc = ATH79_SOC_AR7241;
+ chip = "7241";
+ rev = (id & AR724X_REV_ID_REVISION_MASK);
+ break;
+
+ case REV_ID_MAJOR_AR7242:
+ ath79_soc = ATH79_SOC_AR7242;
+ chip = "7242";
+ rev = (id & AR724X_REV_ID_REVISION_MASK);
+ break;
+
+ case REV_ID_MAJOR_AR913X:
+ minor = id & AR913X_REV_ID_MINOR_MASK;
+ rev = id >> AR913X_REV_ID_REVISION_SHIFT;
+ rev &= AR913X_REV_ID_REVISION_MASK;
+ switch (minor) {
+ case AR913X_REV_ID_MINOR_AR9130:
+ ath79_soc = ATH79_SOC_AR9130;
+ chip = "9130";
+ break;
+
+ case AR913X_REV_ID_MINOR_AR9132:
+ ath79_soc = ATH79_SOC_AR9132;
+ chip = "9132";
+ break;
+ }
+ break;
+
+ default:
+ panic("ath79: unknown SoC, id:0x%08x\n", id);
+ }
+
+ sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev);
+ pr_info("SoC: %s\n", ath79_sys_type);
+}
+
+const char *get_system_type(void)
+{
+ return ath79_sys_type;
+}
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+ return CP0_LEGACY_COMPARE_IRQ;
+}
+
+void __init plat_mem_setup(void)
+{
+ set_io_port_base(KSEG1);
+
+ ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
+ AR71XX_RESET_SIZE);
+ ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
+ AR71XX_PLL_SIZE);
+ ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
+ AR71XX_DDR_CTRL_SIZE);
+
+ ath79_detect_sys_type();
+ ath79_detect_mem_size();
+ ath79_clocks_init();
+
+ _machine_restart = ath79_restart;
+ _machine_halt = ath79_halt;
+ pm_power_off = ath79_halt;
+}
+
+void __init plat_time_init(void)
+{
+ struct clk *clk;
+
+ clk = clk_get(NULL, "cpu");
+ if (IS_ERR(clk))
+ panic("unable to get CPU clock, err=%ld", PTR_ERR(clk));
+
+ mips_hpt_frequency = clk_get_rate(clk) / 2;
+}
+
+static int __init ath79_setup(void)
+{
+ ath79_gpio_init();
+ ath79_register_uart();
+ ath79_register_wdt();
+
+ mips_machine_setup();
+
+ return 0;
+}
+
+arch_initcall(ath79_setup);
+
+static void __init ath79_generic_init(void)
+{
+ /* Nothing to do */
+}
+
+MIPS_MACHINE(ATH79_MACH_GENERIC,
+ "Generic",
+ "Generic AR71XX/AR724X/AR913X based board",
+ ath79_generic_init);
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index b455d0f36486..9d03b68aece8 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -369,7 +369,10 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_CIRRUS=y
# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_HID=m
CONFIG_LEDS_CLASS=m
CONFIG_LEDS_TRIGGER_TIMER=m
diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h
index 37f175c42bb5..650ac9ba734c 100644
--- a/arch/mips/include/asm/cache.h
+++ b/arch/mips/include/asm/cache.h
@@ -17,4 +17,6 @@
#define SMP_CACHE_SHIFT L1_CACHE_SHIFT
#define SMP_CACHE_BYTES L1_CACHE_BYTES
+#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+
#endif /* _ASM_CACHE_H */
diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index b39def3f6e03..c454550eb0c0 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -78,6 +78,7 @@ struct cpuinfo_mips {
unsigned int watch_reg_use_cnt; /* Usable by ptrace */
#define NUM_WATCH_REGS 4
u16 watch_reg_masks[NUM_WATCH_REGS];
+ unsigned int kscratch_mask; /* Usable KScratch mask. */
} __attribute__((aligned(SMP_CACHE_BYTES)));
extern struct cpuinfo_mips cpu_data[];
diff --git a/arch/mips/include/asm/inst.h b/arch/mips/include/asm/inst.h
index 444ff71aa0e8..7ebfc392e58d 100644
--- a/arch/mips/include/asm/inst.h
+++ b/arch/mips/include/asm/inst.h
@@ -72,6 +72,7 @@ enum spec2_op {
enum spec3_op {
ext_op, dextm_op, dextu_op, dext_op,
ins_op, dinsm_op, dinsu_op, dins_op,
+ lx_op = 0x0a,
bshfl_op = 0x20,
dbshfl_op = 0x24,
rdhwr_op = 0x3b
@@ -179,6 +180,19 @@ enum mad_func {
};
/*
+ * func field for special3 lx opcodes (Cavium Octeon).
+ */
+enum lx_func {
+ lwx_op = 0x00,
+ lhx_op = 0x04,
+ lbux_op = 0x06,
+ ldx_op = 0x08,
+ lwux_op = 0x10,
+ lhux_op = 0x14,
+ lbx_op = 0x16,
+};
+
+/*
* Damn ... bitfields depend from byteorder :-(
*/
#ifdef __MIPSEB__
diff --git a/arch/mips/include/asm/jump_label.h b/arch/mips/include/asm/jump_label.h
new file mode 100644
index 000000000000..7622ccf75076
--- /dev/null
+++ b/arch/mips/include/asm/jump_label.h
@@ -0,0 +1,48 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2010 Cavium Networks, Inc.
+ */
+#ifndef _ASM_MIPS_JUMP_LABEL_H
+#define _ASM_MIPS_JUMP_LABEL_H
+
+#include <linux/types.h>
+
+#ifdef __KERNEL__
+
+#define JUMP_LABEL_NOP_SIZE 4
+
+#ifdef CONFIG_64BIT
+#define WORD_INSN ".dword"
+#else
+#define WORD_INSN ".word"
+#endif
+
+#define JUMP_LABEL(key, label) \
+ do { \
+ asm goto("1:\tnop\n\t" \
+ "nop\n\t" \
+ ".pushsection __jump_table, \"a\"\n\t" \
+ WORD_INSN " 1b, %l[" #label "], %0\n\t" \
+ ".popsection\n\t" \
+ : : "i" (key) : : label); \
+ } while (0)
+
+
+#endif /* __KERNEL__ */
+
+#ifdef CONFIG_64BIT
+typedef u64 jump_label_t;
+#else
+typedef u32 jump_label_t;
+#endif
+
+struct jump_entry {
+ jump_label_t code;
+ jump_label_t target;
+ jump_label_t key;
+};
+
+#endif /* _ASM_MIPS_JUMP_LABEL_H */
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
new file mode 100644
index 000000000000..cda1c8070b27
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -0,0 +1,233 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X SoC register definitions
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_AR71XX_REGS_H
+#define __ASM_MACH_AR71XX_REGS_H
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+
+#define AR71XX_APB_BASE 0x18000000
+#define AR71XX_SPI_BASE 0x1f000000
+#define AR71XX_SPI_SIZE 0x01000000
+
+#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000)
+#define AR71XX_DDR_CTRL_SIZE 0x100
+#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
+#define AR71XX_UART_SIZE 0x100
+#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000)
+#define AR71XX_GPIO_SIZE 0x100
+#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
+#define AR71XX_PLL_SIZE 0x100
+#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
+#define AR71XX_RESET_SIZE 0x100
+
+#define AR913X_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000)
+#define AR913X_WMAC_SIZE 0x30000
+
+/*
+ * DDR_CTRL block
+ */
+#define AR71XX_DDR_REG_PCI_WIN0 0x7c
+#define AR71XX_DDR_REG_PCI_WIN1 0x80
+#define AR71XX_DDR_REG_PCI_WIN2 0x84
+#define AR71XX_DDR_REG_PCI_WIN3 0x88
+#define AR71XX_DDR_REG_PCI_WIN4 0x8c
+#define AR71XX_DDR_REG_PCI_WIN5 0x90
+#define AR71XX_DDR_REG_PCI_WIN6 0x94
+#define AR71XX_DDR_REG_PCI_WIN7 0x98
+#define AR71XX_DDR_REG_FLUSH_GE0 0x9c
+#define AR71XX_DDR_REG_FLUSH_GE1 0xa0
+#define AR71XX_DDR_REG_FLUSH_USB 0xa4
+#define AR71XX_DDR_REG_FLUSH_PCI 0xa8
+
+#define AR724X_DDR_REG_FLUSH_GE0 0x7c
+#define AR724X_DDR_REG_FLUSH_GE1 0x80
+#define AR724X_DDR_REG_FLUSH_USB 0x84
+#define AR724X_DDR_REG_FLUSH_PCIE 0x88
+
+#define AR913X_DDR_REG_FLUSH_GE0 0x7c
+#define AR913X_DDR_REG_FLUSH_GE1 0x80
+#define AR913X_DDR_REG_FLUSH_USB 0x84
+#define AR913X_DDR_REG_FLUSH_WMAC 0x88
+
+/*
+ * PLL block
+ */
+#define AR71XX_PLL_REG_CPU_CONFIG 0x00
+#define AR71XX_PLL_REG_SEC_CONFIG 0x04
+#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10
+#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14
+
+#define AR71XX_PLL_DIV_SHIFT 3
+#define AR71XX_PLL_DIV_MASK 0x1f
+#define AR71XX_CPU_DIV_SHIFT 16
+#define AR71XX_CPU_DIV_MASK 0x3
+#define AR71XX_DDR_DIV_SHIFT 18
+#define AR71XX_DDR_DIV_MASK 0x3
+#define AR71XX_AHB_DIV_SHIFT 20
+#define AR71XX_AHB_DIV_MASK 0x7
+
+#define AR724X_PLL_REG_CPU_CONFIG 0x00
+#define AR724X_PLL_REG_PCIE_CONFIG 0x18
+
+#define AR724X_PLL_DIV_SHIFT 0
+#define AR724X_PLL_DIV_MASK 0x3ff
+#define AR724X_PLL_REF_DIV_SHIFT 10
+#define AR724X_PLL_REF_DIV_MASK 0xf
+#define AR724X_AHB_DIV_SHIFT 19
+#define AR724X_AHB_DIV_MASK 0x1
+#define AR724X_DDR_DIV_SHIFT 22
+#define AR724X_DDR_DIV_MASK 0x3
+
+#define AR913X_PLL_REG_CPU_CONFIG 0x00
+#define AR913X_PLL_REG_ETH_CONFIG 0x04
+#define AR913X_PLL_REG_ETH0_INT_CLOCK 0x14
+#define AR913X_PLL_REG_ETH1_INT_CLOCK 0x18
+
+#define AR913X_PLL_DIV_SHIFT 0
+#define AR913X_PLL_DIV_MASK 0x3ff
+#define AR913X_DDR_DIV_SHIFT 22
+#define AR913X_DDR_DIV_MASK 0x3
+#define AR913X_AHB_DIV_SHIFT 19
+#define AR913X_AHB_DIV_MASK 0x1
+
+/*
+ * RESET block
+ */
+#define AR71XX_RESET_REG_TIMER 0x00
+#define AR71XX_RESET_REG_TIMER_RELOAD 0x04
+#define AR71XX_RESET_REG_WDOG_CTRL 0x08
+#define AR71XX_RESET_REG_WDOG 0x0c
+#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10
+#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14
+#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18
+#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c
+#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20
+#define AR71XX_RESET_REG_RESET_MODULE 0x24
+#define AR71XX_RESET_REG_PERFC_CTRL 0x2c
+#define AR71XX_RESET_REG_PERFC0 0x30
+#define AR71XX_RESET_REG_PERFC1 0x34
+#define AR71XX_RESET_REG_REV_ID 0x90
+
+#define AR913X_RESET_REG_GLOBAL_INT_STATUS 0x18
+#define AR913X_RESET_REG_RESET_MODULE 0x1c
+#define AR913X_RESET_REG_PERF_CTRL 0x20
+#define AR913X_RESET_REG_PERFC0 0x24
+#define AR913X_RESET_REG_PERFC1 0x28
+
+#define AR724X_RESET_REG_RESET_MODULE 0x1c
+
+#define MISC_INT_DMA BIT(7)
+#define MISC_INT_OHCI BIT(6)
+#define MISC_INT_PERFC BIT(5)
+#define MISC_INT_WDOG BIT(4)
+#define MISC_INT_UART BIT(3)
+#define MISC_INT_GPIO BIT(2)
+#define MISC_INT_ERROR BIT(1)
+#define MISC_INT_TIMER BIT(0)
+
+#define AR71XX_RESET_EXTERNAL BIT(28)
+#define AR71XX_RESET_FULL_CHIP BIT(24)
+#define AR71XX_RESET_CPU_NMI BIT(21)
+#define AR71XX_RESET_CPU_COLD BIT(20)
+#define AR71XX_RESET_DMA BIT(19)
+#define AR71XX_RESET_SLIC BIT(18)
+#define AR71XX_RESET_STEREO BIT(17)
+#define AR71XX_RESET_DDR BIT(16)
+#define AR71XX_RESET_GE1_MAC BIT(13)
+#define AR71XX_RESET_GE1_PHY BIT(12)
+#define AR71XX_RESET_USBSUS_OVERRIDE BIT(10)
+#define AR71XX_RESET_GE0_MAC BIT(9)
+#define AR71XX_RESET_GE0_PHY BIT(8)
+#define AR71XX_RESET_USB_OHCI_DLL BIT(6)
+#define AR71XX_RESET_USB_HOST BIT(5)
+#define AR71XX_RESET_USB_PHY BIT(4)
+#define AR71XX_RESET_PCI_BUS BIT(1)
+#define AR71XX_RESET_PCI_CORE BIT(0)
+
+#define AR724X_RESET_GE1_MDIO BIT(23)
+#define AR724X_RESET_GE0_MDIO BIT(22)
+#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10)
+#define AR724X_RESET_PCIE_PHY BIT(7)
+#define AR724X_RESET_PCIE BIT(6)
+#define AR724X_RESET_OHCI_DLL BIT(3)
+
+#define AR913X_RESET_AMBA2WMAC BIT(22)
+
+#define REV_ID_MAJOR_MASK 0xfff0
+#define REV_ID_MAJOR_AR71XX 0x00a0
+#define REV_ID_MAJOR_AR913X 0x00b0
+#define REV_ID_MAJOR_AR7240 0x00c0
+#define REV_ID_MAJOR_AR7241 0x0100
+#define REV_ID_MAJOR_AR7242 0x1100
+
+#define AR71XX_REV_ID_MINOR_MASK 0x3
+#define AR71XX_REV_ID_MINOR_AR7130 0x0
+#define AR71XX_REV_ID_MINOR_AR7141 0x1
+#define AR71XX_REV_ID_MINOR_AR7161 0x2
+#define AR71XX_REV_ID_REVISION_MASK 0x3
+#define AR71XX_REV_ID_REVISION_SHIFT 2
+
+#define AR913X_REV_ID_MINOR_MASK 0x3
+#define AR913X_REV_ID_MINOR_AR9130 0x0
+#define AR913X_REV_ID_MINOR_AR9132 0x1
+#define AR913X_REV_ID_REVISION_MASK 0x3
+#define AR913X_REV_ID_REVISION_SHIFT 2
+
+#define AR724X_REV_ID_REVISION_MASK 0x3
+
+/*
+ * SPI block
+ */
+#define AR71XX_SPI_REG_FS 0x00 /* Function Select */
+#define AR71XX_SPI_REG_CTRL 0x04 /* SPI Control */
+#define AR71XX_SPI_REG_IOC 0x08 /* SPI I/O Control */
+#define AR71XX_SPI_REG_RDS 0x0c /* Read Data Shift */
+
+#define AR71XX_SPI_FS_GPIO BIT(0) /* Enable GPIO mode */
+
+#define AR71XX_SPI_CTRL_RD BIT(6) /* Remap Disable */
+#define AR71XX_SPI_CTRL_DIV_MASK 0x3f
+
+#define AR71XX_SPI_IOC_DO BIT(0) /* Data Out pin */
+#define AR71XX_SPI_IOC_CLK BIT(8) /* CLK pin */
+#define AR71XX_SPI_IOC_CS(n) BIT(16 + (n))
+#define AR71XX_SPI_IOC_CS0 AR71XX_SPI_IOC_CS(0)
+#define AR71XX_SPI_IOC_CS1 AR71XX_SPI_IOC_CS(1)
+#define AR71XX_SPI_IOC_CS2 AR71XX_SPI_IOC_CS(2)
+#define AR71XX_SPI_IOC_CS_ALL (AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1 | \
+ AR71XX_SPI_IOC_CS2)
+
+/*
+ * GPIO block
+ */
+#define AR71XX_GPIO_REG_OE 0x00
+#define AR71XX_GPIO_REG_IN 0x04
+#define AR71XX_GPIO_REG_OUT 0x08
+#define AR71XX_GPIO_REG_SET 0x0c
+#define AR71XX_GPIO_REG_CLEAR 0x10
+#define AR71XX_GPIO_REG_INT_MODE 0x14
+#define AR71XX_GPIO_REG_INT_TYPE 0x18
+#define AR71XX_GPIO_REG_INT_POLARITY 0x1c
+#define AR71XX_GPIO_REG_INT_PENDING 0x20
+#define AR71XX_GPIO_REG_INT_ENABLE 0x24
+#define AR71XX_GPIO_REG_FUNC 0x28
+
+#define AR71XX_GPIO_COUNT 16
+#define AR724X_GPIO_COUNT 18
+#define AR913X_GPIO_COUNT 22
+
+#endif /* __ASM_MACH_AR71XX_REGS_H */
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
new file mode 100644
index 000000000000..6a9f168506fe
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -0,0 +1,96 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common definitions
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_ATH79_H
+#define __ASM_MACH_ATH79_H
+
+#include <linux/types.h>
+#include <linux/io.h>
+
+enum ath79_soc_type {
+ ATH79_SOC_UNKNOWN,
+ ATH79_SOC_AR7130,
+ ATH79_SOC_AR7141,
+ ATH79_SOC_AR7161,
+ ATH79_SOC_AR7240,
+ ATH79_SOC_AR7241,
+ ATH79_SOC_AR7242,
+ ATH79_SOC_AR9130,
+ ATH79_SOC_AR9132
+};
+
+extern enum ath79_soc_type ath79_soc;
+
+static inline int soc_is_ar71xx(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7130 ||
+ ath79_soc == ATH79_SOC_AR7141 ||
+ ath79_soc == ATH79_SOC_AR7161);
+}
+
+static inline int soc_is_ar724x(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7240 ||
+ ath79_soc == ATH79_SOC_AR7241 ||
+ ath79_soc == ATH79_SOC_AR7242);
+}
+
+static inline int soc_is_ar7240(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7240);
+}
+
+static inline int soc_is_ar7241(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7241);
+}
+
+static inline int soc_is_ar7242(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7242);
+}
+
+static inline int soc_is_ar913x(void)
+{
+ return (ath79_soc == ATH79_SOC_AR9130 ||
+ ath79_soc == ATH79_SOC_AR9132);
+}
+
+extern void __iomem *ath79_ddr_base;
+extern void __iomem *ath79_pll_base;
+extern void __iomem *ath79_reset_base;
+
+static inline void ath79_pll_wr(unsigned reg, u32 val)
+{
+ __raw_writel(val, ath79_pll_base + reg);
+}
+
+static inline u32 ath79_pll_rr(unsigned reg)
+{
+ return __raw_readl(ath79_pll_base + reg);
+}
+
+static inline void ath79_reset_wr(unsigned reg, u32 val)
+{
+ __raw_writel(val, ath79_reset_base + reg);
+}
+
+static inline u32 ath79_reset_rr(unsigned reg)
+{
+ return __raw_readl(ath79_reset_base + reg);
+}
+
+void ath79_device_reset_set(u32 mask);
+void ath79_device_reset_clear(u32 mask);
+
+#endif /* __ASM_MACH_ATH79_H */
diff --git a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
new file mode 100644
index 000000000000..aa2283e602fc
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
@@ -0,0 +1,23 @@
+/*
+ * Platform data definition for Atheros AR71XX/AR724X/AR913X SPI controller
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_SPI_PLATFORM_H
+#define _ATH79_SPI_PLATFORM_H
+
+struct ath79_spi_platform_data {
+ unsigned bus_num;
+ unsigned num_chipselect;
+};
+
+struct ath79_spi_controller_data {
+ unsigned gpio;
+};
+
+#endif /* _ATH79_SPI_PLATFORM_H */
diff --git a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
new file mode 100644
index 000000000000..4476fa03bf36
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
@@ -0,0 +1,56 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X specific CPU feature overrides
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This file was derived from: include/asm-mips/cpu-features.h
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ * Copyright (C) 2004 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 1
+#define cpu_has_tx39_cache 0
+#define cpu_has_sb1_cache 0
+#define cpu_has_fpu 0
+#define cpu_has_32fpr 0
+#define cpu_has_counter 1
+#define cpu_has_watch 1
+#define cpu_has_divec 1
+
+#define cpu_has_prefetch 1
+#define cpu_has_ejtag 1
+#define cpu_has_llsc 1
+
+#define cpu_has_mips16 1
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+
+#define cpu_has_mips32r1 1
+#define cpu_has_mips32r2 1
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+
+#define cpu_has_64bits 0
+#define cpu_has_64bit_zero_reg 0
+#define cpu_has_64bit_gp_regs 0
+#define cpu_has_64bit_addresses 0
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+
+#endif /* __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-ath79/gpio.h b/arch/mips/include/asm/mach-ath79/gpio.h
new file mode 100644
index 000000000000..60dcb62785b4
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/gpio.h
@@ -0,0 +1,26 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X GPIO API definitions
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ASM_MACH_ATH79_GPIO_H
+#define __ASM_MACH_ATH79_GPIO_H
+
+#define ARCH_NR_GPIOS 64
+#include <asm-generic/gpio.h>
+
+int gpio_to_irq(unsigned gpio);
+int irq_to_gpio(unsigned irq);
+int gpio_get_value(unsigned gpio);
+void gpio_set_value(unsigned gpio, int value);
+
+#define gpio_cansleep __gpio_cansleep
+
+#endif /* __ASM_MACH_ATH79_GPIO_H */
diff --git a/arch/mips/include/asm/mach-ath79/irq.h b/arch/mips/include/asm/mach-ath79/irq.h
new file mode 100644
index 000000000000..189bc6eb9c10
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/irq.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+#ifndef __ASM_MACH_ATH79_IRQ_H
+#define __ASM_MACH_ATH79_IRQ_H
+
+#define MIPS_CPU_IRQ_BASE 0
+#define NR_IRQS 16
+
+#define ATH79_MISC_IRQ_BASE 8
+#define ATH79_MISC_IRQ_COUNT 8
+
+#define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2)
+#define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3)
+#define ATH79_CPU_IRQ_GE0 (MIPS_CPU_IRQ_BASE + 4)
+#define ATH79_CPU_IRQ_GE1 (MIPS_CPU_IRQ_BASE + 5)
+#define ATH79_CPU_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6)
+#define ATH79_CPU_IRQ_TIMER (MIPS_CPU_IRQ_BASE + 7)
+
+#define ATH79_MISC_IRQ_TIMER (ATH79_MISC_IRQ_BASE + 0)
+#define ATH79_MISC_IRQ_ERROR (ATH79_MISC_IRQ_BASE + 1)
+#define ATH79_MISC_IRQ_GPIO (ATH79_MISC_IRQ_BASE + 2)
+#define ATH79_MISC_IRQ_UART (ATH79_MISC_IRQ_BASE + 3)
+#define ATH79_MISC_IRQ_WDOG (ATH79_MISC_IRQ_BASE + 4)
+#define ATH79_MISC_IRQ_PERFC (ATH79_MISC_IRQ_BASE + 5)
+#define ATH79_MISC_IRQ_OHCI (ATH79_MISC_IRQ_BASE + 6)
+#define ATH79_MISC_IRQ_DMA (ATH79_MISC_IRQ_BASE + 7)
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_ATH79_IRQ_H */
diff --git a/arch/mips/include/asm/mach-ath79/kernel-entry-init.h b/arch/mips/include/asm/mach-ath79/kernel-entry-init.h
new file mode 100644
index 000000000000..d8d046bccc8e
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/kernel-entry-init.h
@@ -0,0 +1,32 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X specific kernel entry setup
+ *
+ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_MACH_ATH79_KERNEL_ENTRY_H
+#define __ASM_MACH_ATH79_KERNEL_ENTRY_H
+
+ /*
+ * Some bootloaders set the 'Kseg0 coherency algorithm' to
+ * 'Cacheable, noncoherent, write-through, no write allocate'
+ * and this cause performance issues. Let's go and change it to
+ * 'Cacheable, noncoherent, write-back, write allocate'
+ */
+ .macro kernel_entry_setup
+ mfc0 t0, CP0_CONFIG
+ li t1, ~CONF_CM_CMASK
+ and t0, t1
+ ori t0, CONF_CM_CACHABLE_NONCOHERENT
+ mtc0 t0, CP0_CONFIG
+ nop
+ .endm
+
+ .macro smp_slave_setup
+ .endm
+
+#endif /* __ASM_MACH_ATH79_KERNEL_ENTRY_H */
diff --git a/arch/mips/include/asm/mach-ath79/war.h b/arch/mips/include/asm/mach-ath79/war.h
new file mode 100644
index 000000000000..323d9f1d8c45
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MACH_ATH79_WAR_H
+#define __ASM_MACH_ATH79_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MACH_ATH79_WAR_H */
diff --git a/arch/mips/include/asm/mips_machine.h b/arch/mips/include/asm/mips_machine.h
new file mode 100644
index 000000000000..363bb352c7f7
--- /dev/null
+++ b/arch/mips/include/asm/mips_machine.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ASM_MIPS_MACHINE_H
+#define __ASM_MIPS_MACHINE_H
+
+#include <linux/init.h>
+#include <linux/stddef.h>
+
+#include <asm/bootinfo.h>
+
+struct mips_machine {
+ unsigned long mach_type;
+ const char *mach_id;
+ const char *mach_name;
+ void (*mach_setup)(void);
+};
+
+#define MIPS_MACHINE(_type, _id, _name, _setup) \
+static const char machine_name_##_type[] __initconst \
+ __aligned(1) = _name; \
+static const char machine_id_##_type[] __initconst \
+ __aligned(1) = _id; \
+static struct mips_machine machine_##_type \
+ __used __section(.mips.machines.init) = \
+{ \
+ .mach_type = _type, \
+ .mach_id = machine_id_##_type, \
+ .mach_name = machine_name_##_type, \
+ .mach_setup = _setup, \
+};
+
+extern long __mips_machines_start;
+extern long __mips_machines_end;
+
+#ifdef CONFIG_MIPS_MACHINE
+int mips_machtype_setup(char *id) __init;
+void mips_machine_setup(void) __init;
+void mips_set_machine_name(const char *name) __init;
+char *mips_get_machine_name(void);
+#else
+static inline int mips_machtype_setup(char *id) { return 1; }
+static inline void mips_machine_setup(void) { }
+static inline void mips_set_machine_name(const char *name) { }
+static inline char *mips_get_machine_name(void) { return NULL; }
+#endif /* CONFIG_MIPS_MACHINE */
+
+#endif /* __ASM_MIPS_MACHINE_H */
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h
index d9592733a7ba..73c0d45798de 100644
--- a/arch/mips/include/asm/mmu_context.h
+++ b/arch/mips/include/asm/mmu_context.h
@@ -29,13 +29,7 @@
#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
tlbmiss_handler_setup_pgd((unsigned long)(pgd))
-static inline void tlbmiss_handler_setup_pgd(unsigned long pgd)
-{
- /* Check for swapper_pg_dir and convert to physical address. */
- if ((pgd & CKSEG3) == CKSEG0)
- pgd = CPHYSADDR(pgd);
- write_c0_context(pgd << 11);
-}
+extern void tlbmiss_handler_setup_pgd(unsigned long pgd);
#define TLBMISS_HANDLER_SETUP() \
do { \
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h
index 892062d6d748..dcbd4bb417ec 100644
--- a/arch/mips/include/asm/uasm.h
+++ b/arch/mips/include/asm/uasm.h
@@ -115,7 +115,12 @@ Ip_0(_tlbwr);
Ip_u3u1u2(_xor);
Ip_u2u1u3(_xori);
Ip_u2u1msbu3(_dins);
+Ip_u2u1msbu3(_dinsm);
Ip_u1(_syscall);
+Ip_u1u2s3(_bbit0);
+Ip_u1u2s3(_bbit1);
+Ip_u3u1u2(_lwx);
+Ip_u3u1u2(_ldx);
/* Handle labels. */
struct uasm_label {
@@ -153,6 +158,7 @@ static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_dsubu(buf, rs, rt, rd)
# define UASM_i_LL(buf, rs, rt, off) uasm_i_lld(buf, rs, rt, off)
# define UASM_i_SC(buf, rs, rt, off) uasm_i_scd(buf, rs, rt, off)
+# define UASM_i_LWX(buf, rs, rt, rd) uasm_i_ldx(buf, rs, rt, rd)
#else
# define UASM_i_LW(buf, rs, rt, off) uasm_i_lw(buf, rs, rt, off)
# define UASM_i_SW(buf, rs, rt, off) uasm_i_sw(buf, rs, rt, off)
@@ -167,6 +173,7 @@ static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_subu(buf, rs, rt, rd)
# define UASM_i_LL(buf, rs, rt, off) uasm_i_ll(buf, rs, rt, off)
# define UASM_i_SC(buf, rs, rt, off) uasm_i_sc(buf, rs, rt, off)
+# define UASM_i_LWX(buf, rs, rt, rd) uasm_i_lwx(buf, rs, rt, rd)
#endif
#define uasm_i_b(buf, off) uasm_i_beq(buf, 0, 0, off)
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 22b2e0e38617..cedee2bcbd18 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o
+obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o
obj-$(CONFIG_OF) += prom.o
@@ -106,4 +107,6 @@ obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
+obj-$(CONFIG_JUMP_LABEL) += jump_label.o
+
CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 68dae7b6b5db..f65d4c8c65a6 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -739,6 +739,8 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
&& cpu_has_tlb)
c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
+ c->kscratch_mask = (config4 >> 16) & 0xff;
+
return config4 & MIPS_CONF_M;
}
diff --git a/arch/mips/kernel/jump_label.c b/arch/mips/kernel/jump_label.c
new file mode 100644
index 000000000000..6001610cfe55
--- /dev/null
+++ b/arch/mips/kernel/jump_label.c
@@ -0,0 +1,54 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2010 Cavium Networks, Inc.
+ */
+
+#include <linux/jump_label.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/cpu.h>
+
+#include <asm/cacheflush.h>
+#include <asm/inst.h>
+
+#ifdef HAVE_JUMP_LABEL
+
+#define J_RANGE_MASK ((1ul << 28) - 1)
+
+void arch_jump_label_transform(struct jump_entry *e,
+ enum jump_label_type type)
+{
+ union mips_instruction insn;
+ union mips_instruction *insn_p =
+ (union mips_instruction *)(unsigned long)e->code;
+
+ /* Jump only works within a 256MB aligned region. */
+ BUG_ON((e->target & ~J_RANGE_MASK) != (e->code & ~J_RANGE_MASK));
+
+ /* Target must have 4 byte alignment. */
+ BUG_ON((e->target & 3) != 0);
+
+ if (type == JUMP_LABEL_ENABLE) {
+ insn.j_format.opcode = j_op;
+ insn.j_format.target = (e->target & J_RANGE_MASK) >> 2;
+ } else {
+ insn.word = 0; /* nop */
+ }
+
+ get_online_cpus();
+ mutex_lock(&text_mutex);
+ *insn_p = insn;
+
+ flush_icache_range((unsigned long)insn_p,
+ (unsigned long)insn_p + sizeof(*insn_p));
+
+ mutex_unlock(&text_mutex);
+ put_online_cpus();
+}
+
+#endif /* HAVE_JUMP_LABEL */
diff --git a/arch/mips/kernel/mips_machine.c b/arch/mips/kernel/mips_machine.c
new file mode 100644
index 000000000000..411a058d2c53
--- /dev/null
+++ b/arch/mips/kernel/mips_machine.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include <asm/mips_machine.h>
+
+static struct mips_machine *mips_machine __initdata;
+static char *mips_machine_name = "Unknown";
+
+#define for_each_machine(mach) \
+ for ((mach) = (struct mips_machine *)&__mips_machines_start; \
+ (mach) && \
+ (unsigned long)(mach) < (unsigned long)&__mips_machines_end; \
+ (mach)++)
+
+__init void mips_set_machine_name(const char *name)
+{
+ char *p;
+
+ if (name == NULL)
+ return;
+
+ p = kstrdup(name, GFP_KERNEL);
+ if (!p)
+ pr_err("MIPS: no memory for machine_name\n");
+
+ mips_machine_name = p;
+}
+
+char *mips_get_machine_name(void)
+{
+ return mips_machine_name;
+}
+
+__init int mips_machtype_setup(char *id)
+{
+ struct mips_machine *mach;
+
+ for_each_machine(mach) {
+ if (mach->mach_id == NULL)
+ continue;
+
+ if (strcmp(mach->mach_id, id) == 0) {
+ mips_machtype = mach->mach_type;
+ return 0;
+ }
+ }
+
+ pr_err("MIPS: no machine found for id '%s', supported machines:\n", id);
+ pr_err("%-24s %s\n", "id", "name");
+ for_each_machine(mach)
+ pr_err("%-24s %s\n", mach->mach_id, mach->mach_name);
+
+ return 1;
+}
+
+__setup("machtype=", mips_machtype_setup);
+
+__init void mips_machine_setup(void)
+{
+ struct mips_machine *mach;
+
+ for_each_machine(mach) {
+ if (mips_machtype == mach->mach_type) {
+ mips_machine = mach;
+ break;
+ }
+ }
+
+ if (!mips_machine)
+ return;
+
+ mips_set_machine_name(mips_machine->mach_name);
+ pr_info("MIPS: machine is %s\n", mips_machine_name);
+
+ if (mips_machine->mach_setup)
+ mips_machine->mach_setup();
+}
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index d87a72e9fac7..dd940b701963 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -30,6 +30,8 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
+#include <linux/jump_label.h>
+
#include <asm/pgtable.h> /* MODULE_START */
struct mips_hi16 {
@@ -382,6 +384,9 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *s;
char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+ /* Make jump label nops. */
+ jump_label_apply_nops(me);
+
INIT_LIST_HEAD(&me->arch.dbe_list);
for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
if (strcmp("__dbe_table", secstrings + s->sh_name) != 0)
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index 26109c4d5170..e309665b6c81 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -12,6 +12,7 @@
#include <asm/cpu-features.h>
#include <asm/mipsregs.h>
#include <asm/processor.h>
+#include <asm/mips_machine.h>
unsigned int vced_count, vcei_count;
@@ -31,8 +32,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
/*
* For the first processor also print the system type
*/
- if (n == 0)
+ if (n == 0) {
seq_printf(m, "system type\t\t: %s\n", get_system_type());
+ if (mips_get_machine_name())
+ seq_printf(m, "machine\t\t\t: %s\n",
+ mips_get_machine_name());
+ }
seq_printf(m, "processor\t\t: %ld\n", n);
sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
@@ -69,6 +74,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
);
seq_printf(m, "shadow register sets\t: %d\n",
cpu_data[n].srsets);
+ seq_printf(m, "kscratch registers\t: %d\n",
+ hweight8(cpu_data[n].kscratch_mask));
seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index 9dbe58368953..a19811e98a41 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -45,11 +45,9 @@ void __init free_mem_mach(unsigned long addr, unsigned long size)
return free_bootmem(addr, size);
}
-u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
{
- return virt_to_phys(
- __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS))
- );
+ return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
}
#ifdef CONFIG_BLK_DEV_INITRD
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index acd3f2c49c06..8ad1d5679f14 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -70,7 +70,7 @@ static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
* mips_io_port_base is the begin of the address space to which x86 style
* I/O ports are mapped.
*/
-const unsigned long mips_io_port_base __read_mostly = -1;
+const unsigned long mips_io_port_base = -1;
EXPORT_SYMBOL(mips_io_port_base);
static struct resource code_resource = { .name = "Kernel code", };
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index e97104302541..71350f7f2d88 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1592,7 +1592,6 @@ void __cpuinit per_cpu_trap_init(void)
#endif /* CONFIG_MIPS_MT_SMTC */
cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
- TLBMISS_HANDLER_SETUP();
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
@@ -1614,6 +1613,7 @@ void __cpuinit per_cpu_trap_init(void)
write_c0_wired(0);
}
#endif /* CONFIG_MIPS_MT_SMTC */
+ TLBMISS_HANDLER_SETUP();
}
/* Install CPU exception handler */
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index f25df73db923..570607b376b5 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -98,6 +98,13 @@ SECTIONS
INIT_TEXT_SECTION(PAGE_SIZE)
INIT_DATA_SECTION(16)
+ . = ALIGN(4);
+ .mips.machines.init : AT(ADDR(.mips.machines.init) - LOAD_OFFSET) {
+ __mips_machines_start = .;
+ *(.mips.machines.init)
+ __mips_machines_end = .;
+ }
+
/* .exit.text is discarded at runtime, not link time, to deal with
* references from .rodata
*/
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 93816f3bca67..083d3412d0bc 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -26,8 +26,10 @@
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/init.h>
+#include <linux/cache.h>
-#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+#include <asm/pgtable.h>
#include <asm/war.h>
#include <asm/uasm.h>
@@ -63,6 +65,52 @@ static inline int __maybe_unused r10000_llsc_war(void)
return R10000_LLSC_WAR;
}
+static int use_bbit_insns(void)
+{
+ switch (current_cpu_type()) {
+ case CPU_CAVIUM_OCTEON:
+ case CPU_CAVIUM_OCTEON_PLUS:
+ case CPU_CAVIUM_OCTEON2:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int use_lwx_insns(void)
+{
+ switch (current_cpu_type()) {
+ case CPU_CAVIUM_OCTEON2:
+ return 1;
+ default:
+ return 0;
+ }
+}
+#if defined(CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE) && \
+ CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
+static bool scratchpad_available(void)
+{
+ return true;
+}
+static int scratchpad_offset(int i)
+{
+ /*
+ * CVMSEG starts at address -32768 and extends for
+ * CAVIUM_OCTEON_CVMSEG_SIZE 128 byte cache lines.
+ */
+ i += 1; /* Kernel use starts at the top and works down. */
+ return CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128 - (8 * i) - 32768;
+}
+#else
+static bool scratchpad_available(void)
+{
+ return false;
+}
+static int scratchpad_offset(int i)
+{
+ BUG();
+}
+#endif
/*
* Found by experiment: At least some revisions of the 4kc throw under
* some circumstances a machine check exception, triggered by invalid
@@ -173,11 +221,41 @@ static struct uasm_reloc relocs[128] __cpuinitdata;
static int check_for_high_segbits __cpuinitdata;
#endif
+static int check_for_high_segbits __cpuinitdata;
+
+static unsigned int kscratch_used_mask __cpuinitdata;
+
+static int __cpuinit allocate_kscratch(void)
+{
+ int r;
+ unsigned int a = cpu_data[0].kscratch_mask & ~kscratch_used_mask;
+
+ r = ffs(a);
+
+ if (r == 0)
+ return -1;
+
+ r--; /* make it zero based */
+
+ kscratch_used_mask |= (1 << r);
+
+ return r;
+}
+
+static int scratch_reg __cpuinitdata;
+static int pgd_reg __cpuinitdata;
+enum vmalloc64_mode {not_refill, refill_scratch, refill_noscratch};
+
#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+
/*
* CONFIG_MIPS_PGD_C0_CONTEXT implies 64 bit and lack of pgd_current,
* we cannot do r3000 under these circumstances.
+ *
+ * Declare pgd_current here instead of including mmu_context.h to avoid type
+ * conflicts for tlbmiss_handler_setup_pgd
*/
+extern unsigned long pgd_current[];
/*
* The R3000 TLB handler is simple.
@@ -440,21 +518,43 @@ static __cpuinit __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
static __cpuinit void build_restore_pagemask(u32 **p,
struct uasm_reloc **r,
unsigned int tmp,
- enum label_id lid)
+ enum label_id lid,
+ int restore_scratch)
{
- /* Reset default page size */
- if (PM_DEFAULT_MASK >> 16) {
- uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16);
- uasm_i_ori(p, tmp, tmp, PM_DEFAULT_MASK & 0xffff);
- uasm_il_b(p, r, lid);
- uasm_i_mtc0(p, tmp, C0_PAGEMASK);
- } else if (PM_DEFAULT_MASK) {
- uasm_i_ori(p, tmp, 0, PM_DEFAULT_MASK);
- uasm_il_b(p, r, lid);
- uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ if (restore_scratch) {
+ /* Reset default page size */
+ if (PM_DEFAULT_MASK >> 16) {
+ uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16);
+ uasm_i_ori(p, tmp, tmp, PM_DEFAULT_MASK & 0xffff);
+ uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ uasm_il_b(p, r, lid);
+ } else if (PM_DEFAULT_MASK) {
+ uasm_i_ori(p, tmp, 0, PM_DEFAULT_MASK);
+ uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ uasm_il_b(p, r, lid);
+ } else {
+ uasm_i_mtc0(p, 0, C0_PAGEMASK);
+ uasm_il_b(p, r, lid);
+ }
+ if (scratch_reg > 0)
+ UASM_i_MFC0(p, 1, 31, scratch_reg);
+ else
+ UASM_i_LW(p, 1, scratchpad_offset(0), 0);
} else {
- uasm_il_b(p, r, lid);
- uasm_i_mtc0(p, 0, C0_PAGEMASK);
+ /* Reset default page size */
+ if (PM_DEFAULT_MASK >> 16) {
+ uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16);
+ uasm_i_ori(p, tmp, tmp, PM_DEFAULT_MASK & 0xffff);
+ uasm_il_b(p, r, lid);
+ uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ } else if (PM_DEFAULT_MASK) {
+ uasm_i_ori(p, tmp, 0, PM_DEFAULT_MASK);
+ uasm_il_b(p, r, lid);
+ uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ } else {
+ uasm_il_b(p, r, lid);
+ uasm_i_mtc0(p, 0, C0_PAGEMASK);
+ }
}
}
@@ -462,7 +562,8 @@ static __cpuinit void build_huge_tlb_write_entry(u32 **p,
struct uasm_label **l,
struct uasm_reloc **r,
unsigned int tmp,
- enum tlb_write_entry wmode)
+ enum tlb_write_entry wmode,
+ int restore_scratch)
{
/* Set huge page tlb entry size */
uasm_i_lui(p, tmp, PM_HUGE_MASK >> 16);
@@ -471,7 +572,7 @@ static __cpuinit void build_huge_tlb_write_entry(u32 **p,
build_tlb_write_entry(p, l, r, wmode);
- build_restore_pagemask(p, r, tmp, label_leave);
+ build_restore_pagemask(p, r, tmp, label_leave, restore_scratch);
}
/*
@@ -482,8 +583,12 @@ build_is_huge_pte(u32 **p, struct uasm_reloc **r, unsigned int tmp,
unsigned int pmd, int lid)
{
UASM_i_LW(p, tmp, 0, pmd);
- uasm_i_andi(p, tmp, tmp, _PAGE_HUGE);
- uasm_il_bnez(p, r, tmp, lid);
+ if (use_bbit_insns()) {
+ uasm_il_bbit1(p, r, tmp, ilog2(_PAGE_HUGE), lid);
+ } else {
+ uasm_i_andi(p, tmp, tmp, _PAGE_HUGE);
+ uasm_il_bnez(p, r, tmp, lid);
+ }
}
static __cpuinit void build_huge_update_entries(u32 **p,
@@ -532,7 +637,7 @@ static __cpuinit void build_huge_handler_tail(u32 **p,
UASM_i_SW(p, pte, 0, ptr);
#endif
build_huge_update_entries(p, pte, ptr);
- build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed);
+ build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed, 0);
}
#endif /* CONFIG_HUGETLB_PAGE */
@@ -573,13 +678,22 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
/* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
- /*
- * &pgd << 11 stored in CONTEXT [23..63].
- */
- UASM_i_MFC0(p, ptr, C0_CONTEXT);
- uasm_i_dins(p, ptr, 0, 0, 23); /* Clear lower 23 bits of context. */
- uasm_i_ori(p, ptr, ptr, 0x540); /* 1 0 1 0 1 << 6 xkphys cached */
- uasm_i_drotr(p, ptr, ptr, 11);
+ if (pgd_reg != -1) {
+ /* pgd is in pgd_reg */
+ UASM_i_MFC0(p, ptr, 31, pgd_reg);
+ } else {
+ /*
+ * &pgd << 11 stored in CONTEXT [23..63].
+ */
+ UASM_i_MFC0(p, ptr, C0_CONTEXT);
+
+ /* Clear lower 23 bits of context. */
+ uasm_i_dins(p, ptr, 0, 0, 23);
+
+ /* 1 0 1 0 1 << 6 xkphys cached */
+ uasm_i_ori(p, ptr, ptr, 0x540);
+ uasm_i_drotr(p, ptr, ptr, 11);
+ }
#elif defined(CONFIG_SMP)
# ifdef CONFIG_MIPS_MT_SMTC
/*
@@ -620,7 +734,6 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
#endif
}
-enum vmalloc64_mode {not_refill, refill};
/*
* BVADDR is the faulting address, PTR is scratch.
* PTR will hold the pgd for vmalloc.
@@ -638,7 +751,7 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
uasm_l_vmalloc(l, *p);
- if (mode == refill && check_for_high_segbits) {
+ if (mode != not_refill && check_for_high_segbits) {
if (single_insn_swpd) {
uasm_il_bltz(p, r, bvaddr, label_vmalloc_done);
uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
@@ -661,7 +774,7 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
}
}
- if (mode == refill && check_for_high_segbits) {
+ if (mode != not_refill && check_for_high_segbits) {
uasm_l_large_segbits_fault(l, *p);
/*
* We get here if we are an xsseg address, or if we are
@@ -677,7 +790,15 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
*/
UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0);
uasm_i_jr(p, ptr);
- uasm_i_nop(p);
+
+ if (mode == refill_scratch) {
+ if (scratch_reg > 0)
+ UASM_i_MFC0(p, 1, 31, scratch_reg);
+ else
+ UASM_i_LW(p, 1, scratchpad_offset(0), 0);
+ } else {
+ uasm_i_nop(p);
+ }
}
}
@@ -834,6 +955,185 @@ static void __cpuinit build_update_entries(u32 **p, unsigned int tmp,
#endif
}
+struct mips_huge_tlb_info {
+ int huge_pte;
+ int restore_scratch;
+};
+
+static struct mips_huge_tlb_info __cpuinit
+build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r, unsigned int tmp,
+ unsigned int ptr, int c0_scratch)
+{
+ struct mips_huge_tlb_info rv;
+ unsigned int even, odd;
+ int vmalloc_branch_delay_filled = 0;
+ const int scratch = 1; /* Our extra working register */
+
+ rv.huge_pte = scratch;
+ rv.restore_scratch = 0;
+
+ if (check_for_high_segbits) {
+ UASM_i_MFC0(p, tmp, C0_BADVADDR);
+
+ if (pgd_reg != -1)
+ UASM_i_MFC0(p, ptr, 31, pgd_reg);
+ else
+ UASM_i_MFC0(p, ptr, C0_CONTEXT);
+
+ if (c0_scratch >= 0)
+ UASM_i_MTC0(p, scratch, 31, c0_scratch);
+ else
+ UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
+
+ uasm_i_dsrl_safe(p, scratch, tmp,
+ PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
+ uasm_il_bnez(p, r, scratch, label_vmalloc);
+
+ if (pgd_reg == -1) {
+ vmalloc_branch_delay_filled = 1;
+ /* Clear lower 23 bits of context. */
+ uasm_i_dins(p, ptr, 0, 0, 23);
+ }
+ } else {
+ if (pgd_reg != -1)
+ UASM_i_MFC0(p, ptr, 31, pgd_reg);
+ else
+ UASM_i_MFC0(p, ptr, C0_CONTEXT);
+
+ UASM_i_MFC0(p, tmp, C0_BADVADDR);
+
+ if (c0_scratch >= 0)
+ UASM_i_MTC0(p, scratch, 31, c0_scratch);
+ else
+ UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
+
+ if (pgd_reg == -1)
+ /* Clear lower 23 bits of context. */
+ uasm_i_dins(p, ptr, 0, 0, 23);
+
+ uasm_il_bltz(p, r, tmp, label_vmalloc);
+ }
+
+ if (pgd_reg == -1) {
+ vmalloc_branch_delay_filled = 1;
+ /* 1 0 1 0 1 << 6 xkphys cached */
+ uasm_i_ori(p, ptr, ptr, 0x540);
+ uasm_i_drotr(p, ptr, ptr, 11);
+ }
+
+#ifdef __PAGETABLE_PMD_FOLDED
+#define LOC_PTEP scratch
+#else
+#define LOC_PTEP ptr
+#endif
+
+ if (!vmalloc_branch_delay_filled)
+ /* get pgd offset in bytes */
+ uasm_i_dsrl_safe(p, scratch, tmp, PGDIR_SHIFT - 3);
+
+ uasm_l_vmalloc_done(l, *p);
+
+ /*
+ * tmp ptr
+ * fall-through case = badvaddr *pgd_current
+ * vmalloc case = badvaddr swapper_pg_dir
+ */
+
+ if (vmalloc_branch_delay_filled)
+ /* get pgd offset in bytes */
+ uasm_i_dsrl_safe(p, scratch, tmp, PGDIR_SHIFT - 3);
+
+#ifdef __PAGETABLE_PMD_FOLDED
+ GET_CONTEXT(p, tmp); /* get context reg */
+#endif
+ uasm_i_andi(p, scratch, scratch, (PTRS_PER_PGD - 1) << 3);
+
+ if (use_lwx_insns()) {
+ UASM_i_LWX(p, LOC_PTEP, scratch, ptr);
+ } else {
+ uasm_i_daddu(p, ptr, ptr, scratch); /* add in pgd offset */
+ uasm_i_ld(p, LOC_PTEP, 0, ptr); /* get pmd pointer */
+ }
+
+#ifndef __PAGETABLE_PMD_FOLDED
+ /* get pmd offset in bytes */
+ uasm_i_dsrl_safe(p, scratch, tmp, PMD_SHIFT - 3);
+ uasm_i_andi(p, scratch, scratch, (PTRS_PER_PMD - 1) << 3);
+ GET_CONTEXT(p, tmp); /* get context reg */
+
+ if (use_lwx_insns()) {
+ UASM_i_LWX(p, scratch, scratch, ptr);
+ } else {
+ uasm_i_daddu(p, ptr, ptr, scratch); /* add in pmd offset */
+ UASM_i_LW(p, scratch, 0, ptr);
+ }
+#endif
+ /* Adjust the context during the load latency. */
+ build_adjust_context(p, tmp);
+
+#ifdef CONFIG_HUGETLB_PAGE
+ uasm_il_bbit1(p, r, scratch, ilog2(_PAGE_HUGE), label_tlb_huge_update);
+ /*
+ * The in the LWX case we don't want to do the load in the
+ * delay slot. It cannot issue in the same cycle and may be
+ * speculative and unneeded.
+ */
+ if (use_lwx_insns())
+ uasm_i_nop(p);
+#endif /* CONFIG_HUGETLB_PAGE */
+
+
+ /* build_update_entries */
+ if (use_lwx_insns()) {
+ even = ptr;
+ odd = tmp;
+ UASM_i_LWX(p, even, scratch, tmp);
+ UASM_i_ADDIU(p, tmp, tmp, sizeof(pte_t));
+ UASM_i_LWX(p, odd, scratch, tmp);
+ } else {
+ UASM_i_ADDU(p, ptr, scratch, tmp); /* add in offset */
+ even = tmp;
+ odd = ptr;
+ UASM_i_LW(p, even, 0, ptr); /* get even pte */
+ UASM_i_LW(p, odd, sizeof(pte_t), ptr); /* get odd pte */
+ }
+ if (kernel_uses_smartmips_rixi) {
+ uasm_i_dsrl_safe(p, even, even, ilog2(_PAGE_NO_EXEC));
+ uasm_i_dsrl_safe(p, odd, odd, ilog2(_PAGE_NO_EXEC));
+ uasm_i_drotr(p, even, even,
+ ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ UASM_i_MTC0(p, even, C0_ENTRYLO0); /* load it */
+ uasm_i_drotr(p, odd, odd,
+ ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ } else {
+ uasm_i_dsrl_safe(p, even, even, ilog2(_PAGE_GLOBAL));
+ UASM_i_MTC0(p, even, C0_ENTRYLO0); /* load it */
+ uasm_i_dsrl_safe(p, odd, odd, ilog2(_PAGE_GLOBAL));
+ }
+ UASM_i_MTC0(p, odd, C0_ENTRYLO1); /* load it */
+
+ if (c0_scratch >= 0) {
+ UASM_i_MFC0(p, scratch, 31, c0_scratch);
+ build_tlb_write_entry(p, l, r, tlb_random);
+ uasm_l_leave(l, *p);
+ rv.restore_scratch = 1;
+ } else if (PAGE_SHIFT == 14 || PAGE_SHIFT == 13) {
+ build_tlb_write_entry(p, l, r, tlb_random);
+ uasm_l_leave(l, *p);
+ UASM_i_LW(p, scratch, scratchpad_offset(0), 0);
+ } else {
+ UASM_i_LW(p, scratch, scratchpad_offset(0), 0);
+ build_tlb_write_entry(p, l, r, tlb_random);
+ uasm_l_leave(l, *p);
+ rv.restore_scratch = 1;
+ }
+
+ uasm_i_eret(p); /* return from trap */
+
+ return rv;
+}
+
/*
* For a 64-bit kernel, we are using the 64-bit XTLB refill exception
* because EXL == 0. If we wrap, we can also use the 32 instruction
@@ -849,54 +1149,67 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
struct uasm_reloc *r = relocs;
u32 *f;
unsigned int final_len;
+ struct mips_huge_tlb_info htlb_info;
+ enum vmalloc64_mode vmalloc_mode;
memset(tlb_handler, 0, sizeof(tlb_handler));
memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs));
memset(final_handler, 0, sizeof(final_handler));
- /*
- * create the plain linear handler
- */
- if (bcm1250_m3_war()) {
- unsigned int segbits = 44;
+ if (scratch_reg == 0)
+ scratch_reg = allocate_kscratch();
- uasm_i_dmfc0(&p, K0, C0_BADVADDR);
- uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
- uasm_i_xor(&p, K0, K0, K1);
- uasm_i_dsrl_safe(&p, K1, K0, 62);
- uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
- uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
- uasm_i_or(&p, K0, K0, K1);
- uasm_il_bnez(&p, &r, K0, label_leave);
- /* No need for uasm_i_nop */
- }
+ if ((scratch_reg > 0 || scratchpad_available()) && use_bbit_insns()) {
+ htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1,
+ scratch_reg);
+ vmalloc_mode = refill_scratch;
+ } else {
+ htlb_info.huge_pte = K0;
+ htlb_info.restore_scratch = 0;
+ vmalloc_mode = refill_noscratch;
+ /*
+ * create the plain linear handler
+ */
+ if (bcm1250_m3_war()) {
+ unsigned int segbits = 44;
+
+ uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+ uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
+ uasm_i_xor(&p, K0, K0, K1);
+ uasm_i_dsrl_safe(&p, K1, K0, 62);
+ uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
+ uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
+ uasm_i_or(&p, K0, K0, K1);
+ uasm_il_bnez(&p, &r, K0, label_leave);
+ /* No need for uasm_i_nop */
+ }
#ifdef CONFIG_64BIT
- build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
+ build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
#else
- build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
+ build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
#endif
#ifdef CONFIG_HUGETLB_PAGE
- build_is_huge_pte(&p, &r, K0, K1, label_tlb_huge_update);
+ build_is_huge_pte(&p, &r, K0, K1, label_tlb_huge_update);
#endif
- build_get_ptep(&p, K0, K1);
- build_update_entries(&p, K0, K1);
- build_tlb_write_entry(&p, &l, &r, tlb_random);
- uasm_l_leave(&l, p);
- uasm_i_eret(&p); /* return from trap */
-
+ build_get_ptep(&p, K0, K1);
+ build_update_entries(&p, K0, K1);
+ build_tlb_write_entry(&p, &l, &r, tlb_random);
+ uasm_l_leave(&l, p);
+ uasm_i_eret(&p); /* return from trap */
+ }
#ifdef CONFIG_HUGETLB_PAGE
uasm_l_tlb_huge_update(&l, p);
- UASM_i_LW(&p, K0, 0, K1);
- build_huge_update_entries(&p, K0, K1);
- build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random);
+ build_huge_update_entries(&p, htlb_info.huge_pte, K1);
+ build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random,
+ htlb_info.restore_scratch);
#endif
#ifdef CONFIG_64BIT
- build_get_pgd_vmalloc64(&p, &l, &r, K0, K1, refill);
+ build_get_pgd_vmalloc64(&p, &l, &r, K0, K1, vmalloc_mode);
#endif
/*
@@ -1014,6 +1327,55 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
u32 handle_tlbl[FASTPATH_SIZE] __cacheline_aligned;
u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned;
u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned;
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+u32 tlbmiss_handler_setup_pgd[16] __cacheline_aligned;
+
+static void __cpuinit build_r4000_setup_pgd(void)
+{
+ const int a0 = 4;
+ const int a1 = 5;
+ u32 *p = tlbmiss_handler_setup_pgd;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+
+ memset(tlbmiss_handler_setup_pgd, 0, sizeof(tlbmiss_handler_setup_pgd));
+ memset(labels, 0, sizeof(labels));
+ memset(relocs, 0, sizeof(relocs));
+
+ pgd_reg = allocate_kscratch();
+
+ if (pgd_reg == -1) {
+ /* PGD << 11 in c0_Context */
+ /*
+ * If it is a ckseg0 address, convert to a physical
+ * address. Shifting right by 29 and adding 4 will
+ * result in zero for these addresses.
+ *
+ */
+ UASM_i_SRA(&p, a1, a0, 29);
+ UASM_i_ADDIU(&p, a1, a1, 4);
+ uasm_il_bnez(&p, &r, a1, label_tlbl_goaround1);
+ uasm_i_nop(&p);
+ uasm_i_dinsm(&p, a0, 0, 29, 64 - 29);
+ uasm_l_tlbl_goaround1(&l, p);
+ UASM_i_SLL(&p, a0, a0, 11);
+ uasm_i_jr(&p, 31);
+ UASM_i_MTC0(&p, a0, C0_CONTEXT);
+ } else {
+ /* PGD in c0_KScratch */
+ uasm_i_jr(&p, 31);
+ UASM_i_MTC0(&p, a0, 31, pgd_reg);
+ }
+ if (p - tlbmiss_handler_setup_pgd > ARRAY_SIZE(tlbmiss_handler_setup_pgd))
+ panic("tlbmiss_handler_setup_pgd space exceeded");
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote tlbmiss_handler_setup_pgd (%u instructions).\n",
+ (unsigned int)(p - tlbmiss_handler_setup_pgd));
+
+ dump_handler(tlbmiss_handler_setup_pgd,
+ ARRAY_SIZE(tlbmiss_handler_setup_pgd));
+}
+#endif
static void __cpuinit
iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
@@ -1100,14 +1462,20 @@ build_pte_present(u32 **p, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
if (kernel_uses_smartmips_rixi) {
- uasm_i_andi(p, pte, pte, _PAGE_PRESENT);
- uasm_il_beqz(p, r, pte, lid);
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid);
+ uasm_i_nop(p);
+ } else {
+ uasm_i_andi(p, pte, pte, _PAGE_PRESENT);
+ uasm_il_beqz(p, r, pte, lid);
+ iPTE_LW(p, pte, ptr);
+ }
} else {
uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
uasm_il_bnez(p, r, pte, lid);
+ iPTE_LW(p, pte, ptr);
}
- iPTE_LW(p, pte, ptr);
}
/* Make PTE valid, store result in PTR. */
@@ -1128,10 +1496,17 @@ static void __cpuinit
build_pte_writable(u32 **p, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
- uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
- uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
- uasm_il_bnez(p, r, pte, lid);
- iPTE_LW(p, pte, ptr);
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid);
+ uasm_i_nop(p);
+ uasm_il_bbit0(p, r, pte, ilog2(_PAGE_WRITE), lid);
+ uasm_i_nop(p);
+ } else {
+ uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+ uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+ uasm_il_bnez(p, r, pte, lid);
+ iPTE_LW(p, pte, ptr);
+ }
}
/* Make PTE writable, update software status bits as well, then store
@@ -1155,12 +1530,19 @@ static void __cpuinit
build_pte_modifiable(u32 **p, struct uasm_reloc **r,
unsigned int pte, unsigned int ptr, enum label_id lid)
{
- uasm_i_andi(p, pte, pte, _PAGE_WRITE);
- uasm_il_beqz(p, r, pte, lid);
- iPTE_LW(p, pte, ptr);
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(p, r, pte, ilog2(_PAGE_WRITE), lid);
+ uasm_i_nop(p);
+ } else {
+ uasm_i_andi(p, pte, pte, _PAGE_WRITE);
+ uasm_il_beqz(p, r, pte, lid);
+ iPTE_LW(p, pte, ptr);
+ }
}
#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+
+
/*
* R3000 style TLB load/store/modify handlers.
*/
@@ -1402,14 +1784,23 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
* If the page is not _PAGE_VALID, RI or XI could not
* have triggered it. Skip the expensive test..
*/
- uasm_i_andi(&p, K0, K0, _PAGE_VALID);
- uasm_il_beqz(&p, &r, K0, label_tlbl_goaround1);
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(&p, &r, K0, ilog2(_PAGE_VALID),
+ label_tlbl_goaround1);
+ } else {
+ uasm_i_andi(&p, K0, K0, _PAGE_VALID);
+ uasm_il_beqz(&p, &r, K0, label_tlbl_goaround1);
+ }
uasm_i_nop(&p);
uasm_i_tlbr(&p);
/* Examine entrylo 0 or 1 based on ptr. */
- uasm_i_andi(&p, K0, K1, sizeof(pte_t));
- uasm_i_beqz(&p, K0, 8);
+ if (use_bbit_insns()) {
+ uasm_i_bbit0(&p, K1, ilog2(sizeof(pte_t)), 8);
+ } else {
+ uasm_i_andi(&p, K0, K1, sizeof(pte_t));
+ uasm_i_beqz(&p, K0, 8);
+ }
UASM_i_MFC0(&p, K0, C0_ENTRYLO0); /* load it in the delay slot*/
UASM_i_MFC0(&p, K0, C0_ENTRYLO1); /* load it if ptr is odd */
@@ -1417,12 +1808,18 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
* If the entryLo (now in K0) is valid (bit 1), RI or
* XI must have triggered it.
*/
- uasm_i_andi(&p, K0, K0, 2);
- uasm_il_bnez(&p, &r, K0, label_nopage_tlbl);
-
- uasm_l_tlbl_goaround1(&l, p);
- /* Reload the PTE value */
- iPTE_LW(&p, K0, K1);
+ if (use_bbit_insns()) {
+ uasm_il_bbit1(&p, &r, K0, 1, label_nopage_tlbl);
+ /* Reload the PTE value */
+ iPTE_LW(&p, K0, K1);
+ uasm_l_tlbl_goaround1(&l, p);
+ } else {
+ uasm_i_andi(&p, K0, K0, 2);
+ uasm_il_bnez(&p, &r, K0, label_nopage_tlbl);
+ uasm_l_tlbl_goaround1(&l, p);
+ /* Reload the PTE value */
+ iPTE_LW(&p, K0, K1);
+ }
}
build_make_valid(&p, &r, K0, K1);
build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
@@ -1442,23 +1839,35 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
* If the page is not _PAGE_VALID, RI or XI could not
* have triggered it. Skip the expensive test..
*/
- uasm_i_andi(&p, K0, K0, _PAGE_VALID);
- uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(&p, &r, K0, ilog2(_PAGE_VALID),
+ label_tlbl_goaround2);
+ } else {
+ uasm_i_andi(&p, K0, K0, _PAGE_VALID);
+ uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
+ }
uasm_i_nop(&p);
uasm_i_tlbr(&p);
/* Examine entrylo 0 or 1 based on ptr. */
- uasm_i_andi(&p, K0, K1, sizeof(pte_t));
- uasm_i_beqz(&p, K0, 8);
-
+ if (use_bbit_insns()) {
+ uasm_i_bbit0(&p, K1, ilog2(sizeof(pte_t)), 8);
+ } else {
+ uasm_i_andi(&p, K0, K1, sizeof(pte_t));
+ uasm_i_beqz(&p, K0, 8);
+ }
UASM_i_MFC0(&p, K0, C0_ENTRYLO0); /* load it in the delay slot*/
UASM_i_MFC0(&p, K0, C0_ENTRYLO1); /* load it if ptr is odd */
/*
* If the entryLo (now in K0) is valid (bit 1), RI or
* XI must have triggered it.
*/
- uasm_i_andi(&p, K0, K0, 2);
- uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(&p, &r, K0, 1, label_tlbl_goaround2);
+ } else {
+ uasm_i_andi(&p, K0, K0, 2);
+ uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
+ }
/* Reload the PTE value */
iPTE_LW(&p, K0, K1);
@@ -1466,7 +1875,7 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
* We clobbered C0_PAGEMASK, restore it. On the other branch
* it is restored in build_huge_tlb_write_entry.
*/
- build_restore_pagemask(&p, &r, K0, label_nopage_tlbl);
+ build_restore_pagemask(&p, &r, K0, label_nopage_tlbl, 0);
uasm_l_tlbl_goaround2(&l, p);
}
@@ -1623,13 +2032,16 @@ void __cpuinit build_tlb_refill_handler(void)
break;
default:
- build_r4000_tlb_refill_handler();
if (!run_once) {
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+ build_r4000_setup_pgd();
+#endif
build_r4000_tlb_load_handler();
build_r4000_tlb_store_handler();
build_r4000_tlb_modify_handler();
run_once++;
}
+ build_r4000_tlb_refill_handler();
}
}
@@ -1641,4 +2053,8 @@ void __cpuinit flush_tlb_handlers(void)
(unsigned long)handle_tlbs + sizeof(handle_tlbs));
local_flush_icache_range((unsigned long)handle_tlbm,
(unsigned long)handle_tlbm + sizeof(handle_tlbm));
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+ local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd,
+ (unsigned long)tlbmiss_handler_setup_pgd + sizeof(handle_tlbm));
+#endif
}
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index 23afdebc8e5c..5fa185151fc8 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -68,7 +68,8 @@ enum opcode {
insn_pref, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw, insn_tlbp,
insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
- insn_dins, insn_syscall, insn_bbit0, insn_bbit1
+ insn_dins, insn_dinsm, insn_syscall, insn_bbit0, insn_bbit1,
+ insn_lwx, insn_ldx
};
struct insn {
@@ -142,9 +143,12 @@ static struct insn insn_table[] __uasminitdata = {
{ insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
{ insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
{ insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
+ { insn_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE },
{ insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
{ insn_bbit0, M(lwc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
{ insn_bbit1, M(swc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD },
+ { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD },
{ insn_invalid, 0, 0 }
};
@@ -152,91 +156,83 @@ static struct insn insn_table[] __uasminitdata = {
static inline __uasminit u32 build_rs(u32 arg)
{
- if (arg & ~RS_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~RS_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return (arg & RS_MASK) << RS_SH;
}
static inline __uasminit u32 build_rt(u32 arg)
{
- if (arg & ~RT_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~RT_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return (arg & RT_MASK) << RT_SH;
}
static inline __uasminit u32 build_rd(u32 arg)
{
- if (arg & ~RD_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~RD_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return (arg & RD_MASK) << RD_SH;
}
static inline __uasminit u32 build_re(u32 arg)
{
- if (arg & ~RE_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~RE_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return (arg & RE_MASK) << RE_SH;
}
static inline __uasminit u32 build_simm(s32 arg)
{
- if (arg > 0x7fff || arg < -0x8000)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg > 0x7fff || arg < -0x8000,
+ KERN_WARNING "Micro-assembler field overflow\n");
return arg & 0xffff;
}
static inline __uasminit u32 build_uimm(u32 arg)
{
- if (arg & ~IMM_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~IMM_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return arg & IMM_MASK;
}
static inline __uasminit u32 build_bimm(s32 arg)
{
- if (arg > 0x1ffff || arg < -0x20000)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg > 0x1ffff || arg < -0x20000,
+ KERN_WARNING "Micro-assembler field overflow\n");
- if (arg & 0x3)
- printk(KERN_WARNING "Invalid micro-assembler branch target\n");
+ WARN(arg & 0x3, KERN_WARNING "Invalid micro-assembler branch target\n");
return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
}
static inline __uasminit u32 build_jimm(u32 arg)
{
- if (arg & ~((JIMM_MASK) << 2))
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~(JIMM_MASK << 2),
+ KERN_WARNING "Micro-assembler field overflow\n");
return (arg >> 2) & JIMM_MASK;
}
static inline __uasminit u32 build_scimm(u32 arg)
{
- if (arg & ~SCIMM_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~SCIMM_MASK,
+ KERN_WARNING "Micro-assembler field overflow\n");
return (arg & SCIMM_MASK) << SCIMM_SH;
}
static inline __uasminit u32 build_func(u32 arg)
{
- if (arg & ~FUNC_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~FUNC_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return arg & FUNC_MASK;
}
static inline __uasminit u32 build_set(u32 arg)
{
- if (arg & ~SET_MASK)
- printk(KERN_WARNING "Micro-assembler field overflow\n");
+ WARN(arg & ~SET_MASK, KERN_WARNING "Micro-assembler field overflow\n");
return arg & SET_MASK;
}
@@ -340,6 +336,13 @@ Ip_u2u1msbu3(op) \
} \
UASM_EXPORT_SYMBOL(uasm_i##op);
+#define I_u2u1msb32u3(op) \
+Ip_u2u1msbu3(op) \
+{ \
+ build_insn(buf, insn##op, b, a, c+d-33, c); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
#define I_u1u2(op) \
Ip_u1u2(op) \
{ \
@@ -422,9 +425,12 @@ I_0(_tlbwr)
I_u3u1u2(_xor)
I_u2u1u3(_xori)
I_u2u1msbu3(_dins);
+I_u2u1msb32u3(_dinsm);
I_u1(_syscall);
I_u1u2s3(_bbit0);
I_u1u2s3(_bbit1);
+I_u3u1u2(_lwx)
+I_u3u1u2(_ldx)
#ifdef CONFIG_CPU_CAVIUM_OCTEON
#include <asm/octeon/octeon.h>
diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c
index 87ccdb4b5ac9..48853ab5bcf0 100644
--- a/arch/mips/sibyte/common/sb_tbprof.c
+++ b/arch/mips/sibyte/common/sb_tbprof.c
@@ -410,14 +410,13 @@ static int sbprof_tb_open(struct inode *inode, struct file *filp)
return -EBUSY;
memset(&sbp, 0, sizeof(struct sbprof_tb));
- sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES);
+ sbp.sbprof_tbbuf = vzalloc(MAX_TBSAMPLE_BYTES);
if (!sbp.sbprof_tbbuf) {
sbp.open = SB_CLOSED;
wmb();
return -ENOMEM;
}
- memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES);
init_waitqueue_head(&sbp.tb_sync);
init_waitqueue_head(&sbp.tb_read);
mutex_init(&sbp.lock);
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c
index 96e69a00ffc8..85a87de17eb4 100644
--- a/arch/mips/txx9/generic/pci.c
+++ b/arch/mips/txx9/generic/pci.c
@@ -213,11 +213,8 @@ txx9_alloc_pci_controller(struct pci_controller *pcic,
pcic->mem_offset = 0; /* busaddr == physaddr */
- printk(KERN_INFO "PCI: IO 0x%08llx-0x%08llx MEM 0x%08llx-0x%08llx\n",
- (unsigned long long)pcic->mem_resource[1].start,
- (unsigned long long)pcic->mem_resource[1].end,
- (unsigned long long)pcic->mem_resource[0].start,
- (unsigned long long)pcic->mem_resource[0].end);
+ printk(KERN_INFO "PCI: IO %pR MEM %pR\n",
+ &pcic->mem_resource[1], &pcic->mem_resource[0]);
/* register_pci_controller() will request MEM resource */
release_resource(&pcic->mem_resource[0]);
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index df971fa0c32f..4896ed090585 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -1126,15 +1126,13 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)
unsigned int i;
unsigned long flags;
- for (i = 0; i < count && i < 79;) {
+ for (i = 0; i < count;) {
switch(str[i]) {
case '\n':
iodc_dbuf[i+0] = '\r';
iodc_dbuf[i+1] = '\n';
i += 2;
goto print;
- case '\b': /* BS */
- i--; /* overwrite last */
default:
iodc_dbuf[i] = str[i];
i++;
@@ -1142,15 +1140,6 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)
}
}
- /* if we're at the end of line, and not already inserting a newline,
- * insert one anyway. iodc console doesn't claim to support >79 char
- * lines. don't account for this in the return value.
- */
- if (i == 79 && iodc_dbuf[i-1] != '\n') {
- iodc_dbuf[i+0] = '\r';
- iodc_dbuf[i+1] = '\n';
- }
-
print:
spin_lock_irqsave(&pdc_lock, flags);
real32_call(PAGE0->mem_cons.iodc_io,
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c
index 567480705789..ab6f6beadb57 100644
--- a/arch/powerpc/kernel/perf_event.c
+++ b/arch/powerpc/kernel/perf_event.c
@@ -1212,6 +1212,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
if (left <= 0)
left = period;
record = 1;
+ event->hw.last_period = event->hw.sample_period;
}
if (left < 0x80000000LL)
val = 0x80000000LL - left;
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 9e3132db718b..7185f0da7dc3 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -519,9 +519,9 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
memblock_add(base, size);
}
-u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
{
- return memblock_alloc(size, align);
+ return __va(memblock_alloc(size, align));
}
#ifdef CONFIG_BLK_DEV_INITRD
diff --git a/arch/x86/include/asm/numa_32.h b/arch/x86/include/asm/numa_32.h
index a37229011b56..b0ef2b449a9d 100644
--- a/arch/x86/include/asm/numa_32.h
+++ b/arch/x86/include/asm/numa_32.h
@@ -1,6 +1,8 @@
#ifndef _ASM_X86_NUMA_32_H
#define _ASM_X86_NUMA_32_H
+extern int numa_off;
+
extern int pxm_to_nid(int pxm);
extern void numa_remove_cpu(int cpu);
diff --git a/arch/x86/include/asm/numa_64.h b/arch/x86/include/asm/numa_64.h
index 5ae87285a502..0493be39607c 100644
--- a/arch/x86/include/asm/numa_64.h
+++ b/arch/x86/include/asm/numa_64.h
@@ -40,6 +40,7 @@ extern void __cpuinit numa_remove_cpu(int cpu);
#ifdef CONFIG_NUMA_EMU
#define FAKE_NODE_MIN_SIZE ((u64)32 << 20)
#define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1UL))
+void numa_emu_cmdline(char *);
#endif /* CONFIG_NUMA_EMU */
#else
static inline void init_cpu_to_node(void) { }
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 48ff6dcffa02..9974d21048fd 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -129,8 +129,7 @@ void __cpuinit irq_ctx_init(int cpu)
irqctx = page_address(alloc_pages_node(cpu_to_node(cpu),
THREAD_FLAGS,
THREAD_ORDER));
- irqctx->tinfo.task = NULL;
- irqctx->tinfo.exec_domain = NULL;
+ memset(&irqctx->tinfo, 0, sizeof(struct thread_info));
irqctx->tinfo.cpu = cpu;
irqctx->tinfo.preempt_count = HARDIRQ_OFFSET;
irqctx->tinfo.addr_limit = MAKE_MM_SEG(0);
@@ -140,10 +139,8 @@ void __cpuinit irq_ctx_init(int cpu)
irqctx = page_address(alloc_pages_node(cpu_to_node(cpu),
THREAD_FLAGS,
THREAD_ORDER));
- irqctx->tinfo.task = NULL;
- irqctx->tinfo.exec_domain = NULL;
+ memset(&irqctx->tinfo, 0, sizeof(struct thread_info));
irqctx->tinfo.cpu = cpu;
- irqctx->tinfo.preempt_count = 0;
irqctx->tinfo.addr_limit = MAKE_MM_SEG(0);
per_cpu(softirq_ctx, cpu) = irqctx;
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
index 787c52ca49c3..ebf6d7887a38 100644
--- a/arch/x86/mm/numa.c
+++ b/arch/x86/mm/numa.c
@@ -2,6 +2,28 @@
#include <linux/topology.h>
#include <linux/module.h>
#include <linux/bootmem.h>
+#include <asm/numa.h>
+#include <asm/acpi.h>
+
+int __initdata numa_off;
+
+static __init int numa_setup(char *opt)
+{
+ if (!opt)
+ return -EINVAL;
+ if (!strncmp(opt, "off", 3))
+ numa_off = 1;
+#ifdef CONFIG_NUMA_EMU
+ if (!strncmp(opt, "fake=", 5))
+ numa_emu_cmdline(opt + 5);
+#endif
+#ifdef CONFIG_ACPI_NUMA
+ if (!strncmp(opt, "noacpi", 6))
+ acpi_numa = -1;
+#endif
+ return 0;
+}
+early_param("numa", numa_setup);
/*
* Which logical CPUs are on which nodes
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 1e72102e80c9..95ea1551eebc 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -30,7 +30,6 @@ s16 apicid_to_node[MAX_LOCAL_APIC] __cpuinitdata = {
[0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
};
-int numa_off __initdata;
static unsigned long __initdata nodemap_addr;
static unsigned long __initdata nodemap_size;
@@ -263,6 +262,11 @@ static struct bootnode nodes[MAX_NUMNODES] __initdata;
static struct bootnode physnodes[MAX_NUMNODES] __cpuinitdata;
static char *cmdline __initdata;
+void __init numa_emu_cmdline(char *str)
+{
+ cmdline = str;
+}
+
static int __init setup_physnodes(unsigned long start, unsigned long end,
int acpi, int amd)
{
@@ -670,24 +674,6 @@ unsigned long __init numa_free_all_bootmem(void)
return pages;
}
-static __init int numa_setup(char *opt)
-{
- if (!opt)
- return -EINVAL;
- if (!strncmp(opt, "off", 3))
- numa_off = 1;
-#ifdef CONFIG_NUMA_EMU
- if (!strncmp(opt, "fake=", 5))
- cmdline = opt + 5;
-#endif
-#ifdef CONFIG_ACPI_NUMA
- if (!strncmp(opt, "noacpi", 6))
- acpi_numa = -1;
-#endif
- return 0;
-}
-early_param("numa", numa_setup);
-
#ifdef CONFIG_NUMA
static __init int find_near_online_node(int node)
diff --git a/arch/x86/mm/srat_32.c b/arch/x86/mm/srat_32.c
index f16434568a51..ae96e7b8051d 100644
--- a/arch/x86/mm/srat_32.c
+++ b/arch/x86/mm/srat_32.c
@@ -59,7 +59,6 @@ static struct node_memory_chunk_s __initdata node_memory_chunk[MAXCHUNKS];
static int __initdata num_memory_chunks; /* total number of memory chunks */
static u8 __initdata apicid_to_pxm[MAX_APICID];
-int numa_off __initdata;
int acpi_numa __initdata;
static __init void bad_srat(void)