Commit cf17c020 authored by Dave Jones's avatar Dave Jones

Merge tetrachloride.(none):/mnt/raid/src/kernel/2.5/bk-linus

into tetrachloride.(none):/mnt/raid/src/kernel/2.5/agpgart
parents 30ffac45 f55ae64b
/* /*
* Copyright (C) 1995-2001 Russell King * Copyright (C) 1995-2003 Russell King
* 2001-2002 Keith Owens * 2001-2002 Keith Owens
* *
* Generate definitions needed by assembly language modules. * Generate definitions needed by assembly language modules.
...@@ -24,12 +24,21 @@ ...@@ -24,12 +24,21 @@
#if defined(__APCS_26__) #if defined(__APCS_26__)
#error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32 #error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32
#endif #endif
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95) /*
#error Sorry, your compiler is known to miscompile kernels. Only use gcc 2.95.3 and later. * GCC 2.95.1, 2.95.2: ignores register clobber list in asm().
#endif * GCC 3.0, 3.1: general bad code generation.
#if __GNUC__ == 2 && __GNUC_MINOR__ == 95 * GCC 3.2.0: incorrect function argument offset calculation.
/* shame we can't detect the .1 or .2 releases */ * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c
#warning GCC 2.95.2 and earlier miscompiles kernels. * (http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view&pr=8896)
*/
#if __GNUC__ < 2 || \
(__GNUC__ == 2 && __GNUC_MINOR__ < 95) || \
(__GNUC__ == 2 && __GNUC_MINOR__ == 95 && __GNUC_PATCHLEVEL__ != 0 && \
__GNUC_PATCHLEVEL__ < 3) || \
(__GNUC__ == 3 && __GNUC_MINOR__ < 2) || \
(__GNUC__ == 3 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ < 1)
#error Your compiler is too buggy; it is known to miscompile kernels.
#error Known good compilers: 2.95.3, 2.95.4, 2.96, 3.2.2+PR8896
#endif #endif
/* Use marker if you need to separate the values later */ /* Use marker if you need to separate the values later */
...@@ -62,7 +71,6 @@ int main(void) ...@@ -62,7 +71,6 @@ int main(void)
DEFINE(LPTE_EXEC, L_PTE_EXEC); DEFINE(LPTE_EXEC, L_PTE_EXEC);
DEFINE(LPTE_DIRTY, L_PTE_DIRTY); DEFINE(LPTE_DIRTY, L_PTE_DIRTY);
BLANK(); BLANK();
BLANK();
DEFINE(PAGE_SZ, PAGE_SIZE); DEFINE(PAGE_SZ, PAGE_SIZE);
BLANK(); BLANK();
DEFINE(SYS_ERROR0, 0x9f0000); DEFINE(SYS_ERROR0, 0x9f0000);
......
/* /*
* linux/arch/arm/lib/calls.h * linux/arch/arm/kernel/calls.S
* *
* Copyright (C) 1995-1998 Russell King * Copyright (C) 1995-2003 Russell King
* *
* 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
......
...@@ -621,7 +621,7 @@ ENTRY(anakin_active_irqs) ...@@ -621,7 +621,7 @@ ENTRY(anakin_active_irqs)
rsb \irqstat, \irqnr, #0 rsb \irqstat, \irqnr, #0
and \irqstat, \irqstat, \irqnr and \irqstat, \irqstat, \irqnr
clz \irqnr, \irqstat clz \irqnr, \irqstat
rsb \irqnr, \irqnr, #23 rsb \irqnr, \irqnr, #(31 - PXA_IRQ_SKIP)
1001: 1001:
.endm .endm
......
...@@ -58,6 +58,11 @@ void dummy_mask_unmask_irq(unsigned int irq) ...@@ -58,6 +58,11 @@ void dummy_mask_unmask_irq(unsigned int irq)
{ {
} }
irqreturn_t no_action(int irq, void *dev_id, struct pt_regs *regs)
{
return IRQ_NONE;
}
void do_bad_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) void do_bad_IRQ(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs)
{ {
irq_err_count += 1; irq_err_count += 1;
...@@ -222,6 +227,7 @@ static void ...@@ -222,6 +227,7 @@ static void
__do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs) __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
{ {
unsigned int status; unsigned int status;
int retval = 0;
spin_unlock(&irq_controller_lock); spin_unlock(&irq_controller_lock);
...@@ -231,7 +237,7 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs) ...@@ -231,7 +237,7 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
status = 0; status = 0;
do { do {
status |= action->flags; status |= action->flags;
action->handler(irq, action->dev_id, regs); retval |= action->handler(irq, action->dev_id, regs);
action = action->next; action = action->next;
} while (action); } while (action);
...@@ -239,6 +245,19 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs) ...@@ -239,6 +245,19 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
add_interrupt_randomness(irq); add_interrupt_randomness(irq);
spin_lock_irq(&irq_controller_lock); spin_lock_irq(&irq_controller_lock);
if (retval != 1) {
static int count = 100;
if (count) {
count--;
if (retval) {
printk("irq event %d: bogus retval mask %x\n",
irq, retval);
} else {
printk("irq %d: nobody cared\n", irq);
}
}
}
} }
/* /*
...@@ -606,7 +625,7 @@ int setup_irq(unsigned int irq, struct irqaction *new) ...@@ -606,7 +625,7 @@ int setup_irq(unsigned int irq, struct irqaction *new)
* SA_SAMPLE_RANDOM The interrupt can be used for entropy * SA_SAMPLE_RANDOM The interrupt can be used for entropy
* *
*/ */
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long irq_flags, const char * devname, void *dev_id) unsigned long irq_flags, const char * devname, void *dev_id)
{ {
unsigned long retval; unsigned long retval;
......
...@@ -16,10 +16,18 @@ ...@@ -16,10 +16,18 @@
#include <asm/leds.h> #include <asm/leds.h>
#include <asm/system.h> #include <asm/system.h>
/*
* Tell the linker that pm_do_suspend may not be present.
*/
extern int pm_do_suspend(void) __attribute__((weak));
int suspend(void) int suspend(void)
{ {
int ret; int ret;
if (!pm_do_suspend)
return -ENOSYS;
/* /*
* Suspend "legacy" devices. * Suspend "legacy" devices.
*/ */
...@@ -82,9 +90,26 @@ int suspend(void) ...@@ -82,9 +90,26 @@ int suspend(void)
} }
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
/*
* We really want this to die. It's a disgusting hack using unallocated
* sysctl numbers. We should be using a real interface.
*/
#include <linux/init.h> #include <linux/init.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
static int
pm_sysctl_proc_handler(ctl_table *ctl, int write, struct file *filp,
void *buffer, size_t *lenp)
{
int ret = -EIO;
printk("PM: task %s (pid %d) uses deprecated sysctl PM interface\n",
current->comm, current->pid);
if (write)
ret = suspend();
return ret;
}
/* /*
* This came from arch/arm/mach-sa1100/pm.c: * This came from arch/arm/mach-sa1100/pm.c:
* Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
...@@ -102,13 +127,23 @@ int suspend(void) ...@@ -102,13 +127,23 @@ int suspend(void)
static struct ctl_table pm_table[] = static struct ctl_table pm_table[] =
{ {
{ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, (proc_handler *)&suspend}, {
.ctl_name = ACPI_S1_SLP_TYP,
.procname = "suspend",
.mode = 0200,
.proc_handler = pm_sysctl_proc_handler,
},
{0} {0}
}; };
static struct ctl_table pm_dir_table[] = static struct ctl_table pm_dir_table[] =
{ {
{CTL_ACPI, "pm", NULL, 0, 0555, pm_table}, {
.ctl_name = CTL_ACPI,
.procname = "pm",
.mode = 0555,
.child = pm_table,
},
{0} {0}
}; };
......
...@@ -18,10 +18,12 @@ ...@@ -18,10 +18,12 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/user.h> #include <linux/user.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/init.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/traps.h>
#include "ptrace.h" #include "ptrace.h"
...@@ -32,7 +34,7 @@ ...@@ -32,7 +34,7 @@
* in exit.c or in signal.c. * in exit.c or in signal.c.
*/ */
#if 1 #if 0
/* /*
* Breakpoint SWI instruction: SWI &9F0001 * Breakpoint SWI instruction: SWI &9F0001
*/ */
...@@ -479,25 +481,47 @@ void ptrace_break(struct task_struct *tsk, struct pt_regs *regs) ...@@ -479,25 +481,47 @@ void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
{ {
siginfo_t info; siginfo_t info;
/*
* The PC is always left pointing at the next instruction. Fix this.
*/
regs->ARM_pc -= 4;
if (tsk->thread.debug.nsaved == 0)
printk(KERN_ERR "ptrace: bogus breakpoint trap\n");
ptrace_cancel_bpt(tsk); ptrace_cancel_bpt(tsk);
info.si_signo = SIGTRAP; info.si_signo = SIGTRAP;
info.si_errno = 0; info.si_errno = 0;
info.si_code = TRAP_BRKPT; info.si_code = TRAP_BRKPT;
info.si_addr = (void *)instruction_pointer(regs) - info.si_addr = (void *)instruction_pointer(regs);
(thumb_mode(regs) ? 2 : 4);
force_sig_info(SIGTRAP, &info, tsk); force_sig_info(SIGTRAP, &info, tsk);
} }
static int break_trap(struct pt_regs *regs, unsigned int instr)
{
ptrace_break(current, regs);
return 0;
}
static struct undef_hook arm_break_hook = {
.instr_mask = 0x0fffffff,
.instr_val = 0x07f001f0,
.cpsr_mask = PSR_T_BIT,
.cpsr_val = 0,
.fn = break_trap,
};
static struct undef_hook thumb_break_hook = {
.instr_mask = 0xffff,
.instr_val = 0xde01,
.cpsr_mask = PSR_T_BIT,
.cpsr_val = PSR_T_BIT,
.fn = break_trap,
};
static int __init ptrace_break_init(void)
{
register_undef_hook(&arm_break_hook);
register_undef_hook(&thumb_break_hook);
return 0;
}
core_initcall(ptrace_break_init);
/* /*
* Read the word at offset "off" into the "struct user". We * Read the word at offset "off" into the "struct user". We
* actually access the pt_regs stored on the kernel stack. * actually access the pt_regs stored on the kernel stack.
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include <asm/semaphore.h> #include <asm/traps.h>
#include "ptrace.h" #include "ptrace.h"
...@@ -240,17 +240,56 @@ void die_if_kernel(const char *str, struct pt_regs *regs, int err) ...@@ -240,17 +240,56 @@ void die_if_kernel(const char *str, struct pt_regs *regs, int err)
die(str, regs, err); die(str, regs, err);
} }
static LIST_HEAD(undef_hook);
static spinlock_t undef_lock = SPIN_LOCK_UNLOCKED;
void register_undef_hook(struct undef_hook *hook)
{
spin_lock_irq(&undef_lock);
list_add(&hook->node, &undef_hook);
spin_unlock_irq(&undef_lock);
}
void unregister_undef_hook(struct undef_hook *hook)
{
spin_lock_irq(&undef_lock);
list_del(&hook->node);
spin_unlock_irq(&undef_lock);
}
asmlinkage void do_undefinstr(struct pt_regs *regs) asmlinkage void do_undefinstr(struct pt_regs *regs)
{ {
unsigned long *pc; unsigned int correction = thumb_mode(regs) ? 2 : 4;
unsigned int instr;
struct undef_hook *hook;
siginfo_t info; siginfo_t info;
void *pc;
/* /*
* According to the ARM ARM, PC is 2 or 4 bytes ahead, depending * According to the ARM ARM, PC is 2 or 4 bytes ahead,
* whether we're in Thumb mode or not. * depending whether we're in Thumb mode or not.
* Correct this offset.
*/ */
regs->ARM_pc -= thumb_mode(regs) ? 2 : 4; regs->ARM_pc -= correction;
pc = (unsigned long *)instruction_pointer(regs);
pc = (void *)instruction_pointer(regs);
if (thumb_mode(regs)) {
get_user(instr, (u16 *)pc);
} else {
get_user(instr, (u32 *)pc);
}
spin_lock_irq(&undef_lock);
list_for_each_entry(hook, &undef_hook, node) {
if ((instr & hook->instr_mask) == hook->instr_val &&
(regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) {
if (hook->fn(regs, instr) == 0) {
spin_unlock_irq(&undef_lock);
return;
}
}
}
spin_unlock_irq(&undef_lock);
#ifdef CONFIG_DEBUG_USER #ifdef CONFIG_DEBUG_USER
printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
...@@ -377,6 +416,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) ...@@ -377,6 +416,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
return 0; return 0;
case NR(breakpoint): /* SWI BREAK_POINT */ case NR(breakpoint): /* SWI BREAK_POINT */
regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
ptrace_break(current, regs); ptrace_break(current, regs);
return regs->ARM_r0; return regs->ARM_r0;
......
...@@ -13,11 +13,7 @@ ...@@ -13,11 +13,7 @@
#include <asm/assembler.h> #include <asm/assembler.h>
#include <asm/constants.h> #include <asm/constants.h>
#ifndef PLD #define COPY_COUNT (PAGE_SZ/64 PLD( -1 ))
#define COPY_COUNT PAGE_SZ/64
#else
#define COPY_COUNT PAGE_SZ/64-1
#endif
.text .text
.align 5 .align 5
......
...@@ -65,7 +65,7 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where, ...@@ -65,7 +65,7 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 *value) int size, u32 *value)
{ {
unsigned long addr = dc21285_base_address(bus, devfn); unsigned long addr = dc21285_base_address(bus, devfn);
u32 v; u32 v = 0xffffffff;
if (addr) if (addr)
switch (size) { switch (size) {
...@@ -82,8 +82,6 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where, ...@@ -82,8 +82,6 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where,
: "=r" (v) : "r" (addr), "r" (where)); : "=r" (v) : "r" (addr), "r" (where));
break; break;
} }
else
v = 0xffffffff;
*value = v; *value = v;
...@@ -154,7 +152,7 @@ static void dc21285_enable_error(unsigned long __data) ...@@ -154,7 +152,7 @@ static void dc21285_enable_error(unsigned long __data)
/* /*
* Warn on PCI errors. * Warn on PCI errors.
*/ */
static void dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs)
{ {
unsigned int cmd; unsigned int cmd;
unsigned int status; unsigned int status;
...@@ -180,9 +178,11 @@ static void dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -180,9 +178,11 @@ static void dc21285_abort_irq(int irq, void *dev_id, struct pt_regs *regs)
} }
*CSR_PCICMD = cmd; *CSR_PCICMD = cmd;
return IRQ_HANDLED;
} }
static void dc21285_serr_irq(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t dc21285_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct timer_list *timer = dev_id; struct timer_list *timer = dev_id;
unsigned int cntl; unsigned int cntl;
...@@ -200,15 +200,19 @@ static void dc21285_serr_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -200,15 +200,19 @@ static void dc21285_serr_irq(int irq, void *dev_id, struct pt_regs *regs)
disable_irq(irq); disable_irq(irq);
timer->expires = jiffies + HZ; timer->expires = jiffies + HZ;
add_timer(timer); add_timer(timer);
return IRQ_HANDLED;
} }
static void dc21285_discard_irq(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t dc21285_discard_irq(int irq, void *dev_id, struct pt_regs *regs)
{ {
printk(KERN_DEBUG "PCI: discard timer expired\n"); printk(KERN_DEBUG "PCI: discard timer expired\n");
*CSR_SA110_CNTL &= 0xffffde07; *CSR_SA110_CNTL &= 0xffffde07;
return IRQ_HANDLED;
} }
static void dc21285_dparity_irq(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t dc21285_dparity_irq(int irq, void *dev_id, struct pt_regs *regs)
{ {
unsigned int cmd; unsigned int cmd;
...@@ -218,9 +222,11 @@ static void dc21285_dparity_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -218,9 +222,11 @@ static void dc21285_dparity_irq(int irq, void *dev_id, struct pt_regs *regs)
cmd = *CSR_PCICMD & 0xffff; cmd = *CSR_PCICMD & 0xffff;
*CSR_PCICMD = cmd | 1 << 24; *CSR_PCICMD = cmd | 1 << 24;
return IRQ_HANDLED;
} }
static void dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct timer_list *timer = dev_id; struct timer_list *timer = dev_id;
unsigned int cmd; unsigned int cmd;
...@@ -238,6 +244,8 @@ static void dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -238,6 +244,8 @@ static void dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs)
disable_irq(irq); disable_irq(irq);
timer->expires = jiffies + HZ; timer->expires = jiffies + HZ;
add_timer(timer); add_timer(timer);
return IRQ_HANDLED;
} }
int __init dc21285_setup(int nr, struct pci_sys_data *sys) int __init dc21285_setup(int nr, struct pci_sys_data *sys)
......
...@@ -43,8 +43,6 @@ ...@@ -43,8 +43,6 @@
* f1500000 15000000 RTC * f1500000 15000000 RTC
* f1600000 16000000 UART 0 * f1600000 16000000 UART 0
* f1700000 17000000 UART 1 * f1700000 17000000 UART 1
* f1800000 18000000 Keyboard
* f1900000 19000000 Mouse
* f1a00000 1a000000 Debug LEDs * f1a00000 1a000000 Debug LEDs
* f1b00000 1b000000 GPIO * f1b00000 1b000000 GPIO
*/ */
...@@ -58,8 +56,6 @@ static struct map_desc integrator_io_desc[] __initdata = { ...@@ -58,8 +56,6 @@ static struct map_desc integrator_io_desc[] __initdata = {
{ IO_ADDRESS(INTEGRATOR_RTC_BASE), INTEGRATOR_RTC_BASE, SZ_4K, MT_DEVICE }, { IO_ADDRESS(INTEGRATOR_RTC_BASE), INTEGRATOR_RTC_BASE, SZ_4K, MT_DEVICE },
{ IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE }, { IO_ADDRESS(INTEGRATOR_UART0_BASE), INTEGRATOR_UART0_BASE, SZ_4K, MT_DEVICE },
{ IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE }, { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE },
{ IO_ADDRESS(INTEGRATOR_KBD_BASE), INTEGRATOR_KBD_BASE, SZ_4K, MT_DEVICE },
{ IO_ADDRESS(INTEGRATOR_MOUSE_BASE), INTEGRATOR_MOUSE_BASE, SZ_4K, MT_DEVICE },
{ IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE }, { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE },
{ IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE }, { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE },
{ PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M, MT_DEVICE }, { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M, MT_DEVICE },
......
...@@ -50,9 +50,9 @@ static struct irqchip pxa_internal_chip = { ...@@ -50,9 +50,9 @@ static struct irqchip pxa_internal_chip = {
* Use this instead of directly setting GRER/GFER. * Use this instead of directly setting GRER/GFER.
*/ */
static int GPIO_IRQ_rising_edge[3]; static long GPIO_IRQ_rising_edge[3];
static int GPIO_IRQ_falling_edge[3]; static long GPIO_IRQ_falling_edge[3];
static int GPIO_IRQ_mask[3]; static long GPIO_IRQ_mask[3];
static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
{ {
...@@ -189,7 +189,6 @@ static struct irqchip pxa_muxed_gpio_chip = { ...@@ -189,7 +189,6 @@ static struct irqchip pxa_muxed_gpio_chip = {
.ack = pxa_ack_muxed_gpio, .ack = pxa_ack_muxed_gpio,
.mask = pxa_mask_muxed_gpio, .mask = pxa_mask_muxed_gpio,
.unmask = pxa_unmask_muxed_gpio, .unmask = pxa_unmask_muxed_gpio,
.rerun = pxa_manual_rerun,
.type = pxa_gpio_irq_type, .type = pxa_gpio_irq_type,
}; };
...@@ -217,21 +216,18 @@ void __init pxa_init_irq(void) ...@@ -217,21 +216,18 @@ void __init pxa_init_irq(void)
/* GPIO 0 and 1 must have their mask bit always set */ /* GPIO 0 and 1 must have their mask bit always set */
GPIO_IRQ_mask[0] = 3; GPIO_IRQ_mask[0] = 3;
for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) {
set_irq_chip(irq, &pxa_internal_chip);
set_irq_handler(irq, do_level_IRQ);
set_irq_flags(irq, IRQF_VALID);
}
for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) { for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
set_irq_chip(irq, &pxa_low_gpio_chip); set_irq_chip(irq, &pxa_low_gpio_chip);
set_irq_handler(irq, do_edge_IRQ); set_irq_handler(irq, do_edge_IRQ);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
} }
for (irq = PXA_IRQ(11); irq <= PXA_IRQ(31); irq++) {
set_irq_chip(irq, &pxa_internal_chip);
set_irq_handler(irq, do_level_IRQ);
set_irq_flags(irq, IRQF_VALID);
}
/* Those are reserved */
set_irq_flags(PXA_IRQ(15), 0);
set_irq_flags(PXA_IRQ(16), 0);
for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(80); irq++) { for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(80); irq++) {
set_irq_chip(irq, &pxa_muxed_gpio_chip); set_irq_chip(irq, &pxa_muxed_gpio_chip);
set_irq_handler(irq, do_edge_IRQ); set_irq_handler(irq, do_edge_IRQ);
......
...@@ -33,57 +33,41 @@ ...@@ -33,57 +33,41 @@
#include "generic.h" #include "generic.h"
static void lubbock_ack_irq(unsigned int irq)
{ static unsigned long lubbock_irq_enabled;
int lubbock_irq = (irq - LUBBOCK_IRQ(0));
LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq);
}
static void lubbock_mask_irq(unsigned int irq) static void lubbock_mask_irq(unsigned int irq)
{ {
int lubbock_irq = (irq - LUBBOCK_IRQ(0)); int lubbock_irq = (irq - LUBBOCK_IRQ(0));
LUB_IRQ_MASK_EN &= ~(1 << lubbock_irq); LUB_IRQ_MASK_EN = (lubbock_irq_enabled &= ~(1 << lubbock_irq));
} }
static void lubbock_unmask_irq(unsigned int irq) static void lubbock_unmask_irq(unsigned int irq)
{ {
int lubbock_irq = (irq - LUBBOCK_IRQ(0)); int lubbock_irq = (irq - LUBBOCK_IRQ(0));
LUB_IRQ_MASK_EN |= (1 << lubbock_irq); /* the irq can be acknowledged only if deasserted, so it's done here */
LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq);
LUB_IRQ_MASK_EN = (lubbock_irq_enabled |= (1 << lubbock_irq));
} }
static struct irqchip lubbock_irq_chip = { static struct irqchip lubbock_irq_chip = {
.ack = lubbock_ack_irq, .ack = lubbock_mask_irq,
.mask = lubbock_mask_irq, .mask = lubbock_mask_irq,
.unmask = lubbock_unmask_irq, .unmask = lubbock_unmask_irq,
}; };
void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc, static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc,
struct pt_regs *regs) struct pt_regs *regs)
{ {
unsigned int enabled, pending; unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
/* get active pending irq mask */
enabled = LUB_IRQ_MASK_EN & 0x003f;
pending = LUB_IRQ_SET_CLR & enabled;
do { do {
//printk("%s a: set_clr %#x, mask_en %#x LR/DR %d/%d\n", __FUNCTION__, LUB_IRQ_SET_CLR, LUB_IRQ_MASK_EN, GPLR(0)&1, GEDR(0)&1 ); GEDR(0) = GPIO_bit(0); /* clear our parent irq */
/* clear our parent irq */ if (likely(pending)) {
GEDR(0) = GPIO_bit(0); irq = LUBBOCK_IRQ(0) + __ffs(pending);
desc = irq_desc + irq;
/* process them */ desc->handle(irq, desc, regs);
irq = LUBBOCK_IRQ(0); }
desc = irq_desc + irq; pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
do {
if (pending & 1)
desc->handle(irq, desc, regs);
irq++;
desc++;
pending >>= 1;
} while (pending);
//printk("%s b: set_clr %#x, mask_en %#x LR/DR %d/%d\n", __FUNCTION__, LUB_IRQ_SET_CLR, LUB_IRQ_MASK_EN, GPLR(0)&1, GEDR(0)&1 );
enabled = LUB_IRQ_MASK_EN & 0x003f;
pending = LUB_IRQ_SET_CLR & enabled;
} while (pending); } while (pending);
} }
......
...@@ -83,7 +83,7 @@ static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma) ...@@ -83,7 +83,7 @@ static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma)
sg->length |= flags; sg->length |= flags;
} }
static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
{ {
dma_t *dma = (dma_t *)dev_id; dma_t *dma = (dma_t *)dev_id;
unsigned long base = dma->dma_base; unsigned long base = dma->dma_base;
...@@ -93,7 +93,7 @@ static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs) ...@@ -93,7 +93,7 @@ static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
status = iomd_readb(base + ST); status = iomd_readb(base + ST);
if (!(status & DMA_ST_INT)) if (!(status & DMA_ST_INT))
return; return IRQ_HANDLED;
if (status & DMA_ST_OFL && !dma->sg) if (status & DMA_ST_OFL && !dma->sg)
break; break;
...@@ -117,6 +117,8 @@ static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs) ...@@ -117,6 +117,8 @@ static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
iomd_writeb(0, dma->dma_base + CR); iomd_writeb(0, dma->dma_base + CR);
disable_irq(irq); disable_irq(irq);
return IRQ_HANDLED;
} }
static int iomd_request_dma(dmach_t channel, dma_t *dma) static int iomd_request_dma(dmach_t channel, dma_t *dma)
......
...@@ -330,7 +330,7 @@ static int __init consistent_init(void) ...@@ -330,7 +330,7 @@ static int __init consistent_init(void)
core_initcall(consistent_init); core_initcall(consistent_init);
/* /*
* make an area consistent for devices. * Make an area consistent for devices.
*/ */
void consistent_sync(void *vaddr, size_t size, int direction) void consistent_sync(void *vaddr, size_t size, int direction)
{ {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# To add an entry into this database, please see Documentation/arm/README, # To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk # or contact rmk@arm.linux.org.uk
# #
# Last update: Sat Apr 26 11:41:41 2003 # Last update: Wed May 7 23:43:08 2003
# #
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
# #
...@@ -328,3 +328,14 @@ m7100 SA1100_M7100 M7100 316 ...@@ -328,3 +328,14 @@ m7100 SA1100_M7100 M7100 316
nipc2 ARCH_NIPC2 NIPC2 317 nipc2 ARCH_NIPC2 NIPC2 317
fu7202 ARCH_FU7202 FU7202 318 fu7202 ARCH_FU7202 FU7202 318
adsagx ARCH_ADSAGX ADSAGX 319 adsagx ARCH_ADSAGX ADSAGX 319
pxa_pooh ARCH_PXA_POOH PXA_POOH 320
bandon ARCH_BANDON BANDON 321
pcm7210 ARCH_PCM7210 PCM7210 322
nms9200 ARCH_NMS9200 NMS9200 323
gealog ARCH_GEALOG GEALOG 324
m7140 SA1100_M7140 M7140 325
korebot ARCH_KOREBOT KOREBOT 326
iq31244 ARCH_IQ31244 IQ31244 327
koan393 SA1100_KOAN393 KOAN393 328
inhandftip3 ARCH_INHANDFTIP3 INHANDFTIP3 329
gonzo ARCH_GONZO GONZO 330
...@@ -68,7 +68,7 @@ static unsigned int net_debug = NET_DEBUG; ...@@ -68,7 +68,7 @@ static unsigned int net_debug = NET_DEBUG;
static int ether1_open(struct net_device *dev); static int ether1_open(struct net_device *dev);
static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev); static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev);
static void ether1_interrupt(int irq, void *dev_id, struct pt_regs *regs); static irqreturn_t ether1_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static int ether1_close(struct net_device *dev); static int ether1_close(struct net_device *dev);
static struct net_device_stats *ether1_getstats(struct net_device *dev); static struct net_device_stats *ether1_getstats(struct net_device *dev);
static void ether1_setmulticastlist(struct net_device *dev); static void ether1_setmulticastlist(struct net_device *dev);
...@@ -908,7 +908,7 @@ ether1_recv_done (struct net_device *dev) ...@@ -908,7 +908,7 @@ ether1_recv_done (struct net_device *dev)
} while (1); } while (1);
} }
static void static irqreturn_t
ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs) ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs)
{ {
struct net_device *dev = (struct net_device *)dev_id; struct net_device *dev = (struct net_device *)dev_id;
...@@ -953,7 +953,9 @@ ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs) ...@@ -953,7 +953,9 @@ ether1_interrupt (int irq, void *dev_id, struct pt_regs *regs)
NORMALIRQS)); NORMALIRQS));
} }
} else } else
outb (CTRL_ACK, REG_CONTROL); outb (CTRL_ACK, REG_CONTROL);
return IRQ_HANDLED;
} }
static int static int
......
...@@ -82,7 +82,7 @@ static int ether3_rx(struct net_device *dev, struct dev_priv *priv, unsigned int ...@@ -82,7 +82,7 @@ static int ether3_rx(struct net_device *dev, struct dev_priv *priv, unsigned int
static void ether3_tx(struct net_device *dev, struct dev_priv *priv); static void ether3_tx(struct net_device *dev, struct dev_priv *priv);
static int ether3_open (struct net_device *dev); static int ether3_open (struct net_device *dev);
static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev); static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev);
static void ether3_interrupt (int irq, void *dev_id, struct pt_regs *regs); static irqreturn_t ether3_interrupt (int irq, void *dev_id, struct pt_regs *regs);
static int ether3_close (struct net_device *dev); static int ether3_close (struct net_device *dev);
static struct net_device_stats *ether3_getstats (struct net_device *dev); static struct net_device_stats *ether3_getstats (struct net_device *dev);
static void ether3_setmulticastlist (struct net_device *dev); static void ether3_setmulticastlist (struct net_device *dev);
...@@ -576,12 +576,12 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev) ...@@ -576,12 +576,12 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
return 0; return 0;
} }
static void static irqreturn_t
ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs) ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct net_device *dev = (struct net_device *)dev_id; struct net_device *dev = (struct net_device *)dev_id;
struct dev_priv *priv; struct dev_priv *priv;
unsigned int status; unsigned int status, handled = IRQ_NONE;
#if NET_DEBUG > 1 #if NET_DEBUG > 1
if(net_debug & DEBUG_INT) if(net_debug & DEBUG_INT)
...@@ -595,17 +595,20 @@ ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -595,17 +595,20 @@ ether3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (status & STAT_INTRX) { if (status & STAT_INTRX) {
ether3_outw(CMD_ACKINTRX | priv->regs.command, REG_COMMAND); ether3_outw(CMD_ACKINTRX | priv->regs.command, REG_COMMAND);
ether3_rx(dev, priv, 12); ether3_rx(dev, priv, 12);
handled = IRQ_HANDLED;
} }
if (status & STAT_INTTX) { if (status & STAT_INTTX) {
ether3_outw(CMD_ACKINTTX | priv->regs.command, REG_COMMAND); ether3_outw(CMD_ACKINTTX | priv->regs.command, REG_COMMAND);
ether3_tx(dev, priv); ether3_tx(dev, priv);
handled = IRQ_HANDLED;
} }
#if NET_DEBUG > 1 #if NET_DEBUG > 1
if(net_debug & DEBUG_INT) if(net_debug & DEBUG_INT)
printk("done\n"); printk("done\n");
#endif #endif
return handled;
} }
/* /*
......
...@@ -2466,18 +2466,14 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) ...@@ -2466,18 +2466,14 @@ intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq)
* dev_id - device specific data (AS_Host structure) * dev_id - device specific data (AS_Host structure)
* regs - processor registers when interrupt occurred * regs - processor registers when interrupt occurred
*/ */
static static irqreturn_t
void acornscsi_intr(int irq, void *dev_id, struct pt_regs *regs) acornscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
{ {
AS_Host *host = (AS_Host *)dev_id; AS_Host *host = (AS_Host *)dev_id;
intr_ret_t ret; intr_ret_t ret;
int iostatus; int iostatus;
int in_irq = 0; int in_irq = 0;
if (host->scsi.interrupt)
printk("scsi%d: interrupt re-entered\n", host->host->host_no);
host->scsi.interrupt = 1;
do { do {
ret = INTR_IDLE; ret = INTR_IDLE;
...@@ -2505,7 +2501,7 @@ void acornscsi_intr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -2505,7 +2501,7 @@ void acornscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
in_irq = 1; in_irq = 1;
} while (ret != INTR_IDLE); } while (ret != INTR_IDLE);
host->scsi.interrupt = 0; return IRQ_HANDLED;
} }
/*============================================================================================= /*=============================================================================================
......
...@@ -141,12 +141,12 @@ cumanascsi_2_terminator_ctl(struct Scsi_Host *host, int on_off) ...@@ -141,12 +141,12 @@ cumanascsi_2_terminator_ctl(struct Scsi_Host *host, int on_off)
* dev_id - user-defined (Scsi_Host structure) * dev_id - user-defined (Scsi_Host structure)
* regs - processor registers at interrupt * regs - processor registers at interrupt
*/ */
static void static irqreturn_t
cumanascsi_2_intr(int irq, void *dev_id, struct pt_regs *regs) cumanascsi_2_intr(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct cumanascsi2_info *info = dev_id; struct cumanascsi2_info *info = dev_id;
fas216_intr(&info->info); return fas216_intr(&info->info);
} }
/* Prototype: fasdmatype_t cumanascsi_2_dma_setup(host, SCpnt, direction, min_type) /* Prototype: fasdmatype_t cumanascsi_2_dma_setup(host, SCpnt, direction, min_type)
......
...@@ -141,12 +141,12 @@ eesoxscsi_terminator_ctl(struct Scsi_Host *host, int on_off) ...@@ -141,12 +141,12 @@ eesoxscsi_terminator_ctl(struct Scsi_Host *host, int on_off)
* dev_id - user-defined (Scsi_Host structure) * dev_id - user-defined (Scsi_Host structure)
* regs - processor registers at interrupt * regs - processor registers at interrupt
*/ */
static void static irqreturn_t
eesoxscsi_intr(int irq, void *dev_id, struct pt_regs *regs) eesoxscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct eesoxscsi_info *info = dev_id; struct eesoxscsi_info *info = dev_id;
fas216_intr(&info->info); return fas216_intr(&info->info);
} }
/* Prototype: fasdmatype_t eesoxscsi_dma_setup(host, SCpnt, direction, min_type) /* Prototype: fasdmatype_t eesoxscsi_dma_setup(host, SCpnt, direction, min_type)
......
...@@ -1824,9 +1824,10 @@ static void fas216_bus_reset(FAS216_Info *info) ...@@ -1824,9 +1824,10 @@ static void fas216_bus_reset(FAS216_Info *info)
* *
* Handle interrupts from the interface to progress a command * Handle interrupts from the interface to progress a command
*/ */
void fas216_intr(FAS216_Info *info) irqreturn_t fas216_intr(FAS216_Info *info)
{ {
unsigned char isr, ssr, stat; unsigned char isr, ssr, stat;
int handled = IRQ_NONE;
fas216_checkmagic(info); fas216_checkmagic(info);
...@@ -1857,7 +1858,9 @@ void fas216_intr(FAS216_Info *info) ...@@ -1857,7 +1858,9 @@ void fas216_intr(FAS216_Info *info)
fas216_log(info, 0, "unknown interrupt received:" fas216_log(info, 0, "unknown interrupt received:"
" phase %s isr %02X ssr %02X stat %02X", " phase %s isr %02X ssr %02X stat %02X",
fas216_drv_phase(info), isr, ssr, stat); fas216_drv_phase(info), isr, ssr, stat);
handled = IRQ_HANDLED;
} }
return handled;
} }
static void __fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt) static void __fas216_start_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
......
...@@ -351,11 +351,11 @@ extern int fas216_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); ...@@ -351,11 +351,11 @@ extern int fas216_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
*/ */
extern int fas216_command (Scsi_Cmnd *); extern int fas216_command (Scsi_Cmnd *);
/* Function: void fas216_intr (FAS216_Info *info) /* Function: irqreturn_t fas216_intr (FAS216_Info *info)
* Purpose : handle interrupts from the interface to progress a command * Purpose : handle interrupts from the interface to progress a command
* Params : info - interface to service * Params : info - interface to service
*/ */
extern void fas216_intr (FAS216_Info *info); extern irqreturn_t fas216_intr (FAS216_Info *info);
extern void fas216_remove (struct Scsi_Host *instance); extern void fas216_remove (struct Scsi_Host *instance);
......
...@@ -113,12 +113,12 @@ powertecscsi_terminator_ctl(struct Scsi_Host *host, int on_off) ...@@ -113,12 +113,12 @@ powertecscsi_terminator_ctl(struct Scsi_Host *host, int on_off)
* dev_id - user-defined (Scsi_Host structure) * dev_id - user-defined (Scsi_Host structure)
* regs - processor registers at interrupt * regs - processor registers at interrupt
*/ */
static void static irqreturn_t
powertecscsi_intr(int irq, void *dev_id, struct pt_regs *regs) powertecscsi_intr(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct powertec_info *info = dev_id; struct powertec_info *info = dev_id;
fas216_intr(&info->info); return fas216_intr(&info->info);
} }
/* Prototype: fasdmatype_t powertecscsi_dma_setup(host, SCpnt, direction, min_type) /* Prototype: fasdmatype_t powertecscsi_dma_setup(host, SCpnt, direction, min_type)
......
...@@ -1616,7 +1616,8 @@ static int __make_request(request_queue_t *q, struct bio *bio) ...@@ -1616,7 +1616,8 @@ static int __make_request(request_queue_t *q, struct bio *bio)
sector = bio->bi_sector; sector = bio->bi_sector;
nr_sectors = bio_sectors(bio); nr_sectors = bio_sectors(bio);
cur_nr_sectors = bio_iovec(bio)->bv_len >> 9; cur_nr_sectors = bio_cur_sectors(bio);
rw = bio_data_dir(bio); rw = bio_data_dir(bio);
/* /*
...@@ -1672,7 +1673,10 @@ static int __make_request(request_queue_t *q, struct bio *bio) ...@@ -1672,7 +1673,10 @@ static int __make_request(request_queue_t *q, struct bio *bio)
} }
bio->bi_next = req->bio; bio->bi_next = req->bio;
req->bio = bio; req->cbio = req->bio = bio;
req->nr_cbio_segments = bio_segments(bio);
req->nr_cbio_sectors = bio_sectors(bio);
/* /*
* may not be valid. if the low level driver said * may not be valid. if the low level driver said
* it didn't need a bounce buffer then it better * it didn't need a bounce buffer then it better
...@@ -1740,9 +1744,11 @@ static int __make_request(request_queue_t *q, struct bio *bio) ...@@ -1740,9 +1744,11 @@ static int __make_request(request_queue_t *q, struct bio *bio)
req->current_nr_sectors = req->hard_cur_sectors = cur_nr_sectors; req->current_nr_sectors = req->hard_cur_sectors = cur_nr_sectors;
req->nr_phys_segments = bio_phys_segments(q, bio); req->nr_phys_segments = bio_phys_segments(q, bio);
req->nr_hw_segments = bio_hw_segments(q, bio); req->nr_hw_segments = bio_hw_segments(q, bio);
req->nr_cbio_segments = bio_segments(bio);
req->nr_cbio_sectors = bio_sectors(bio);
req->buffer = bio_data(bio); /* see ->buffer comment above */ req->buffer = bio_data(bio); /* see ->buffer comment above */
req->waiting = NULL; req->waiting = NULL;
req->bio = req->biotail = bio; req->cbio = req->bio = req->biotail = bio;
req->rq_disk = bio->bi_bdev->bd_disk; req->rq_disk = bio->bi_bdev->bd_disk;
req->start_time = jiffies; req->start_time = jiffies;
...@@ -1914,6 +1920,81 @@ int submit_bio(int rw, struct bio *bio) ...@@ -1914,6 +1920,81 @@ int submit_bio(int rw, struct bio *bio)
return 1; return 1;
} }
/**
* blk_rq_next_segment
* @rq: the request being processed
*
* Description:
* Points to the next segment in the request if the current segment
* is complete. Leaves things unchanged if this segment is not over
* or if no more segments are left in this request.
*
* Meant to be used for bio traversal during I/O submission
* Does not affect any I/O completions or update completion state
* in the request, and does not modify any bio fields.
*
* Decrementing rq->nr_sectors, rq->current_nr_sectors and
* rq->nr_cbio_sectors as data is transferred is the caller's
* responsibility and should be done before calling this routine.
**/
void blk_rq_next_segment(struct request *rq)
{
if (rq->current_nr_sectors > 0)
return;
if (rq->nr_cbio_sectors > 0) {
--rq->nr_cbio_segments;
rq->current_nr_sectors = blk_rq_vec(rq)->bv_len >> 9;
} else {
if ((rq->cbio = rq->cbio->bi_next)) {
rq->nr_cbio_segments = bio_segments(rq->cbio);
rq->nr_cbio_sectors = bio_sectors(rq->cbio);
rq->current_nr_sectors = bio_cur_sectors(rq->cbio);
}
}
/* remember the size of this segment before we start I/O */
rq->hard_cur_sectors = rq->current_nr_sectors;
}
/**
* process_that_request_first - process partial request submission
* @req: the request being processed
* @nr_sectors: number of sectors I/O has been submitted on
*
* Description:
* May be used for processing bio's while submitting I/O without
* signalling completion. Fails if more data is requested than is
* available in the request in which case it doesn't advance any
* pointers.
*
* Assumes a request is correctly set up. No sanity checks.
*
* Return:
* 0 - no more data left to submit (not processed)
* 1 - data available to submit for this request (processed)
**/
int process_that_request_first(struct request *req, unsigned int nr_sectors)
{
unsigned int nsect;
if (req->nr_sectors < nr_sectors)
return 0;
req->nr_sectors -= nr_sectors;
req->sector += nr_sectors;
while (nr_sectors) {
nsect = min_t(unsigned, req->current_nr_sectors, nr_sectors);
req->current_nr_sectors -= nsect;
nr_sectors -= nsect;
if (req->cbio) {
req->nr_cbio_sectors -= nsect;
blk_rq_next_segment(req);
}
}
return 1;
}
void blk_recalc_rq_segments(struct request *rq) void blk_recalc_rq_segments(struct request *rq)
{ {
struct bio *bio; struct bio *bio;
...@@ -1922,8 +2003,6 @@ void blk_recalc_rq_segments(struct request *rq) ...@@ -1922,8 +2003,6 @@ void blk_recalc_rq_segments(struct request *rq)
if (!rq->bio) if (!rq->bio)
return; return;
rq->buffer = bio_data(rq->bio);
nr_phys_segs = nr_hw_segs = 0; nr_phys_segs = nr_hw_segs = 0;
rq_for_each_bio(bio, rq) { rq_for_each_bio(bio, rq) {
/* Force bio hw/phys segs to be recalculated. */ /* Force bio hw/phys segs to be recalculated. */
...@@ -1941,11 +2020,24 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect) ...@@ -1941,11 +2020,24 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect)
{ {
if (blk_fs_request(rq)) { if (blk_fs_request(rq)) {
rq->hard_sector += nsect; rq->hard_sector += nsect;
rq->nr_sectors = rq->hard_nr_sectors -= nsect; rq->hard_nr_sectors -= nsect;
rq->sector = rq->hard_sector;
rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9; /*
rq->hard_cur_sectors = rq->current_nr_sectors; * Move the I/O submission pointers ahead if required,
* i.e. for drivers not aware of rq->cbio.
*/
if ((rq->nr_sectors >= rq->hard_nr_sectors) &&
(rq->sector <= rq->hard_sector)) {
rq->sector = rq->hard_sector;
rq->nr_sectors = rq->hard_nr_sectors;
rq->hard_cur_sectors = bio_cur_sectors(rq->bio);
rq->current_nr_sectors = rq->hard_cur_sectors;
rq->nr_cbio_segments = bio_segments(rq->bio);
rq->nr_cbio_sectors = bio_sectors(rq->bio);
rq->buffer = bio_data(rq->bio);
rq->cbio = rq->bio;
}
/* /*
* if total number of sectors is less than the first segment * if total number of sectors is less than the first segment
...@@ -2139,9 +2231,27 @@ void blk_rq_bio_prep(request_queue_t *q, struct request *rq, struct bio *bio) ...@@ -2139,9 +2231,27 @@ void blk_rq_bio_prep(request_queue_t *q, struct request *rq, struct bio *bio)
rq->current_nr_sectors = bio_cur_sectors(bio); rq->current_nr_sectors = bio_cur_sectors(bio);
rq->hard_cur_sectors = rq->current_nr_sectors; rq->hard_cur_sectors = rq->current_nr_sectors;
rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio); rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio);
rq->nr_cbio_segments = bio_segments(bio);
rq->nr_cbio_sectors = bio_sectors(bio);
rq->buffer = bio_data(bio); rq->buffer = bio_data(bio);
rq->bio = rq->biotail = bio; rq->cbio = rq->bio = rq->biotail = bio;
}
void blk_rq_prep_restart(struct request *rq)
{
struct bio *bio;
bio = rq->cbio = rq->bio;
if (bio) {
rq->nr_cbio_segments = bio_segments(bio);
rq->nr_cbio_sectors = bio_sectors(bio);
rq->hard_cur_sectors = bio_cur_sectors(bio);
rq->buffer = bio_data(bio);
}
rq->sector = rq->hard_sector;
rq->nr_sectors = rq->hard_nr_sectors;
rq->current_nr_sectors = rq->hard_cur_sectors;
} }
int __init blk_dev_init(void) int __init blk_dev_init(void)
...@@ -2169,6 +2279,7 @@ int __init blk_dev_init(void) ...@@ -2169,6 +2279,7 @@ int __init blk_dev_init(void)
return 0; return 0;
}; };
EXPORT_SYMBOL(process_that_request_first);
EXPORT_SYMBOL(end_that_request_first); EXPORT_SYMBOL(end_that_request_first);
EXPORT_SYMBOL(end_that_request_chunk); EXPORT_SYMBOL(end_that_request_chunk);
EXPORT_SYMBOL(end_that_request_last); EXPORT_SYMBOL(end_that_request_last);
......
...@@ -212,7 +212,7 @@ static int sg_io(request_queue_t *q, struct block_device *bdev, ...@@ -212,7 +212,7 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
} }
} }
rq = blk_get_request(q, WRITE, __GFP_WAIT); rq = blk_get_request(q, writing ? WRITE : READ, __GFP_WAIT);
/* /*
* fill in request structure * fill in request structure
...@@ -227,8 +227,6 @@ static int sg_io(request_queue_t *q, struct block_device *bdev, ...@@ -227,8 +227,6 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
rq->sense_len = 0; rq->sense_len = 0;
rq->flags |= REQ_BLOCK_PC; rq->flags |= REQ_BLOCK_PC;
if (writing)
rq->flags |= REQ_RW;
rq->hard_nr_sectors = rq->nr_sectors = nr_sectors; rq->hard_nr_sectors = rq->nr_sectors = nr_sectors;
rq->hard_cur_sectors = rq->current_nr_sectors = nr_sectors; rq->hard_cur_sectors = rq->current_nr_sectors = nr_sectors;
...@@ -329,7 +327,7 @@ static int sg_scsi_ioctl(request_queue_t *q, struct block_device *bdev, ...@@ -329,7 +327,7 @@ static int sg_scsi_ioctl(request_queue_t *q, struct block_device *bdev,
memset(buffer, 0, bytes); memset(buffer, 0, bytes);
} }
rq = blk_get_request(q, WRITE, __GFP_WAIT); rq = blk_get_request(q, in_len ? WRITE : READ, __GFP_WAIT);
cmdlen = COMMAND_SIZE(opcode); cmdlen = COMMAND_SIZE(opcode);
...@@ -373,8 +371,6 @@ static int sg_scsi_ioctl(request_queue_t *q, struct block_device *bdev, ...@@ -373,8 +371,6 @@ static int sg_scsi_ioctl(request_queue_t *q, struct block_device *bdev,
rq->data = buffer; rq->data = buffer;
rq->data_len = bytes; rq->data_len = bytes;
rq->flags |= REQ_BLOCK_PC; rq->flags |= REQ_BLOCK_PC;
if (in_len)
rq->flags |= REQ_RW;
blk_do_rq(q, bdev, rq); blk_do_rq(q, bdev, rq);
err = rq->errors & 0xff; /* only 8 bit SCSI status */ err = rq->errors & 0xff; /* only 8 bit SCSI status */
......
...@@ -146,7 +146,7 @@ static void button_sequence_finished (unsigned long parameters) ...@@ -146,7 +146,7 @@ static void button_sequence_finished (unsigned long parameters)
* increments the counter. * increments the counter.
*/ */
static void button_handler (int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t button_handler (int irq, void *dev_id, struct pt_regs *regs)
{ {
if (button_press_count) { if (button_press_count) {
del_timer (&button_timer); del_timer (&button_timer);
...@@ -156,6 +156,8 @@ static void button_handler (int irq, void *dev_id, struct pt_regs *regs) ...@@ -156,6 +156,8 @@ static void button_handler (int irq, void *dev_id, struct pt_regs *regs)
button_timer.function = button_sequence_finished; button_timer.function = button_sequence_finished;
button_timer.expires = (jiffies + bdelay); button_timer.expires = (jiffies + bdelay);
add_timer (&button_timer); add_timer (&button_timer);
return IRQ_HANDLED;
} }
/* /*
......
...@@ -2070,6 +2070,7 @@ static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) ...@@ -2070,6 +2070,7 @@ static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
req.sense = sense; req.sense = sense;
req.cmd[0] = GPCMD_TEST_UNIT_READY; req.cmd[0] = GPCMD_TEST_UNIT_READY;
req.flags |= REQ_QUIET;
#if ! STANDARD_ATAPI #if ! STANDARD_ATAPI
/* the Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to /* the Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to
......
...@@ -1479,7 +1479,7 @@ static int probe_lba_addressing (ide_drive_t *drive, int arg) ...@@ -1479,7 +1479,7 @@ static int probe_lba_addressing (ide_drive_t *drive, int arg)
static int set_lba_addressing (ide_drive_t *drive, int arg) static int set_lba_addressing (ide_drive_t *drive, int arg)
{ {
return (probe_lba_addressing(drive, arg)); return probe_lba_addressing(drive, arg);
} }
static void idedisk_add_settings(ide_drive_t *drive) static void idedisk_add_settings(ide_drive_t *drive)
...@@ -1566,6 +1566,18 @@ static void idedisk_setup (ide_drive_t *drive) ...@@ -1566,6 +1566,18 @@ static void idedisk_setup (ide_drive_t *drive)
(void) probe_lba_addressing(drive, 1); (void) probe_lba_addressing(drive, 1);
if (drive->addressing == 1) {
ide_hwif_t *hwif = HWIF(drive);
int max_s = 2048;
if (max_s > hwif->rqsize)
max_s = hwif->rqsize;
blk_queue_max_sectors(&drive->queue, max_s);
}
printk("%s: max request size: %dKiB\n", drive->name, drive->queue.max_sectors / 2);
/* Extract geometry if we did not already have one for the drive */ /* Extract geometry if we did not already have one for the drive */
if (!drive->cyl || !drive->head || !drive->sect) { if (!drive->cyl || !drive->head || !drive->sect) {
drive->cyl = drive->bios_cyl = id->cyls; drive->cyl = drive->bios_cyl = id->cyls;
......
...@@ -998,6 +998,7 @@ EXPORT_SYMBOL(save_match); ...@@ -998,6 +998,7 @@ EXPORT_SYMBOL(save_match);
static void ide_init_queue(ide_drive_t *drive) static void ide_init_queue(ide_drive_t *drive)
{ {
request_queue_t *q = &drive->queue; request_queue_t *q = &drive->queue;
ide_hwif_t *hwif = HWIF(drive);
int max_sectors = 256; int max_sectors = 256;
/* /*
...@@ -1013,8 +1014,10 @@ static void ide_init_queue(ide_drive_t *drive) ...@@ -1013,8 +1014,10 @@ static void ide_init_queue(ide_drive_t *drive)
drive->queue_setup = 1; drive->queue_setup = 1;
blk_queue_segment_boundary(q, 0xffff); blk_queue_segment_boundary(q, 0xffff);
if (HWIF(drive)->rqsize) if (!hwif->rqsize)
max_sectors = HWIF(drive)->rqsize; hwif->rqsize = hwif->addressing ? 256 : 65536;
if (hwif->rqsize < max_sectors)
max_sectors = hwif->rqsize;
blk_queue_max_sectors(q, max_sectors); blk_queue_max_sectors(q, max_sectors);
/* IDE DMA can do PRD_ENTRIES number of segments. */ /* IDE DMA can do PRD_ENTRIES number of segments. */
......
...@@ -51,9 +51,58 @@ ...@@ -51,9 +51,58 @@
*/ */
#undef IDE_TCQ_FIDDLE_SI #undef IDE_TCQ_FIDDLE_SI
/*
* bad drive blacklist, for drives that raport tcq capability but don't
* work reliably with the default config. initially from freebsd table.
*/
struct ide_tcq_blacklist {
char *model;
char works;
unsigned int max_sectors;
};
static struct ide_tcq_blacklist ide_tcq_blacklist[] = {
{
.model = "IBM-DTTA",
.works = 1,
.max_sectors = 128,
},
{
.model = "IBM-DJNA",
.works = 0,
},
{
.model = "WDC AC",
.works = 0,
},
{
.model = NULL,
},
};
ide_startstop_t ide_dmaq_intr(ide_drive_t *drive); ide_startstop_t ide_dmaq_intr(ide_drive_t *drive);
ide_startstop_t ide_service(ide_drive_t *drive); ide_startstop_t ide_service(ide_drive_t *drive);
static struct ide_tcq_blacklist *ide_find_drive_blacklist(ide_drive_t *drive)
{
struct ide_tcq_blacklist *itb;
int i = 0;
do {
itb = &ide_tcq_blacklist[i];
if (!itb->model)
break;
if (!strncmp(drive->id->model, itb->model, strlen(itb->model)))
return itb;
i++;
} while (1);
return NULL;
}
static inline void drive_ctl_nien(ide_drive_t *drive, int set) static inline void drive_ctl_nien(ide_drive_t *drive, int set)
{ {
#ifdef IDE_TCQ_NIEN #ifdef IDE_TCQ_NIEN
...@@ -502,7 +551,7 @@ static int ide_tcq_configure(ide_drive_t *drive) ...@@ -502,7 +551,7 @@ static int ide_tcq_configure(ide_drive_t *drive)
return 0; return 0;
err: err:
kfree(args); kfree(args);
return 1; return -EIO;
} }
/* /*
...@@ -511,6 +560,7 @@ static int ide_tcq_configure(ide_drive_t *drive) ...@@ -511,6 +560,7 @@ static int ide_tcq_configure(ide_drive_t *drive)
*/ */
static int ide_enable_queued(ide_drive_t *drive, int on) static int ide_enable_queued(ide_drive_t *drive, int on)
{ {
struct ide_tcq_blacklist *itb;
int depth = drive->using_tcq ? drive->queue_depth : 0; int depth = drive->using_tcq ? drive->queue_depth : 0;
/* /*
...@@ -529,6 +579,17 @@ static int ide_enable_queued(ide_drive_t *drive, int on) ...@@ -529,6 +579,17 @@ static int ide_enable_queued(ide_drive_t *drive, int on)
return 1; return 1;
} }
/*
* some drives need limited transfer size in tcq
*/
itb = ide_find_drive_blacklist(drive);
if (itb && itb->max_sectors) {
if (itb->max_sectors > HWIF(drive)->rqsize)
itb->max_sectors = HWIF(drive)->rqsize;
blk_queue_max_sectors(&drive->queue, itb->max_sectors);
}
/* /*
* enable block tagging * enable block tagging
*/ */
...@@ -582,13 +643,36 @@ int ide_tcq_wait_dataphase(ide_drive_t *drive) ...@@ -582,13 +643,36 @@ int ide_tcq_wait_dataphase(ide_drive_t *drive)
return 0; return 0;
} }
static int ide_tcq_check_blacklist(ide_drive_t *drive)
{
struct ide_tcq_blacklist *itb = ide_find_drive_blacklist(drive);
if (!itb)
return 0;
return !itb->works;
}
int __ide_dma_queued_on(ide_drive_t *drive) int __ide_dma_queued_on(ide_drive_t *drive)
{ {
if (!drive->using_dma) if (!drive->using_dma)
return 1; return 1;
if (HWIF(drive)->chipset == ide_pdc4030)
return 1;
if (ide_tcq_check_blacklist(drive)) {
printk(KERN_WARNING "%s: tcq forbidden by blacklist\n",
drive->name);
return 1;
}
if (drive->next != drive) {
printk(KERN_WARNING "%s: only one drive on a channel supported"
" for tcq\n", drive->name);
return 1;
}
if (ata_pending_commands(drive)) { if (ata_pending_commands(drive)) {
printk(KERN_WARNING "ide-tcq; can't toggle tcq feature on busy drive\n"); printk(KERN_WARNING "ide-tcq; can't toggle tcq feature on "
"busy drive\n");
return 1; return 1;
} }
......
...@@ -49,7 +49,7 @@ static struct input_dev rpcmouse_dev = { ...@@ -49,7 +49,7 @@ static struct input_dev rpcmouse_dev = {
}, },
}; };
static void rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct input_dev *dev = dev_id; struct input_dev *dev = dev_id;
short x, y, dx, dy, b; short x, y, dx, dy, b;
...@@ -74,6 +74,8 @@ static void rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -74,6 +74,8 @@ static void rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs)
input_report_key(dev, BTN_RIGHT, b & 0x10); input_report_key(dev, BTN_RIGHT, b & 0x10);
input_sync(dev); input_sync(dev);
return IRQ_HANDLED;
} }
static int __init rpcmouse_init(void) static int __init rpcmouse_init(void)
......
...@@ -28,22 +28,27 @@ ...@@ -28,22 +28,27 @@
struct amba_kmi_port { struct amba_kmi_port {
struct serio io; struct serio io;
struct amba_kmi_port *next; struct amba_kmi_port *next;
unsigned long base; void *base;
unsigned int irq; unsigned int irq;
unsigned int divisor; unsigned int divisor;
char name[32]; char name[32];
char phys[16]; char phys[16];
struct resource *res;
}; };
static void amba_kmi_int(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t amba_kmi_int(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct amba_kmi_port *kmi = dev_id; struct amba_kmi_port *kmi = dev_id;
unsigned int status = __raw_readb(KMIIR); unsigned int status = readb(KMIIR);
int handled = IRQ_NONE;
while (status & KMIIR_RXINTR) { while (status & KMIIR_RXINTR) {
serio_interrupt(&kmi->io, __raw_readb(KMIDATA), 0, regs); serio_interrupt(&kmi->io, readb(KMIDATA), 0, regs);
status = __raw_readb(KMIIR); status = readb(KMIIR);
handled = IRQ_HANDLED;
} }
return handled;
} }
static int amba_kmi_write(struct serio *io, unsigned char val) static int amba_kmi_write(struct serio *io, unsigned char val)
...@@ -51,11 +56,11 @@ static int amba_kmi_write(struct serio *io, unsigned char val) ...@@ -51,11 +56,11 @@ static int amba_kmi_write(struct serio *io, unsigned char val)
struct amba_kmi_port *kmi = io->driver; struct amba_kmi_port *kmi = io->driver;
unsigned int timeleft = 10000; /* timeout in 100ms */ unsigned int timeleft = 10000; /* timeout in 100ms */
while ((__raw_readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && timeleft--) while ((readb(KMISTAT) & KMISTAT_TXEMPTY) == 0 && timeleft--)
udelay(10); udelay(10);
if (timeleft) if (timeleft)
__raw_writeb(val, KMIDATA); writeb(val, KMIDATA);
return timeleft ? 0 : SERIO_TIMEOUT; return timeleft ? 0 : SERIO_TIMEOUT;
} }
...@@ -65,17 +70,17 @@ static int amba_kmi_open(struct serio *io) ...@@ -65,17 +70,17 @@ static int amba_kmi_open(struct serio *io)
struct amba_kmi_port *kmi = io->driver; struct amba_kmi_port *kmi = io->driver;
int ret; int ret;
__raw_writeb(kmi->divisor, KMICLKDIV); writeb(kmi->divisor, KMICLKDIV);
__raw_writeb(KMICR_EN, KMICR); writeb(KMICR_EN, KMICR);
ret = request_irq(kmi->irq, amba_kmi_int, 0, kmi->phys, kmi); ret = request_irq(kmi->irq, amba_kmi_int, 0, kmi->phys, kmi);
if (ret) { if (ret) {
printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq); printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq);
__raw_writeb(0, KMICR); writeb(0, KMICR);
return ret; return ret;
} }
__raw_writeb(KMICR_EN | KMICR_RXINTREN, KMICR); writeb(KMICR_EN | KMICR_RXINTREN, KMICR);
return 0; return 0;
} }
...@@ -84,9 +89,9 @@ static void amba_kmi_close(struct serio *io) ...@@ -84,9 +89,9 @@ static void amba_kmi_close(struct serio *io)
{ {
struct amba_kmi_port *kmi = io->driver; struct amba_kmi_port *kmi = io->driver;
free_irq(kmi->irq, kmi); writeb(0, KMICR);
__raw_writeb(0, KMICR); free_irq(kmi->irq, kmi);
} }
static struct amba_kmi_port *list; static struct amba_kmi_port *list;
...@@ -109,24 +114,36 @@ static int __init amba_kmi_init_one(char *type, unsigned long base, int irq, int ...@@ -109,24 +114,36 @@ static int __init amba_kmi_init_one(char *type, unsigned long base, int irq, int
kmi->io.phys = kmi->phys; kmi->io.phys = kmi->phys;
kmi->io.driver = kmi; kmi->io.driver = kmi;
kmi->base = base; snprintf(kmi->name, sizeof(kmi->name), "AMBA KMI PS/2 %s port", type);
snprintf(kmi->phys, sizeof(kmi->phys), "amba/serio%d", nr);
kmi->res = request_mem_region(base, KMI_SIZE, kmi->phys);
if (!kmi->res) {
kfree(kmi);
return -EBUSY;
}
kmi->base = ioremap(base, KMI_SIZE);
if (!kmi->base) {
release_resource(kmi->res);
kfree(kmi);
return -ENOMEM;
}
kmi->irq = irq; kmi->irq = irq;
kmi->divisor = 24 / 8 - 1; kmi->divisor = 24 / 8 - 1;
kmi->next = list; kmi->next = list;
list = kmi; list = kmi;
snprintf(kmi->name, sizeof(kmi->name), "AMBA KMI PS/2 %s port", type);
snprintf(kmi->phys, sizeof(kmi->phys), "amba/serio%d", nr);
serio_register_port(&kmi->io); serio_register_port(&kmi->io);
return 0; return 0;
} }
static int __init amba_kmi_init(void) static int __init amba_kmi_init(void)
{ {
amba_kmi_init_one("keyboard", IO_ADDRESS(KMI0_BASE), IRQ_KMIINT0, 0); amba_kmi_init_one("keyboard", KMI0_BASE, IRQ_KMIINT0, 0);
amba_kmi_init_one("mouse", IO_ADDRESS(KMI1_BASE), IRQ_KMIINT1, 1); amba_kmi_init_one("mouse", KMI1_BASE, IRQ_KMIINT1, 1);
return 0; return 0;
} }
...@@ -139,6 +156,8 @@ static void __exit amba_kmi_exit(void) ...@@ -139,6 +156,8 @@ static void __exit amba_kmi_exit(void)
next = kmi->next; next = kmi->next;
serio_unregister_port(&kmi->io); serio_unregister_port(&kmi->io);
iounmap(kmi->base);
release_resource(kmi->res);
kfree(kmi); kfree(kmi);
kmi = next; kmi = next;
......
...@@ -54,20 +54,24 @@ static int rpckbd_write(struct serio *port, unsigned char val) ...@@ -54,20 +54,24 @@ static int rpckbd_write(struct serio *port, unsigned char val)
return 0; return 0;
} }
static void rpckbd_rx(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t rpckbd_rx(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct serio *port = dev_id; struct serio *port = dev_id;
unsigned int byte; unsigned int byte;
int handled = IRQ_NONE;
while (iomd_readb(IOMD_KCTRL) & (1 << 5)) { while (iomd_readb(IOMD_KCTRL) & (1 << 5)) {
byte = iomd_readb(IOMD_KARTRX); byte = iomd_readb(IOMD_KARTRX);
serio_interrupt(port, byte, 0, regs); serio_interrupt(port, byte, 0, regs);
handled = IRQ_HANDLED;
} }
return handled;
} }
static void rpckbd_tx(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t rpckbd_tx(int irq, void *dev_id, struct pt_regs *regs)
{ {
return IRQ_HANDLED;
} }
static int rpckbd_open(struct serio *port) static int rpckbd_open(struct serio *port)
......
...@@ -41,10 +41,11 @@ struct ps2if { ...@@ -41,10 +41,11 @@ struct ps2if {
* at the most one, but we loop for safety. If there was a * at the most one, but we loop for safety. If there was a
* framing error, we have to manually clear the status. * framing error, we have to manually clear the status.
*/ */
static void ps2_rxint(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t ps2_rxint(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct ps2if *ps2if = dev_id; struct ps2if *ps2if = dev_id;
unsigned int scancode, flag, status; unsigned int scancode, flag, status;
int handled = IRQ_NONE;
status = sa1111_readl(ps2if->base + SA1111_PS2STAT); status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
while (status & PS2STAT_RXF) { while (status & PS2STAT_RXF) {
...@@ -62,13 +63,17 @@ static void ps2_rxint(int irq, void *dev_id, struct pt_regs *regs) ...@@ -62,13 +63,17 @@ static void ps2_rxint(int irq, void *dev_id, struct pt_regs *regs)
serio_interrupt(&ps2if->io, scancode, flag, regs); serio_interrupt(&ps2if->io, scancode, flag, regs);
status = sa1111_readl(ps2if->base + SA1111_PS2STAT); status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
handled = IRQ_HANDLED;
} }
return handled;
} }
/* /*
* Completion of ps2 write * Completion of ps2 write
*/ */
static void ps2_txint(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t ps2_txint(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct ps2if *ps2if = dev_id; struct ps2if *ps2if = dev_id;
unsigned int status; unsigned int status;
...@@ -83,6 +88,8 @@ static void ps2_txint(int irq, void *dev_id, struct pt_regs *regs) ...@@ -83,6 +88,8 @@ static void ps2_txint(int irq, void *dev_id, struct pt_regs *regs)
ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1); ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1);
} }
spin_unlock(&ps2if->lock); spin_unlock(&ps2if->lock);
return IRQ_HANDLED;
} }
/* /*
......
This diff is collapsed.
...@@ -133,7 +133,6 @@ typedef struct socket_info_t { ...@@ -133,7 +133,6 @@ typedef struct socket_info_t {
u_short lock_count; u_short lock_count;
client_handle_t clients; client_handle_t clients;
u_int real_clients; u_int real_clients;
client_handle_t reset_handle;
pccard_mem_map cis_mem; pccard_mem_map cis_mem;
u_char *cis_virt; u_char *cis_virt;
config_t *config; config_t *config;
...@@ -155,6 +154,14 @@ typedef struct socket_info_t { ...@@ -155,6 +154,14 @@ typedef struct socket_info_t {
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc; struct proc_dir_entry *proc;
#endif #endif
struct semaphore skt_sem; /* protects socket h/w state */
struct task_struct *thread;
struct completion thread_done;
wait_queue_head_t thread_wait;
spinlock_t thread_lock; /* protects thread_events */
unsigned int thread_events;
} socket_info_t; } socket_info_t;
/* Flags in config state */ /* Flags in config state */
......
...@@ -120,7 +120,6 @@ sa1100_pcmcia_set_mecr(struct sa1100_pcmcia_socket *skt, unsigned int cpu_clock) ...@@ -120,7 +120,6 @@ sa1100_pcmcia_set_mecr(struct sa1100_pcmcia_socket *skt, unsigned int cpu_clock)
unsigned long flags; unsigned long flags;
unsigned short speed; unsigned short speed;
unsigned int bs_io, bs_mem, bs_attr; unsigned int bs_io, bs_mem, bs_attr;
int i;
speed = calc_speed(skt->spd_io, MAX_IO_WIN, SA1100_PCMCIA_IO_ACCESS); speed = calc_speed(skt->spd_io, MAX_IO_WIN, SA1100_PCMCIA_IO_ACCESS);
bs_io = skt->ops->socket_get_timing(skt, cpu_clock, speed); bs_io = skt->ops->socket_get_timing(skt, cpu_clock, speed);
...@@ -324,13 +323,15 @@ static void sa1100_pcmcia_poll_event(unsigned long dummy) ...@@ -324,13 +323,15 @@ static void sa1100_pcmcia_poll_event(unsigned long dummy)
* handling code performs scheduling operations which cannot be * handling code performs scheduling operations which cannot be
* executed from within an interrupt context. * executed from within an interrupt context.
*/ */
static void sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs) static irqreturn_t sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
{ {
struct sa1100_pcmcia_socket *skt = dev; struct sa1100_pcmcia_socket *skt = dev;
DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq); DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
schedule_work(&skt->work); schedule_work(&skt->work);
return IRQ_HANDLED;
} }
/* sa1100_pcmcia_register_callback() /* sa1100_pcmcia_register_callback()
......
...@@ -85,7 +85,7 @@ static void serial21285_enable_ms(struct uart_port *port) ...@@ -85,7 +85,7 @@ static void serial21285_enable_ms(struct uart_port *port)
{ {
} }
static void serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct uart_port *port = dev_id; struct uart_port *port = dev_id;
struct tty_struct *tty = port->info->tty; struct tty_struct *tty = port->info->tty;
...@@ -97,7 +97,7 @@ static void serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *regs) ...@@ -97,7 +97,7 @@ static void serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
tty->flip.work.func((void *)tty); tty->flip.work.func((void *)tty);
if (tty->flip.count >= TTY_FLIPBUF_SIZE) { if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
printk(KERN_WARNING "TTY_DONT_FLIP set\n"); printk(KERN_WARNING "TTY_DONT_FLIP set\n");
return; goto out;
} }
} }
...@@ -143,9 +143,12 @@ static void serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *regs) ...@@ -143,9 +143,12 @@ static void serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *regs)
status = *CSR_UARTFLG; status = *CSR_UARTFLG;
} }
tty_flip_buffer_push(tty); tty_flip_buffer_push(tty);
out:
return IRQ_HANDLED;
} }
static void serial21285_tx_chars(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t serial21285_tx_chars(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct uart_port *port = dev_id; struct uart_port *port = dev_id;
struct circ_buf *xmit = &port->info->xmit; struct circ_buf *xmit = &port->info->xmit;
...@@ -155,11 +158,11 @@ static void serial21285_tx_chars(int irq, void *dev_id, struct pt_regs *regs) ...@@ -155,11 +158,11 @@ static void serial21285_tx_chars(int irq, void *dev_id, struct pt_regs *regs)
*CSR_UARTDR = port->x_char; *CSR_UARTDR = port->x_char;
port->icount.tx++; port->icount.tx++;
port->x_char = 0; port->x_char = 0;
return; goto out;
} }
if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
serial21285_stop_tx(port, 0); serial21285_stop_tx(port, 0);
return; goto out;
} }
do { do {
...@@ -175,6 +178,9 @@ static void serial21285_tx_chars(int irq, void *dev_id, struct pt_regs *regs) ...@@ -175,6 +178,9 @@ static void serial21285_tx_chars(int irq, void *dev_id, struct pt_regs *regs)
if (uart_circ_empty(xmit)) if (uart_circ_empty(xmit))
serial21285_stop_tx(port, 0); serial21285_stop_tx(port, 0);
out:
return IRQ_HANDLED;
} }
static unsigned int serial21285_tx_empty(struct uart_port *port) static unsigned int serial21285_tx_empty(struct uart_port *port)
......
...@@ -278,7 +278,7 @@ static void ambauart_modem_status(struct uart_port *port) ...@@ -278,7 +278,7 @@ static void ambauart_modem_status(struct uart_port *port)
wake_up_interruptible(&uap->port.info->delta_msr_wait); wake_up_interruptible(&uap->port.info->delta_msr_wait);
} }
static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t ambauart_int(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct uart_port *port = dev_id; struct uart_port *port = dev_id;
unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
...@@ -302,6 +302,8 @@ static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs) ...@@ -302,6 +302,8 @@ static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs)
status = UART_GET_INT_STATUS(port); status = UART_GET_INT_STATUS(port);
} while (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS | } while (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS |
AMBA_UARTIIR_TIS)); AMBA_UARTIIR_TIS));
return IRQ_HANDLED;
} }
static unsigned int ambauart_tx_empty(struct uart_port *port) static unsigned int ambauart_tx_empty(struct uart_port *port)
......
...@@ -312,7 +312,7 @@ static void sa1100_tx_chars(struct sa1100_port *sport) ...@@ -312,7 +312,7 @@ static void sa1100_tx_chars(struct sa1100_port *sport)
sa1100_stop_tx(&sport->port, 0); sa1100_stop_tx(&sport->port, 0);
} }
static void sa1100_int(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t sa1100_int(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct sa1100_port *sport = dev_id; struct sa1100_port *sport = dev_id;
unsigned int status, pass_counter = 0; unsigned int status, pass_counter = 0;
...@@ -347,6 +347,8 @@ static void sa1100_int(int irq, void *dev_id, struct pt_regs *regs) ...@@ -347,6 +347,8 @@ static void sa1100_int(int irq, void *dev_id, struct pt_regs *regs)
~UTSR0_TFS; ~UTSR0_TFS;
} while (status & (UTSR0_TFS | UTSR0_RFS | UTSR0_RID)); } while (status & (UTSR0_TFS | UTSR0_RFS | UTSR0_RID));
spin_unlock(&sport->port.lock); spin_unlock(&sport->port.lock);
return IRQ_HANDLED;
} }
/* /*
...@@ -830,7 +832,7 @@ static struct console sa1100_console = { ...@@ -830,7 +832,7 @@ static struct console sa1100_console = {
.setup = sa1100_console_setup, .setup = sa1100_console_setup,
.flags = CON_PRINTBUFFER, .flags = CON_PRINTBUFFER,
.index = -1, .index = -1,
.data = sa1100_reg, .data = &sa1100_reg,
}; };
static int __init sa1100_rs_console_init(void) static int __init sa1100_rs_console_init(void)
......
...@@ -14,10 +14,11 @@ ...@@ -14,10 +14,11 @@
#ifndef __ASM_ARCH_TIME_H #ifndef __ASM_ARCH_TIME_H
#define __ASM_ARCH_TIME_H #define __ASM_ARCH_TIME_H
static void static irqreturn_t
anakin_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) anakin_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
do_timer(regs); do_timer(regs);
return IRQ_HANDLED;
} }
void __init time_init(void) void __init time_init(void)
......
...@@ -14,11 +14,13 @@ ...@@ -14,11 +14,13 @@
*/ */
extern void ioctime_init(void); extern void ioctime_init(void);
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
do_timer(regs); do_timer(regs);
do_set_rtc(); do_set_rtc();
do_profile(regs); do_profile(regs);
return IRQ_HANDLED;
} }
/* /*
......
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
extern void ioctime_init(void); extern void ioctime_init(void);
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
do_timer(regs); do_timer(regs);
do_set_rtc(); do_set_rtc();
...@@ -26,6 +27,7 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -26,6 +27,7 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*((volatile unsigned int *)LED_ADDRESS) = state; *((volatile unsigned int *)LED_ADDRESS) = state;
} }
} }
return IRQ_HANDLED;
} }
/* /*
......
...@@ -25,11 +25,13 @@ extern void clps711x_setup_timer(void); ...@@ -25,11 +25,13 @@ extern void clps711x_setup_timer(void);
/* /*
* IRQ handler for the timer * IRQ handler for the timer
*/ */
static void p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
do_leds(); do_leds();
do_timer(regs); do_timer(regs);
do_profile(regs); do_profile(regs);
return IRQ_HANDLED;
} }
/* /*
......
...@@ -74,7 +74,8 @@ static unsigned long ebsa110_gettimeoffset(void) ...@@ -74,7 +74,8 @@ static unsigned long ebsa110_gettimeoffset(void)
return offset; return offset;
} }
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
u32 count; u32 count;
...@@ -91,6 +92,8 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -91,6 +92,8 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
do_leds(); do_leds();
do_timer(regs); do_timer(regs);
do_profile(regs); do_profile(regs);
return IRQ_HANDLED;
} }
/* /*
......
...@@ -69,7 +69,8 @@ static unsigned long isa_gettimeoffset(void) ...@@ -69,7 +69,8 @@ static unsigned long isa_gettimeoffset(void)
return count; return count;
} }
static void isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
if (machine_is_netwinder()) if (machine_is_netwinder())
do_leds(); do_leds();
...@@ -77,6 +78,8 @@ static void isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -77,6 +78,8 @@ static void isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
do_timer(regs); do_timer(regs);
do_set_rtc(); do_set_rtc();
do_profile(regs); do_profile(regs);
return IRQ_HANDLED;
} }
static unsigned long __init get_isa_cmos_time(void) static unsigned long __init get_isa_cmos_time(void)
...@@ -186,7 +189,8 @@ static unsigned long timer1_gettimeoffset (void) ...@@ -186,7 +189,8 @@ static unsigned long timer1_gettimeoffset (void)
return ((tick_nsec / 1000) * value) / LATCH; return ((tick_nsec / 1000) * value) / LATCH;
} }
static void timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
*CSR_TIMER1_CLR = 0; *CSR_TIMER1_CLR = 0;
...@@ -195,6 +199,8 @@ static void timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -195,6 +199,8 @@ static void timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
do_timer(regs); do_timer(regs);
do_set_rtc(); do_set_rtc();
do_profile(regs); do_profile(regs);
return IRQ_HANDLED;
} }
/* /*
......
...@@ -27,7 +27,8 @@ ...@@ -27,7 +27,8 @@
/* /*
* IRQ handler for the timer * IRQ handler for the timer
*/ */
static void excalibur_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
excalibur_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
// ...clear the interrupt // ...clear the interrupt
...@@ -36,6 +37,8 @@ static void excalibur_timer_interrupt(int irq, void *dev_id, struct pt_regs *reg ...@@ -36,6 +37,8 @@ static void excalibur_timer_interrupt(int irq, void *dev_id, struct pt_regs *reg
do_leds(); do_leds();
do_timer(regs); do_timer(regs);
do_profile(regs); do_profile(regs);
return IRQ_HANDLED;
} }
/* /*
......
...@@ -98,7 +98,8 @@ static unsigned long integrator_gettimeoffset(void) ...@@ -98,7 +98,8 @@ static unsigned long integrator_gettimeoffset(void)
/* /*
* IRQ handler for the timer * IRQ handler for the timer
*/ */
static void integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
...@@ -108,6 +109,8 @@ static void integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *re ...@@ -108,6 +109,8 @@ static void integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *re
do_leds(); do_leds();
do_timer(regs); do_timer(regs);
do_profile(regs); do_profile(regs);
return IRQ_HANDLED;
} }
/* /*
......
...@@ -42,11 +42,14 @@ ...@@ -42,11 +42,14 @@
/* /*
* Handler for RTC timer interrupt * Handler for RTC timer interrupt
*/ */
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
do_timer(regs); do_timer(regs);
do_profile(regs); do_profile(regs);
RTC_RTCC = 0; /* Clear interrupt */ RTC_RTCC = 0; /* Clear interrupt */
return IRQ_HANDLED;
} }
/* /*
......
...@@ -14,7 +14,8 @@ ...@@ -14,7 +14,8 @@
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
static int count = 25; static int count = 25;
unsigned char stat = __raw_readb(DUART_BASE + 0x14); unsigned char stat = __raw_readb(DUART_BASE + 0x14);
...@@ -40,7 +41,9 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -40,7 +41,9 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
__raw_readb(DUART_BASE + 0x14); __raw_readb(DUART_BASE + 0x14);
__raw_readb(DUART_BASE + 0x14); __raw_readb(DUART_BASE + 0x14);
do_timer(regs); do_timer(regs);
return IRQ_HANDLED;
} }
void __init time_init(void) void __init time_init(void)
......
...@@ -10,9 +10,10 @@ ...@@ -10,9 +10,10 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#define PXA_IRQ_SKIP 8 /* The first 8 IRQs are reserved */ #define PXA_IRQ_SKIP 7 /* The first 7 IRQs are not yet used */
#define PXA_IRQ(x) ((x) - PXA_IRQ_SKIP) #define PXA_IRQ(x) ((x) - PXA_IRQ_SKIP)
#define IRQ_HWUART PXA_IRQ(7) /* HWUART Transmit/Receive/Error */
#define IRQ_GPIO0 PXA_IRQ(8) /* GPIO0 Edge Detect */ #define IRQ_GPIO0 PXA_IRQ(8) /* GPIO0 Edge Detect */
#define IRQ_GPIO1 PXA_IRQ(9) /* GPIO1 Edge Detect */ #define IRQ_GPIO1 PXA_IRQ(9) /* GPIO1 Edge Detect */
#define IRQ_GPIO_2_80 PXA_IRQ(10) /* GPIO[2-80] Edge Detect */ #define IRQ_GPIO_2_80 PXA_IRQ(10) /* GPIO[2-80] Edge Detect */
...@@ -20,6 +21,8 @@ ...@@ -20,6 +21,8 @@
#define IRQ_PMU PXA_IRQ(12) /* Performance Monitoring Unit */ #define IRQ_PMU PXA_IRQ(12) /* Performance Monitoring Unit */
#define IRQ_I2S PXA_IRQ(13) /* I2S Interrupt */ #define IRQ_I2S PXA_IRQ(13) /* I2S Interrupt */
#define IRQ_AC97 PXA_IRQ(14) /* AC97 Interrupt */ #define IRQ_AC97 PXA_IRQ(14) /* AC97 Interrupt */
#define IRQ_ASSP PXA_IRQ(15) /* Audio SSP Service Request */
#define IRQ_NSSP PXA_IRQ(16) /* Network SSP Service Request */
#define IRQ_LCD PXA_IRQ(17) /* LCD Controller Service Request */ #define IRQ_LCD PXA_IRQ(17) /* LCD Controller Service Request */
#define IRQ_I2C PXA_IRQ(18) /* I2C Service Request */ #define IRQ_I2C PXA_IRQ(18) /* I2C Service Request */
#define IRQ_ICP PXA_IRQ(19) /* ICP Transmit/Receive/Error */ #define IRQ_ICP PXA_IRQ(19) /* ICP Transmit/Receive/Error */
......
...@@ -47,7 +47,8 @@ static unsigned long pxa_gettimeoffset (void) ...@@ -47,7 +47,8 @@ static unsigned long pxa_gettimeoffset (void)
return usec; return usec;
} }
static void pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
int next_match; int next_match;
...@@ -66,6 +67,8 @@ static void pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -66,6 +67,8 @@ static void pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *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) <= 0 );
return IRQ_HANDLED;
} }
void __init time_init(void) void __init time_init(void)
......
...@@ -14,11 +14,14 @@ ...@@ -14,11 +14,14 @@
*/ */
extern void ioctime_init(void); extern void ioctime_init(void);
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
do_timer(regs); do_timer(regs);
do_set_rtc(); do_set_rtc();
do_profile(regs); do_profile(regs);
return IRQ_HANDLED;
} }
/* /*
......
...@@ -72,7 +72,8 @@ static unsigned long sa1100_gettimeoffset (void) ...@@ -72,7 +72,8 @@ static unsigned long sa1100_gettimeoffset (void)
* 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.
*/ */
static void sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
unsigned int next_match; unsigned int next_match;
...@@ -85,6 +86,8 @@ static void sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -85,6 +86,8 @@ static void sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
} while ((signed long)(next_match - OSCR) <= 0); } while ((signed long)(next_match - OSCR) <= 0);
do_profile(regs); do_profile(regs);
return IRQ_HANDLED;
} }
void __init time_init(void) void __init time_init(void)
......
...@@ -13,11 +13,14 @@ ...@@ -13,11 +13,14 @@
#define IRQ_TIMER 0 #define IRQ_TIMER 0
#define HZ_TIME ((1193180 + HZ/2) / HZ) #define HZ_TIME ((1193180 + HZ/2) / HZ)
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
do_leds(); do_leds();
do_timer(regs); do_timer(regs);
do_profile(regs); do_profile(regs);
return IRQ_HANDLED;
} }
/* /*
......
...@@ -20,13 +20,16 @@ ...@@ -20,13 +20,16 @@
#define update_rtc() #define update_rtc()
static void timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t
timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
{ {
/* Clear irq */ /* Clear irq */
__raw_writel(1, FPGA1CONT + 0xc); __raw_writel(1, FPGA1CONT + 0xc);
__raw_writel(0, FPGA1CONT + 0xc); __raw_writel(0, FPGA1CONT + 0xc);
do_timer(regs); do_timer(regs);
return IRQ_HANDLED;
} }
void __init time_init(void) void __init time_init(void)
......
...@@ -173,7 +173,7 @@ static inline int __test_and_change_bit(int nr, volatile unsigned long *p) ...@@ -173,7 +173,7 @@ static inline int __test_and_change_bit(int nr, volatile unsigned long *p)
*/ */
static inline int __test_bit(int nr, const unsigned long * p) static inline int __test_bit(int nr, const unsigned long * p)
{ {
return p[nr >> 5] & (1UL << (nr & 31)); return (p[nr >> 5] >> (nr & 31)) & 1UL;
} }
/* /*
...@@ -277,6 +277,8 @@ extern int _find_next_zero_bit_be(void * p, int size, int offset); ...@@ -277,6 +277,8 @@ extern int _find_next_zero_bit_be(void * p, int size, int offset);
#endif #endif
#if __LINUX_ARM_ARCH__ < 5
/* /*
* ffz = Find First Zero in word. Undefined if no zero exists, * ffz = Find First Zero in word. Undefined if no zero exists,
* so code should check against ~0UL first.. * so code should check against ~0UL first..
...@@ -326,6 +328,23 @@ static inline unsigned long __ffs(unsigned long word) ...@@ -326,6 +328,23 @@ static inline unsigned long __ffs(unsigned long word)
#define ffs(x) generic_ffs(x) #define ffs(x) generic_ffs(x)
#else
/*
* On ARMv5 and above those functions can be implemented around
* the clz instruction for much better code efficiency.
*/
extern __inline__ int generic_fls(int x);
#define fls(x) \
( __builtin_constant_p(x) ? generic_fls(x) : \
({ int __r; asm("clz%?\t%0, %1" : "=r"(__r) : "r"(x)); 32-__r; }) )
#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
#define __ffs(x) (ffs(x) - 1)
#define ffz(x) __ffs( ~(x) )
#endif
/* /*
* Find first bit set in a 168-bit bitmap, where the first * Find first bit set in a 168-bit bitmap, where the first
* 128 bits are unlikely to be set. * 128 bits are unlikely to be set.
......
...@@ -10,8 +10,6 @@ ...@@ -10,8 +10,6 @@
#ifndef __ASM_BUGS_H #ifndef __ASM_BUGS_H
#define __ASM_BUGS_H #define __ASM_BUGS_H
#include <asm/proc-fns.h>
#define check_bugs() do { } while (0) #define check_bugs() do { } while (0)
#endif #endif
...@@ -54,39 +54,37 @@ struct machine_desc { ...@@ -54,39 +54,37 @@ struct machine_desc {
#define MACHINE_START(_type,_name) \ #define MACHINE_START(_type,_name) \
const struct machine_desc __mach_desc_##_type \ const struct machine_desc __mach_desc_##_type \
__attribute__((__section__(".arch.info"))) = { \ __attribute__((__section__(".arch.info"))) = { \
nr: MACH_TYPE_##_type, \ .nr = MACH_TYPE_##_type, \
name: _name, .name = _name,
#define MAINTAINER(n) #define MAINTAINER(n)
#define BOOT_MEM(_pram,_pio,_vio) \ #define BOOT_MEM(_pram,_pio,_vio) \
phys_ram: _pram, \ .phys_ram = _pram, \
phys_io: _pio, \ .phys_io = _pio, \
io_pg_offst: ((_vio)>>18)&0xfffc, .io_pg_offst = ((_vio)>>18)&0xfffc,
#define BOOT_PARAMS(_params) \ #define BOOT_PARAMS(_params) \
param_offset: _params, .param_offset = _params,
#define VIDEO(_start,_end) \ #define VIDEO(_start,_end) \
video_start: _start, \ .video_start = _start, \
video_end: _end, .video_end = _end,
#define DISABLE_PARPORT(_n) \ #define DISABLE_PARPORT(_n) \
reserve_lp##_n: 1, .reserve_lp##_n = 1,
#define BROKEN_HLT /* unused */
#define SOFT_REBOOT \ #define SOFT_REBOOT \
soft_reboot: 1, .soft_reboot = 1,
#define FIXUP(_func) \ #define FIXUP(_func) \
fixup: _func, .fixup = _func,
#define MAPIO(_func) \ #define MAPIO(_func) \
map_io: _func, .map_io = _func,
#define INITIRQ(_func) \ #define INITIRQ(_func) \
init_irq: _func, .init_irq = _func,
#define MACHINE_END \ #define MACHINE_END \
}; };
......
...@@ -74,6 +74,29 @@ unsigned long get_wchan(struct task_struct *p); ...@@ -74,6 +74,29 @@ unsigned long get_wchan(struct task_struct *p);
*/ */
extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
/*
* Prefetching support - only ARMv5.
*/
#if __LINUX_ARM_ARCH__ >= 5
#define ARCH_HAS_PREFETCH
#define prefetch(ptr) \
({ \
__asm__ __volatile__( \
"pld\t%0" \
: \
: "o" (*(char *)(ptr)) \
: "cc"); \
})
#define ARCH_HAS_PREFETCHW
#define prefetchw(ptr) prefetch(ptr)
#define ARCH_HAS_SPINLOCK_PREFETCH
#define spin_lock_prefetch(x) do { } while (0)
#endif
#endif #endif
#endif /* __ASM_ARM_PROCESSOR_H */ #endif /* __ASM_ARM_PROCESSOR_H */
#ifndef _ASMARM_TRAP_H
#define _ASMARM_TRAP_H
#include <linux/list.h>
struct undef_hook {
struct list_head node;
u32 instr_mask;
u32 instr_val;
u32 cpsr_mask;
u32 cpsr_val;
int (*fn)(struct pt_regs *regs, unsigned int instr);
};
void register_undef_hook(struct undef_hook *hook);
void unregister_undef_hook(struct undef_hook *hook);
#endif
...@@ -131,6 +131,7 @@ struct bio { ...@@ -131,6 +131,7 @@ struct bio {
#define bio_iovec(bio) bio_iovec_idx((bio), (bio)->bi_idx) #define bio_iovec(bio) bio_iovec_idx((bio), (bio)->bi_idx)
#define bio_page(bio) bio_iovec((bio))->bv_page #define bio_page(bio) bio_iovec((bio))->bv_page
#define bio_offset(bio) bio_iovec((bio))->bv_offset #define bio_offset(bio) bio_iovec((bio))->bv_offset
#define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx)
#define bio_sectors(bio) ((bio)->bi_size >> 9) #define bio_sectors(bio) ((bio)->bi_size >> 9)
#define bio_cur_sectors(bio) (bio_iovec(bio)->bv_len >> 9) #define bio_cur_sectors(bio) (bio_iovec(bio)->bv_len >> 9)
#define bio_data(bio) (page_address(bio_page((bio))) + bio_offset((bio))) #define bio_data(bio) (page_address(bio_page((bio))) + bio_offset((bio)))
...@@ -226,12 +227,12 @@ extern void bio_check_pages_dirty(struct bio *bio); ...@@ -226,12 +227,12 @@ extern void bio_check_pages_dirty(struct bio *bio);
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
/* /*
* remember to add offset! and never ever reenable interrupts between a * remember to add offset! and never ever reenable interrupts between a
* bio_kmap_irq and bio_kunmap_irq!! * bvec_kmap_irq and bvec_kunmap_irq!!
* *
* This function MUST be inlined - it plays with the CPU interrupt flags. * This function MUST be inlined - it plays with the CPU interrupt flags.
* Hence the `extern inline'. * Hence the `extern inline'.
*/ */
extern inline char *bio_kmap_irq(struct bio *bio, unsigned long *flags) extern inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags)
{ {
unsigned long addr; unsigned long addr;
...@@ -240,15 +241,15 @@ extern inline char *bio_kmap_irq(struct bio *bio, unsigned long *flags) ...@@ -240,15 +241,15 @@ extern inline char *bio_kmap_irq(struct bio *bio, unsigned long *flags)
* balancing is a lot nicer this way * balancing is a lot nicer this way
*/ */
local_irq_save(*flags); local_irq_save(*flags);
addr = (unsigned long) kmap_atomic(bio_page(bio), KM_BIO_SRC_IRQ); addr = (unsigned long) kmap_atomic(bvec->bv_page, KM_BIO_SRC_IRQ);
if (addr & ~PAGE_MASK) if (addr & ~PAGE_MASK)
BUG(); BUG();
return (char *) addr + bio_offset(bio); return (char *) addr + bvec->bv_offset;
} }
extern inline void bio_kunmap_irq(char *buffer, unsigned long *flags) extern inline void bvec_kunmap_irq(char *buffer, unsigned long *flags)
{ {
unsigned long ptr = (unsigned long) buffer & PAGE_MASK; unsigned long ptr = (unsigned long) buffer & PAGE_MASK;
...@@ -257,8 +258,19 @@ extern inline void bio_kunmap_irq(char *buffer, unsigned long *flags) ...@@ -257,8 +258,19 @@ extern inline void bio_kunmap_irq(char *buffer, unsigned long *flags)
} }
#else #else
#define bio_kmap_irq(bio, flags) (bio_data(bio)) #define bvec_kmap_irq(bvec, flags) (page_address((bvec)->bv_page) + (bvec)->bv_offset)
#define bio_kunmap_irq(buf, flags) do { *(flags) = 0; } while (0) #define bvec_kunmap_irq(buf, flags) do { *(flags) = 0; } while (0)
#endif #endif
extern inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx,
unsigned long *flags)
{
return bvec_kmap_irq(bio_iovec_idx(bio, idx), flags);
}
#define __bio_kunmap_irq(buf, flags) bvec_kunmap_irq(buf, flags)
#define bio_kmap_irq(bio, flags) \
__bio_kmap_irq((bio), (bio)->bi_idx, (flags))
#define bio_kunmap_irq(buf,flags) __bio_kunmap_irq(buf, flags)
#endif /* __LINUX_BIO_H */ #endif /* __LINUX_BIO_H */
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/mempool.h> #include <linux/mempool.h>
#include <linux/bio.h>
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
...@@ -36,25 +37,35 @@ struct request { ...@@ -36,25 +37,35 @@ struct request {
* blkdev_dequeue_request! */ * blkdev_dequeue_request! */
unsigned long flags; /* see REQ_ bits below */ unsigned long flags; /* see REQ_ bits below */
sector_t sector; /* Maintain bio traversal state for part by part I/O submission.
unsigned long nr_sectors; * hard_* are block layer internals, no driver should touch them!
*/
sector_t sector; /* next sector to submit */
unsigned long nr_sectors; /* no. of sectors left to submit */
/* no. of sectors left to submit in the current segment */
unsigned int current_nr_sectors; unsigned int current_nr_sectors;
sector_t hard_sector; /* next sector to complete */
unsigned long hard_nr_sectors; /* no. of sectors left to complete */
/* no. of sectors left to complete in the current segment */
unsigned int hard_cur_sectors;
/* no. of segments left to submit in the current bio */
unsigned short nr_cbio_segments;
/* no. of sectors left to submit in the current bio */
unsigned long nr_cbio_sectors;
struct bio *cbio; /* next bio to submit */
struct bio *bio; /* next unfinished bio to complete */
struct bio *biotail;
void *elevator_private; void *elevator_private;
int rq_status; /* should split this into a few status bits */ int rq_status; /* should split this into a few status bits */
struct gendisk *rq_disk; struct gendisk *rq_disk;
int errors; int errors;
unsigned long start_time; unsigned long start_time;
sector_t hard_sector; /* the hard_* are block layer
* internals, no driver should
* touch them
*/
unsigned long hard_nr_sectors;
unsigned int hard_cur_sectors;
struct bio *bio;
struct bio *biotail;
/* Number of scatter-gather DMA addr+len pairs after /* Number of scatter-gather DMA addr+len pairs after
* physical address coalescing is performed. * physical address coalescing is performed.
...@@ -284,6 +295,32 @@ struct request_queue ...@@ -284,6 +295,32 @@ struct request_queue
*/ */
#define blk_queue_headactive(q, head_active) #define blk_queue_headactive(q, head_active)
/* current index into bio being processed for submission */
#define blk_rq_idx(rq) ((rq)->cbio->bi_vcnt - (rq)->nr_cbio_segments)
/* current bio vector being processed */
#define blk_rq_vec(rq) (bio_iovec_idx((rq)->cbio, blk_rq_idx(rq)))
/* current offset with respect to start of the segment being submitted */
#define blk_rq_offset(rq) \
(((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
/*
* temporarily mapping a (possible) highmem bio (typically for PIO transfer)
*/
/* Assumes rq->cbio != NULL */
static inline char * rq_map_buffer(struct request *rq, unsigned long *flags)
{
return (__bio_kmap_irq(rq->cbio, blk_rq_idx(rq), flags)
+ blk_rq_offset(rq));
}
static inline void rq_unmap_buffer(char *buffer, unsigned long *flags)
{
__bio_kunmap_irq(buffer, flags);
}
/* /*
* q->prep_rq_fn return values * q->prep_rq_fn return values
*/ */
...@@ -362,6 +399,7 @@ static inline request_queue_t *bdev_get_queue(struct block_device *bdev) ...@@ -362,6 +399,7 @@ static inline request_queue_t *bdev_get_queue(struct block_device *bdev)
extern int end_that_request_first(struct request *, int, int); extern int end_that_request_first(struct request *, int, int);
extern int end_that_request_chunk(struct request *, int, int); extern int end_that_request_chunk(struct request *, int, int);
extern void end_that_request_last(struct request *); extern void end_that_request_last(struct request *);
extern int process_that_request_first(struct request *, unsigned int);
extern void end_request(struct request *req, int uptodate); extern void end_request(struct request *req, int uptodate);
static inline void blkdev_dequeue_request(struct request *req) static inline void blkdev_dequeue_request(struct request *req)
......
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