Commit 589bf8d5 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/home/rmk/linux-2.6-arm

* master.kernel.org:/home/rmk/linux-2.6-arm: (24 commits)
  ARM: force dcache flush if dcache_dirty bit set
  [ARM] pxa: workaround errata #37 by not using half turbo switching
  [ARM] pxamci: fix printing gpio numbers in pxamci_probe
  [ARM] pxa/csb726: adjust duplicate structure field initialization
  ARM: Add kmap_atomic type debugging
  ARM: boolean bit testing
  ARM: update die() output
  ARM: Dump code/mem oops lines with the appropriate log level
  ARM: Dump memory and backtrace as one printk per line
  ARM: 5756/1: ep93xx: introduce clk parent
  ARM: 5754/1: ep93xx: update i2c support
  ARM: 5753/1: ep93xx: remove old EP93XX_GPIO_* defines
  ARM: 5729/1: ep93xx: define EP93XX_*_PHYS_BASE with macros
  ARM: 5751/1: ep93xx/micro9: Add Micro9-Slim
  ARM: 5750/1: ep93xx/micro9: Update platform code
  ARM: 5749/1: ep93xx/micro9: Update maintainer
  ARM: 5752/1: SA1100: fix building of h3100
  ARM: 5748/1: bcmring: fix build warning messages
  ARM: 5747/1: Fix the start_pg value in free_memmap()
  ARM: 5746/1: Handle possible translation errors in ARMv6/v7 coherent_user_range
  ...
