Commit 42c1faa2 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.6-exp

into home.osdl.org:/home/torvalds/v2.5/linux
parents 0b170e19 f23e0372
...@@ -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
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include <asm/hardware/sa1111.h> #include <asm/hardware/sa1111.h>
extern void __init sa1110_mb_enable(void);
/* /*
* We keep the following data for the overall SA1111. Note that the * We keep the following data for the overall SA1111. Note that the
* struct device and struct resource are "fake"; they should be supplied * struct device and struct resource are "fake"; they should be supplied
...@@ -561,6 +563,8 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, ...@@ -561,6 +563,8 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
dev->res.name = dev->dev.bus_id; dev->res.name = dev->dev.bus_id;
dev->res.flags = IORESOURCE_MEM; dev->res.flags = IORESOURCE_MEM;
dev->mapbase = sachip->base + info->offset; dev->mapbase = sachip->base + info->offset;
dev->skpcr_mask = info->skpcr_mask;
memmove(dev->irq, info->irq, sizeof(dev->irq));
ret = request_resource(parent, &dev->res); ret = request_resource(parent, &dev->res);
if (ret) { if (ret) {
......
This diff is collapsed.
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);
......
...@@ -271,6 +271,20 @@ __syscall_start: ...@@ -271,6 +271,20 @@ __syscall_start:
.long sys_ni_syscall /* sys_set_thread_area */ .long sys_ni_syscall /* sys_set_thread_area */
/* 255 */ .long sys_ni_syscall /* sys_get_thread_area */ /* 255 */ .long sys_ni_syscall /* sys_get_thread_area */
.long sys_ni_syscall /* sys_set_tid_address */ .long sys_ni_syscall /* sys_set_tid_address */
.long sys_timer_create
.long sys_timer_settime
.long sys_timer_gettime
/* 260 */ .long sys_timer_getoverrun
.long sys_timer_delete
.long sys_clock_settime
.long sys_clock_gettime
.long sys_clock_getres
/* 265 */ .long sys_clock_nanosleep
.long sys_statfs64
.long sys_fstatfs64
.long sys_tgkill
.long sys_utimes
/* 270 */ .long sys_fadvise64_64
__syscall_end: __syscall_end:
.rept NR_syscalls - (__syscall_end - __syscall_start) / 4 .rept NR_syscalls - (__syscall_end - __syscall_start) / 4
......
/*
* 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 are 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 is worthless to compare with
@ divisor at this point since divisor can not be smaller than 3 here.
@ If possible, branch for another shift in the division loop.
@ If no bit position left then we are 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;
......
...@@ -33,7 +33,7 @@ static int pxa_set_rtc(void) ...@@ -33,7 +33,7 @@ static int pxa_set_rtc(void)
/* IRQs are disabled before entering here from do_gettimeofday() */ /* IRQs are disabled before entering here from do_gettimeofday() */
static unsigned long pxa_gettimeoffset (void) static unsigned long pxa_gettimeoffset (void)
{ {
unsigned long ticks_to_match, elapsed, usec; long ticks_to_match, elapsed, usec;
/* Get ticks before next timer match */ /* Get ticks before next timer match */
ticks_to_match = OSMR0 - OSCR; ticks_to_match = OSMR0 - OSCR;
...@@ -41,6 +41,10 @@ static unsigned long pxa_gettimeoffset (void) ...@@ -41,6 +41,10 @@ static unsigned long pxa_gettimeoffset (void)
/* We need elapsed ticks since last match */ /* We need elapsed ticks since last match */
elapsed = LATCH - ticks_to_match; elapsed = LATCH - ticks_to_match;
/* don't get fooled by the workaround in pxa_timer_interrupt() */
if (elapsed <= 0)
return 0;
/* Now convert them to usec */ /* Now convert them to usec */
usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH; usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
...@@ -59,6 +63,15 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -59,6 +63,15 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* IRQs are disabled inside the loop to ensure coherence between * IRQs are disabled inside the loop to ensure coherence between
* lost_ticks (updated in do_timer()) and the match reg value, so we * lost_ticks (updated in do_timer()) and the match reg value, so we
* can use do_gettimeofday() from interrupt handlers. * can use do_gettimeofday() from interrupt handlers.
*
* HACK ALERT: it seems that the PXA timer regs aren't updated right
* away in all cases when a write occurs. We therefore compare with
* 8 instead of 0 in the while() condition below to avoid missing a
* match if OSCR has already reached the next OSMR value.
* Experience has shown that up to 6 ticks are needed to work around
* this problem, but let's use 8 to be conservative. Note that this
* affect things only when the timer IRQ has been delayed by nearly
* exactly one tick period which should be a pretty rare event.
*/ */
do { do {
do_leds(); do_leds();
...@@ -66,16 +79,22 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -66,16 +79,22 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
do_timer(regs); do_timer(regs);
OSSR = OSSR_M0; /* Clear match on timer 0 */ OSSR = OSSR_M0; /* Clear match on timer 0 */
next_match = (OSMR0 += LATCH); next_match = (OSMR0 += LATCH);
} while( (signed long)(next_match - OSCR) <= 0 ); } while( (signed long)(next_match - OSCR) <= 8 );
return IRQ_HANDLED; return IRQ_HANDLED;
} }
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
...@@ -5,8 +5,21 @@ ...@@ -5,8 +5,21 @@
* This is the "bare minimum". AIO seems to require this. * This is the "bare minimum". AIO seems to require this.
*/ */
enum km_type { enum km_type {
KM_BOUNCE_READ,
KM_SKB_SUNRPC_DATA,
KM_SKB_DATA_SOFTIRQ,
KM_USER0,
KM_USER1,
KM_BIO_SRC_IRQ,
KM_BIO_DST_IRQ,
KM_PTE0,
KM_PTE1,
KM_PTE2,
KM_IRQ0, KM_IRQ0,
KM_USER1 KM_IRQ1,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
KM_TYPE_NR
}; };
#endif #endif
...@@ -159,7 +159,7 @@ static inline void __put_unaligned_8_be(const unsigned long long __v, register _ ...@@ -159,7 +159,7 @@ static inline void __put_unaligned_8_be(const unsigned long long __v, register _
(void) 0; \ (void) 0; \
}) })
#define put_unaligned_be(val,ptr) \ #define __put_unaligned_be(val,ptr) \
({ \ ({ \
switch (sizeof(*(ptr))) { \ switch (sizeof(*(ptr))) { \
case 1: \ case 1: \
......
...@@ -282,6 +282,20 @@ ...@@ -282,6 +282,20 @@
/* 254 for set_thread_area */ /* 254 for set_thread_area */
/* 255 for get_thread_area */ /* 255 for get_thread_area */
/* 256 for set_tid_address */ /* 256 for set_tid_address */
#define __NR_timer_create (__NR_SYSCALL_BASE+257)
#define __NR_timer_settime (__NR_SYSCALL_BASE+258)
#define __NR_timer_gettime (__NR_SYSCALL_BASE+259)
#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260)
#define __NR_timer_delete (__NR_SYSCALL_BASE+261)
#define __NR_clock_settime (__NR_SYSCALL_BASE+262)
#define __NR_clock_gettime (__NR_SYSCALL_BASE+263)
#define __NR_clock_getres (__NR_SYSCALL_BASE+264)
#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265)
#define __NR_statfs64 (__NR_SYSCALL_BASE+266)
#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267)
#define __NR_tgkill (__NR_SYSCALL_BASE+268)
#define __NR_utimes (__NR_SYSCALL_BASE+269)
#define __NR_fadvise64_64 (__NR_SYSCALL_BASE+270)
/* /*
* The following SWIs are ARM private. * The following SWIs are ARM private.
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#endif #endif
#define VIDC_SOUND_CLOCK (250000) #define VIDC_SOUND_CLOCK (250000)
#define VIDC_SOUND_CLOCK_EXT (176400)
/* /*
* When using SERIAL SOUND mode (external DAC), the number of physical * When using SERIAL SOUND mode (external DAC), the number of physical
...@@ -81,17 +82,9 @@ static unsigned char vidc_level_r[SOUND_MIXER_NRDEVICES] = { ...@@ -81,17 +82,9 @@ static unsigned char vidc_level_r[SOUND_MIXER_NRDEVICES] = {
static unsigned int vidc_audio_volume_l; /* left PCM vol, 0 - 65536 */ static unsigned int vidc_audio_volume_l; /* left PCM vol, 0 - 65536 */
static unsigned int vidc_audio_volume_r; /* right PCM vol, 0 - 65536 */ static unsigned int vidc_audio_volume_r; /* right PCM vol, 0 - 65536 */
static void (*old_mksound)(unsigned int hz, unsigned int ticks);
extern void (*kd_mksound)(unsigned int hz, unsigned int ticks);
extern void vidc_update_filler(int bits, int channels); extern void vidc_update_filler(int bits, int channels);
extern int softoss_dev; extern int softoss_dev;
static void
vidc_mksound(unsigned int hz, unsigned int ticks)
{
// printk("BEEP - %d %d!\n", hz, ticks);
}
static void static void
vidc_mixer_set(int mdev, unsigned int level) vidc_mixer_set(int mdev, unsigned int level)
{ {
...@@ -193,28 +186,50 @@ static unsigned int vidc_audio_set_format(int dev, unsigned int fmt) ...@@ -193,28 +186,50 @@ static unsigned int vidc_audio_set_format(int dev, unsigned int fmt)
return vidc_audio_format; return vidc_audio_format;
} }
#define my_abs(i) ((i)<0 ? -(i) : (i))
static int vidc_audio_set_speed(int dev, int rate) static int vidc_audio_set_speed(int dev, int rate)
{ {
if (rate) { if (rate) {
unsigned int hwctrl, hwrate; unsigned int hwctrl, hwrate, hwrate_ext, rate_int, rate_ext;
unsigned int diff_int, diff_ext;
unsigned int newsize, new2size; unsigned int newsize, new2size;
/* hwctrl = 0x00000003;
* If we have selected 44.1kHz, use the DAC clock.
*/ /* Using internal clock */
if (0 && rate == 44100) { hwrate = (((VIDC_SOUND_CLOCK * 2) / rate) + 1) >> 1;
hwctrl = 0x00000002; if (hwrate < 3)
hwrate = 3; hwrate = 3;
if (hwrate > 255)
hwrate = 255;
/* Using exernal clock */
hwrate_ext = (((VIDC_SOUND_CLOCK_EXT * 2) / rate) + 1) >> 1;
if (hwrate_ext < 3)
hwrate_ext = 3;
if (hwrate_ext > 255)
hwrate_ext = 255;
rate_int = VIDC_SOUND_CLOCK / hwrate;
rate_ext = VIDC_SOUND_CLOCK_EXT / hwrate_ext;
/* Chose between external and internal clock */
diff_int = my_abs(rate_ext-rate);
diff_ext = my_abs(rate_int-rate);
if (diff_ext < diff_int) {
/*printk("VIDC: external %d %d %d\n", rate, rate_ext, hwrate_ext);*/
hwrate=hwrate_ext;
hwctrl=0x00000002;
/* Allow roughly 0.4% tolerance */
if (diff_ext > (rate/256))
rate=rate_ext;
} else { } else {
hwctrl = 0x00000003; /*printk("VIDC: internal %d %d %d\n", rate, rate_int, hwrate);*/
hwctrl=0x00000003;
hwrate = (((VIDC_SOUND_CLOCK * 2) / rate) + 1) >> 1; /* Allow rougly 0.4% tolerance */
if (hwrate < 3) if (diff_int > (rate/256))
hwrate = 3; rate=rate_int;
if (hwrate > 255)
hwrate = 255;
rate = VIDC_SOUND_CLOCK / hwrate;
} }
vidc_writel(0xb0000000 | (hwrate - 2)); vidc_writel(0xb0000000 | (hwrate - 2));
...@@ -226,13 +241,14 @@ static int vidc_audio_set_speed(int dev, int rate) ...@@ -226,13 +241,14 @@ static int vidc_audio_set_speed(int dev, int rate)
if (newsize > 4096) if (newsize > 4096)
newsize = 4096; newsize = 4096;
for (new2size = 128; new2size < newsize; new2size <<= 1); for (new2size = 128; new2size < newsize; new2size <<= 1);
if (new2size - newsize > newsize - (new2size >> 1)) if (new2size - newsize > newsize - (new2size >> 1))
new2size >>= 1; new2size >>= 1;
if (new2size > 4096) { if (new2size > 4096) {
printk(KERN_ERR "VIDC: error: dma buffer (%d) %d > 4K\n", printk(KERN_ERR "VIDC: error: dma buffer (%d) %d > 4K\n",
newsize, new2size); newsize, new2size);
new2size = 4096; new2size = 4096;
} }
/*printk("VIDC: dma size %d\n", new2size);*/
dma_bufsize = new2size; dma_bufsize = new2size;
vidc_audio_rate = rate; vidc_audio_rate = rate;
} }
...@@ -471,8 +487,6 @@ static void __init attach_vidc(struct address_info *hw_config) ...@@ -471,8 +487,6 @@ static void __init attach_vidc(struct address_info *hw_config)
printk(KERN_ERR "%s: IRQ %d is in use\n", name, hw_config->irq); printk(KERN_ERR "%s: IRQ %d is in use\n", name, hw_config->irq);
goto irq_failed; goto irq_failed;
} }
old_mksound = kd_mksound;
kd_mksound = vidc_mksound;
vidc_adev = adev; vidc_adev = adev;
vidc_mixer_set(SOUND_MIXER_VOLUME, (85 | 85 << 8)); vidc_mixer_set(SOUND_MIXER_VOLUME, (85 | 85 << 8));
...@@ -510,9 +524,6 @@ static void __exit unload_vidc(struct address_info *hw_config) ...@@ -510,9 +524,6 @@ static void __exit unload_vidc(struct address_info *hw_config)
vidc_adev = -1; vidc_adev = -1;
if (old_mksound)
kd_mksound = old_mksound;
free_irq(hw_config->irq, &dma_start); free_irq(hw_config->irq, &dma_start);
sound_free_dma(hw_config->dma); sound_free_dma(hw_config->dma);
......
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