Commit 7266355c authored by Russell King's avatar Russell King

[ARM] Merge current 2.6 into experimental tree.

parents 67e9bb60 f5793133
...@@ -23,10 +23,6 @@ ifeq ($(CONFIG_ARCH_SHARK),y) ...@@ -23,10 +23,6 @@ ifeq ($(CONFIG_ARCH_SHARK),y)
OBJS += head-shark.o ofw-shark.o OBJS += head-shark.o ofw-shark.o
endif endif
ifeq ($(CONFIG_ARCH_INTEGRATOR),y)
OBJS += head-integrator.o
endif
ifeq ($(CONFIG_ARCH_CAMELOT),y) ifeq ($(CONFIG_ARCH_CAMELOT),y)
OBJS += head-epxa10db.o OBJS += head-epxa10db.o
endif endif
......
#include <asm/mach-types.h>
.section ".start", "ax"
mov r7, #MACH_TYPE_INTEGRATOR
...@@ -503,12 +503,6 @@ proc_types: ...@@ -503,12 +503,6 @@ proc_types:
@ Everything from here on will be the new ID system. @ Everything from here on will be the new ID system.
.word 0x41129200 @ ARM920T
.word 0xff00fff0
b __armv4_cache_on
b __armv4_cache_off
b __armv4_cache_flush
.word 0x4401a100 @ sa110 / sa1100 .word 0x4401a100 @ sa110 / sa1100
.word 0xffffffe0 .word 0xffffffe0
b __armv4_cache_on b __armv4_cache_on
...@@ -523,6 +517,12 @@ proc_types: ...@@ -523,6 +517,12 @@ proc_types:
@ These match on the architecture ID @ These match on the architecture ID
.word 0x00020000 @ ARMv4T
.word 0x000f0000
b __armv4_cache_on
b __armv4_cache_off
b __armv4_cache_flush
.word 0x00050000 @ ARMv5TE .word 0x00050000 @ ARMv5TE
.word 0x000f0000 .word 0x000f0000
b __armv4_cache_on b __armv4_cache_on
......
This diff is collapsed.
...@@ -68,8 +68,8 @@ extern void __umoddi3(void); ...@@ -68,8 +68,8 @@ extern void __umoddi3(void);
extern void __udivmoddi4(void); extern void __udivmoddi4(void);
extern void __udivsi3(void); extern void __udivsi3(void);
extern void __umodsi3(void); extern void __umodsi3(void);
extern void __do_div64(void);
extern void abort(void); extern void abort(void);
extern void do_div64(void);
extern void ret_from_exception(void); extern void ret_from_exception(void);
extern void fpundefinstr(void); extern void fpundefinstr(void);
...@@ -223,7 +223,7 @@ EXPORT_SYMBOL_NOVERS(__umoddi3); ...@@ -223,7 +223,7 @@ EXPORT_SYMBOL_NOVERS(__umoddi3);
EXPORT_SYMBOL_NOVERS(__udivmoddi4); EXPORT_SYMBOL_NOVERS(__udivmoddi4);
EXPORT_SYMBOL_NOVERS(__udivsi3); EXPORT_SYMBOL_NOVERS(__udivsi3);
EXPORT_SYMBOL_NOVERS(__umodsi3); EXPORT_SYMBOL_NOVERS(__umodsi3);
EXPORT_SYMBOL_NOVERS(do_div64); EXPORT_SYMBOL_NOVERS(__do_div64);
/* bitops */ /* bitops */
EXPORT_SYMBOL(_set_bit_le); EXPORT_SYMBOL(_set_bit_le);
......
/*
* linux/arch/arm/lib/div64.S
*
* Optimized computation of 64-bit dividend / 32-bit divisor
*
* Author: Nicolas Pitre
* Created: Oct 5, 2003
* Copyright: Monta Vista Software, Inc.
*
* 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/linkage.h> #include <linux/linkage.h>
#ifndef __ARMEB__ #ifdef __ARMEB__
ql .req r0 @ quotient low #define xh r0
qh .req r1 @ quotient high #define xl r1
onl .req r0 @ original dividend low #define yh r2
onh .req r1 @ original dividend high #define yl r3
nl .req r4 @ dividend low
nh .req r5 @ dividend high
res .req r4 @ result
#else #else
ql .req r1 #define xl r0
qh .req r0 #define xh r1
onl .req r1 #define yl r2
onh .req r0 #define yh r3
nl .req r5
nh .req r4
res .req r5
#endif #endif
dl .req r3 @ divisor low /*
dh .req r2 @ divsor high * __do_div64: perform a division with 64-bit dividend and 32-bit divisor.
*
* Note: Calling convention is totally non standard for optimal code.
ENTRY(do_div64) * This is meant to be used by do_div() from include/asm/div64.h only.
stmfd sp!, {r4, r5, lr} *
mov nl, onl * Input parameters:
movs nh, onh @ if high bits are zero * xh-xl = dividend (clobbered)
movne lr, #33 * r4 = divisor (preserved)
moveq lr, #1 @ only divide low bits *
moveq nh, onl * Output values:
* yh-yl = result
tst dh, #0x80000000 * xh = remainder
bne 2f *
1: cmp nh, dh * Clobbered regs: xl, ip
bls 2f */
add lr, lr, #1
movs dh, dh, lsl #1 @ left justify disor ENTRY(__do_div64)
bpl 1b
@ Test for easy paths first.
2: movs nh, onh subs ip, r4, #1
moveq dl, dh bls 9f @ divisor is 0 or 1
moveq dh, #0 tst ip, r4
movne dl, #0 beq 8f @ divisor is power of 2
mov ql, #0
mov qh, #0 @ See if we need to handle upper 32-bit result.
3: subs ip, nl, dl @ trial subtraction cmp xh, r4
sbcs ip, nh, dh mov yh, #0
movcs nh, ip @ only update if successful blo 3f
subcs nl, nl, dl @ (repeat the subtraction)
adcs ql, ql, ql @ C=1 if successful, shift into @ Align divisor with upper part of dividend.
adc qh, qh, qh @ quotient @ The aligned divisor is stored in yl preserving the original.
movs dh, dh, lsr #1 @ shift base high part right @ The bit position is stored in ip.
mov dl, dl, rrx @ shift base low part right
subs lr, lr, #1 #if __LINUX_ARM_ARCH__ >= 5
bne 3b
clz yl, r4
mov r2, res clz ip, xh
ldmfd sp!, {r4, r5, pc} sub yl, yl, ip
mov ip, #1
mov ip, ip, lsl yl
mov yl, r4, lsl yl
#else
mov yl, r4
mov ip, #1
1: cmp yl, #0x80000000
cmpcc yl, xh
movcc yl, yl, lsl #1
movcc ip, ip, lsl #1
bcc 1b
#endif
@ The division loop for needed upper bit positions.
@ Break out early if dividend reaches 0.
2: cmp xh, yl
orrcs yh, yh, ip
subcss xh, xh, yl
movnes ip, ip, lsr #1
mov yl, yl, lsr #1
bne 2b
@ See if we need to handle lower 32-bit result.
3: cmp xh, #0
mov yl, #0
cmpeq xl, r4
movlo xh, xl
movlo pc, lr
@ The division loop for lower bit positions.
@ Here we shift remainer bits leftwards rather than moving the
@ divisor for comparisons, considering the carry-out bit as well.
mov ip, #0x80000000
4: movs xl, xl, lsl #1
adcs xh, xh, xh
beq 6f
cmpcc xh, r4
5: orrcs yl, yl, ip
subcs xh, xh, r4
movs ip, ip, lsr #1
bne 4b
mov pc, lr
@ The top part of remainder became zero. If carry is set
@ (the 33th bit) this is a false positive so resume the loop.
@ Otherwise, if lower part is also null then we're done.
6: bcs 5b
cmp xl, #0
moveq pc, lr
@ We still have remainer bits in the low part. Bring them up.
#if __LINUX_ARM_ARCH__ >= 5
clz xh, xl @ we know xh is zero here so...
add xh, xh, #1
mov xl, xl, lsl xh
mov ip, ip, lsr xh
#else
7: movs xl, xl, lsl #1
mov ip, ip, lsr #1
bcc 7b
#endif
@ Current remainder is now 1. It's worthless to compare with
@ divisor at this point since divisor can't be smaller than 3 here.
@ If possible, branch for another shift in the division loop.
@ If no bit position left then we're done.
movs ip, ip, lsr #1
mov xh, #1
bne 4b
mov pc, lr
8: @ Division by a power of 2: determine what that divisor order is
@ then simply shift values around
#if __LINUX_ARM_ARCH__ >= 5
clz ip, r4
rsb ip, ip, #31
#else
mov yl, r4
cmp r4, #(1 << 16)
mov ip, #0
movhs yl, yl, lsr #16
movhs ip, #16
cmp yl, #(1 << 8)
movhs yl, yl, lsr #8
addhs ip, ip, #8
cmp yl, #(1 << 4)
movhs yl, yl, lsr #4
addhs ip, ip, #4
cmp yl, #(1 << 2)
addhi ip, ip, #3
addls ip, ip, yl, lsr #1
#endif
mov yh, xh, lsr ip
mov yl, xl, lsr ip
rsb ip, ip, #32
orr yl, yl, xh, lsl ip
mov xh, xl, lsl ip
mov xh, xh, lsr ip
mov pc, lr
@ eq -> division by 1: obvious enough...
9: moveq yl, xl
moveq yh, xh
moveq xh, #0
moveq pc, lr
@ Division by 0:
str lr, [sp, #-4]!
bl __div0
@ as wrong as it could be...
mov yl, #0
mov yh, #0
mov xh, #0
ldr pc, [sp], #4
...@@ -40,6 +40,7 @@ static unsigned long clps711x_gettimeoffset(void) ...@@ -40,6 +40,7 @@ static unsigned long clps711x_gettimeoffset(void)
void __init clps711x_setup_timer(void) void __init clps711x_setup_timer(void)
{ {
struct timespec tv;
unsigned int syscon; unsigned int syscon;
gettimeoffset = clps711x_gettimeoffset; gettimeoffset = clps711x_gettimeoffset;
...@@ -50,5 +51,7 @@ void __init clps711x_setup_timer(void) ...@@ -50,5 +51,7 @@ void __init clps711x_setup_timer(void)
clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */ clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */
xtime.tv_sec = clps_readl(RTCDR); tv.tv_nsec = 0;
tv.tv_sec = clps_readl(RTCDR);
do_settimeofday(&tv);
} }
...@@ -126,7 +126,7 @@ static void __init ap_init_irq(void) ...@@ -126,7 +126,7 @@ static void __init ap_init_irq(void)
writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
for (i = 0; i < NR_IRQS; i++) { for (i = 0; i < NR_IRQS; i++) {
if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) { if (((1 << i) & INTEGRATOR_SC_VALID_INT) != 0) {
set_irq_chip(i, &sc_chip); set_irq_chip(i, &sc_chip);
set_irq_handler(i, do_level_IRQ); set_irq_handler(i, do_level_IRQ);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE); set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
......
...@@ -32,14 +32,14 @@ ENTRY(v3_flush_kern_cache_all) ...@@ -32,14 +32,14 @@ ENTRY(v3_flush_kern_cache_all)
/* FALLTHROUGH */ /* FALLTHROUGH */
/* /*
* flush_user_cache_range(start, end, vm_flags) * flush_user_cache_range(start, end, flags)
* *
* Invalidate a range of cache entries in the specified * Invalidate a range of cache entries in the specified
* address space. * address space.
* *
* - start - start address (may not be aligned) * - start - start address (may not be aligned)
* - end - end address (exclusive, may not be aligned) * - end - end address (exclusive, may not be aligned)
* - vma - vma_area_struct describing address space * - flags - vma_area_struct flags describing address space
*/ */
ENTRY(v3_flush_user_cache_range) ENTRY(v3_flush_user_cache_range)
mov ip, #0 mov ip, #0
......
...@@ -34,14 +34,14 @@ ENTRY(v4_flush_kern_cache_all) ...@@ -34,14 +34,14 @@ ENTRY(v4_flush_kern_cache_all)
mov pc, lr mov pc, lr
/* /*
* flush_user_cache_range(start, end, vma) * flush_user_cache_range(start, end, flags)
* *
* Invalidate a range of cache entries in the specified * Invalidate a range of cache entries in the specified
* address space. * address space.
* *
* - start - start address (may not be aligned) * - start - start address (may not be aligned)
* - end - end address (exclusive, may not be aligned) * - end - end address (exclusive, may not be aligned)
* - vma - vma_area_struct describing address space * - flags - vma_area_struct flags describing address space
*/ */
ENTRY(v4_flush_user_cache_range) ENTRY(v4_flush_user_cache_range)
mov ip, #0 mov ip, #0
......
...@@ -72,14 +72,14 @@ __flush_whole_cache: ...@@ -72,14 +72,14 @@ __flush_whole_cache:
mov pc, lr mov pc, lr
/* /*
* flush_user_cache_range(start, end, vm_flags) * flush_user_cache_range(start, end, flags)
* *
* Invalidate a range of cache entries in the specified * Invalidate a range of cache entries in the specified
* address space. * address space.
* *
* - start - start address (inclusive, page aligned) * - start - start address (inclusive, page aligned)
* - end - end address (exclusive, page aligned) * - end - end address (exclusive, page aligned)
* - vma - vma_area_struct describing address space * - flags - vma_area_struct flags describing address space
*/ */
ENTRY(v4wb_flush_user_cache_range) ENTRY(v4wb_flush_user_cache_range)
sub r3, r1, r0 @ calculate total size sub r3, r1, r0 @ calculate total size
......
...@@ -64,14 +64,14 @@ __flush_whole_cache: ...@@ -64,14 +64,14 @@ __flush_whole_cache:
mov pc, lr mov pc, lr
/* /*
* flush_user_cache_range(start, end, vm_flags) * flush_user_cache_range(start, end, flags)
* *
* Clean and invalidate a range of cache entries in the specified * Clean and invalidate a range of cache entries in the specified
* address space. * address space.
* *
* - start - start address (inclusive, page aligned) * - start - start address (inclusive, page aligned)
* - end - end address (exclusive, page aligned) * - end - end address (exclusive, page aligned)
* - vma - vma_area_struct describing address space * - flags - vma_area_struct flags describing address space
*/ */
ENTRY(v4wt_flush_user_cache_range) ENTRY(v4wt_flush_user_cache_range)
sub r3, r1, r0 @ calculate total size sub r3, r1, r0 @ calculate total size
......
...@@ -280,13 +280,15 @@ static int ioc_client_reg(struct i2c_client *client) ...@@ -280,13 +280,15 @@ static int ioc_client_reg(struct i2c_client *client)
client->addr == 0x50) { client->addr == 0x50) {
struct rtc_tm rtctm; struct rtc_tm rtctm;
unsigned int year; unsigned int year;
struct timespec tv;
rtc_client = client; rtc_client = client;
get_rtc_time(&rtctm, &year); get_rtc_time(&rtctm, &year);
xtime.tv_nsec = rtctm.cs * 10000000; tv.tv_nsec = rtctm.cs * 10000000;
xtime.tv_sec = mktime(year, rtctm.mon, rtctm.mday, tv.tv_sec = mktime(year, rtctm.mon, rtctm.mday,
rtctm.hours, rtctm.mins, rtctm.secs); rtctm.hours, rtctm.mins, rtctm.secs);
do_settimeofday(&tv);
set_rtc = k_set_rtc_time; set_rtc = k_set_rtc_time;
} }
......
...@@ -243,6 +243,7 @@ void __init time_init(void) ...@@ -243,6 +243,7 @@ void __init time_init(void)
if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ && if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ &&
CMOS_READ(RTC_REG_B) == reg_b) { CMOS_READ(RTC_REG_B) == reg_b) {
struct timespec tv;
/* /*
* We have a RTC. Check the battery * We have a RTC. Check the battery
...@@ -250,7 +251,9 @@ void __init time_init(void) ...@@ -250,7 +251,9 @@ void __init time_init(void)
if ((reg_d & 0x80) == 0) if ((reg_d & 0x80) == 0)
printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n"); printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n");
xtime.tv_sec = get_isa_cmos_time(); tv.tv_nsec = 0;
tv.tv_sec = get_isa_cmos_time();
do_settimeofday(&tv);
set_rtc = set_isa_cmos_time; set_rtc = set_isa_cmos_time;
} else } else
rtc_base = 0; rtc_base = 0;
......
...@@ -73,9 +73,15 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -73,9 +73,15 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
void __init time_init(void) void __init time_init(void)
{ {
struct timespec tv;
gettimeoffset = pxa_gettimeoffset; gettimeoffset = pxa_gettimeoffset;
set_rtc = pxa_set_rtc; set_rtc = pxa_set_rtc;
xtime.tv_sec = pxa_get_rtc_time();
tv.tv_nsec = 0;
tv.tv_sec = pxa_get_rtc_time();
do_settimeofday(&tv);
timer_irq.handler = pxa_timer_interrupt; timer_irq.handler = pxa_timer_interrupt;
OSMR0 = 0; /* set initial match at 0 */ OSMR0 = 0; /* set initial match at 0 */
OSSR = 0xf; /* clear status on all timers */ OSSR = 0xf; /* clear status on all timers */
......
...@@ -92,9 +92,15 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -92,9 +92,15 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
void __init time_init(void) void __init time_init(void)
{ {
struct timespec tv;
gettimeoffset = sa1100_gettimeoffset; gettimeoffset = sa1100_gettimeoffset;
set_rtc = sa1100_set_rtc; set_rtc = sa1100_set_rtc;
xtime.tv_sec = sa1100_get_rtc_time();
tv.tv.nsec = 0;
tv.tv_sec = sa1100_get_rtc_time();
do_settimeofday(&tv);
timer_irq.handler = sa1100_timer_interrupt; timer_irq.handler = sa1100_timer_interrupt;
OSMR0 = 0; /* set initial match at 0 */ OSMR0 = 0; /* set initial match at 0 */
OSSR = 0xf; /* clear status on all timers */ OSSR = 0xf; /* clear status on all timers */
......
...@@ -34,8 +34,6 @@ void __init time_init(void) ...@@ -34,8 +34,6 @@ void __init time_init(void)
outb(HZ_TIME & 0xff, 0x40); /* LSB of count */ outb(HZ_TIME & 0xff, 0x40); /* LSB of count */
outb(HZ_TIME >> 8, 0x40); outb(HZ_TIME >> 8, 0x40);
xtime.tv_sec = 0;
timer_irq.handler = timer_interrupt; timer_irq.handler = timer_interrupt;
setup_irq(IRQ_TIMER, &timer_irq); setup_irq(IRQ_TIMER, &timer_irq);
} }
#ifndef __ASM_ARM_DIV64 #ifndef __ASM_ARM_DIV64
#define __ASM_ARM_DIV64 #define __ASM_ARM_DIV64
/* We're not 64-bit, but... */ /*
* The semantics of do_div() are:
*
* uint32_t do_div(uint64_t *n, uint32_t base)
* {
* uint32_t remainder = *n % base;
* *n = *n / base;
* return remainder;
* }
*
* In other words, a 64-bit dividend with a 32-bit divisor producing
* a 64-bit result and a 32-bit remainder. To accomplish this optimally
* we call a special __do_div64 helper with completely non standard
* calling convention for arguments and results (beware).
*/
#ifdef __ARMEB__
#define __xh "r0"
#define __xl "r1"
#else
#define __xl "r0"
#define __xh "r1"
#endif
#define do_div(n,base) \ #define do_div(n,base) \
({ \ ({ \
register int __res asm("r2") = base; \ register unsigned int __base asm("r4") = base; \
register unsigned long long __n asm("r0") = n; \ register unsigned long long __n asm("r0") = n; \
asm("bl do_div64" \ register unsigned long long __res asm("r2"); \
: "=r" (__n), "=r" (__res) \ register unsigned int __rem asm(__xh); \
: "0" (__n), "1" (__res) \ asm("bl __do_div64" \
: "r3", "ip", "lr", "cc"); \ : "=r" (__rem), "=r" (__res) \
n = __n; \ : "r" (__n), "r" (__base) \
__res; \ : "ip", "lr", "cc"); \
n = __res; \
__rem; \
}) })
#endif #endif
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