parents e3c6f15f 787b2faa
...@@ -577,6 +577,11 @@ M: Mike Rapoport <mike@compulab.co.il> ...@@ -577,6 +577,11 @@ M: Mike Rapoport <mike@compulab.co.il>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained S: Maintained
ARM/CONTEC MICRO9 MACHINE SUPPORT
M: Hubert Feurstein <hubert.feurstein@contec.at>
S: Maintained
F: arch/arm/mach-ep93xx/micro9.c
ARM/CORGI MACHINE SUPPORT ARM/CORGI MACHINE SUPPORT
M: Richard Purdie <rpurdie@rpsys.net> M: Richard Purdie <rpurdie@rpsys.net>
S: Maintained S: Maintained
......
...@@ -84,7 +84,7 @@ ____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p) ...@@ -84,7 +84,7 @@ ____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
*p = res | mask; *p = res | mask;
raw_local_irq_restore(flags); raw_local_irq_restore(flags);
return res & mask; return (res & mask) != 0;
} }
static inline int static inline int
...@@ -101,7 +101,7 @@ ____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p) ...@@ -101,7 +101,7 @@ ____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
*p = res & ~mask; *p = res & ~mask;
raw_local_irq_restore(flags); raw_local_irq_restore(flags);
return res & mask; return (res & mask) != 0;
} }
static inline int static inline int
...@@ -118,7 +118,7 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p) ...@@ -118,7 +118,7 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
*p = res ^ mask; *p = res ^ mask;
raw_local_irq_restore(flags); raw_local_irq_restore(flags);
return res & mask; return (res & mask) != 0;
} }
#include <asm-generic/bitops/non-atomic.h> #include <asm-generic/bitops/non-atomic.h>
......
...@@ -45,21 +45,21 @@ static int __init user_debug_setup(char *str) ...@@ -45,21 +45,21 @@ static int __init user_debug_setup(char *str)
__setup("user_debug=", user_debug_setup); __setup("user_debug=", user_debug_setup);
#endif #endif
static void dump_mem(const char *str, unsigned long bottom, unsigned long top); static void dump_mem(const char *, const char *, unsigned long, unsigned long);
void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
{ {
#ifdef CONFIG_KALLSYMS #ifdef CONFIG_KALLSYMS
printk("[<%08lx>] ", where); char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN];
print_symbol("(%s) ", where); sprint_symbol(sym1, where);
printk("from [<%08lx>] ", from); sprint_symbol(sym2, from);
print_symbol("(%s)\n", from); printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2);
#else #else
printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
#endif #endif
if (in_exception_text(where)) if (in_exception_text(where))
dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs)); dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
} }
#ifndef CONFIG_ARM_UNWIND #ifndef CONFIG_ARM_UNWIND
...@@ -81,9 +81,10 @@ static int verify_stack(unsigned long sp) ...@@ -81,9 +81,10 @@ static int verify_stack(unsigned long sp)
/* /*
* Dump out the contents of some memory nicely... * Dump out the contents of some memory nicely...
*/ */
static void dump_mem(const char *str, unsigned long bottom, unsigned long top) static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
unsigned long top)
{ {
unsigned long p = bottom & ~31; unsigned long first;
mm_segment_t fs; mm_segment_t fs;
int i; int i;
...@@ -95,33 +96,37 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top) ...@@ -95,33 +96,37 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
fs = get_fs(); fs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); printk("%s%s(0x%08lx to 0x%08lx)\n", lvl, str, bottom, top);
for (p = bottom & ~31; p < top;) { for (first = bottom & ~31; first < top; first += 32) {
printk("%04lx: ", p & 0xffff); unsigned long p;
char str[sizeof(" 12345678") * 8 + 1];
for (i = 0; i < 8; i++, p += 4) { memset(str, ' ', sizeof(str));
unsigned int val; str[sizeof(str) - 1] = '\0';
if (p < bottom || p >= top) for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
printk(" "); if (p >= bottom && p < top) {
else { unsigned long val;
__get_user(val, (unsigned long *)p); if (__get_user(val, (unsigned long *)p) == 0)
printk("%08x ", val); sprintf(str + i * 9, " %08lx", val);
else
sprintf(str + i * 9, " ????????");
} }
} }
printk ("\n"); printk("%s%04lx:%s\n", lvl, first & 0xffff, str);
} }
set_fs(fs); set_fs(fs);
} }
static void dump_instr(struct pt_regs *regs) static void dump_instr(const char *lvl, struct pt_regs *regs)
{ {
unsigned long addr = instruction_pointer(regs); unsigned long addr = instruction_pointer(regs);
const int thumb = thumb_mode(regs); const int thumb = thumb_mode(regs);
const int width = thumb ? 4 : 8; const int width = thumb ? 4 : 8;
mm_segment_t fs; mm_segment_t fs;
char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
int i; int i;
/* /*
...@@ -132,7 +137,6 @@ static void dump_instr(struct pt_regs *regs) ...@@ -132,7 +137,6 @@ static void dump_instr(struct pt_regs *regs)
fs = get_fs(); fs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
printk("Code: ");
for (i = -4; i < 1; i++) { for (i = -4; i < 1; i++) {
unsigned int val, bad; unsigned int val, bad;
...@@ -142,13 +146,14 @@ static void dump_instr(struct pt_regs *regs) ...@@ -142,13 +146,14 @@ static void dump_instr(struct pt_regs *regs)
bad = __get_user(val, &((u32 *)addr)[i]); bad = __get_user(val, &((u32 *)addr)[i]);
if (!bad) if (!bad)
printk(i == 0 ? "(%0*x) " : "%0*x ", width, val); p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
width, val);
else { else {
printk("bad PC value."); p += sprintf(p, "bad PC value");
break; break;
} }
} }
printk("\n"); printk("%sCode: %s\n", lvl, str);
set_fs(fs); set_fs(fs);
} }
...@@ -224,18 +229,19 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p ...@@ -224,18 +229,19 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p
struct task_struct *tsk = thread->task; struct task_struct *tsk = thread->task;
static int die_counter; static int die_counter;
printk("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n", printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
str, err, ++die_counter); str, err, ++die_counter);
sysfs_printk_last_file();
print_modules(); print_modules();
__show_regs(regs); __show_regs(regs);
printk("Process %s (pid: %d, stack limit = 0x%p)\n", printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
tsk->comm, task_pid_nr(tsk), thread + 1); TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
if (!user_mode(regs) || in_interrupt()) { if (!user_mode(regs) || in_interrupt()) {
dump_mem("Stack: ", regs->ARM_sp, dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
THREAD_SIZE + (unsigned long)task_stack_page(tsk)); THREAD_SIZE + (unsigned long)task_stack_page(tsk));
dump_backtrace(regs, tsk); dump_backtrace(regs, tsk);
dump_instr(regs); dump_instr(KERN_EMERG, regs);
} }
} }
...@@ -250,13 +256,14 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) ...@@ -250,13 +256,14 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
oops_enter(); oops_enter();
console_verbose();
spin_lock_irq(&die_lock); spin_lock_irq(&die_lock);
console_verbose();
bust_spinlocks(1); bust_spinlocks(1);
__die(str, err, thread, regs); __die(str, err, thread, regs);
bust_spinlocks(0); bust_spinlocks(0);
add_taint(TAINT_DIE); add_taint(TAINT_DIE);
spin_unlock_irq(&die_lock); spin_unlock_irq(&die_lock);
oops_exit();
if (in_interrupt()) if (in_interrupt())
panic("Fatal exception in interrupt"); panic("Fatal exception in interrupt");
...@@ -264,7 +271,6 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) ...@@ -264,7 +271,6 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
if (panic_on_oops) if (panic_on_oops)
panic("Fatal exception"); panic("Fatal exception");
oops_exit();
do_exit(SIGSEGV); do_exit(SIGSEGV);
} }
...@@ -349,7 +355,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) ...@@ -349,7 +355,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
if (user_debug & UDBG_UNDEFINED) { if (user_debug & UDBG_UNDEFINED) {
printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
current->comm, task_pid_nr(current), pc); current->comm, task_pid_nr(current), pc);
dump_instr(regs); dump_instr(KERN_INFO, regs);
} }
#endif #endif
...@@ -400,7 +406,7 @@ static int bad_syscall(int n, struct pt_regs *regs) ...@@ -400,7 +406,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
if (user_debug & UDBG_SYSCALL) { if (user_debug & UDBG_SYSCALL) {
printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n", printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
task_pid_nr(current), current->comm, n); task_pid_nr(current), current->comm, n);
dump_instr(regs); dump_instr(KERN_ERR, regs);
} }
#endif #endif
...@@ -579,7 +585,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) ...@@ -579,7 +585,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
if (user_debug & UDBG_SYSCALL) { if (user_debug & UDBG_SYSCALL) {
printk("[%d] %s: arm syscall %d\n", printk("[%d] %s: arm syscall %d\n",
task_pid_nr(current), current->comm, no); task_pid_nr(current), current->comm, no);
dump_instr(regs); dump_instr("", regs);
if (user_mode(regs)) { if (user_mode(regs)) {
__show_regs(regs); __show_regs(regs);
c_backtrace(regs->ARM_fp, processor_mode(regs)); c_backtrace(regs->ARM_fp, processor_mode(regs));
...@@ -656,7 +662,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs) ...@@ -656,7 +662,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
if (user_debug & UDBG_BADABORT) { if (user_debug & UDBG_BADABORT) {
printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n", printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
task_pid_nr(current), current->comm, code, instr); task_pid_nr(current), current->comm, code, instr);
dump_instr(regs); dump_instr(KERN_ERR, regs);
show_pte(current->mm, addr); show_pte(current->mm, addr);
} }
#endif #endif
......
...@@ -271,12 +271,12 @@ static struct irqaction bcmring_timer_irq = { ...@@ -271,12 +271,12 @@ static struct irqaction bcmring_timer_irq = {
.handler = bcmring_timer_interrupt, .handler = bcmring_timer_interrupt,
}; };
static cycle_t bcmring_get_cycles_timer1(void) static cycle_t bcmring_get_cycles_timer1(struct clocksource *cs)
{ {
return ~readl(TIMER1_VA_BASE + TIMER_VALUE); return ~readl(TIMER1_VA_BASE + TIMER_VALUE);
} }
static cycle_t bcmring_get_cycles_timer3(void) static cycle_t bcmring_get_cycles_timer3(struct clocksource *cs)
{ {
return ~readl(TIMER3_VA_BASE + TIMER_VALUE); return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
} }
......
...@@ -29,7 +29,7 @@ static inline void arch_idle(void) ...@@ -29,7 +29,7 @@ static inline void arch_idle(void)
cpu_do_idle(); cpu_do_idle();
} }
static inline void arch_reset(char mode, char *cmd) static inline void arch_reset(char mode, const char *cmd)
{ {
printk("arch_reset:%c %x\n", mode, bcmring_arch_warm_reboot); printk("arch_reset:%c %x\n", mode, bcmring_arch_warm_reboot);
......
...@@ -17,13 +17,31 @@ config EP93XX_SDCE3_SYNC_PHYS_OFFSET ...@@ -17,13 +17,31 @@ config EP93XX_SDCE3_SYNC_PHYS_OFFSET
bool "0x00000000 - SDCE3/SyncBoot" bool "0x00000000 - SDCE3/SyncBoot"
help help
Select this option if you want support for EP93xx boards with the Select this option if you want support for EP93xx boards with the
first SDRAM bank at 0x00000000 first SDRAM bank at 0x00000000.
config EP93XX_SDCE0_PHYS_OFFSET config EP93XX_SDCE0_PHYS_OFFSET
bool "0xc0000000 - SDCEO" bool "0xc0000000 - SDCEO"
help help
Select this option if you want support for EP93xx boards with the Select this option if you want support for EP93xx boards with the
first SDRAM bank at 0xc0000000 first SDRAM bank at 0xc0000000.
config EP93XX_SDCE1_PHYS_OFFSET
bool "0xd0000000 - SDCE1"
help
Select this option if you want support for EP93xx boards with the
first SDRAM bank at 0xd0000000.
config EP93XX_SDCE2_PHYS_OFFSET
bool "0xe0000000 - SDCE2"
help
Select this option if you want support for EP93xx boards with the
first SDRAM bank at 0xe0000000.
config EP93XX_SDCE3_ASYNC_PHYS_OFFSET
bool "0xf0000000 - SDCE3/AsyncBoot"
help
Select this option if you want support for EP93xx boards with the
first SDRAM bank at 0xf0000000.
endchoice endchoice
...@@ -112,28 +130,36 @@ config MACH_MICRO9 ...@@ -112,28 +130,36 @@ config MACH_MICRO9
bool bool
config MACH_MICRO9H config MACH_MICRO9H
bool "Support Contec Hypercontrol Micro9-H" bool "Support Contec Micro9-High"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_MICRO9 select MACH_MICRO9
help help
Say 'Y' here if you want your kernel to support the Say 'Y' here if you want your kernel to support the
Contec Hypercontrol Micro9-H board. Contec Micro9-High board.
config MACH_MICRO9M config MACH_MICRO9M
bool "Support Contec Hypercontrol Micro9-M" bool "Support Contec Micro9-Mid"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET
select MACH_MICRO9 select MACH_MICRO9
help help
Say 'Y' here if you want your kernel to support the Say 'Y' here if you want your kernel to support the
Contec Hypercontrol Micro9-M board. Contec Micro9-Mid board.
config MACH_MICRO9L config MACH_MICRO9L
bool "Support Contec Hypercontrol Micro9-L" bool "Support Contec Micro9-Lite"
depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
select MACH_MICRO9 select MACH_MICRO9
help help
Say 'Y' here if you want your kernel to support the Say 'Y' here if you want your kernel to support the
Contec Hypercontrol Micro9-L board. Contec Micro9-Lite board.
config MACH_MICRO9S
bool "Support Contec Micro9-Slim"
depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET
select MACH_MICRO9
help
Say 'Y' here if you want your kernel to support the
Contec Micro9-Slim board.
config MACH_TS72XX config MACH_TS72XX
bool "Support Technologic Systems TS-72xx SBC" bool "Support Technologic Systems TS-72xx SBC"
......
...@@ -3,3 +3,12 @@ params_phys-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) := 0x00000100 ...@@ -3,3 +3,12 @@ params_phys-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) := 0x00000100
zreladdr-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0008000 zreladdr-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0008000
params_phys-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0000100 params_phys-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0000100
zreladdr-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) := 0xd0008000
params_phys-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) := 0xd0000100
zreladdr-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) := 0xe0008000
params_phys-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) := 0xe0000100
zreladdr-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) := 0xf0008000
params_phys-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) := 0xf0000100
...@@ -16,13 +16,16 @@ ...@@ -16,13 +16,16 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/spinlock.h>
#include <mach/hardware.h>
#include <asm/clkdev.h> #include <asm/clkdev.h>
#include <asm/div64.h> #include <asm/div64.h>
#include <mach/hardware.h>
struct clk { struct clk {
struct clk *parent;
unsigned long rate; unsigned long rate;
int users; int users;
int sw_locked; int sw_locked;
...@@ -39,40 +42,60 @@ static unsigned long get_uart_rate(struct clk *clk); ...@@ -39,40 +42,60 @@ static unsigned long get_uart_rate(struct clk *clk);
static int set_keytchclk_rate(struct clk *clk, unsigned long rate); static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
static int set_div_rate(struct clk *clk, unsigned long rate); static int set_div_rate(struct clk *clk, unsigned long rate);
static struct clk clk_xtali = {
.rate = EP93XX_EXT_CLK_RATE,
};
static struct clk clk_uart1 = { static struct clk clk_uart1 = {
.parent = &clk_xtali,
.sw_locked = 1, .sw_locked = 1,
.enable_reg = EP93XX_SYSCON_DEVCFG, .enable_reg = EP93XX_SYSCON_DEVCFG,
.enable_mask = EP93XX_SYSCON_DEVCFG_U1EN, .enable_mask = EP93XX_SYSCON_DEVCFG_U1EN,
.get_rate = get_uart_rate, .get_rate = get_uart_rate,
}; };
static struct clk clk_uart2 = { static struct clk clk_uart2 = {
.parent = &clk_xtali,
.sw_locked = 1, .sw_locked = 1,
.enable_reg = EP93XX_SYSCON_DEVCFG, .enable_reg = EP93XX_SYSCON_DEVCFG,
.enable_mask = EP93XX_SYSCON_DEVCFG_U2EN, .enable_mask = EP93XX_SYSCON_DEVCFG_U2EN,
.get_rate = get_uart_rate, .get_rate = get_uart_rate,
}; };
static struct clk clk_uart3 = { static struct clk clk_uart3 = {
.parent = &clk_xtali,
.sw_locked = 1, .sw_locked = 1,
.enable_reg = EP93XX_SYSCON_DEVCFG, .enable_reg = EP93XX_SYSCON_DEVCFG,
.enable_mask = EP93XX_SYSCON_DEVCFG_U3EN, .enable_mask = EP93XX_SYSCON_DEVCFG_U3EN,
.get_rate = get_uart_rate, .get_rate = get_uart_rate,
}; };
static struct clk clk_pll1; static struct clk clk_pll1 = {
static struct clk clk_f; .parent = &clk_xtali,
static struct clk clk_h; };
static struct clk clk_p; static struct clk clk_f = {
static struct clk clk_pll2; .parent = &clk_pll1,
};
static struct clk clk_h = {
.parent = &clk_pll1,
};
static struct clk clk_p = {
.parent = &clk_pll1,
};
static struct clk clk_pll2 = {
.parent = &clk_xtali,
};
static struct clk clk_usb_host = { static struct clk clk_usb_host = {
.parent = &clk_pll2,
.enable_reg = EP93XX_SYSCON_PWRCNT, .enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_USH_EN, .enable_mask = EP93XX_SYSCON_PWRCNT_USH_EN,
}; };
static struct clk clk_keypad = { static struct clk clk_keypad = {
.parent = &clk_xtali,
.sw_locked = 1, .sw_locked = 1,
.enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV, .enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV,
.enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN, .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
.set_rate = set_keytchclk_rate, .set_rate = set_keytchclk_rate,
}; };
static struct clk clk_pwm = { static struct clk clk_pwm = {
.parent = &clk_xtali,
.rate = EP93XX_EXT_CLK_RATE, .rate = EP93XX_EXT_CLK_RATE,
}; };
...@@ -85,50 +108,62 @@ static struct clk clk_video = { ...@@ -85,50 +108,62 @@ static struct clk clk_video = {
/* DMA Clocks */ /* DMA Clocks */
static struct clk clk_m2p0 = { static struct clk clk_m2p0 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT, .enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P0, .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P0,
}; };
static struct clk clk_m2p1 = { static struct clk clk_m2p1 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT, .enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P1, .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P1,
}; };
static struct clk clk_m2p2 = { static struct clk clk_m2p2 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT, .enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P2, .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P2,
}; };
static struct clk clk_m2p3 = { static struct clk clk_m2p3 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT, .enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P3, .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P3,
}; };
static struct clk clk_m2p4 = { static struct clk clk_m2p4 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT, .enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P4, .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P4,
}; };
static struct clk clk_m2p5 = { static struct clk clk_m2p5 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT, .enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P5, .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P5,
}; };
static struct clk clk_m2p6 = { static struct clk clk_m2p6 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT, .enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P6, .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P6,
}; };
static struct clk clk_m2p7 = { static struct clk clk_m2p7 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT, .enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P7, .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P7,
}; };
static struct clk clk_m2p8 = { static struct clk clk_m2p8 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT, .enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P8, .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P8,
}; };
static struct clk clk_m2p9 = { static struct clk clk_m2p9 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT, .enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P9, .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P9,
}; };
static struct clk clk_m2m0 = { static struct clk clk_m2m0 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT, .enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M0, .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M0,
}; };
static struct clk clk_m2m1 = { static struct clk clk_m2m1 = {
.parent = &clk_h,
.enable_reg = EP93XX_SYSCON_PWRCNT, .enable_reg = EP93XX_SYSCON_PWRCNT,
.enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M1, .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M1,
}; };
...@@ -137,6 +172,7 @@ static struct clk clk_m2m1 = { ...@@ -137,6 +172,7 @@ static struct clk clk_m2m1 = {
{ .dev_id = dev, .con_id = con, .clk = ck } { .dev_id = dev, .con_id = con, .clk = ck }
static struct clk_lookup clocks[] = { static struct clk_lookup clocks[] = {
INIT_CK(NULL, "xtali", &clk_xtali),
INIT_CK("apb:uart1", NULL, &clk_uart1), INIT_CK("apb:uart1", NULL, &clk_uart1),
INIT_CK("apb:uart2", NULL, &clk_uart2), INIT_CK("apb:uart2", NULL, &clk_uart2),
INIT_CK("apb:uart3", NULL, &clk_uart3), INIT_CK("apb:uart3", NULL, &clk_uart3),
...@@ -163,48 +199,84 @@ static struct clk_lookup clocks[] = { ...@@ -163,48 +199,84 @@ static struct clk_lookup clocks[] = {
INIT_CK(NULL, "m2m1", &clk_m2m1), INIT_CK(NULL, "m2m1", &clk_m2m1),
}; };
static DEFINE_SPINLOCK(clk_lock);
static void __clk_enable(struct clk *clk)
{
if (!clk->users++) {
if (clk->parent)
__clk_enable(clk->parent);
if (clk->enable_reg) {
u32 v;
v = __raw_readl(clk->enable_reg);
v |= clk->enable_mask;
if (clk->sw_locked)
ep93xx_syscon_swlocked_write(v, clk->enable_reg);
else
__raw_writel(v, clk->enable_reg);
}
}
}
int clk_enable(struct clk *clk) int clk_enable(struct clk *clk)
{ {
if (!clk->users++ && clk->enable_reg) { unsigned long flags;
u32 value;
value = __raw_readl(clk->enable_reg); if (!clk)
value |= clk->enable_mask; return -EINVAL;
if (clk->sw_locked)
ep93xx_syscon_swlocked_write(value, clk->enable_reg); spin_lock_irqsave(&clk_lock, flags);
else __clk_enable(clk);
__raw_writel(value, clk->enable_reg); spin_unlock_irqrestore(&clk_lock, flags);
}
return 0; return 0;
} }
EXPORT_SYMBOL(clk_enable); EXPORT_SYMBOL(clk_enable);
void clk_disable(struct clk *clk) static void __clk_disable(struct clk *clk)
{ {
if (!--clk->users && clk->enable_reg) { if (!--clk->users) {
u32 value; if (clk->enable_reg) {
u32 v;
v = __raw_readl(clk->enable_reg);
v &= ~clk->enable_mask;
if (clk->sw_locked)
ep93xx_syscon_swlocked_write(v, clk->enable_reg);
else
__raw_writel(v, clk->enable_reg);
}
value = __raw_readl(clk->enable_reg); if (clk->parent)
value &= ~clk->enable_mask; __clk_disable(clk->parent);
if (clk->sw_locked)
ep93xx_syscon_swlocked_write(value, clk->enable_reg);
else
__raw_writel(value, clk->enable_reg);
} }
} }
void clk_disable(struct clk *clk)
{
unsigned long flags;
if (!clk)
return;
spin_lock_irqsave(&clk_lock, flags);
__clk_disable(clk);
spin_unlock_irqrestore(&clk_lock, flags);
}
EXPORT_SYMBOL(clk_disable); EXPORT_SYMBOL(clk_disable);
static unsigned long get_uart_rate(struct clk *clk) static unsigned long get_uart_rate(struct clk *clk)
{ {
unsigned long rate = clk_get_rate(clk->parent);
u32 value; u32 value;
value = __raw_readl(EP93XX_SYSCON_PWRCNT); value = __raw_readl(EP93XX_SYSCON_PWRCNT);
if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD) if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
return EP93XX_EXT_CLK_RATE; return rate;
else else
return EP93XX_EXT_CLK_RATE / 2; return rate / 2;
} }
unsigned long clk_get_rate(struct clk *clk) unsigned long clk_get_rate(struct clk *clk)
...@@ -244,16 +316,16 @@ static int set_keytchclk_rate(struct clk *clk, unsigned long rate) ...@@ -244,16 +316,16 @@ static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
return 0; return 0;
} }
static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel, static int calc_clk_div(struct clk *clk, unsigned long rate,
int *pdiv, int *div) int *psel, int *esel, int *pdiv, int *div)
{ {
unsigned long max_rate, best_rate = 0, struct clk *mclk;
actual_rate = 0, mclk_rate = 0, rate_err = -1; unsigned long max_rate, actual_rate, mclk_rate, rate_err = -1;
int i, found = 0, __div = 0, __pdiv = 0; int i, found = 0, __div = 0, __pdiv = 0;
/* Don't exceed the maximum rate */ /* Don't exceed the maximum rate */
max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4), max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4),
(unsigned long)EP93XX_EXT_CLK_RATE / 4); clk_xtali.rate / 4);
rate = min(rate, max_rate); rate = min(rate, max_rate);
/* /*
...@@ -267,11 +339,12 @@ static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel, ...@@ -267,11 +339,12 @@ static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
*/ */
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
if (i == 0) if (i == 0)
mclk_rate = EP93XX_EXT_CLK_RATE * 2; mclk = &clk_xtali;
else if (i == 1) else if (i == 1)
mclk_rate = clk_pll1.rate * 2; mclk = &clk_pll1;
else if (i == 2) else
mclk_rate = clk_pll2.rate * 2; mclk = &clk_pll2;
mclk_rate = mclk->rate * 2;
/* Try each predivider value */ /* Try each predivider value */
for (__pdiv = 4; __pdiv <= 6; __pdiv++) { for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
...@@ -286,7 +359,8 @@ static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel, ...@@ -286,7 +359,8 @@ static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
*div = __div; *div = __div;
*psel = (i == 2); *psel = (i == 2);
*esel = (i != 0); *esel = (i != 0);
best_rate = actual_rate; clk->parent = mclk;
clk->rate = actual_rate;
rate_err = abs(actual_rate - rate); rate_err = abs(actual_rate - rate);
found = 1; found = 1;
} }
...@@ -294,21 +368,19 @@ static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel, ...@@ -294,21 +368,19 @@ static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
} }
if (!found) if (!found)
return 0; return -EINVAL;
return best_rate; return 0;
} }
static int set_div_rate(struct clk *clk, unsigned long rate) static int set_div_rate(struct clk *clk, unsigned long rate)
{ {
unsigned long actual_rate; int err, psel = 0, esel = 0, pdiv = 0, div = 0;
int psel = 0, esel = 0, pdiv = 0, div = 0;
u32 val; u32 val;
actual_rate = calc_clk_div(rate, &psel, &esel, &pdiv, &div); err = calc_clk_div(clk, rate, &psel, &esel, &pdiv, &div);
if (actual_rate == 0) if (err)
return -EINVAL; return err;
clk->rate = actual_rate;
/* Clear the esel, psel, pdiv and div bits */ /* Clear the esel, psel, pdiv and div bits */
val = __raw_readl(clk->enable_reg); val = __raw_readl(clk->enable_reg);
...@@ -344,7 +416,7 @@ static unsigned long calc_pll_rate(u32 config_word) ...@@ -344,7 +416,7 @@ static unsigned long calc_pll_rate(u32 config_word)
unsigned long long rate; unsigned long long rate;
int i; int i;
rate = EP93XX_EXT_CLK_RATE; rate = clk_xtali.rate;
rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */ rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */
rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */ rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */
do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */ do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */
...@@ -377,7 +449,7 @@ static int __init ep93xx_clock_init(void) ...@@ -377,7 +449,7 @@ static int __init ep93xx_clock_init(void)
value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1); value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1);
if (!(value & 0x00800000)) { /* PLL1 bypassed? */ if (!(value & 0x00800000)) { /* PLL1 bypassed? */
clk_pll1.rate = EP93XX_EXT_CLK_RATE; clk_pll1.rate = clk_xtali.rate;
} else { } else {
clk_pll1.rate = calc_pll_rate(value); clk_pll1.rate = calc_pll_rate(value);
} }
...@@ -388,7 +460,7 @@ static int __init ep93xx_clock_init(void) ...@@ -388,7 +460,7 @@ static int __init ep93xx_clock_init(void)
value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2); value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2);
if (!(value & 0x00080000)) { /* PLL2 bypassed? */ if (!(value & 0x00080000)) { /* PLL2 bypassed? */
clk_pll2.rate = EP93XX_EXT_CLK_RATE; clk_pll2.rate = clk_xtali.rate;
} else if (value & 0x00040000) { /* PLL2 enabled? */ } else if (value & 0x00040000) { /* PLL2 enabled? */
clk_pll2.rate = calc_pll_rate(value); clk_pll2.rate = calc_pll_rate(value);
} else { } else {
......
...@@ -550,13 +550,11 @@ void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr) ...@@ -550,13 +550,11 @@ void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)
platform_device_register(&ep93xx_eth_device); platform_device_register(&ep93xx_eth_device);
} }
static struct i2c_gpio_platform_data ep93xx_i2c_data = {
.sda_pin = EP93XX_GPIO_LINE_EEDAT, /*************************************************************************
.sda_is_open_drain = 0, * EP93xx i2c peripheral handling
.scl_pin = EP93XX_GPIO_LINE_EECLK, *************************************************************************/
.scl_is_open_drain = 0, static struct i2c_gpio_platform_data ep93xx_i2c_data;
.udelay = 2,
};
static struct platform_device ep93xx_i2c_device = { static struct platform_device ep93xx_i2c_device = {
.name = "i2c-gpio", .name = "i2c-gpio",
...@@ -564,8 +562,25 @@ static struct platform_device ep93xx_i2c_device = { ...@@ -564,8 +562,25 @@ static struct platform_device ep93xx_i2c_device = {
.dev.platform_data = &ep93xx_i2c_data, .dev.platform_data = &ep93xx_i2c_data,
}; };
void __init ep93xx_register_i2c(struct i2c_board_info *devices, int num) void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
struct i2c_board_info *devices, int num)
{ {
/*
* Set the EEPROM interface pin drive type control.
* Defines the driver type for the EECLK and EEDAT pins as either
* open drain, which will require an external pull-up, or a normal
* CMOS driver.
*/
if (data->sda_is_open_drain && data->sda_pin != EP93XX_GPIO_LINE_EEDAT)
pr_warning("ep93xx: sda != EEDAT, open drain has no effect\n");
if (data->scl_is_open_drain && data->scl_pin != EP93XX_GPIO_LINE_EECLK)
pr_warning("ep93xx: scl != EECLK, open drain has no effect\n");
__raw_writel((data->sda_is_open_drain << 1) |
(data->scl_is_open_drain << 0),
EP93XX_GPIO_EEDRIVE);
ep93xx_i2c_data = *data;
i2c_register_board_info(0, devices, num); i2c_register_board_info(0, devices, num);
platform_device_register(&ep93xx_i2c_device); platform_device_register(&ep93xx_i2c_device);
} }
......
...@@ -27,8 +27,10 @@ ...@@ -27,8 +27,10 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <mach/hardware.h> #include <mach/hardware.h>
...@@ -76,13 +78,26 @@ static struct ep93xx_eth_data edb93xx_eth_data = { ...@@ -76,13 +78,26 @@ static struct ep93xx_eth_data edb93xx_eth_data = {
.phy_id = 1, .phy_id = 1,
}; };
static struct i2c_board_info __initdata edb93xxa_i2c_data[] = {
/*************************************************************************
* EDB93xx i2c peripheral handling
*************************************************************************/
static struct i2c_gpio_platform_data edb93xx_i2c_gpio_data = {
.sda_pin = EP93XX_GPIO_LINE_EEDAT,
.sda_is_open_drain = 0,
.scl_pin = EP93XX_GPIO_LINE_EECLK,
.scl_is_open_drain = 0,
.udelay = 0, /* default to 100 kHz */
.timeout = 0, /* default to 100 ms */
};
static struct i2c_board_info __initdata edb93xxa_i2c_board_info[] = {
{ {
I2C_BOARD_INFO("isl1208", 0x6f), I2C_BOARD_INFO("isl1208", 0x6f),
}, },
}; };
static struct i2c_board_info __initdata edb93xx_i2c_data[] = { static struct i2c_board_info __initdata edb93xx_i2c_board_info[] = {
{ {
I2C_BOARD_INFO("ds1337", 0x68), I2C_BOARD_INFO("ds1337", 0x68),
}, },
...@@ -92,12 +107,14 @@ static void __init edb93xx_register_i2c(void) ...@@ -92,12 +107,14 @@ static void __init edb93xx_register_i2c(void)
{ {
if (machine_is_edb9302a() || machine_is_edb9307a() || if (machine_is_edb9302a() || machine_is_edb9307a() ||
machine_is_edb9315a()) { machine_is_edb9315a()) {
ep93xx_register_i2c(edb93xxa_i2c_data, ep93xx_register_i2c(&edb93xx_i2c_gpio_data,
ARRAY_SIZE(edb93xxa_i2c_data)); edb93xxa_i2c_board_info,
ARRAY_SIZE(edb93xxa_i2c_board_info));
} else if (machine_is_edb9307() || machine_is_edb9312() || } else if (machine_is_edb9307() || machine_is_edb9312() ||
machine_is_edb9315()) { machine_is_edb9315()) {
ep93xx_register_i2c(edb93xx_i2c_data, ep93xx_register_i2c(&edb93xx_i2c_gpio_data
ARRAY_SIZE(edb93xx_i2c_data)); edb93xx_i2c_board_info,
ARRAY_SIZE(edb93xx_i2c_board_info));
} }
} }
......
...@@ -52,25 +52,27 @@ ...@@ -52,25 +52,27 @@
#define EP93XX_AHB_VIRT_BASE 0xfef00000 #define EP93XX_AHB_VIRT_BASE 0xfef00000
#define EP93XX_AHB_SIZE 0x00100000 #define EP93XX_AHB_SIZE 0x00100000
#define EP93XX_AHB_PHYS(x) (EP93XX_AHB_PHYS_BASE + (x))
#define EP93XX_AHB_IOMEM(x) IOMEM(EP93XX_AHB_VIRT_BASE + (x)) #define EP93XX_AHB_IOMEM(x) IOMEM(EP93XX_AHB_VIRT_BASE + (x))
#define EP93XX_APB_PHYS_BASE 0x80800000 #define EP93XX_APB_PHYS_BASE 0x80800000
#define EP93XX_APB_VIRT_BASE 0xfed00000 #define EP93XX_APB_VIRT_BASE 0xfed00000
#define EP93XX_APB_SIZE 0x00200000 #define EP93XX_APB_SIZE 0x00200000
#define EP93XX_APB_PHYS(x) (EP93XX_APB_PHYS_BASE + (x))
#define EP93XX_APB_IOMEM(x) IOMEM(EP93XX_APB_VIRT_BASE + (x)) #define EP93XX_APB_IOMEM(x) IOMEM(EP93XX_APB_VIRT_BASE + (x))
/* AHB peripherals */ /* AHB peripherals */
#define EP93XX_DMA_BASE EP93XX_AHB_IOMEM(0x00000000) #define EP93XX_DMA_BASE EP93XX_AHB_IOMEM(0x00000000)
#define EP93XX_ETHERNET_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00010000) #define EP93XX_ETHERNET_PHYS_BASE EP93XX_AHB_PHYS(0x00010000)
#define EP93XX_ETHERNET_BASE EP93XX_AHB_IOMEM(0x00010000) #define EP93XX_ETHERNET_BASE EP93XX_AHB_IOMEM(0x00010000)
#define EP93XX_USB_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00020000) #define EP93XX_USB_PHYS_BASE EP93XX_AHB_PHYS(0x00020000)
#define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000) #define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000)
#define EP93XX_RASTER_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00030000) #define EP93XX_RASTER_PHYS_BASE EP93XX_AHB_PHYS(0x00030000)
#define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000) #define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000)
#define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000) #define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000)
...@@ -112,21 +114,10 @@ ...@@ -112,21 +114,10 @@
#define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000) #define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000)
#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x)) #define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x))
#define EP93XX_GPIO_F_INT_TYPE1 EP93XX_GPIO_REG(0x4c)
#define EP93XX_GPIO_F_INT_TYPE2 EP93XX_GPIO_REG(0x50)
#define EP93XX_GPIO_F_INT_ACK EP93XX_GPIO_REG(0x54)
#define EP93XX_GPIO_F_INT_ENABLE EP93XX_GPIO_REG(0x58)
#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c) #define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c)
#define EP93XX_GPIO_A_INT_TYPE1 EP93XX_GPIO_REG(0x90)
#define EP93XX_GPIO_A_INT_TYPE2 EP93XX_GPIO_REG(0x94)
#define EP93XX_GPIO_A_INT_ACK EP93XX_GPIO_REG(0x98)
#define EP93XX_GPIO_A_INT_ENABLE EP93XX_GPIO_REG(0x9c)
#define EP93XX_GPIO_A_INT_STATUS EP93XX_GPIO_REG(0xa0) #define EP93XX_GPIO_A_INT_STATUS EP93XX_GPIO_REG(0xa0)
#define EP93XX_GPIO_B_INT_TYPE1 EP93XX_GPIO_REG(0xac)
#define EP93XX_GPIO_B_INT_TYPE2 EP93XX_GPIO_REG(0xb0)
#define EP93XX_GPIO_B_INT_ACK EP93XX_GPIO_REG(0xb4)
#define EP93XX_GPIO_B_INT_ENABLE EP93XX_GPIO_REG(0xb8)
#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc) #define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc)
#define EP93XX_GPIO_EEDRIVE EP93XX_GPIO_REG(0xc8)
#define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000) #define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000)
...@@ -134,13 +125,13 @@ ...@@ -134,13 +125,13 @@
#define EP93XX_IRDA_BASE EP93XX_APB_IOMEM(0x000b0000) #define EP93XX_IRDA_BASE EP93XX_APB_IOMEM(0x000b0000)
#define EP93XX_UART1_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000c0000) #define EP93XX_UART1_PHYS_BASE EP93XX_APB_PHYS(0x000c0000)
#define EP93XX_UART1_BASE EP93XX_APB_IOMEM(0x000c0000) #define EP93XX_UART1_BASE EP93XX_APB_IOMEM(0x000c0000)
#define EP93XX_UART2_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000d0000) #define EP93XX_UART2_PHYS_BASE EP93XX_APB_PHYS(0x000d0000)
#define EP93XX_UART2_BASE EP93XX_APB_IOMEM(0x000d0000) #define EP93XX_UART2_BASE EP93XX_APB_IOMEM(0x000d0000)
#define EP93XX_UART3_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000e0000) #define EP93XX_UART3_PHYS_BASE EP93XX_APB_PHYS(0x000e0000)
#define EP93XX_UART3_BASE EP93XX_APB_IOMEM(0x000e0000) #define EP93XX_UART3_BASE EP93XX_APB_IOMEM(0x000e0000)
#define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000) #define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000)
...@@ -148,10 +139,10 @@ ...@@ -148,10 +139,10 @@
#define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000) #define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000)
#define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000) #define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000)
#define EP93XX_PWM_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00110000) #define EP93XX_PWM_PHYS_BASE EP93XX_APB_PHYS(0x00110000)
#define EP93XX_PWM_BASE EP93XX_APB_IOMEM(0x00110000) #define EP93XX_PWM_BASE EP93XX_APB_IOMEM(0x00110000)
#define EP93XX_RTC_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00120000) #define EP93XX_RTC_PHYS_BASE EP93XX_APB_PHYS(0x00120000)
#define EP93XX_RTC_BASE EP93XX_APB_IOMEM(0x00120000) #define EP93XX_RTC_BASE EP93XX_APB_IOMEM(0x00120000)
#define EP93XX_SYSCON_BASE EP93XX_APB_IOMEM(0x00130000) #define EP93XX_SYSCON_BASE EP93XX_APB_IOMEM(0x00130000)
...@@ -218,6 +209,17 @@ ...@@ -218,6 +209,17 @@
#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16) #define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16)
#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15) #define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15)
#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0) #define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0)
#define EP93XX_SYSCON_SYSCFG EP93XX_SYSCON_REG(0x9c)
#define EP93XX_SYSCON_SYSCFG_REV_MASK (0xf0000000)
#define EP93XX_SYSCON_SYSCFG_REV_SHIFT (28)
#define EP93XX_SYSCON_SYSCFG_SBOOT (1<<8)
#define EP93XX_SYSCON_SYSCFG_LCSN7 (1<<7)
#define EP93XX_SYSCON_SYSCFG_LCSN6 (1<<6)
#define EP93XX_SYSCON_SYSCFG_LASDO (1<<5)
#define EP93XX_SYSCON_SYSCFG_LEEDA (1<<4)
#define EP93XX_SYSCON_SYSCFG_LEECLK (1<<3)
#define EP93XX_SYSCON_SYSCFG_LCSN2 (1<<1)
#define EP93XX_SYSCON_SYSCFG_LCSN1 (1<<0)
#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) #define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0)
#define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000) #define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000)
......
...@@ -114,17 +114,9 @@ extern void ep93xx_gpio_int_debounce(unsigned int irq, int enable); ...@@ -114,17 +114,9 @@ extern void ep93xx_gpio_int_debounce(unsigned int irq, int enable);
* B0..B7 (7..15) to irq 72..79, and * B0..B7 (7..15) to irq 72..79, and
* F0..F7 (16..24) to irq 80..87. * F0..F7 (16..24) to irq 80..87.
*/ */
static inline int gpio_to_irq(unsigned gpio) #define gpio_to_irq(gpio) \
{ (((gpio) <= EP93XX_GPIO_LINE_MAX_IRQ) ? (64 + (gpio)) : -EINVAL)
if (gpio <= EP93XX_GPIO_LINE_MAX_IRQ)
return 64 + gpio; #define irq_to_gpio(irq) ((irq) - gpio_to_irq(0))
return -EINVAL;
}
static inline int irq_to_gpio(unsigned irq)
{
return irq - gpio_to_irq(0);
}
#endif #endif
...@@ -9,6 +9,12 @@ ...@@ -9,6 +9,12 @@
#define PHYS_OFFSET UL(0x00000000) #define PHYS_OFFSET UL(0x00000000)
#elif defined(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) #elif defined(CONFIG_EP93XX_SDCE0_PHYS_OFFSET)
#define PHYS_OFFSET UL(0xc0000000) #define PHYS_OFFSET UL(0xc0000000)
#elif defined(CONFIG_EP93XX_SDCE1_PHYS_OFFSET)
#define PHYS_OFFSET UL(0xd0000000)
#elif defined(CONFIG_EP93XX_SDCE2_PHYS_OFFSET)
#define PHYS_OFFSET UL(0xe0000000)
#elif defined(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET)
#define PHYS_OFFSET UL(0xf0000000)
#else #else
#error "Kconfig bug: No EP93xx PHYS_OFFSET set" #error "Kconfig bug: No EP93xx PHYS_OFFSET set"
#endif #endif
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
struct i2c_gpio_platform_data;
struct i2c_board_info; struct i2c_board_info;
struct platform_device; struct platform_device;
struct ep93xxfb_mach_info; struct ep93xxfb_mach_info;
...@@ -33,7 +34,8 @@ static inline void ep93xx_devcfg_clear_bits(unsigned int bits) ...@@ -33,7 +34,8 @@ static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
} }
void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
void ep93xx_register_i2c(struct i2c_board_info *devices, int num); void ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
struct i2c_board_info *devices, int num);
void ep93xx_register_fb(struct ep93xxfb_mach_info *data); void ep93xx_register_fb(struct ep93xxfb_mach_info *data);
void ep93xx_register_pwm(int pwm0, int pwm1); void ep93xx_register_pwm(int pwm0, int pwm1);
int ep93xx_pwm_acquire_gpio(struct platform_device *pdev); int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
* linux/arch/arm/mach-ep93xx/micro9.c * linux/arch/arm/mach-ep93xx/micro9.c
* *
* Copyright (C) 2006 Contec Steuerungstechnik & Automation GmbH * Copyright (C) 2006 Contec Steuerungstechnik & Automation GmbH
* Manfred Gruber <manfred.gruber@contec.at> * Manfred Gruber <m.gruber@tirol.com>
* Copyright (C) 2009 Contec Steuerungstechnik & Automation GmbH
* Hubert Feurstein <hubert.feurstein@contec.at>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -20,104 +22,124 @@ ...@@ -20,104 +22,124 @@
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
static struct ep93xx_eth_data micro9_eth_data = { /*************************************************************************
.phy_id = 0x1f, * Micro9 NOR Flash
}; *
* Micro9-High has up to 64MB of 32-bit flash on CS1
static void __init micro9_init(void) * Micro9-Mid has up to 64MB of either 32-bit or 16-bit flash on CS1
{ * Micro9-Lite uses a seperate MTD map driver for flash support
ep93xx_register_eth(&micro9_eth_data, 1); * Micro9-Slim has up to 64MB of either 32-bit or 16-bit flash on CS1
} *************************************************************************/
static struct physmap_flash_data micro9_flash_data;
/*
* Micro9-H static struct resource micro9_flash_resource = {
*/
#ifdef CONFIG_MACH_MICRO9H
static struct physmap_flash_data micro9h_flash_data = {
.width = 4,
};
static struct resource micro9h_flash_resource = {
.start = EP93XX_CS1_PHYS_BASE, .start = EP93XX_CS1_PHYS_BASE,
.end = EP93XX_CS1_PHYS_BASE + SZ_64M - 1, .end = EP93XX_CS1_PHYS_BASE + SZ_64M - 1,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}; };
static struct platform_device micro9h_flash = { static struct platform_device micro9_flash = {
.name = "physmap-flash", .name = "physmap-flash",
.id = 0, .id = 0,
.dev = { .dev = {
.platform_data = &micro9h_flash_data, .platform_data = &micro9_flash_data,
}, },
.num_resources = 1, .num_resources = 1,
.resource = &micro9h_flash_resource, .resource = &micro9_flash_resource,
}; };
static void __init micro9h_init(void) static void __init __micro9_register_flash(unsigned int width)
{
micro9_flash_data.width = width;
platform_device_register(&micro9_flash);
}
static unsigned int __init micro9_detect_bootwidth(void)
{
u32 v;
/* Detect the bus width of the external flash memory */
v = __raw_readl(EP93XX_SYSCON_SYSCFG);
if (v & EP93XX_SYSCON_SYSCFG_LCSN7)
return 4; /* 32-bit */
else
return 2; /* 16-bit */
}
static void __init micro9_register_flash(void)
{ {
platform_device_register(&micro9h_flash); if (machine_is_micro9())
__micro9_register_flash(4);
else if (machine_is_micro9m() || machine_is_micro9s())
__micro9_register_flash(micro9_detect_bootwidth());
} }
static void __init micro9h_init_machine(void)
/*************************************************************************
* Micro9 Ethernet
*************************************************************************/
static struct ep93xx_eth_data micro9_eth_data = {
.phy_id = 0x1f,
};
static void __init micro9_init_machine(void)
{ {
ep93xx_init_devices(); ep93xx_init_devices();
micro9_init(); ep93xx_register_eth(&micro9_eth_data, 1);
micro9h_init(); micro9_register_flash();
} }
MACHINE_START(MICRO9, "Contec Hypercontrol Micro9-H")
/* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */ #ifdef CONFIG_MACH_MICRO9H
MACHINE_START(MICRO9, "Contec Micro9-High")
/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
.phys_io = EP93XX_APB_PHYS_BASE, .phys_io = EP93XX_APB_PHYS_BASE,
.io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io, .map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq, .init_irq = ep93xx_init_irq,
.timer = &ep93xx_timer, .timer = &ep93xx_timer,
.init_machine = micro9h_init_machine, .init_machine = micro9_init_machine,
MACHINE_END MACHINE_END
#endif #endif
/*
* Micro9-M
*/
#ifdef CONFIG_MACH_MICRO9M #ifdef CONFIG_MACH_MICRO9M
static void __init micro9m_init_machine(void) MACHINE_START(MICRO9M, "Contec Micro9-Mid")
{ /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
ep93xx_init_devices();
micro9_init();
}
MACHINE_START(MICRO9M, "Contec Hypercontrol Micro9-M")
/* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */
.phys_io = EP93XX_APB_PHYS_BASE, .phys_io = EP93XX_APB_PHYS_BASE,
.io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, .boot_params = EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
.map_io = ep93xx_map_io, .map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq, .init_irq = ep93xx_init_irq,
.timer = &ep93xx_timer, .timer = &ep93xx_timer,
.init_machine = micro9m_init_machine, .init_machine = micro9_init_machine,
MACHINE_END MACHINE_END
#endif #endif
/*
* Micro9-L
*/
#ifdef CONFIG_MACH_MICRO9L #ifdef CONFIG_MACH_MICRO9L
static void __init micro9l_init_machine(void) MACHINE_START(MICRO9L, "Contec Micro9-Lite")
{ /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
ep93xx_init_devices();
micro9_init();
}
MACHINE_START(MICRO9L, "Contec Hypercontrol Micro9-L")
/* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */
.phys_io = EP93XX_APB_PHYS_BASE, .phys_io = EP93XX_APB_PHYS_BASE,
.io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
.map_io = ep93xx_map_io, .map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq, .init_irq = ep93xx_init_irq,
.timer = &ep93xx_timer, .timer = &ep93xx_timer,
.init_machine = micro9l_init_machine, .init_machine = micro9_init_machine,
MACHINE_END MACHINE_END
#endif #endif
#ifdef CONFIG_MACH_MICRO9S
MACHINE_START(MICRO9S, "Contec Micro9-Slim")
/* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
.phys_io = EP93XX_APB_PHYS_BASE,
.io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
.map_io = ep93xx_map_io,
.init_irq = ep93xx_init_irq,
.timer = &ep93xx_timer,
.init_machine = micro9_init_machine,
MACHINE_END
#endif
...@@ -155,7 +155,7 @@ MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table ...@@ -155,7 +155,7 @@ MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table
static pxa_freqs_t pxa27x_freqs[] = { static pxa_freqs_t pxa27x_freqs[] = {
{104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1), 900000, 1705000 }, {104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1), 900000, 1705000 },
{156000, 104000, PXA27x_CCCR(1, 8, 6), 0, CCLKCFG2(1, 1, 1), 1000000, 1705000 }, {156000, 104000, PXA27x_CCCR(1, 8, 3), 0, CCLKCFG2(1, 0, 1), 1000000, 1705000 },
{208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1), 1180000, 1705000 }, {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1), 1180000, 1705000 },
{312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1), 1250000, 1705000 }, {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1), 1250000, 1705000 },
{416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1), 1350000, 1705000 }, {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1), 1350000, 1705000 },
......
...@@ -238,7 +238,7 @@ static struct resource csb726_lan_resources[] = { ...@@ -238,7 +238,7 @@ static struct resource csb726_lan_resources[] = {
}; };
struct smsc911x_platform_config csb726_lan_config = { struct smsc911x_platform_config csb726_lan_config = {
.irq_type = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
.irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
.flags = SMSC911X_USE_32BIT, .flags = SMSC911X_USE_32BIT,
.phy_interface = PHY_INTERFACE_MODE_MII, .phy_interface = PHY_INTERFACE_MODE_MII,
......
...@@ -25,6 +25,7 @@ led-$(CONFIG_SA1100_CERF) += leds-cerf.o ...@@ -25,6 +25,7 @@ led-$(CONFIG_SA1100_CERF) += leds-cerf.o
obj-$(CONFIG_SA1100_COLLIE) += collie.o obj-$(CONFIG_SA1100_COLLIE) += collie.o
obj-$(CONFIG_SA1100_H3100) += h3600.o
obj-$(CONFIG_SA1100_H3600) += h3600.o obj-$(CONFIG_SA1100_H3600) += h3600.o
obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/assembler.h> #include <asm/assembler.h>
#include <asm/unwind.h>
#include "proc-macros.S" #include "proc-macros.S"
...@@ -121,11 +122,13 @@ ENTRY(v6_coherent_kern_range) ...@@ -121,11 +122,13 @@ ENTRY(v6_coherent_kern_range)
* - the Icache does not read data from the write buffer * - the Icache does not read data from the write buffer
*/ */
ENTRY(v6_coherent_user_range) ENTRY(v6_coherent_user_range)
UNWIND(.fnstart )
#ifdef HARVARD_CACHE #ifdef HARVARD_CACHE
bic r0, r0, #CACHE_LINE_SIZE - 1 bic r0, r0, #CACHE_LINE_SIZE - 1
1: mcr p15, 0, r0, c7, c10, 1 @ clean D line 1:
USER( mcr p15, 0, r0, c7, c10, 1 ) @ clean D line
add r0, r0, #CACHE_LINE_SIZE add r0, r0, #CACHE_LINE_SIZE
2:
cmp r0, r1 cmp r0, r1
blo 1b blo 1b
#endif #endif
...@@ -142,6 +145,19 @@ ENTRY(v6_coherent_user_range) ...@@ -142,6 +145,19 @@ ENTRY(v6_coherent_user_range)
#endif #endif
mov pc, lr mov pc, lr
/*
* Fault handling for the cache operation above. If the virtual address in r0
* isn't mapped, just try the next page.
*/
9001:
mov r0, r0, lsr #12
mov r0, r0, lsl #12
add r0, r0, #4096
b 2b
UNWIND(.fnend )
ENDPROC(v6_coherent_user_range)
ENDPROC(v6_coherent_kern_range)
/* /*
* v6_flush_kern_dcache_page(kaddr) * v6_flush_kern_dcache_page(kaddr)
* *
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/assembler.h> #include <asm/assembler.h>
#include <asm/unwind.h>
#include "proc-macros.S" #include "proc-macros.S"
...@@ -153,13 +154,16 @@ ENTRY(v7_coherent_kern_range) ...@@ -153,13 +154,16 @@ ENTRY(v7_coherent_kern_range)
* - the Icache does not read data from the write buffer * - the Icache does not read data from the write buffer
*/ */
ENTRY(v7_coherent_user_range) ENTRY(v7_coherent_user_range)
UNWIND(.fnstart )
dcache_line_size r2, r3 dcache_line_size r2, r3
sub r3, r2, #1 sub r3, r2, #1
bic r0, r0, r3 bic r0, r0, r3
1: mcr p15, 0, r0, c7, c11, 1 @ clean D line to the point of unification 1:
USER( mcr p15, 0, r0, c7, c11, 1 ) @ clean D line to the point of unification
dsb dsb
mcr p15, 0, r0, c7, c5, 1 @ invalidate I line USER( mcr p15, 0, r0, c7, c5, 1 ) @ invalidate I line
add r0, r0, r2 add r0, r0, r2
2:
cmp r0, r1 cmp r0, r1
blo 1b blo 1b
mov r0, #0 mov r0, #0
...@@ -167,6 +171,17 @@ ENTRY(v7_coherent_user_range) ...@@ -167,6 +171,17 @@ ENTRY(v7_coherent_user_range)
dsb dsb
isb isb
mov pc, lr mov pc, lr
/*
* Fault handling for the cache operation above. If the virtual address in r0
* isn't mapped, just try the next page.
*/
9001:
mov r0, r0, lsr #12
mov r0, r0, lsl #12
add r0, r0, #4096
b 2b
UNWIND(.fnend )
ENDPROC(v7_coherent_kern_range) ENDPROC(v7_coherent_kern_range)
ENDPROC(v7_coherent_user_range) ENDPROC(v7_coherent_user_range)
......
...@@ -153,14 +153,11 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte) ...@@ -153,14 +153,11 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
page = pfn_to_page(pfn); page = pfn_to_page(pfn);
mapping = page_mapping(page); mapping = page_mapping(page);
if (mapping) {
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
__flush_dcache_page(mapping, page);
if (dirty)
__flush_dcache_page(mapping, page);
#endif #endif
if (mapping) {
if (cache_is_vivt()) if (cache_is_vivt())
make_coherent(mapping, vma, addr, pfn); make_coherent(mapping, vma, addr, pfn);
else if (vma->vm_flags & VM_EXEC) else if (vma->vm_flags & VM_EXEC)
......
...@@ -292,6 +292,11 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) ...@@ -292,6 +292,11 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
* down_read() * down_read()
*/ */
might_sleep(); might_sleep();
#ifdef CONFIG_DEBUG_VM
if (!user_mode(regs) &&
!search_exception_tables(regs->ARM_pc))
goto no_context;
#endif
} }
fault = __do_page_fault(mm, addr, fsr, tsk); fault = __do_page_fault(mm, addr, fsr, tsk);
......
...@@ -46,6 +46,8 @@ void *kmap_atomic(struct page *page, enum km_type type) ...@@ -46,6 +46,8 @@ void *kmap_atomic(struct page *page, enum km_type type)
if (!PageHighMem(page)) if (!PageHighMem(page))
return page_address(page); return page_address(page);
debug_kmap_atomic(type);
kmap = kmap_high_get(page); kmap = kmap_high_get(page);
if (kmap) if (kmap)
return kmap; return kmap;
......
...@@ -483,7 +483,7 @@ free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn) ...@@ -483,7 +483,7 @@ free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn)
/* /*
* Convert start_pfn/end_pfn to a struct page pointer. * Convert start_pfn/end_pfn to a struct page pointer.
*/ */
start_pg = pfn_to_page(start_pfn); start_pg = pfn_to_page(start_pfn - 1) + 1;
end_pg = pfn_to_page(end_pfn); end_pg = pfn_to_page(end_pfn);
/* /*
......
...@@ -693,7 +693,7 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -693,7 +693,7 @@ static int pxamci_probe(struct platform_device *pdev)
if (gpio_is_valid(gpio_ro)) { if (gpio_is_valid(gpio_ro)) {
ret = gpio_request(gpio_ro, "mmc card read only"); ret = gpio_request(gpio_ro, "mmc card read only");
if (ret) { if (ret) {
dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n", gpio_power); dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n", gpio_ro);
goto err_gpio_ro; goto err_gpio_ro;
} }
gpio_direction_input(gpio_ro); gpio_direction_input(gpio_ro);
...@@ -701,7 +701,7 @@ static int pxamci_probe(struct platform_device *pdev) ...@@ -701,7 +701,7 @@ static int pxamci_probe(struct platform_device *pdev)
if (gpio_is_valid(gpio_cd)) { if (gpio_is_valid(gpio_cd)) {
ret = gpio_request(gpio_cd, "mmc card detect"); ret = gpio_request(gpio_cd, "mmc card detect");
if (ret) { if (ret) {
dev_err(&pdev->dev, "Failed requesting gpio_cd %d\n", gpio_power); dev_err(&pdev->dev, "Failed requesting gpio_cd %d\n", gpio_cd);
goto err_gpio_cd; goto err_gpio_cd;
} }
gpio_direction_input(gpio_cd); gpio_direction_input(gpio_cd);
......
...@@ -1826,7 +1826,7 @@ static struct amba_id pl022_ids[] = { ...@@ -1826,7 +1826,7 @@ static struct amba_id pl022_ids[] = {
* ST Micro derivative, this has 32bit wide * ST Micro derivative, this has 32bit wide
* and 32 locations deep TX/RX FIFO * and 32 locations deep TX/RX FIFO
*/ */
.id = 0x00108022, .id = 0x01080022,
.mask = 0xffffffff, .mask = 0xffffffff,
.data = &vendor_st, .data = &vendor_st,
}, },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment