Commit bb5f2af5 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 979feacc 9ddc01bf
...@@ -210,7 +210,6 @@ zi:; $(Q)$(MAKE) $(build)=$(boot) zinstall ...@@ -210,7 +210,6 @@ zi:; $(Q)$(MAKE) $(build)=$(boot) zinstall
arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \ arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
include/config/MARKER include/config/MARKER
@:
include/asm-$(ARCH)/constants.h: arch/$(ARCH)/kernel/asm-offsets.s include/asm-$(ARCH)/constants.h: arch/$(ARCH)/kernel/asm-offsets.s
@echo -n ' Generating $@' @echo -n ' Generating $@'
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
HEAD = head.o HEAD = head.o
OBJS = misc.o OBJS = misc.o
FONTC = drivers/video/font_acorn_8x8.c FONTC = drivers/video/console/font_acorn_8x8.c
# #
# Architecture dependencies # Architecture dependencies
......
...@@ -127,7 +127,8 @@ EXPORT_SYMBOL(enable_irq); ...@@ -127,7 +127,8 @@ EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(disable_irq);
EXPORT_SYMBOL(probe_irq_mask); EXPORT_SYMBOL(probe_irq_mask);
EXPORT_SYMBOL(set_irq_type); EXPORT_SYMBOL(set_irq_type);
EXPORT_SYMBOL(set_irq_wake); EXPORT_SYMBOL(enable_irq_wake);
EXPORT_SYMBOL(disable_irq_wake);
EXPORT_SYMBOL(pm_idle); EXPORT_SYMBOL(pm_idle);
EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(pm_power_off);
EXPORT_SYMBOL(fp_init); EXPORT_SYMBOL(fp_init);
...@@ -201,7 +202,6 @@ EXPORT_SYMBOL(__arch_clear_user); ...@@ -201,7 +202,6 @@ EXPORT_SYMBOL(__arch_clear_user);
EXPORT_SYMBOL(__arch_strnlen_user); EXPORT_SYMBOL(__arch_strnlen_user);
/* consistent area handling */ /* consistent area handling */
EXPORT_SYMBOL(pci_alloc_consistent);
EXPORT_SYMBOL(consistent_alloc); EXPORT_SYMBOL(consistent_alloc);
EXPORT_SYMBOL(consistent_free); EXPORT_SYMBOL(consistent_free);
EXPORT_SYMBOL(consistent_sync); EXPORT_SYMBOL(consistent_sync);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <asm/page.h> /* for BUG() */ #include <asm/page.h> /* for BUG() */
#include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/pci.h> #include <asm/mach/pci.h>
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#else #else
__syscall_start: __syscall_start:
/* 0 */ .long sys_ni_syscall /* 0 */ .long sys_restart_syscall
.long sys_exit .long sys_exit
.long sys_fork_wrapper .long sys_fork_wrapper
.long sys_read .long sys_read
......
...@@ -129,6 +129,31 @@ void enable_irq(unsigned int irq) ...@@ -129,6 +129,31 @@ void enable_irq(unsigned int irq)
spin_unlock_irqrestore(&irq_controller_lock, flags); spin_unlock_irqrestore(&irq_controller_lock, flags);
} }
/*
* Enable wake on selected irq
*/
void enable_irq_wake(unsigned int irq)
{
struct irqdesc *desc = irq_desc + irq;
unsigned long flags;
spin_lock_irqsave(&irq_controller_lock, flags);
if (desc->chip->wake)
desc->chip->wake(irq, 1);
spin_unlock_irqrestore(&irq_controller_lock, flags);
}
void disable_irq_wake(unsigned int irq)
{
struct irqdesc *desc = irq_desc + irq;
unsigned long flags;
spin_lock_irqsave(&irq_controller_lock, flags);
if (desc->chip->wake)
desc->chip->wake(irq, 0);
spin_unlock_irqrestore(&irq_controller_lock, flags);
}
int show_interrupts(struct seq_file *p, void *v) int show_interrupts(struct seq_file *p, void *v)
{ {
int i; int i;
......
...@@ -603,7 +603,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) ...@@ -603,7 +603,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
case SIGQUIT: case SIGILL: case SIGTRAP: case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV: case SIGABRT: case SIGFPE: case SIGSEGV:
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs)) if (do_coredump(signr, exit_code, regs))
exit_code |= 0x80; exit_code |= 0x80;
/* FALLTHRU */ /* FALLTHRU */
...@@ -615,7 +615,11 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) ...@@ -615,7 +615,11 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
/* Are we from a system call? */ /* Are we from a system call? */
if (syscall) { if (syscall) {
/* If so, check system call restarting.. */
switch (regs->ARM_r0) { switch (regs->ARM_r0) {
case -ERESTART_RESTARTBLOCK:
current_thread_info()->restart_block.fn =
do_no_restart_syscall;
case -ERESTARTNOHAND: case -ERESTARTNOHAND:
regs->ARM_r0 = -EINTR; regs->ARM_r0 = -EINTR;
break; break;
...@@ -638,12 +642,35 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) ...@@ -638,12 +642,35 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
return 1; return 1;
} }
if (syscall && /*
(regs->ARM_r0 == -ERESTARTNOHAND || * No signal to deliver to the process - restart the syscall.
regs->ARM_r0 == -ERESTARTSYS || */
regs->ARM_r0 == -ERESTARTNOINTR)) { if (syscall) {
regs->ARM_r0 = regs->ARM_ORIG_r0; if (regs->ARM_r0 == -ERESTART_RESTARTBLOCK) {
regs->ARM_pc -= 4; if (thumb_mode(regs)) {
regs->ARM_r7 = __NR_restart_syscall;
regs->ARM_pc -= 2;
} else {
u32 *usp;
regs->ARM_sp -= 12;
usp = (u32 *)regs->ARM_sp;
put_user(regs->ARM_pc, &usp[0]);
/* swi __NR_restart_syscall */
put_user(0xef000000 | __NR_restart_syscall, &usp[1]);
/* ldr pc, [sp], #12 */
put_user(0xe49df00c, &usp[2]);
regs->ARM_pc = regs->ARM_sp + 4;
}
}
if (regs->ARM_r0 == -ERESTARTNOHAND ||
regs->ARM_r0 == -ERESTARTSYS ||
regs->ARM_r0 == -ERESTARTNOINTR) {
regs->ARM_r0 = regs->ARM_ORIG_r0;
regs->ARM_pc -= 4;
}
} }
if (single_stepping) if (single_stepping)
ptrace_set_bpt(current); ptrace_set_bpt(current);
......
...@@ -148,9 +148,11 @@ static int integrator_set_policy(struct cpufreq_policy *policy) ...@@ -148,9 +148,11 @@ static int integrator_set_policy(struct cpufreq_policy *policy)
static struct cpufreq_policy integrator_policy = { static struct cpufreq_policy integrator_policy = {
.cpu = 0, .cpu = 0,
.policy = CPUFREQ_POLICY_POWERSAVE, .policy = CPUFREQ_POLICY_POWERSAVE,
.cpuinfo.max_cpu_freq = 160000, .cpuinfo = {
.cpuinfo.min_cpu_freq = 12000, .max_cpu_freq = 160000,
.cpuinfo.transition_latency = CPUFREQ_ETERNAL, .min_cpu_freq = 12000,
.transition_latency = CPUFREQ_ETERNAL,
},
}; };
static struct cpufreq_driver integrator_driver = { static struct cpufreq_driver integrator_driver = {
......
...@@ -21,8 +21,7 @@ obj-$(CONFIG_SA1100_PT_SYSTEM3) += cpu-sa1110.o ...@@ -21,8 +21,7 @@ obj-$(CONFIG_SA1100_PT_SYSTEM3) += cpu-sa1110.o
endif endif
# Next, the SA1111 stuff. # Next, the SA1111 stuff.
obj-$(CONFIG_SA1111) += sa1111.o obj-$(CONFIG_SA1111) += sa1111.o sa1111-pcibuf.o pcipool.o
obj-$(CONFIG_USB_OHCI_HCD) += sa1111-pcibuf.o pcipool.o
# Specific board support # Specific board support
obj-$(CONFIG_SA1100_ADSBITSY) += adsbitsy.o obj-$(CONFIG_SA1100_ADSBITSY) += adsbitsy.o
......
...@@ -203,9 +203,11 @@ static int sa1100_setspeed(struct cpufreq_policy *policy) ...@@ -203,9 +203,11 @@ static int sa1100_setspeed(struct cpufreq_policy *policy)
static struct cpufreq_policy sa1100_policy = { static struct cpufreq_policy sa1100_policy = {
.cpu = 0, .cpu = 0,
.policy = CPUFREQ_POLICY_POWERSAVE, .policy = CPUFREQ_POLICY_POWERSAVE,
.cpuinfo.max_freq = 287000, .cpuinfo = {
.cpuinfo.min_freq = 59000, .max_freq = 287000,
.cpuinfo.transition_latency = CPUFREQ_ETERNAL, .min_freq = 59000,
.transition_latency = CPUFREQ_ETERNAL,
},
}; };
static struct cpufreq_driver sa1100_driver = { static struct cpufreq_driver sa1100_driver = {
......
...@@ -298,9 +298,11 @@ static int sa1110_setspeed(struct cpufreq_policy *policy) ...@@ -298,9 +298,11 @@ static int sa1110_setspeed(struct cpufreq_policy *policy)
static struct cpufreq_policy sa1110_policy = { static struct cpufreq_policy sa1110_policy = {
.cpu = 0, .cpu = 0,
.policy = CPUFREQ_POLICY_POWERSAVE, .policy = CPUFREQ_POLICY_POWERSAVE,
.cpuinfo.max_freq = 287000, .cpuinfo = {
.cpuinfo.min_freq = 59000, .max_freq = 287000,
.cpuinfo.transition_latency = CPUFREQ_ETERNAL, .min_freq = 59000,
.transition_latency = CPUFREQ_ETERNAL,
},
}; };
static struct cpufreq_driver sa1110_driver = { static struct cpufreq_driver sa1110_driver = {
......
...@@ -92,12 +92,22 @@ static void sa1100_low_gpio_unmask(unsigned int irq) ...@@ -92,12 +92,22 @@ static void sa1100_low_gpio_unmask(unsigned int irq)
ICMR |= 1 << irq; ICMR |= 1 << irq;
} }
static int sa1100_low_gpio_wake(unsigned int irq, unsigned int on)
{
if (on)
PWER |= 1 << irq;
else
PWER &= ~(1 << irq);
return 0;
}
static struct irqchip sa1100_low_gpio_chip = { static struct irqchip sa1100_low_gpio_chip = {
.ack = sa1100_low_gpio_ack, .ack = sa1100_low_gpio_ack,
.mask = sa1100_low_gpio_mask, .mask = sa1100_low_gpio_mask,
.unmask = sa1100_low_gpio_unmask, .unmask = sa1100_low_gpio_unmask,
.rerun = sa1100_manual_rerun, .rerun = sa1100_manual_rerun,
.type = sa1100_gpio_type, .type = sa1100_gpio_type,
.wake = sa1100_low_gpio_wake,
}; };
/* /*
...@@ -166,12 +176,22 @@ static void sa1100_high_gpio_unmask(unsigned int irq) ...@@ -166,12 +176,22 @@ static void sa1100_high_gpio_unmask(unsigned int irq)
GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask; GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
} }
static int sa1100_high_gpio_wake(unsigned int irq, unsigned int on)
{
if (on)
PWER |= GPIO11_27_MASK(irq);
else
PWER &= ~GPIO11_27_MASK(irq);
return 0;
}
static struct irqchip sa1100_high_gpio_chip = { static struct irqchip sa1100_high_gpio_chip = {
.ack = sa1100_high_gpio_ack, .ack = sa1100_high_gpio_ack,
.mask = sa1100_high_gpio_mask, .mask = sa1100_high_gpio_mask,
.unmask = sa1100_high_gpio_unmask, .unmask = sa1100_high_gpio_unmask,
.rerun = sa1100_manual_rerun, .rerun = sa1100_manual_rerun,
.type = sa1100_gpio_type, .type = sa1100_gpio_type,
.wake = sa1100_high_gpio_wake,
}; };
/* /*
...@@ -252,5 +272,5 @@ void __init sa1100_init_irq(void) ...@@ -252,5 +272,5 @@ void __init sa1100_init_irq(void)
* We generally don't want the LCD IRQ being * We generally don't want the LCD IRQ being
* enabled as soon as we request it. * enabled as soon as we request it.
*/ */
set_irq_flags(IRQ_LCD, IRQF_VALID | IRQF_NOAUTOEN); set_irq_flags(IRQ_LCD, IRQF_VALID/* | IRQF_NOAUTOEN*/);
} }
...@@ -6,9 +6,13 @@ ...@@ -6,9 +6,13 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/device.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/hardware/sa1111.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
...@@ -19,33 +23,29 @@ ...@@ -19,33 +23,29 @@
#define JORTUCR_VAL 0x20000400 #define JORTUCR_VAL 0x20000400
#define JORSKCR_INIT 0x00002081 /* Turn off VCO to enable PLL, set Ready En and enable nOE assertion from DC */
#define JORSKCR_RCLK 0x00002083 /* Add turning on RCLK to above */
#define JORSKCR_VAL 0x0000001B /* sets the 1101 control register to on */
static int __init jornada720_init(void) static int __init jornada720_init(void)
{ {
GPDR |= GPIO_GPIO20; int ret = -ENODEV;
TUCR = JORTUCR_VAL; /* set the oscillator out to the SA-1101 */
GPSR = GPIO_GPIO20; if (machine_is_jornada720()) {
udelay(1); GPDR |= GPIO_GPIO20;
GPCR = GPIO_GPIO20; TUCR = JORTUCR_VAL; /* set the oscillator out to the SA-1101 */
udelay(1);
GPSR = GPIO_GPIO20;
udelay(20);
SKCR = JORSKCR_INIT; /* Turn on the PLL, enable Ready and enable nOE assertion from DC */
mdelay(100);
SBI_SKCR = JORSKCR_RCLK;/* turn on the RCLOCK */ GPSR = GPIO_GPIO20;
SBI_SMCR = 0x35; /* initialize the SMC (debug SA-1111 reset */ udelay(1);
PCCR = 0; /* initialize the S2MC (debug SA-1111 reset) */ GPCR = GPIO_GPIO20;
udelay(1);
GPSR = GPIO_GPIO20;
udelay(20);
/* LDD4 is speaker, LDD3 is microphone */ /* LDD4 is speaker, LDD3 is microphone */
PPSR &= ~(PPC_LDD3 | PPC_LDD4); PPSR &= ~(PPC_LDD3 | PPC_LDD4);
PPDR |= PPC_LDD3 | PPC_LDD4; PPDR |= PPC_LDD3 | PPC_LDD4;
return sa1111_init(0x40000000, IRQ_GPIO1); ret = sa1111_init(0x40000000, IRQ_GPIO1);
}
return ret;
} }
arch_initcall(jornada720_init); arch_initcall(jornada720_init);
......
...@@ -87,6 +87,15 @@ static inline void __init neponset_init_irq(void) ...@@ -87,6 +87,15 @@ static inline void __init neponset_init_irq(void)
set_irq_type(IRQ_GPIO25, IRQT_RISING); set_irq_type(IRQ_GPIO25, IRQT_RISING);
set_irq_chained_handler(IRQ_GPIO25, neponset_irq_handler); set_irq_chained_handler(IRQ_GPIO25, neponset_irq_handler);
/*
* We would set IRQ_GPIO25 to be a wake-up IRQ, but
* unfortunately something on the Neponset activates
* this IRQ on sleep (ethernet?)
*/
#if 0
enable_irq_wake(IRQ_GPIO25);
#endif
/* /*
* Setup other Neponset IRQs. SA1111 will be done by the * Setup other Neponset IRQs. SA1111 will be done by the
* generic SA1111 code. * generic SA1111 code.
...@@ -191,7 +200,7 @@ static int neponset_resume(struct device *dev, u32 level) ...@@ -191,7 +200,7 @@ static int neponset_resume(struct device *dev, u32 level)
} }
static struct device_driver neponset_device_driver = { static struct device_driver neponset_device_driver = {
.name = "NEPONSET", .name = "neponset",
.bus = &system_bus_type, .bus = &system_bus_type,
.suspend = neponset_suspend, .suspend = neponset_suspend,
.resume = neponset_resume, .resume = neponset_resume,
......
...@@ -56,7 +56,7 @@ static inline const char *slot_name(const struct pci_pool *pool) ...@@ -56,7 +56,7 @@ static inline const char *slot_name(const struct pci_pool *pool)
if (pdev == 0) if (pdev == 0)
return "[0]"; return "[0]";
else if (dev_is_sa1111(pdev)) else if (pcidev_is_sa1111(pdev))
return "[SA-1111]"; return "[SA-1111]";
else else
return pdev->slot_name; return pdev->slot_name;
......
...@@ -124,7 +124,7 @@ destroy_safe_buffer_pools(void) ...@@ -124,7 +124,7 @@ destroy_safe_buffer_pools(void)
/* allocate a 'safe' buffer and keep track of it */ /* allocate a 'safe' buffer and keep track of it */
static struct safe_buffer * static struct safe_buffer *
alloc_safe_buffer(struct pci_dev *hwdev, void *ptr, size_t size, int direction) alloc_safe_buffer(void *ptr, size_t size, int direction)
{ {
struct safe_buffer *buf; struct safe_buffer *buf;
struct pci_pool *pool; struct pci_pool *pool;
...@@ -254,7 +254,7 @@ static void print_map_stats(void) ...@@ -254,7 +254,7 @@ static void print_map_stats(void)
#endif #endif
static dma_addr_t static dma_addr_t
map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) map_single(void *ptr, size_t size, int direction)
{ {
dma_addr_t dma_addr; dma_addr_t dma_addr;
...@@ -267,7 +267,7 @@ map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) ...@@ -267,7 +267,7 @@ map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
DO_STATS ( bounce_count++ ) ; DO_STATS ( bounce_count++ ) ;
buf = alloc_safe_buffer(hwdev, ptr, size, direction); buf = alloc_safe_buffer(ptr, size, direction);
if (buf == 0) { if (buf == 0) {
printk(KERN_ERR printk(KERN_ERR
"%s: unable to map unsafe buffer %p!\n", "%s: unable to map unsafe buffer %p!\n",
...@@ -302,8 +302,7 @@ map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) ...@@ -302,8 +302,7 @@ map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
} }
static void static void
unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, unmap_single(dma_addr_t dma_addr, size_t size, int direction)
size_t size, int direction)
{ {
struct safe_buffer *buf; struct safe_buffer *buf;
...@@ -332,8 +331,7 @@ unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, ...@@ -332,8 +331,7 @@ unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
} }
static void static void
sync_single(struct pci_dev *hwdev, dma_addr_t dma_addr, sync_single(dma_addr_t dma_addr, size_t size, int direction)
size_t size, int direction)
{ {
struct safe_buffer *buf; struct safe_buffer *buf;
...@@ -381,20 +379,19 @@ sync_single(struct pci_dev *hwdev, dma_addr_t dma_addr, ...@@ -381,20 +379,19 @@ sync_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
* (basically move the buffer from an unsafe area to a safe one) * (basically move the buffer from an unsafe area to a safe one)
*/ */
dma_addr_t dma_addr_t
sa1111_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) sa1111_map_single(void *ptr, size_t size, int direction)
{ {
unsigned long flags; unsigned long flags;
dma_addr_t dma_addr; dma_addr_t dma_addr;
DPRINTK("%s(hwdev=%p,ptr=%p,size=%d,dir=%x)\n", DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
__func__, hwdev, ptr, size, direction); __func__, ptr, size, direction);
BUG_ON(hwdev != SA1111_FAKE_PCIDEV);
BUG_ON(direction == PCI_DMA_NONE); BUG_ON(direction == PCI_DMA_NONE);
local_irq_save(flags); local_irq_save(flags);
dma_addr = map_single(hwdev, ptr, size, direction); dma_addr = map_single(ptr, size, direction);
local_irq_restore(flags); local_irq_restore(flags);
...@@ -409,35 +406,31 @@ sa1111_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) ...@@ -409,35 +406,31 @@ sa1111_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
*/ */
void void
sa1111_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, sa1111_unmap_single(dma_addr_t dma_addr, size_t size, int direction)
size_t size, int direction)
{ {
unsigned long flags; unsigned long flags;
DPRINTK("%s(hwdev=%p,ptr=%p,size=%d,dir=%x)\n", DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
__func__, hwdev, (void *) dma_addr, size, direction); __func__, (void *) dma_addr, size, direction);
BUG_ON(hwdev != SA1111_FAKE_PCIDEV);
BUG_ON(direction == PCI_DMA_NONE); BUG_ON(direction == PCI_DMA_NONE);
local_irq_save(flags); local_irq_save(flags);
unmap_single(hwdev, dma_addr, size, direction); unmap_single(dma_addr, size, direction);
local_irq_restore(flags); local_irq_restore(flags);
} }
int int
sa1111_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, sa1111_map_sg(struct scatterlist *sg, int nents, int direction)
int nents, int direction)
{ {
unsigned long flags; unsigned long flags;
int i; int i;
DPRINTK("%s(hwdev=%p,sg=%p,nents=%d,dir=%x)\n", DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n",
__func__, hwdev, sg, nents, direction); __func__, sg, nents, direction);
BUG_ON(hwdev != SA1111_FAKE_PCIDEV);
BUG_ON(direction == PCI_DMA_NONE); BUG_ON(direction == PCI_DMA_NONE);
local_irq_save(flags); local_irq_save(flags);
...@@ -449,7 +442,7 @@ sa1111_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, ...@@ -449,7 +442,7 @@ sa1111_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
void *ptr = page_address(page) + offset; void *ptr = page_address(page) + offset;
sg->dma_address = sg->dma_address =
map_single(hwdev, ptr, length, direction); map_single(ptr, length, direction);
} }
local_irq_restore(flags); local_irq_restore(flags);
...@@ -458,16 +451,14 @@ sa1111_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, ...@@ -458,16 +451,14 @@ sa1111_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
} }
void void
sa1111_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, sa1111_unmap_sg(struct scatterlist *sg, int nents, int direction)
int direction)
{ {
unsigned long flags; unsigned long flags;
int i; int i;
DPRINTK("%s(hwdev=%p,sg=%p,nents=%d,dir=%x)\n", DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n",
__func__, hwdev, sg, nents, direction); __func__, sg, nents, direction);
BUG_ON(hwdev != SA1111_FAKE_PCIDEV);
BUG_ON(direction == PCI_DMA_NONE); BUG_ON(direction == PCI_DMA_NONE);
local_irq_save(flags); local_irq_save(flags);
...@@ -476,41 +467,36 @@ sa1111_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, ...@@ -476,41 +467,36 @@ sa1111_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
dma_addr_t dma_addr = sg->dma_address; dma_addr_t dma_addr = sg->dma_address;
unsigned int length = sg->length; unsigned int length = sg->length;
unmap_single(hwdev, dma_addr, length, direction); unmap_single(dma_addr, length, direction);
} }
local_irq_restore(flags); local_irq_restore(flags);
} }
void void
sa1111_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_addr, sa1111_dma_sync_single(dma_addr_t dma_addr, size_t size, int direction)
size_t size, int direction)
{ {
unsigned long flags; unsigned long flags;
DPRINTK("%s(hwdev=%p,ptr=%p,size=%d,dir=%x)\n", DPRINTK("%s(ptr=%p,size=%d,dir=%x)\n",
__func__, hwdev, (void *) dma_addr, size, direction); __func__, (void *) dma_addr, size, direction);
BUG_ON(hwdev != SA1111_FAKE_PCIDEV);
local_irq_save(flags); local_irq_save(flags);
sync_single(hwdev, dma_addr, size, direction); sync_single(dma_addr, size, direction);
local_irq_restore(flags); local_irq_restore(flags);
} }
void void
sa1111_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, sa1111_dma_sync_sg(struct scatterlist *sg, int nents, int direction)
int nents, int direction)
{ {
unsigned long flags; unsigned long flags;
int i; int i;
DPRINTK("%s(hwdev=%p,sg=%p,nents=%d,dir=%x)\n", DPRINTK("%s(sg=%p,nents=%d,dir=%x)\n",
__func__, hwdev, sg, nents, direction); __func__, sg, nents, direction);
BUG_ON(hwdev != SA1111_FAKE_PCIDEV);
BUG_ON(direction == PCI_DMA_NONE); BUG_ON(direction == PCI_DMA_NONE);
local_irq_save(flags); local_irq_save(flags);
...@@ -519,7 +505,7 @@ sa1111_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, ...@@ -519,7 +505,7 @@ sa1111_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg,
dma_addr_t dma_addr = sg->dma_address; dma_addr_t dma_addr = sg->dma_address;
unsigned int length = sg->length; unsigned int length = sg->length;
sync_single(hwdev, dma_addr, length, direction); sync_single(dma_addr, length, direction);
} }
local_irq_restore(flags); local_irq_restore(flags);
......
...@@ -249,6 +249,19 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags) ...@@ -249,6 +249,19 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
INTPOL0 &= ~mask; INTPOL0 &= ~mask;
else else
INTPOL0 |= mask; INTPOL0 |= mask;
WAKE_POL0 = INTPOL0;
return 0;
}
static int sa1111_wake_lowirq(unsigned int irq, unsigned int on)
{
unsigned int mask = SA1111_IRQMASK_LO(irq);
if (on)
WAKE_EN0 |= mask;
else
WAKE_EN0 &= ~mask;
return 0; return 0;
} }
...@@ -259,6 +272,7 @@ static struct irqchip sa1111_low_chip = { ...@@ -259,6 +272,7 @@ static struct irqchip sa1111_low_chip = {
.unmask = sa1111_unmask_lowirq, .unmask = sa1111_unmask_lowirq,
.rerun = sa1111_rerun_lowirq, .rerun = sa1111_rerun_lowirq,
.type = sa1111_type_lowirq, .type = sa1111_type_lowirq,
.wake = sa1111_wake_lowirq,
}; };
static void sa1111_mask_highirq(unsigned int irq) static void sa1111_mask_highirq(unsigned int irq)
...@@ -309,6 +323,19 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags) ...@@ -309,6 +323,19 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
INTPOL1 &= ~mask; INTPOL1 &= ~mask;
else else
INTPOL1 |= mask; INTPOL1 |= mask;
WAKE_POL1 = INTPOL1;
return 0;
}
static int sa1111_wake_highirq(unsigned int irq, unsigned int on)
{
unsigned int mask = SA1111_IRQMASK_HI(irq);
if (on)
WAKE_EN1 |= mask;
else
WAKE_EN1 &= ~mask;
return 0; return 0;
} }
...@@ -319,6 +346,7 @@ static struct irqchip sa1111_high_chip = { ...@@ -319,6 +346,7 @@ static struct irqchip sa1111_high_chip = {
.unmask = sa1111_unmask_highirq, .unmask = sa1111_unmask_highirq,
.rerun = sa1111_rerun_highirq, .rerun = sa1111_rerun_highirq,
.type = sa1111_type_highirq, .type = sa1111_type_highirq,
.wake = sa1111_wake_highirq,
}; };
static void __init sa1111_init_irq(struct sa1111_dev *sadev) static void __init sa1111_init_irq(struct sa1111_dev *sadev)
...@@ -854,7 +882,7 @@ static int sa1111_remove(struct device *dev) ...@@ -854,7 +882,7 @@ static int sa1111_remove(struct device *dev)
* PXA250/SA1110 machine classes. * PXA250/SA1110 machine classes.
*/ */
static struct device_driver sa1111_device_driver = { static struct device_driver sa1111_device_driver = {
.name = "SA1111", .name = "sa1111",
.bus = &system_bus_type, .bus = &system_bus_type,
.probe = sa1111_probe, .probe = sa1111_probe,
.remove = sa1111_remove, .remove = sa1111_remove,
......
...@@ -94,17 +94,6 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) ...@@ -94,17 +94,6 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
return NULL; return NULL;
} }
void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handle)
{
int gfp = GFP_KERNEL;
if (hwdev == NULL || dev_is_sa1111(hwdev) ||
hwdev->dma_mask != 0xffffffff)
gfp |= GFP_DMA;
return consistent_alloc(gfp, size, handle);
}
/* /*
* free a page as defined by the above mapping. We expressly forbid * free a page as defined by the above mapping. We expressly forbid
* calling this from interrupt context. * calling this from interrupt context.
......
...@@ -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 Nov 16 15:57:50 2002 # Last update: Mon Dec 23 18:49:04 2002
# #
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
# #
...@@ -154,7 +154,7 @@ piranha ARCH_PIRANHA PIRANHA 142 ...@@ -154,7 +154,7 @@ piranha ARCH_PIRANHA PIRANHA 142
sbcamelot SA1100_SBCAMELOT SBCAMELOT 143 sbcamelot SA1100_SBCAMELOT SBCAMELOT 143
kings SA1100_KINGS KINGS 144 kings SA1100_KINGS KINGS 144
smdk2400 ARCH_SMDK2400 SMDK2400 145 smdk2400 ARCH_SMDK2400 SMDK2400 145
collie ARCH_COLLIE COLLIE 146 collie SA1100_COLLIE COLLIE 146
idr ARCH_IDR IDR 147 idr ARCH_IDR IDR 147
badge4 SA1100_BADGE4 BADGE4 148 badge4 SA1100_BADGE4 BADGE4 148
webnet ARCH_WEBNET WEBNET 149 webnet ARCH_WEBNET WEBNET 149
...@@ -258,3 +258,18 @@ chimp ARCH_CHIMP CHIMP 246 ...@@ -258,3 +258,18 @@ chimp ARCH_CHIMP CHIMP 246
stork_nest ARCH_STORK_NEST STORK_NEST 247 stork_nest ARCH_STORK_NEST STORK_NEST 247
stork_egg ARCH_STORK_EGG STORK_EGG 248 stork_egg ARCH_STORK_EGG STORK_EGG 248
wismo SA1100_WISMO WISMO 249 wismo SA1100_WISMO WISMO 249
ezlinx ARCH_EZLINX EZLINX 250
at91rm9200 ARCH_AT91 AT91 251
orion ARCH_ORION ORION 252
neptune ARCH_NEPTUNE NEPTUNE 253
hackkit SA1100_HACKKIT HACKKIT 254
pxa_wins30 ARCH_PXA_WINS30 PXA_WINS30 255
lavinna SA1100_LAVINNA LAVINNA 256
pxa_uengine ARCH_PXA_UENGINE PXA_UENGINE 257
innokom ARCH_INNOKOM INNOKOM 258
bms ARCH_BMS BMS 259
ixcdp1100 ARCH_IXCDP1100 IXCDP1100 260
prpmc1100 ARCH_PRPMC1100 PRPMC1100 261
at91rm9200dk ARCH_AT91RM9200DK AT91RM9200DK 262
armstick ARCH_ARMSTICK ARMSTICK 263
armonie ARCH_ARMONIE ARMONIE 264
...@@ -26,6 +26,9 @@ SECTIONS ...@@ -26,6 +26,9 @@ SECTIONS
__setup_start = .; __setup_start = .;
*(.init.setup) *(.init.setup)
__setup_end = .; __setup_end = .;
__start___param = .;
*(__param)
__stop___param = .;
__initcall_start = .; __initcall_start = .;
*(.initcall1.init) *(.initcall1.init)
*(.initcall2.init) *(.initcall2.init)
......
...@@ -145,6 +145,8 @@ static int ps2_open(struct serio *io) ...@@ -145,6 +145,8 @@ static int ps2_open(struct serio *io)
ps2if->open = 1; ps2if->open = 1;
enable_irq_wake(ps2if->dev->irq[0]);
sa1111_writel(PS2CR_ENA, ps2if->base + SA1111_PS2CR); sa1111_writel(PS2CR_ENA, ps2if->base + SA1111_PS2CR);
return 0; return 0;
} }
...@@ -155,6 +157,8 @@ static void ps2_close(struct serio *io) ...@@ -155,6 +157,8 @@ static void ps2_close(struct serio *io)
sa1111_writel(0, ps2if->base + SA1111_PS2CR); sa1111_writel(0, ps2if->base + SA1111_PS2CR);
disable_irq_wake(ps2if->dev->irq[0]);
ps2if->open = 0; ps2if->open = 0;
free_irq(ps2if->dev->irq[1], ps2if); free_irq(ps2if->dev->irq[1], ps2if);
...@@ -337,7 +341,7 @@ static int ps2_resume(struct device *dev, u32 level) ...@@ -337,7 +341,7 @@ static int ps2_resume(struct device *dev, u32 level)
*/ */
static struct sa1111_driver ps2_driver = { static struct sa1111_driver ps2_driver = {
.drv = { .drv = {
.name = "SA1111 PS2", .name = "sa1111-ps2",
.bus = &sa1111_bus_type, .bus = &sa1111_bus_type,
.probe = ps2_probe, .probe = ps2_probe,
.remove = ps2_remove, .remove = ps2_remove,
......
...@@ -6,9 +6,12 @@ ...@@ -6,9 +6,12 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/hardware/sa1111.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include "sa1100_generic.h" #include "sa1100_generic.h"
...@@ -76,6 +79,9 @@ printk("%s(): config socket %d vcc %d vpp %d\n", __FUNCTION__, ...@@ -76,6 +79,9 @@ printk("%s(): config socket %d vcc %d vpp %d\n", __FUNCTION__,
case 50: pa_dwr_set = SOCKET1_POWER; break; case 50: pa_dwr_set = SOCKET1_POWER; break;
} }
break; break;
default:
return -1;
} }
if (conf->vpp != conf->vcc && conf->vpp != 0) { if (conf->vpp != conf->vcc && conf->vpp != 0) {
...@@ -90,7 +96,7 @@ printk("%s(): config socket %d vcc %d vpp %d\n", __FUNCTION__, ...@@ -90,7 +96,7 @@ printk("%s(): config socket %d vcc %d vpp %d\n", __FUNCTION__,
local_irq_save(flags); local_irq_save(flags);
PA_DWR = (PA_DWR & ~pa_dwr_mask) | pa_dwr_set; PA_DWR = (PA_DWR & ~pa_dwr_mask) | pa_dwr_set;
locla_irq_restore(flags); local_irq_restore(flags);
} }
return ret; return ret;
...@@ -117,7 +123,7 @@ int __init pcmcia_jornada720_init(void) ...@@ -117,7 +123,7 @@ int __init pcmcia_jornada720_init(void)
return ret; return ret;
} }
void __exit pcmcia_jornada720_exit(void) void __devexit pcmcia_jornada720_exit(void)
{ {
sa1100_unregister_pcmcia(&jornada720_pcmcia_ops); sa1100_unregister_pcmcia(&jornada720_pcmcia_ops);
} }
...@@ -36,11 +36,11 @@ int sa1111_pcmcia_init(struct pcmcia_init *init) ...@@ -36,11 +36,11 @@ int sa1111_pcmcia_init(struct pcmcia_init *init)
int i, ret; int i, ret;
for (i = ret = 0; i < ARRAY_SIZE(irqs); i++) { for (i = ret = 0; i < ARRAY_SIZE(irqs); i++) {
set_irq_type(irqs[i].irq, IRQT_FALLING);
ret = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT, ret = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
irqs[i].str, NULL); irqs[i].str, NULL);
if (ret) if (ret)
break; break;
set_irq_type(irqs[i].irq, IRQT_FALLING);
} }
if (i < ARRAY_SIZE(irqs)) { if (i < ARRAY_SIZE(irqs)) {
...@@ -280,7 +280,7 @@ static int pcmcia_resume(struct device *dev, u32 level) ...@@ -280,7 +280,7 @@ static int pcmcia_resume(struct device *dev, u32 level)
static struct sa1111_driver pcmcia_driver = { static struct sa1111_driver pcmcia_driver = {
.drv = { .drv = {
.name = "SA1111 PCMCIA", .name = "sa1111-pcmcia",
.bus = &sa1111_bus_type, .bus = &sa1111_bus_type,
.probe = pcmcia_probe, .probe = pcmcia_probe,
.remove = __devexit_p(pcmcia_remove), .remove = __devexit_p(pcmcia_remove),
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H
#include <linux/config.h> #include <linux/config.h>
#include <asm/arch/iop310.h>
/* /*
* Task size: 3GB * Task size: 3GB
......
#ifndef _ASMARM_CURRENT_H #ifndef _ASMARM_CURRENT_H
#define _ASMARM_CURRENT_H #define _ASMARM_CURRENT_H
#include <asm/thread_info.h> #include <linux/thread_info.h>
static inline struct task_struct *get_current(void) __attribute__ (( __const__ )); static inline struct task_struct *get_current(void) __attribute__ (( __const__ ));
......
#include <asm-generic/dma-mapping.h> #ifndef ASMARM_DMA_MAPPING_H
#define ASMARM_DMA_MAPPING_H
#ifdef __KERNEL__
#include <linux/config.h>
#include <linux/mm.h> /* need struct page */
#include <asm/scatterlist.h>
/*
* DMA-consistent mapping functions. These allocate/free a region of
* uncached, unwrite-buffered mapped memory space for use with DMA
* devices. This is the "generic" version. The PCI specific version
* is in pci.h
*/
extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle);
extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle);
extern void consistent_sync(void *kaddr, size_t size, int rw);
/*
* For SA-1111 these functions are "magic" and utilize bounce
* bufferes as needed to work around SA-1111 DMA bugs.
*/
dma_addr_t sa1111_map_single(void *, size_t, int);
void sa1111_unmap_single(dma_addr_t, size_t, int);
int sa1111_map_sg(struct scatterlist *, int, int);
void sa1111_unmap_sg(struct scatterlist *, int, int);
void sa1111_dma_sync_single(dma_addr_t, size_t, int);
void sa1111_dma_sync_sg(struct scatterlist *, int, int);
#ifdef CONFIG_SA1111
extern struct bus_type sa1111_bus_type;
#define dmadev_is_sa1111(dev) ((dev)->bus == &sa1111_bus_type)
#else
#define dmadev_is_sa1111(dev) (0)
#endif
/*
* Return whether the given device DMA address mask can be supported
* properly. For example, if your device can only drive the low 24-bits
* during PCI bus mastering, then you would pass 0x00ffffff as the mask
* to this function.
*/
static inline int dma_supported(struct device *dev, u64 mask)
{
return 1;
}
static inline int dma_set_mask(struct device *dev, u64 dma_mask)
{
if (!dev->dma_mask || !dma_supported(dev, dma_mask))
return -EIO;
*dev->dma_mask = dma_mask;
return 0;
}
static inline int dma_get_cache_alignment(void)
{
return 32;
}
static inline int dma_is_consistent(dma_addr_t handle)
{
return 0;
}
/**
* dma_alloc_coherent - allocate consistent memory for DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @size: required memory size
* @handle: bus-specific DMA address
*
* Allocate some uncached, unbuffered memory for a device for
* performing DMA. This function allocates pages, and will
* return the CPU-viewed address, and sets @handle to be the
* device-viewed address.
*/
static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle)
{
int gfp = GFP_KERNEL;
if (dev == NULL || dmadev_is_sa1111(dev) || *dev->dma_mask != 0xffffffff)
gfp |= GFP_DMA;
return consistent_alloc(gfp, size, handle);
}
/**
* dma_free_coherent - free memory allocated by dma_alloc_coherent
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @size: size of memory originally requested in dma_alloc_coherent
* @cpu_addr: CPU-view address returned from dma_alloc_coherent
* @handle: device-view address returned from dma_alloc_coherent
*
* Free (and unmap) a DMA buffer previously allocated by
* dma_alloc_coherent().
*
* References to memory and mappings associated with cpu_addr/handle
* during and after this call executing are illegal.
*/
static inline void
dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t handle)
{
consistent_free(cpu_addr, size, handle);
}
/**
* dma_map_single - map a single buffer for streaming DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @cpu_addr: CPU direct mapped address of buffer
* @size: size of buffer to map
* @dir: DMA transfer direction
*
* Ensure that any data held in the cache is appropriately discarded
* or written back.
*
* The device owns this memory once this call has completed. The CPU
* can regain ownership by calling dma_unmap_single() or dma_sync_single().
*/
static inline dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
enum dma_data_direction dir)
{
if (dmadev_is_sa1111(dev))
return sa1111_map_single(cpu_addr, size, dir);
consistent_sync(cpu_addr, size, dir);
return __virt_to_bus((unsigned long)cpu_addr);
}
/**
* dma_unmap_single - unmap a single buffer previously mapped
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @handle: DMA address of buffer
* @size: size of buffer to map
* @dir: DMA transfer direction
*
* Unmap a single streaming mode DMA translation. The handle and size
* must match what was provided in the previous dma_map_single() call.
* All other usages are undefined.
*
* After this call, reads by the CPU to the buffer are guaranteed to see
* whatever the device wrote there.
*/
static inline void
dma_unmap_single(struct device *dev, dma_addr_t handle, size_t size,
enum dma_data_direction dir)
{
if (dmadev_is_sa1111(dev))
sa1111_unmap_single(handle, size, dir);
/* nothing to do */
}
#if 0
static inline dma_addr_t
dma_map_page(struct device *dev, struct page *page, unsigned long off,
size_t size, enum dma_data_direction dir)
{
/* fixme */
}
static inline void
dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
enum dma_data_direction dir)
{
/* fixme */
}
#endif
/**
* dma_map_sg - map a set of SG buffers for streaming mode DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @sg: list of buffers
* @nents: number of buffers to map
* @dir: DMA transfer direction
*
* Map a set of buffers described by scatterlist in streaming
* mode for DMA. This is the scather-gather version of the
* above pci_map_single interface. Here the scatter gather list
* elements are each tagged with the appropriate dma address
* and length. They are obtained via sg_dma_{address,length}(SG).
*
* NOTE: An implementation may be able to use a smaller number of
* DMA address/length pairs than there are SG table elements.
* (for example via virtual mapping capabilities)
* The routine returns the number of addr/length pairs actually
* used, at most nents.
*
* Device ownership issues as mentioned above for pci_map_single are
* the same here.
*/
static inline int
dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
int i;
if (dmadev_is_sa1111(dev))
return sa1111_map_sg(sg, nents, dir);
for (i = 0; i < nents; i++, sg++) {
char *virt;
sg->dma_address = page_to_bus(sg->page) + sg->offset;
virt = page_address(sg->page) + sg->offset;
consistent_sync(virt, sg->length, dir);
}
return nents;
}
/**
* dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @sg: list of buffers
* @nents: number of buffers to map
* @dir: DMA transfer direction
*
* Unmap a set of streaming mode DMA translations.
* Again, CPU read rules concerning calls here are the same as for
* pci_unmap_single() above.
*/
static inline void
dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
if (dmadev_is_sa1111(dev)) {
sa1111_unmap_sg(sg, nents, dir);
return;
}
/* nothing to do */
}
/**
* dma_sync_single
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @handle: DMA address of buffer
* @size: size of buffer to map
* @dir: DMA transfer direction
*
* Make physical memory consistent for a single streaming mode DMA
* translation after a transfer.
*
* If you perform a pci_map_single() but wish to interrogate the
* buffer using the cpu, yet do not wish to teardown the PCI dma
* mapping, you must call this function before doing so. At the
* next point you give the PCI dma address back to the card, the
* device again owns the buffer.
*/
static inline void
dma_sync_single(struct device *dev, dma_addr_t handle, size_t size,
enum dma_data_direction dir)
{
if (dmadev_is_sa1111(dev)) {
sa1111_dma_sync_single(handle, size, dir);
return;
}
consistent_sync((void *)__bus_to_virt(handle), size, dir);
}
/**
* dma_sync_sg
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @sg: list of buffers
* @nents: number of buffers to map
* @dir: DMA transfer direction
*
* Make physical memory consistent for a set of streaming
* mode DMA translations after a transfer.
*
* The same as pci_dma_sync_single but for a scatter-gather list,
* same rules and usage.
*/
static inline void
dma_sync_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
int i;
if (dmadev_is_sa1111(dev)) {
sa1111_dma_sync_sg(sg, nents, dir);
return;
}
for (i = 0; i < nents; i++, sg++) {
char *virt = page_address(sg->page) + sg->offset;
consistent_sync(virt, sg->length, dir);
}
}
#endif /* __KERNEL__ */
#endif
...@@ -267,16 +267,6 @@ extern void __iounmap(void *addr); ...@@ -267,16 +267,6 @@ extern void __iounmap(void *addr);
#define iounmap(cookie) __arch_iounmap(cookie) #define iounmap(cookie) __arch_iounmap(cookie)
#endif #endif
/*
* DMA-consistent mapping functions. These allocate/free a region of
* uncached, unwrite-buffered mapped memory space for use with DMA
* devices. This is the "generic" version. The PCI specific version
* is in pci.h
*/
extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle);
extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle);
extern void consistent_sync(void *vaddr, size_t size, int rw);
/* /*
* can the hardware map this into one segment or not, given no other * can the hardware map this into one segment or not, given no other
* constraints. * constraints.
......
...@@ -40,7 +40,8 @@ extern void enable_irq(unsigned int); ...@@ -40,7 +40,8 @@ extern void enable_irq(unsigned int);
#define IRQT_PROBE (1 << 4) #define IRQT_PROBE (1 << 4)
int set_irq_type(unsigned int irq, unsigned int type); int set_irq_type(unsigned int irq, unsigned int type);
void disable_irq_wake(unsigned int irq);
void enable_irq_wake(unsigned int irq);
int setup_irq(unsigned int, struct irqaction *); int setup_irq(unsigned int, struct irqaction *);
#endif #endif
......
...@@ -40,6 +40,10 @@ struct irqchip { ...@@ -40,6 +40,10 @@ struct irqchip {
* Set the type of the IRQ. * Set the type of the IRQ.
*/ */
int (*type)(unsigned int, unsigned int); int (*type)(unsigned int, unsigned int);
/*
* Set wakeup-enable on the selected IRQ
*/
int (*wake)(unsigned int, unsigned int);
}; };
struct irqdesc { struct irqdesc {
......
...@@ -3,36 +3,20 @@ ...@@ -3,36 +3,20 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/config.h> #include <linux/config.h>
#include <linux/mm.h> /* bah! */ #include <linux/dma-mapping.h>
#include <asm/arch/hardware.h> #include <asm/hardware.h> /* for PCIBIOS_MIN_* */
#include <asm/scatterlist.h>
#include <asm/page.h>
#include <asm/io.h>
struct pci_dev;
#ifdef CONFIG_SA1111
/* /*
* For SA-1111 these functions are "magic" and utilize bounce * Keep the SA1111 DMA-mapping tricks until the USB layer gets
* buffers as need to workaround SA-1111 DMA bugs. They are called in * properly converted to the new DMA-mapping API, at which time
* place of their pci_* counterparts when dev_is_sa1111() returns true. * most of this file can die.
*/ */
dma_addr_t sa1111_map_single(struct pci_dev *, void *, size_t, int);
void sa1111_unmap_single(struct pci_dev *, dma_addr_t, size_t, int);
int sa1111_map_sg(struct pci_dev *, struct scatterlist *, int, int);
void sa1111_unmap_sg(struct pci_dev *, struct scatterlist *, int, int);
void sa1111_dma_sync_single(struct pci_dev *, dma_addr_t, size_t, int);
void sa1111_dma_sync_sg(struct pci_dev *, struct scatterlist *, int, int);
#ifdef CONFIG_SA1111
#define SA1111_FAKE_PCIDEV ((struct pci_dev *) 1111) #define SA1111_FAKE_PCIDEV ((struct pci_dev *) 1111)
#define dev_is_sa1111(dev) (dev == SA1111_FAKE_PCIDEV) #define pcidev_is_sa1111(dev) (dev == SA1111_FAKE_PCIDEV)
#else #else
#define pcidev_is_sa1111(dev) (0)
#define dev_is_sa1111(dev) (0)
#endif #endif
...@@ -46,200 +30,116 @@ static inline void pcibios_penalize_isa_irq(int irq) ...@@ -46,200 +30,116 @@ static inline void pcibios_penalize_isa_irq(int irq)
/* We don't do dynamic PCI IRQ allocation */ /* We don't do dynamic PCI IRQ allocation */
} }
/* The PCI address space does equal the physical memory /*
* address space. The networking and block device layers use * The PCI address space does equal the physical memory address space.
* this boolean for bounce buffer decisions. * The networking and block device layers use this boolean for bounce
* buffer decisions.
*/ */
#define PCI_DMA_BUS_IS_PHYS (0) #define PCI_DMA_BUS_IS_PHYS (0)
/* Allocate and map kernel buffer using consistent mode DMA for a device. static inline void *
* hwdev should be valid struct pci_dev pointer for PCI devices, pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handle)
* NULL for PCI-like buses (ISA, EISA). {
* Returns non-NULL cpu-view pointer to the buffer if successful and int gfp = GFP_KERNEL;
* sets *dma_addrp to the pci side dma address as well, else *dma_addrp
* is undefined. if (hwdev == NULL || pcidev_is_sa1111(hwdev) ||
*/ hwdev->dma_mask != 0xffffffff)
extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handle); gfp |= GFP_DMA;
return consistent_alloc(gfp, size, handle);
}
/* Free and unmap a consistent DMA buffer.
* cpu_addr is what was returned from pci_alloc_consistent,
* size must be the same as what as passed into pci_alloc_consistent,
* and likewise dma_addr must be the same as what *dma_addrp was set to.
*
* References to the memory and mappings associated with cpu_addr/dma_addr
* past this call are illegal.
*/
static inline void static inline void
pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr,
dma_addr_t dma_handle) dma_addr_t handle)
{ {
consistent_free(vaddr, size, dma_handle); dma_free_coherent(hwdev ? &hwdev->dev : NULL, size, vaddr, handle);
} }
/* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
*
* Once the device is given the dma address, the device owns this memory
* until either pci_unmap_single or pci_dma_sync_single is performed.
*/
static inline dma_addr_t static inline dma_addr_t
pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int dir)
{ {
if (dev_is_sa1111(hwdev)) if (pcidev_is_sa1111(hwdev))
return sa1111_map_single(hwdev, ptr, size, direction); return sa1111_map_single(ptr, size, dir);
consistent_sync(ptr, size, direction); return dma_map_single(hwdev ? &hwdev->dev : NULL, ptr, size, dir);
return virt_to_bus(ptr);
} }
/* Unmap a single streaming mode DMA translation. The dma_addr and size
* must match what was provided for in a previous pci_map_single call. All
* other usages are undefined.
*
* After this call, reads by the cpu to the buffer are guarenteed to see
* whatever the device wrote there.
*/
static inline void static inline void
pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) pci_unmap_single(struct pci_dev *hwdev, dma_addr_t handle, size_t size, int dir)
{ {
if (dev_is_sa1111(hwdev)) if (pcidev_is_sa1111(hwdev)) {
sa1111_unmap_single(hwdev, dma_addr, size, direction); sa1111_unmap_single(handle, size, dir);
return;
}
/* nothing to do */ return dma_unmap_single(hwdev ? &hwdev->dev : NULL, handle, size, dir);
} }
/*
* Whether pci_unmap_{single,page} is a nop depends upon the
* configuration.
*/
#if defined(CONFIG_PCI) || defined(CONFIG_SA1111)
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME;
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME;
#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME)
#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL))
#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
#else
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
#define pci_unmap_addr(PTR, ADDR_NAME) (0)
#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
#define pci_unmap_len(PTR, LEN_NAME) (0)
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
#endif /* CONFIG_PCI */
/* Map a set of buffers described by scatterlist in streaming
* mode for DMA. This is the scather-gather version of the
* above pci_map_single interface. Here the scatter gather list
* elements are each tagged with the appropriate dma address
* and length. They are obtained via sg_dma_{address,length}(SG).
*
* NOTE: An implementation may be able to use a smaller number of
* DMA address/length pairs than there are SG table elements.
* (for example via virtual mapping capabilities)
* The routine returns the number of addr/length pairs actually
* used, at most nents.
*
* Device ownership issues as mentioned above for pci_map_single are
* the same here.
*/
static inline int static inline int
pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int dir)
{ {
int i; if (pcidev_is_sa1111(hwdev))
return sa1111_map_sg(sg, nents, dir);
if (dev_is_sa1111(hwdev))
return sa1111_map_sg(hwdev, sg, nents, direction);
for (i = 0; i < nents; i++, sg++) {
char *virt;
sg->dma_address = page_to_bus(sg->page) + sg->offset;
virt = page_address(sg->page) + sg->offset;
consistent_sync(virt, sg->length, direction);
}
return nents; return dma_map_sg(hwdev ? &hwdev->dev : NULL, sg, nents, dir);
} }
/* Unmap a set of streaming mode DMA translations.
* Again, cpu read rules concerning calls here are the same as for
* pci_unmap_single() above.
*/
static inline void static inline void
pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int dir)
{ {
if (dev_is_sa1111(hwdev)) { if (pcidev_is_sa1111(hwdev)) {
sa1111_unmap_sg(hwdev, sg, nents, direction); sa1111_unmap_sg(sg, nents, dir);
return; return;
} }
/* nothing to do */ return dma_unmap_sg(hwdev ? &hwdev->dev : NULL, sg, nents, dir);
} }
/* Make physical memory consistent for a single
* streaming mode DMA translation after a transfer.
*
* If you perform a pci_map_single() but wish to interrogate the
* buffer using the cpu, yet do not wish to teardown the PCI dma
* mapping, you must call this function before doing so. At the
* next point you give the PCI dma address back to the card, the
* device again owns the buffer.
*/
static inline void static inline void
pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t handle, size_t size, int dir)
{ {
if (dev_is_sa1111(hwdev)) { if (pcidev_is_sa1111(hwdev)) {
sa1111_dma_sync_single(hwdev, dma_handle, size, direction); sa1111_dma_sync_single(handle, size, dir);
return; return;
} }
consistent_sync(bus_to_virt(dma_handle), size, direction); return dma_sync_single(hwdev ? &hwdev->dev : NULL, handle, size, dir);
} }
/* Make physical memory consistent for a set of streaming
* mode DMA translations after a transfer.
*
* The same as pci_dma_sync_single but for a scatter-gather list,
* same rules and usage.
*/
static inline void static inline void
pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int dir)
{ {
int i; if (pcidev_is_sa1111(hwdev)) {
sa1111_dma_sync_sg(sg, nelems, dir);
if (dev_is_sa1111(hwdev)) {
sa1111_dma_sync_sg(hwdev, sg, nelems, direction);
return; return;
} }
for (i = 0; i < nelems; i++, sg++) { return dma_sync_sg(hwdev ? &hwdev->dev : NULL, sg, nelems, dir);
char *virt = page_address(sg->page) + sg->offset;
consistent_sync(virt, sg->length, direction);
}
} }
/* Return whether the given PCI device DMA address mask can
* be supported properly. For example, if your device can
* only drive the low 24-bits during PCI bus mastering, then
* you would pass 0x00ffffff as the mask to this function.
*/
static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
{ {
return 1; return 1;
} }
/* This isn't fine. */ /*
* We don't support DAC DMA cycles.
*/
#define pci_dac_dma_supported(pci_dev, mask) (0) #define pci_dac_dma_supported(pci_dev, mask) (0)
/* Return the index of the PCI controller for device PDEV. */ /*
* Return the index of the PCI controller for device PDEV.
*/
#define pci_controller_num(PDEV) (0) #define pci_controller_num(PDEV) (0)
#if defined(CONFIG_SA1111) && !defined(CONFIG_PCI) #if defined(CONFIG_SA1111) && !defined(CONFIG_PCI)
/* SA-1111 needs these prototypes even when !defined(CONFIG_PCI) */ /*
* SA-1111 needs these prototypes even when !defined(CONFIG_PCI)
/* kmem_cache style wrapper around pci_alloc_consistent() */ *
* kmem_cache style wrapper around pci_alloc_consistent()
*/
struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev, struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
size_t size, size_t align, size_t allocation); size_t size, size_t align, size_t allocation);
void pci_pool_destroy (struct pci_pool *pool); void pci_pool_destroy (struct pci_pool *pool);
...@@ -248,6 +148,26 @@ void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle); ...@@ -248,6 +148,26 @@ void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr); void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
#endif #endif
/*
* Whether pci_unmap_{single,page} is a nop depends upon the
* configuration.
*/
#if defined(CONFIG_PCI) || defined(CONFIG_SA1111)
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME;
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME;
#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME)
#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL))
#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
#else
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
#define pci_unmap_addr(PTR, ADDR_NAME) (0)
#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
#define pci_unmap_len(PTR, LEN_NAME) (0)
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
#endif
#define HAVE_PCI_MMAP #define HAVE_PCI_MMAP
extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine); enum pci_mmap_state mmap_state, int write_combine);
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
" blmi " #fail \ " blmi " #fail \
: \ : \
: "r" (ptr), "I" (1) \ : "r" (ptr), "I" (1) \
: "ip", "lr", "cc"); \ : "ip", "lr", "cc", "memory"); \
}) })
#define __down_op_ret(ptr,fail) \ #define __down_op_ret(ptr,fail) \
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
" mov %0, ip" \ " mov %0, ip" \
: "=&r" (ret) \ : "=&r" (ret) \
: "r" (ptr), "I" (1) \ : "r" (ptr), "I" (1) \
: "ip", "lr", "cc"); \ : "ip", "lr", "cc", "memory"); \
ret; \ ret; \
}) })
...@@ -94,7 +94,7 @@ ...@@ -94,7 +94,7 @@
" blne " #fail \ " blne " #fail \
: \ : \
: "r" (ptr), "I" (RW_LOCK_BIAS) \ : "r" (ptr), "I" (RW_LOCK_BIAS) \
: "ip", "lr", "cc"); \ : "ip", "lr", "cc", "memory"); \
}) })
#define __up_op_write(ptr,wake) \ #define __up_op_write(ptr,wake) \
...@@ -112,7 +112,7 @@ ...@@ -112,7 +112,7 @@
" blcs " #wake \ " blcs " #wake \
: \ : \
: "r" (ptr), "I" (RW_LOCK_BIAS) \ : "r" (ptr), "I" (RW_LOCK_BIAS) \
: "ip", "lr", "cc"); \ : "ip", "lr", "cc", "memory"); \
}) })
#define __down_op_read(ptr,fail) \ #define __down_op_read(ptr,fail) \
......
...@@ -37,7 +37,7 @@ static inline void set_fs (mm_segment_t fs) ...@@ -37,7 +37,7 @@ static inline void set_fs (mm_segment_t fs)
: "cc"); \ : "cc"); \
(flag == 0); }) (flag == 0); })
#define __put_user_asm_byte(x,addr,err) \ #define __put_user_asm_byte(x,__pu_addr,err) \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: strbt %1,[%2],#0\n" \ "1: strbt %1,[%2],#0\n" \
"2:\n" \ "2:\n" \
...@@ -51,27 +51,26 @@ static inline void set_fs (mm_segment_t fs) ...@@ -51,27 +51,26 @@ static inline void set_fs (mm_segment_t fs)
" .long 1b, 3b\n" \ " .long 1b, 3b\n" \
" .previous" \ " .previous" \
: "=r" (err) \ : "=r" (err) \
: "r" (x), "r" (addr), "i" (-EFAULT), "0" (err)) : "r" (x), "r" (__pu_addr), "i" (-EFAULT), "0" (err) \
: "cc")
#ifndef __ARMEB__ #ifndef __ARMEB__
#define __put_user_asm_half(x,addr,err) \ #define __put_user_asm_half(x,__pu_addr,err) \
({ \ ({ \
unsigned long __temp = (unsigned long)(x); \ unsigned long __temp = (unsigned long)(x); \
unsigned long __ptr = (unsigned long)(addr); \ __put_user_asm_byte(__temp, __pu_addr, err); \
__put_user_asm_byte(__temp, __ptr, err); \ __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \
__put_user_asm_byte(__temp >> 8, __ptr + 1, err); \
}) })
#else #else
#define __put_user_asm_half(x,addr,err) \ #define __put_user_asm_half(x,__pu_addr,err) \
({ \ ({ \
unsigned long __temp = (unsigned long)(x); \ unsigned long __temp = (unsigned long)(x); \
unsigned long __ptr = (unsigned long)(addr); \ __put_user_asm_byte(__temp >> 8, __pu_addr, err); \
__put_user_asm_byte(__temp >> 8, __ptr, err); \ __put_user_asm_byte(__temp, __pu_addr + 1, err); \
__put_user_asm_byte(__temp, __ptr + 1, err); \
}) })
#endif #endif
#define __put_user_asm_word(x,addr,err) \ #define __put_user_asm_word(x,__pu_addr,err) \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: strt %1,[%2],#0\n" \ "1: strt %1,[%2],#0\n" \
"2:\n" \ "2:\n" \
...@@ -85,7 +84,31 @@ static inline void set_fs (mm_segment_t fs) ...@@ -85,7 +84,31 @@ static inline void set_fs (mm_segment_t fs)
" .long 1b, 3b\n" \ " .long 1b, 3b\n" \
" .previous" \ " .previous" \
: "=r" (err) \ : "=r" (err) \
: "r" (x), "r" (addr), "i" (-EFAULT), "0" (err)) : "r" (x), "r" (__pu_addr), "i" (-EFAULT), "0" (err))
#define __put_user_asm_dword(x,__pu_addr,err) \
({ \
unsigned long long __temp = (unsigned long long)x; \
__asm__ __volatile__( \
"1: strt %1, [%2], #0\n" \
"2: strt %3, [%4], #0\n" \
"3:\n" \
" .section .fixup,\"ax\"\n" \
" .align 2\n" \
"4: mov %0, %5\n" \
" b 3b\n" \
" .previous\n" \
" .section __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 4b\n" \
" .long 2b, 4b\n" \
" .previous" \
: "=r" (err) \
: "r" (__temp), "r" (__pu_addr), \
"r" (__temp >> 32), "r" (__pu_addr + 4), \
"i" (-EFAULT), "0" (err) \
: "cc"); \
})
#define __get_user_asm_byte(x,addr,err) \ #define __get_user_asm_byte(x,addr,err) \
__asm__ __volatile__( \ __asm__ __volatile__( \
......
...@@ -22,19 +22,18 @@ struct semaphore { ...@@ -22,19 +22,18 @@ struct semaphore {
}; };
#if WAITQUEUE_DEBUG #if WAITQUEUE_DEBUG
# define __SEM_DEBUG_INIT(name) \ # define __SEM_DEBUG_INIT(name) .__magic = (long)&(name).__magic
, (long)&(name).__magic
#else #else
# define __SEM_DEBUG_INIT(name) # define __SEM_DEBUG_INIT(name)
#endif #endif
#define __SEMAPHORE_INIT(name,count) \ #define __SEMAPHORE_INIT(name,cnt) { \
{ ATOMIC_INIT(count), 0, \ .count = ATOMIC_INIT(cnt), \
__WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
__SEM_DEBUG_INIT(name) } __SEM_DEBUG_INIT(name) \
}
#define __MUTEX_INITIALIZER(name) \ #define __MUTEX_INITIALIZER(name) __SEMAPHORE_INIT(name,1)
__SEMAPHORE_INIT(name,1)
#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
struct semaphore name = __SEMAPHORE_INIT(name,count) struct semaphore name = __SEMAPHORE_INIT(name,count)
...@@ -62,6 +61,11 @@ static inline void init_MUTEX_LOCKED(struct semaphore *sem) ...@@ -62,6 +61,11 @@ static inline void init_MUTEX_LOCKED(struct semaphore *sem)
sema_init(sem, 0); sema_init(sem, 0);
} }
static inline int sema_count(struct semaphore *sem)
{
return atomic_read(&sem->count);
}
/* /*
* special register calling convention * special register calling convention
*/ */
......
...@@ -51,17 +51,21 @@ struct thread_info { ...@@ -51,17 +51,21 @@ struct thread_info {
__u32 cpu; /* cpu */ __u32 cpu; /* cpu */
__u32 cpu_domain; /* cpu domain */ __u32 cpu_domain; /* cpu domain */
struct cpu_context_save cpu_context; /* cpu context */ struct cpu_context_save cpu_context; /* cpu context */
struct restart_block restart_block;
union fp_state fpstate; union fp_state fpstate;
}; };
#define INIT_THREAD_INFO(tsk) \ #define INIT_THREAD_INFO(tsk) \
{ \ { \
task: &tsk, \ .task = &tsk, \
exec_domain: &default_exec_domain, \ .exec_domain = &default_exec_domain, \
flags: 0, \ .flags = 0, \
preempt_count: 0, \ .preempt_count = 1, \
addr_limit: KERNEL_DS, \ .addr_limit = KERNEL_DS, \
INIT_EXTRA_THREAD_INFO, \ .restart_block = { \
.fn = do_no_restart_syscall, \
}, \
INIT_EXTRA_THREAD_INFO, \
} }
#define init_thread_info (init_thread_union.thread_info) #define init_thread_info (init_thread_union.thread_info)
......
...@@ -81,7 +81,7 @@ extern int __get_user_bad(void); ...@@ -81,7 +81,7 @@ extern int __get_user_bad(void);
const register typeof(*(p)) *__p asm("r0") = (p); \ const register typeof(*(p)) *__p asm("r0") = (p); \
register typeof(*(p)) __r1 asm("r1"); \ register typeof(*(p)) __r1 asm("r1"); \
register int __e asm("r0"); \ register int __e asm("r0"); \
switch (sizeof(*(p))) { \ switch (sizeof(*(__p))) { \
case 1: \ case 1: \
__get_user_x(__r1, __p, __e, 1, "lr"); \ __get_user_x(__r1, __p, __e, 1, "lr"); \
break; \ break; \
...@@ -120,7 +120,7 @@ extern int __put_user_bad(void); ...@@ -120,7 +120,7 @@ extern int __put_user_bad(void);
const register typeof(*(p)) __r1 asm("r1") = (x); \ const register typeof(*(p)) __r1 asm("r1") = (x); \
const register typeof(*(p)) *__p asm("r0") = (p); \ const register typeof(*(p)) *__p asm("r0") = (p); \
register int __e asm("r0"); \ register int __e asm("r0"); \
switch (sizeof(*(p))) { \ switch (sizeof(*(__p))) { \
case 1: \ case 1: \
__put_user_x(__r1, __p, __e, 1, "r2", "lr"); \ __put_user_x(__r1, __p, __e, 1, "r2", "lr"); \
break; \ break; \
...@@ -256,14 +256,15 @@ static inline long strnlen_user(const char *s, long n) ...@@ -256,14 +256,15 @@ static inline long strnlen_user(const char *s, long n)
#define __put_user_nocheck(x,ptr,size) \ #define __put_user_nocheck(x,ptr,size) \
({ \ ({ \
long __pu_err = 0; \ long __pu_err = 0; \
__typeof__(*(ptr)) *__pu_addr = (ptr); \ unsigned long __pu_addr = (unsigned long)(ptr); \
__put_user_size((x),__pu_addr,(size),__pu_err); \ __put_user_size((x),__pu_addr,(size),__pu_err); \
__pu_err; \ __pu_err; \
}) })
#define __put_user_nocheck_error(x,ptr,size,err) \ #define __put_user_nocheck_error(x,ptr,size,err) \
({ \ ({ \
__put_user_size((x),(ptr),(size),err); \ unsigned long __pu_addr = (unsigned long)(ptr); \
__put_user_size((x),__pu_addr,(size),err); \
(void) 0; \ (void) 0; \
}) })
...@@ -273,6 +274,7 @@ do { \ ...@@ -273,6 +274,7 @@ do { \
case 1: __get_user_asm_byte(x,ptr,retval); break; \ case 1: __get_user_asm_byte(x,ptr,retval); break; \
case 2: __get_user_asm_half(x,ptr,retval); break; \ case 2: __get_user_asm_half(x,ptr,retval); break; \
case 4: __get_user_asm_word(x,ptr,retval); break; \ case 4: __get_user_asm_word(x,ptr,retval); break; \
case 8: __get_user_asm_dword(x,ptr,retval); break; \
default: (x) = __get_user_bad(); \ default: (x) = __get_user_bad(); \
} \ } \
} while (0) } while (0)
...@@ -283,6 +285,7 @@ do { \ ...@@ -283,6 +285,7 @@ do { \
case 1: __put_user_asm_byte(x,ptr,retval); break; \ case 1: __put_user_asm_byte(x,ptr,retval); break; \
case 2: __put_user_asm_half(x,ptr,retval); break; \ case 2: __put_user_asm_half(x,ptr,retval); break; \
case 4: __put_user_asm_word(x,ptr,retval); break; \ case 4: __put_user_asm_word(x,ptr,retval); break; \
case 8: __put_user_asm_dword(x,ptr,retval); break; \
default: __put_user_bad(); \ default: __put_user_bad(); \
} \ } \
} while (0) } while (0)
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
* This file contains the system call numbers. * This file contains the system call numbers.
*/ */
#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0)
#define __NR_exit (__NR_SYSCALL_BASE+ 1) #define __NR_exit (__NR_SYSCALL_BASE+ 1)
#define __NR_fork (__NR_SYSCALL_BASE+ 2) #define __NR_fork (__NR_SYSCALL_BASE+ 2)
#define __NR_read (__NR_SYSCALL_BASE+ 3) #define __NR_read (__NR_SYSCALL_BASE+ 3)
......
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