aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/pci-noop.c4
-rw-r--r--arch/alpha/kernel/pci_iommu.c24
-rw-r--r--arch/alpha/kernel/setup.c1
-rw-r--r--arch/alpha/kernel/systbls.S2
-rw-r--r--arch/arm/Kconfig21
-rw-r--r--arch/arm/common/time-acorn.c2
-rw-r--r--arch/arm/configs/ixp4xx_defconfig982
-rw-r--r--arch/arm/kernel/Makefile1
-rw-r--r--arch/arm/kernel/atags.c86
-rw-r--r--arch/arm/kernel/atags.h5
-rw-r--r--arch/arm/kernel/calls.S2
-rw-r--r--arch/arm/kernel/machine_kexec.c2
-rw-r--r--arch/arm/kernel/relocate_kernel.S30
-rw-r--r--arch/arm/kernel/setup.c33
-rw-r--r--arch/arm/kernel/smp.c41
-rw-r--r--arch/arm/mach-at91/Kconfig30
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c3
-rw-r--r--arch/arm/mach-at91/generic.h3
-rw-r--r--arch/arm/mach-at91/gpio.c89
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig14
-rw-r--r--arch/arm/mach-ixp4xx/Makefile8
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-power.c125
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-setup.c134
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c29
-rw-r--r--arch/arm/mach-ixp4xx/ixp4xx_npe.c741
-rw-r--r--arch/arm/mach-ixp4xx/ixp4xx_qmgr.c274
-rw-r--r--arch/arm/mach-ixp4xx/nas100d-power.c69
-rw-r--r--arch/arm/mach-ixp4xx/nas100d-setup.c174
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-power.c91
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-setup.c137
-rw-r--r--arch/arm/mach-pxa/Makefile5
-rw-r--r--arch/arm/mach-pxa/cm-x270.c1
-rw-r--r--arch/arm/mach-pxa/devices.c1
-rw-r--r--arch/arm/mach-pxa/generic.c150
-rw-r--r--arch/arm/mach-pxa/generic.h4
-rw-r--r--arch/arm/mach-pxa/gpio.c197
-rw-r--r--arch/arm/mach-pxa/irq.c64
-rw-r--r--arch/arm/mach-pxa/mfp.c11
-rw-r--r--arch/arm/mach-pxa/pcm027.c1
-rw-r--r--arch/arm/mach-pxa/poodle.c8
-rw-r--r--arch/arm/mach-pxa/pxa25x.c43
-rw-r--r--arch/arm/mach-pxa/pxa27x.c49
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c99
-rw-r--r--arch/arm/mach-pxa/sleep.S102
-rw-r--r--arch/arm/mach-pxa/smemc.c88
-rw-r--r--arch/arm/mach-pxa/spitz.c1
-rw-r--r--arch/arm/mach-pxa/tosa.c1
-rw-r--r--arch/arm/mach-realview/Kconfig21
-rw-r--r--arch/arm/mach-realview/Makefile3
-rw-r--r--arch/arm/mach-realview/core.c179
-rw-r--r--arch/arm/mach-realview/core.h71
-rw-r--r--arch/arm/mach-realview/localtimer.c144
-rw-r--r--arch/arm/mach-realview/platsmp.c20
-rw-r--r--arch/arm/mach-realview/realview_eb.c234
-rw-r--r--arch/arm/mach-sa1100/generic.c2
-rw-r--r--arch/arm/mm/ioremap.c2
-rw-r--r--arch/arm/mm/pgd.c8
-rw-r--r--arch/arm/plat-iop/time.c4
-rw-r--r--arch/arm/plat-s3c24xx/time.c2
-rw-r--r--arch/avr32/Kconfig1
-rw-r--r--arch/avr32/mach-at32ap/pio.c172
-rw-r--r--arch/avr32/mach-at32ap/pio.h2
-rw-r--r--arch/blackfin/mach-common/entry.S2
-rw-r--r--arch/cris/Kconfig5
-rw-r--r--arch/cris/arch-v10/Kconfig4
-rw-r--r--arch/cris/arch-v10/drivers/Kconfig4
-rw-r--r--arch/cris/arch-v10/kernel/entry.S2
-rw-r--r--arch/cris/arch-v32/Kconfig4
-rw-r--r--arch/cris/arch-v32/drivers/Kconfig4
-rw-r--r--arch/cris/arch-v32/drivers/pci/dma.c4
-rw-r--r--arch/frv/Kconfig9
-rw-r--r--arch/frv/kernel/vmlinux.lds.S2
-rw-r--r--arch/frv/mm/mmu-context.c2
-rw-r--r--arch/frv/mm/pgalloc.c2
-rw-r--r--arch/ia64/hp/common/sba_iommu.c8
-rw-r--r--arch/ia64/kernel/entry.S2
-rw-r--r--arch/m32r/boot/compressed/m32r_sio.c4
-rw-r--r--arch/m68k/Kconfig14
-rw-r--r--arch/m68k/Makefile11
-rw-r--r--arch/m68k/amiga/Makefile2
-rw-r--r--arch/m68k/amiga/amiga_ksyms.c33
-rw-r--r--arch/m68k/amiga/amisound.c5
-rw-r--r--arch/m68k/amiga/chipram.c7
-rw-r--r--arch/m68k/amiga/config.c12
-rw-r--r--arch/m68k/amiga/pcmcia.c9
-rw-r--r--arch/m68k/atari/Makefile2
-rw-r--r--arch/m68k/atari/ataints.c3
-rw-r--r--arch/m68k/atari/atari_ksyms.c35
-rw-r--r--arch/m68k/atari/atasound.c2
-rw-r--r--arch/m68k/atari/config.c11
-rw-r--r--arch/m68k/atari/debug.c6
-rw-r--r--arch/m68k/atari/hades-pci.c54
-rw-r--r--arch/m68k/atari/stdma.c5
-rw-r--r--arch/m68k/atari/stram.c3
-rw-r--r--arch/m68k/configs/mac_defconfig1
-rw-r--r--arch/m68k/hp300/Makefile2
-rw-r--r--arch/m68k/hp300/ksyms.c9
-rw-r--r--arch/m68k/kernel/entry.S2
-rw-r--r--arch/m68k/mac/Makefile2
-rw-r--r--arch/m68k/mac/config.c2
-rw-r--r--arch/m68k/mac/mac_ksyms.c8
-rw-r--r--arch/m68k/mac/via.c5
-rw-r--r--arch/m68k/mvme16x/Makefile2
-rw-r--r--arch/m68k/mvme16x/config.c2
-rw-r--r--arch/m68k/mvme16x/mvme16x_ksyms.c6
-rw-r--r--arch/m68knommu/Kconfig.debug7
-rw-r--r--arch/m68knommu/defconfig1
-rw-r--r--arch/m68knommu/kernel/m68k_ksyms.c11
-rw-r--r--arch/m68knommu/kernel/setup.c3
-rw-r--r--arch/m68knommu/kernel/syscalltable.S2
-rw-r--r--arch/mips/kernel/scall32-o32.S2
-rw-r--r--arch/mips/kernel/scall64-64.S2
-rw-r--r--arch/mips/kernel/scall64-n32.S2
-rw-r--r--arch/mips/kernel/scall64-o32.S2
-rw-r--r--arch/powerpc/Kconfig3
-rw-r--r--arch/powerpc/kernel/dma_64.c8
-rw-r--r--arch/powerpc/kernel/iommu.c93
-rw-r--r--arch/powerpc/mm/pgtable_32.c6
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c4
-rw-r--r--arch/ppc/mm/pgtable.c6
-rw-r--r--arch/s390/Kconfig8
-rw-r--r--arch/s390/Kconfig.debug8
-rw-r--r--arch/s390/kernel/compat_wrapper.S8
-rw-r--r--arch/s390/kernel/entry.S7
-rw-r--r--arch/s390/kernel/entry64.S7
-rw-r--r--arch/s390/kernel/ipl.c27
-rw-r--r--arch/s390/kernel/setup.c14
-rw-r--r--arch/s390/kernel/smp.c13
-rw-r--r--arch/s390/kernel/stacktrace.c31
-rw-r--r--arch/s390/kernel/syscalls.S2
-rw-r--r--arch/s390/kernel/traps.c5
-rw-r--r--arch/s390/kernel/vmlinux.lds.S2
-rw-r--r--arch/s390/mm/init.c27
-rw-r--r--arch/s390/mm/vmem.c5
-rw-r--r--arch/sparc/kernel/systbls.S2
-rw-r--r--arch/sparc64/kernel/iommu.c2
-rw-r--r--arch/sparc64/kernel/iommu_common.c8
-rw-r--r--arch/sparc64/kernel/iommu_common.h3
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c8
-rw-r--r--arch/sparc64/kernel/systbls.S4
-rw-r--r--arch/um/Kconfig26
-rw-r--r--arch/um/Kconfig.char2
-rw-r--r--arch/um/Kconfig.debug6
-rw-r--r--arch/um/Kconfig.net12
-rw-r--r--arch/um/Makefile12
-rw-r--r--arch/um/Makefile-tt5
-rw-r--r--arch/um/defconfig6
-rw-r--r--arch/um/drivers/line.c28
-rw-r--r--arch/um/drivers/mconsole_kern.c55
-rw-r--r--arch/um/drivers/mconsole_user.c5
-rw-r--r--arch/um/drivers/net_kern.c16
-rw-r--r--arch/um/drivers/net_user.c2
-rw-r--r--arch/um/drivers/port_kern.c7
-rw-r--r--arch/um/drivers/random.c1
-rw-r--r--arch/um/drivers/slip_user.c2
-rw-r--r--arch/um/drivers/slirp_user.c2
-rw-r--r--arch/um/drivers/ssl.c1
-rw-r--r--arch/um/drivers/stdio_console.c1
-rw-r--r--arch/um/drivers/ubd_kern.c30
-rw-r--r--arch/um/drivers/ubd_user.c1
-rw-r--r--arch/um/drivers/vde_user.c2
-rw-r--r--arch/um/include/arch.h2
-rw-r--r--arch/um/include/as-layout.h34
-rw-r--r--arch/um/include/chan_user.h2
-rw-r--r--arch/um/include/common-offsets.h1
-rw-r--r--arch/um/include/init.h25
-rw-r--r--arch/um/include/irq_user.h1
-rw-r--r--arch/um/include/kern_util.h120
-rw-r--r--arch/um/include/mem_user.h5
-rw-r--r--arch/um/include/misc_constants.h6
-rw-r--r--arch/um/include/os.h41
-rw-r--r--arch/um/include/ptrace_user.h11
-rw-r--r--arch/um/include/registers.h7
-rw-r--r--arch/um/include/signal_kern.h22
-rw-r--r--arch/um/include/skas/mode-skas.h11
-rw-r--r--arch/um/include/sysdep-i386/syscalls.h5
-rw-r--r--arch/um/include/sysdep-x86_64/kernel-offsets.h9
-rw-r--r--arch/um/include/sysdep-x86_64/syscalls.h2
-rw-r--r--arch/um/include/um_mmu.h4
-rw-r--r--arch/um/include/um_uaccess.h4
-rw-r--r--arch/um/kernel/exec.c5
-rw-r--r--arch/um/kernel/exitcode.c31
-rw-r--r--arch/um/kernel/gmon_syms.c11
-rw-r--r--arch/um/kernel/gprof_syms.c13
-rw-r--r--arch/um/kernel/initrd.c30
-rw-r--r--arch/um/kernel/irq.c6
-rw-r--r--arch/um/kernel/ksyms.c5
-rw-r--r--arch/um/kernel/mem.c147
-rw-r--r--arch/um/kernel/physmem.c16
-rw-r--r--arch/um/kernel/process.c154
-rw-r--r--arch/um/kernel/reboot.c7
-rw-r--r--arch/um/kernel/sigio.c18
-rw-r--r--arch/um/kernel/signal.c16
-rw-r--r--arch/um/kernel/skas/clone.c32
-rw-r--r--arch/um/kernel/skas/mmu.c127
-rw-r--r--arch/um/kernel/skas/process.c20
-rw-r--r--arch/um/kernel/skas/syscall.c6
-rw-r--r--arch/um/kernel/skas/uaccess.c140
-rw-r--r--arch/um/kernel/smp.c14
-rw-r--r--arch/um/kernel/syscall.c3
-rw-r--r--arch/um/kernel/sysrq.c44
-rw-r--r--arch/um/kernel/time.c14
-rw-r--r--arch/um/kernel/tlb.c51
-rw-r--r--arch/um/kernel/trap.c33
-rw-r--r--arch/um/kernel/uaccess.c11
-rw-r--r--arch/um/kernel/um_arch.c100
-rw-r--r--arch/um/kernel/umid.c15
-rw-r--r--arch/um/os-Linux/Makefile4
-rw-r--r--arch/um/os-Linux/aio.c1
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c2
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c5
-rw-r--r--arch/um/os-Linux/file.c287
-rw-r--r--arch/um/os-Linux/helper.c74
-rw-r--r--arch/um/os-Linux/irq.c39
-rw-r--r--arch/um/os-Linux/main.c14
-rw-r--r--arch/um/os-Linux/mem.c13
-rw-r--r--arch/um/os-Linux/process.c5
-rw-r--r--arch/um/os-Linux/registers.c34
-rw-r--r--arch/um/os-Linux/sigio.c244
-rw-r--r--arch/um/os-Linux/signal.c102
-rw-r--r--arch/um/os-Linux/skas/Makefile6
-rw-r--r--arch/um/os-Linux/skas/process.c281
-rw-r--r--arch/um/os-Linux/skas/trap.c69
-rw-r--r--arch/um/os-Linux/start_up.c17
-rw-r--r--arch/um/os-Linux/trap.c23
-rw-r--r--arch/um/os-Linux/tty.c57
-rw-r--r--arch/um/os-Linux/tty_log.c1
-rw-r--r--arch/um/os-Linux/util.c15
-rw-r--r--arch/um/sys-i386/bug.c1
-rw-r--r--arch/um/sys-i386/bugs.c201
-rw-r--r--arch/um/sys-i386/ldt.c19
-rw-r--r--arch/um/sys-i386/ptrace.c6
-rw-r--r--arch/um/sys-i386/ptrace_user.c14
-rw-r--r--arch/um/sys-i386/signal.c18
-rw-r--r--arch/um/sys-i386/stub.S8
-rw-r--r--arch/um/sys-i386/stub_segv.c19
-rw-r--r--arch/um/sys-i386/sys_call_table.S5
-rw-r--r--arch/um/sys-i386/tls.c41
-rw-r--r--arch/um/sys-ppc/Makefile22
-rw-r--r--arch/um/sys-x86_64/bug.c3
-rw-r--r--arch/um/sys-x86_64/bugs.c7
-rw-r--r--arch/um/sys-x86_64/ptrace.c29
-rw-r--r--arch/um/sys-x86_64/ptrace_user.c46
-rw-r--r--arch/um/sys-x86_64/signal.c4
-rw-r--r--arch/um/sys-x86_64/stub.S8
-rw-r--r--arch/um/sys-x86_64/stub_segv.c39
-rw-r--r--arch/um/sys-x86_64/syscall_table.c43
-rw-r--r--arch/um/sys-x86_64/syscalls.c10
-rw-r--r--arch/um/sys-x86_64/sysrq.c29
-rw-r--r--arch/um/sys-x86_64/um_module.c8
-rw-r--r--arch/x86/Kconfig3
-rw-r--r--arch/x86/ia32/ia32entry.S4
-rw-r--r--arch/x86/kernel/pci-calgary_64.c34
-rw-r--r--arch/x86/kernel/pci-gart_64.c48
-rw-r--r--arch/x86/kernel/syscall_table_32.S4
-rw-r--r--arch/x86/kvm/x86.c8
-rw-r--r--arch/x86/lib/Makefile2
-rw-r--r--arch/x86/lib/bitstr_64.c28
-rw-r--r--arch/x86/mm/pgtable_32.c12
-rw-r--r--arch/x86/pci/i386.c2
260 files changed, 5546 insertions, 3578 deletions
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
index 468b76ce66a1..8ac08311f5a5 100644
--- a/arch/alpha/kernel/pci-noop.c
+++ b/arch/alpha/kernel/pci-noop.c
@@ -165,7 +165,7 @@ dma_alloc_coherent(struct device *dev, size_t size,
165 ret = (void *)__get_free_pages(gfp, get_order(size)); 165 ret = (void *)__get_free_pages(gfp, get_order(size));
166 if (ret) { 166 if (ret) {
167 memset(ret, 0, size); 167 memset(ret, 0, size);
168 *dma_handle = virt_to_bus(ret); 168 *dma_handle = virt_to_phys(ret);
169 } 169 }
170 return ret; 170 return ret;
171} 171}
@@ -184,7 +184,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
184 184
185 BUG_ON(!sg_page(sg)); 185 BUG_ON(!sg_page(sg));
186 va = sg_virt(sg); 186 va = sg_virt(sg);
187 sg_dma_address(sg) = (dma_addr_t)virt_to_bus(va); 187 sg_dma_address(sg) = (dma_addr_t)virt_to_phys(va);
188 sg_dma_len(sg) = sg->length; 188 sg_dma_len(sg) = sg->length;
189 } 189 }
190 190
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 2d00a08d3f08..26d3789dfdd0 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -9,6 +9,7 @@
9#include <linux/bootmem.h> 9#include <linux/bootmem.h>
10#include <linux/scatterlist.h> 10#include <linux/scatterlist.h>
11#include <linux/log2.h> 11#include <linux/log2.h>
12#include <linux/dma-mapping.h>
12 13
13#include <asm/io.h> 14#include <asm/io.h>
14#include <asm/hwrpb.h> 15#include <asm/hwrpb.h>
@@ -470,22 +471,29 @@ EXPORT_SYMBOL(pci_free_consistent);
470#define SG_ENT_PHYS_ADDRESS(SG) __pa(SG_ENT_VIRT_ADDRESS(SG)) 471#define SG_ENT_PHYS_ADDRESS(SG) __pa(SG_ENT_VIRT_ADDRESS(SG))
471 472
472static void 473static void
473sg_classify(struct scatterlist *sg, struct scatterlist *end, int virt_ok) 474sg_classify(struct device *dev, struct scatterlist *sg, struct scatterlist *end,
475 int virt_ok)
474{ 476{
475 unsigned long next_paddr; 477 unsigned long next_paddr;
476 struct scatterlist *leader; 478 struct scatterlist *leader;
477 long leader_flag, leader_length; 479 long leader_flag, leader_length;
480 unsigned int max_seg_size;
478 481
479 leader = sg; 482 leader = sg;
480 leader_flag = 0; 483 leader_flag = 0;
481 leader_length = leader->length; 484 leader_length = leader->length;
482 next_paddr = SG_ENT_PHYS_ADDRESS(leader) + leader_length; 485 next_paddr = SG_ENT_PHYS_ADDRESS(leader) + leader_length;
483 486
487 /* we will not marge sg without device. */
488 max_seg_size = dev ? dma_get_max_seg_size(dev) : 0;
484 for (++sg; sg < end; ++sg) { 489 for (++sg; sg < end; ++sg) {
485 unsigned long addr, len; 490 unsigned long addr, len;
486 addr = SG_ENT_PHYS_ADDRESS(sg); 491 addr = SG_ENT_PHYS_ADDRESS(sg);
487 len = sg->length; 492 len = sg->length;
488 493
494 if (leader_length + len > max_seg_size)
495 goto new_segment;
496
489 if (next_paddr == addr) { 497 if (next_paddr == addr) {
490 sg->dma_address = -1; 498 sg->dma_address = -1;
491 leader_length += len; 499 leader_length += len;
@@ -494,6 +502,7 @@ sg_classify(struct scatterlist *sg, struct scatterlist *end, int virt_ok)
494 leader_flag = 1; 502 leader_flag = 1;
495 leader_length += len; 503 leader_length += len;
496 } else { 504 } else {
505new_segment:
497 leader->dma_address = leader_flag; 506 leader->dma_address = leader_flag;
498 leader->dma_length = leader_length; 507 leader->dma_length = leader_length;
499 leader = sg; 508 leader = sg;
@@ -512,7 +521,7 @@ sg_classify(struct scatterlist *sg, struct scatterlist *end, int virt_ok)
512 in the blanks. */ 521 in the blanks. */
513 522
514static int 523static int
515sg_fill(struct scatterlist *leader, struct scatterlist *end, 524sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
516 struct scatterlist *out, struct pci_iommu_arena *arena, 525 struct scatterlist *out, struct pci_iommu_arena *arena,
517 dma_addr_t max_dma, int dac_allowed) 526 dma_addr_t max_dma, int dac_allowed)
518{ 527{
@@ -562,8 +571,8 @@ sg_fill(struct scatterlist *leader, struct scatterlist *end,
562 571
563 /* Otherwise, break up the remaining virtually contiguous 572 /* Otherwise, break up the remaining virtually contiguous
564 hunks into individual direct maps and retry. */ 573 hunks into individual direct maps and retry. */
565 sg_classify(leader, end, 0); 574 sg_classify(dev, leader, end, 0);
566 return sg_fill(leader, end, out, arena, max_dma, dac_allowed); 575 return sg_fill(dev, leader, end, out, arena, max_dma, dac_allowed);
567 } 576 }
568 577
569 out->dma_address = arena->dma_base + dma_ofs*PAGE_SIZE + paddr; 578 out->dma_address = arena->dma_base + dma_ofs*PAGE_SIZE + paddr;
@@ -619,12 +628,15 @@ pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
619 struct pci_iommu_arena *arena; 628 struct pci_iommu_arena *arena;
620 dma_addr_t max_dma; 629 dma_addr_t max_dma;
621 int dac_allowed; 630 int dac_allowed;
631 struct device *dev;
622 632
623 if (direction == PCI_DMA_NONE) 633 if (direction == PCI_DMA_NONE)
624 BUG(); 634 BUG();
625 635
626 dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0; 636 dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;
627 637
638 dev = pdev ? &pdev->dev : NULL;
639
628 /* Fast path single entry scatterlists. */ 640 /* Fast path single entry scatterlists. */
629 if (nents == 1) { 641 if (nents == 1) {
630 sg->dma_length = sg->length; 642 sg->dma_length = sg->length;
@@ -638,7 +650,7 @@ pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
638 end = sg + nents; 650 end = sg + nents;
639 651
640 /* First, prepare information about the entries. */ 652 /* First, prepare information about the entries. */
641 sg_classify(sg, end, alpha_mv.mv_pci_tbi != 0); 653 sg_classify(dev, sg, end, alpha_mv.mv_pci_tbi != 0);
642 654
643 /* Second, figure out where we're going to map things. */ 655 /* Second, figure out where we're going to map things. */
644 if (alpha_mv.mv_pci_tbi) { 656 if (alpha_mv.mv_pci_tbi) {
@@ -658,7 +670,7 @@ pci_map_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
658 for (out = sg; sg < end; ++sg) { 670 for (out = sg; sg < end; ++sg) {
659 if ((int) sg->dma_address < 0) 671 if ((int) sg->dma_address < 0)
660 continue; 672 continue;
661 if (sg_fill(sg, end, out, arena, max_dma, dac_allowed) < 0) 673 if (sg_fill(dev, sg, end, out, arena, max_dma, dac_allowed) < 0)
662 goto error; 674 goto error;
663 out++; 675 out++;
664 } 676 }
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index bd5e68cd61e8..beff6297f788 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -58,7 +58,6 @@ static struct notifier_block alpha_panic_block = {
58#include <asm/system.h> 58#include <asm/system.h>
59#include <asm/hwrpb.h> 59#include <asm/hwrpb.h>
60#include <asm/dma.h> 60#include <asm/dma.h>
61#include <asm/io.h>
62#include <asm/mmu_context.h> 61#include <asm/mmu_context.h>
63#include <asm/console.h> 62#include <asm/console.h>
64 63
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S
index 79de99e32c35..ba914af18c4f 100644
--- a/arch/alpha/kernel/systbls.S
+++ b/arch/alpha/kernel/systbls.S
@@ -495,7 +495,7 @@ sys_call_table:
495 .quad sys_epoll_pwait 495 .quad sys_epoll_pwait
496 .quad sys_utimensat /* 475 */ 496 .quad sys_utimensat /* 475 */
497 .quad sys_signalfd 497 .quad sys_signalfd
498 .quad sys_timerfd 498 .quad sys_ni_syscall
499 .quad sys_eventfd 499 .quad sys_eventfd
500 500
501 .size sys_call_table, . - sys_call_table 501 .size sys_call_table, . - sys_call_table
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 471637002e8b..e19e7744e366 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -35,6 +35,11 @@ config GENERIC_CLOCKEVENTS
35 bool 35 bool
36 default n 36 default n
37 37
38config GENERIC_CLOCKEVENTS_BROADCAST
39 bool
40 depends on GENERIC_CLOCKEVENTS
41 default y if SMP && !LOCAL_TIMERS
42
38config MMU 43config MMU
39 bool 44 bool
40 default y 45 default y
@@ -187,6 +192,8 @@ config ARCH_REALVIEW
187 bool "ARM Ltd. RealView family" 192 bool "ARM Ltd. RealView family"
188 select ARM_AMBA 193 select ARM_AMBA
189 select ICST307 194 select ICST307
195 select GENERIC_TIME
196 select GENERIC_CLOCKEVENTS
190 help 197 help
191 This enables support for ARM Ltd RealView boards. 198 This enables support for ARM Ltd RealView boards.
192 199
@@ -378,6 +385,7 @@ config ARCH_PXA
378 depends on MMU 385 depends on MMU
379 select ARCH_MTD_XIP 386 select ARCH_MTD_XIP
380 select GENERIC_GPIO 387 select GENERIC_GPIO
388 select HAVE_GPIO_LIB
381 select GENERIC_TIME 389 select GENERIC_TIME
382 select GENERIC_CLOCKEVENTS 390 select GENERIC_CLOCKEVENTS
383 select TICK_ONESHOT 391 select TICK_ONESHOT
@@ -623,7 +631,7 @@ source "kernel/time/Kconfig"
623 631
624config SMP 632config SMP
625 bool "Symmetric Multi-Processing (EXPERIMENTAL)" 633 bool "Symmetric Multi-Processing (EXPERIMENTAL)"
626 depends on EXPERIMENTAL && REALVIEW_MPCORE 634 depends on EXPERIMENTAL && REALVIEW_EB_ARM11MP
627 help 635 help
628 This enables support for systems with more than one CPU. If you have 636 This enables support for systems with more than one CPU. If you have
629 a system with only one CPU, like most personal computers, say N. If 637 a system with only one CPU, like most personal computers, say N. If
@@ -656,7 +664,7 @@ config HOTPLUG_CPU
656 664
657config LOCAL_TIMERS 665config LOCAL_TIMERS
658 bool "Use local timer interrupts" 666 bool "Use local timer interrupts"
659 depends on SMP && REALVIEW_MPCORE 667 depends on SMP && REALVIEW_EB_ARM11MP
660 default y 668 default y
661 help 669 help
662 Enable support for local timers on SMP platforms, rather then the 670 Enable support for local timers on SMP platforms, rather then the
@@ -912,6 +920,13 @@ config KEXEC
912 initially work for you. It may help to enable device hotplugging 920 initially work for you. It may help to enable device hotplugging
913 support. 921 support.
914 922
923config ATAGS_PROC
924 bool "Export atags in procfs"
925 default n
926 help
927 Should the atags used to boot the kernel be exported in an "atags"
928 file in procfs. Useful with kexec.
929
915endmenu 930endmenu
916 931
917if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA) 932if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
@@ -1108,6 +1123,8 @@ source "drivers/i2c/Kconfig"
1108 1123
1109source "drivers/spi/Kconfig" 1124source "drivers/spi/Kconfig"
1110 1125
1126source "drivers/gpio/Kconfig"
1127
1111source "drivers/w1/Kconfig" 1128source "drivers/w1/Kconfig"
1112 1129
1113source "drivers/power/Kconfig" 1130source "drivers/power/Kconfig"
diff --git a/arch/arm/common/time-acorn.c b/arch/arm/common/time-acorn.c
index 34038eccbba9..d544da414731 100644
--- a/arch/arm/common/time-acorn.c
+++ b/arch/arm/common/time-acorn.c
@@ -69,9 +69,7 @@ void __init ioctime_init(void)
69static irqreturn_t 69static irqreturn_t
70ioc_timer_interrupt(int irq, void *dev_id) 70ioc_timer_interrupt(int irq, void *dev_id)
71{ 71{
72 write_seqlock(&xtime_lock);
73 timer_tick(); 72 timer_tick();
74 write_sequnlock(&xtime_lock);
75 return IRQ_HANDLED; 73 return IRQ_HANDLED;
76} 74}
77 75
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index db850a5689eb..efa0485d2f7e 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -1,69 +1,96 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15 3# Linux kernel version: 2.6.24
4# Tue Jan 3 03:20:40 2006 4# Sun Jan 27 07:33:38 2008
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8CONFIG_GENERIC_GPIO=y
9CONFIG_GENERIC_TIME=y
10CONFIG_GENERIC_CLOCKEVENTS=y
7CONFIG_MMU=y 11CONFIG_MMU=y
8CONFIG_UID16=y 12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y
9CONFIG_RWSEM_GENERIC_SPINLOCK=y 19CONFIG_RWSEM_GENERIC_SPINLOCK=y
20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_GENERIC_HWEIGHT=y
10CONFIG_GENERIC_CALIBRATE_DELAY=y 23CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y
25CONFIG_VECTORS_BASE=0xffff0000
26CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
11 27
12# 28#
13# Code maturity level options 29# General setup
14# 30#
15CONFIG_EXPERIMENTAL=y 31CONFIG_EXPERIMENTAL=y
16CONFIG_CLEAN_COMPILE=y
17CONFIG_BROKEN_ON_SMP=y 32CONFIG_BROKEN_ON_SMP=y
18CONFIG_INIT_ENV_ARG_LIMIT=32 33CONFIG_INIT_ENV_ARG_LIMIT=32
19
20#
21# General setup
22#
23CONFIG_LOCALVERSION="" 34CONFIG_LOCALVERSION=""
24CONFIG_LOCALVERSION_AUTO=y 35CONFIG_LOCALVERSION_AUTO=y
25CONFIG_SWAP=y 36CONFIG_SWAP=y
26CONFIG_SYSVIPC=y 37CONFIG_SYSVIPC=y
38CONFIG_SYSVIPC_SYSCTL=y
27# CONFIG_POSIX_MQUEUE is not set 39# CONFIG_POSIX_MQUEUE is not set
28CONFIG_BSD_PROCESS_ACCT=y 40CONFIG_BSD_PROCESS_ACCT=y
29# CONFIG_BSD_PROCESS_ACCT_V3 is not set 41# CONFIG_BSD_PROCESS_ACCT_V3 is not set
30CONFIG_SYSCTL=y 42# CONFIG_TASKSTATS is not set
43# CONFIG_USER_NS is not set
44# CONFIG_PID_NS is not set
31# CONFIG_AUDIT is not set 45# CONFIG_AUDIT is not set
32# CONFIG_HOTPLUG is not set
33CONFIG_KOBJECT_UEVENT=y
34# CONFIG_IKCONFIG is not set 46# CONFIG_IKCONFIG is not set
47CONFIG_LOG_BUF_SHIFT=14
48# CONFIG_CGROUPS is not set
49CONFIG_FAIR_GROUP_SCHED=y
50CONFIG_FAIR_USER_SCHED=y
51# CONFIG_FAIR_CGROUP_SCHED is not set
52CONFIG_SYSFS_DEPRECATED=y
53# CONFIG_RELAY is not set
54CONFIG_BLK_DEV_INITRD=y
35CONFIG_INITRAMFS_SOURCE="" 55CONFIG_INITRAMFS_SOURCE=""
36CONFIG_CC_OPTIMIZE_FOR_SIZE=y 56CONFIG_CC_OPTIMIZE_FOR_SIZE=y
57CONFIG_SYSCTL=y
37CONFIG_EMBEDDED=y 58CONFIG_EMBEDDED=y
59CONFIG_UID16=y
60CONFIG_SYSCTL_SYSCALL=y
38CONFIG_KALLSYMS=y 61CONFIG_KALLSYMS=y
39# CONFIG_KALLSYMS_ALL is not set 62# CONFIG_KALLSYMS_ALL is not set
40# CONFIG_KALLSYMS_EXTRA_PASS is not set 63# CONFIG_KALLSYMS_EXTRA_PASS is not set
64CONFIG_HOTPLUG=y
41CONFIG_PRINTK=y 65CONFIG_PRINTK=y
42CONFIG_BUG=y 66CONFIG_BUG=y
67CONFIG_ELF_CORE=y
43CONFIG_BASE_FULL=y 68CONFIG_BASE_FULL=y
44CONFIG_FUTEX=y 69CONFIG_FUTEX=y
70CONFIG_ANON_INODES=y
45CONFIG_EPOLL=y 71CONFIG_EPOLL=y
72CONFIG_SIGNALFD=y
73CONFIG_EVENTFD=y
46CONFIG_SHMEM=y 74CONFIG_SHMEM=y
47CONFIG_CC_ALIGN_FUNCTIONS=0 75CONFIG_VM_EVENT_COUNTERS=y
48CONFIG_CC_ALIGN_LABELS=0 76CONFIG_SLUB_DEBUG=y
49CONFIG_CC_ALIGN_LOOPS=0 77# CONFIG_SLAB is not set
50CONFIG_CC_ALIGN_JUMPS=0 78CONFIG_SLUB=y
79# CONFIG_SLOB is not set
80CONFIG_SLABINFO=y
81CONFIG_RT_MUTEXES=y
51# CONFIG_TINY_SHMEM is not set 82# CONFIG_TINY_SHMEM is not set
52CONFIG_BASE_SMALL=0 83CONFIG_BASE_SMALL=0
53
54#
55# Loadable module support
56#
57CONFIG_MODULES=y 84CONFIG_MODULES=y
58# CONFIG_MODULE_UNLOAD is not set 85# CONFIG_MODULE_UNLOAD is not set
59CONFIG_OBSOLETE_MODPARM=y
60CONFIG_MODVERSIONS=y 86CONFIG_MODVERSIONS=y
61# CONFIG_MODULE_SRCVERSION_ALL is not set 87# CONFIG_MODULE_SRCVERSION_ALL is not set
62CONFIG_KMOD=y 88CONFIG_KMOD=y
63 89CONFIG_BLOCK=y
64# 90# CONFIG_LBD is not set
65# Block layer 91# CONFIG_BLK_DEV_IO_TRACE is not set
66# 92# CONFIG_LSF is not set
93# CONFIG_BLK_DEV_BSG is not set
67 94
68# 95#
69# IO Schedulers 96# IO Schedulers
@@ -81,28 +108,39 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
81# 108#
82# System Type 109# System Type
83# 110#
111# CONFIG_ARCH_AAEC2000 is not set
112# CONFIG_ARCH_INTEGRATOR is not set
113# CONFIG_ARCH_REALVIEW is not set
114# CONFIG_ARCH_VERSATILE is not set
115# CONFIG_ARCH_AT91 is not set
84# CONFIG_ARCH_CLPS7500 is not set 116# CONFIG_ARCH_CLPS7500 is not set
85# CONFIG_ARCH_CLPS711X is not set 117# CONFIG_ARCH_CLPS711X is not set
86# CONFIG_ARCH_CO285 is not set 118# CONFIG_ARCH_CO285 is not set
87# CONFIG_ARCH_EBSA110 is not set 119# CONFIG_ARCH_EBSA110 is not set
120# CONFIG_ARCH_EP93XX is not set
88# CONFIG_ARCH_FOOTBRIDGE is not set 121# CONFIG_ARCH_FOOTBRIDGE is not set
89# CONFIG_ARCH_INTEGRATOR is not set 122# CONFIG_ARCH_NETX is not set
90# CONFIG_ARCH_IOP3XX is not set 123# CONFIG_ARCH_H720X is not set
91CONFIG_ARCH_IXP4XX=y 124# CONFIG_ARCH_IMX is not set
125# CONFIG_ARCH_IOP13XX is not set
126# CONFIG_ARCH_IOP32X is not set
127# CONFIG_ARCH_IOP33X is not set
128# CONFIG_ARCH_IXP23XX is not set
92# CONFIG_ARCH_IXP2000 is not set 129# CONFIG_ARCH_IXP2000 is not set
130CONFIG_ARCH_IXP4XX=y
93# CONFIG_ARCH_L7200 is not set 131# CONFIG_ARCH_L7200 is not set
132# CONFIG_ARCH_KS8695 is not set
133# CONFIG_ARCH_NS9XXX is not set
134# CONFIG_ARCH_MXC is not set
135# CONFIG_ARCH_PNX4008 is not set
94# CONFIG_ARCH_PXA is not set 136# CONFIG_ARCH_PXA is not set
95# CONFIG_ARCH_RPC is not set 137# CONFIG_ARCH_RPC is not set
96# CONFIG_ARCH_SA1100 is not set 138# CONFIG_ARCH_SA1100 is not set
97# CONFIG_ARCH_S3C2410 is not set 139# CONFIG_ARCH_S3C2410 is not set
98# CONFIG_ARCH_SHARK is not set 140# CONFIG_ARCH_SHARK is not set
99# CONFIG_ARCH_LH7A40X is not set 141# CONFIG_ARCH_LH7A40X is not set
142# CONFIG_ARCH_DAVINCI is not set
100# CONFIG_ARCH_OMAP is not set 143# CONFIG_ARCH_OMAP is not set
101# CONFIG_ARCH_VERSATILE is not set
102# CONFIG_ARCH_REALVIEW is not set
103# CONFIG_ARCH_IMX is not set
104# CONFIG_ARCH_H720X is not set
105# CONFIG_ARCH_AAEC2000 is not set
106CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y 144CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
107 145
108# 146#
@@ -112,8 +150,12 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
112# 150#
113# IXP4xx Platforms 151# IXP4xx Platforms
114# 152#
115CONFIG_ARCH_AVILA=y 153CONFIG_MACH_NSLU2=y
154CONFIG_MACH_AVILA=y
155CONFIG_MACH_LOFT=y
116CONFIG_ARCH_ADI_COYOTE=y 156CONFIG_ARCH_ADI_COYOTE=y
157CONFIG_MACH_GATEWAY7001=y
158CONFIG_MACH_WG302V2=y
117CONFIG_ARCH_IXDP425=y 159CONFIG_ARCH_IXDP425=y
118CONFIG_MACH_IXDPG425=y 160CONFIG_MACH_IXDPG425=y
119CONFIG_MACH_IXDP465=y 161CONFIG_MACH_IXDP465=y
@@ -121,15 +163,27 @@ CONFIG_MACH_KIXRP435=y
121CONFIG_ARCH_IXCDP1100=y 163CONFIG_ARCH_IXCDP1100=y
122CONFIG_ARCH_PRPMC1100=y 164CONFIG_ARCH_PRPMC1100=y
123CONFIG_MACH_NAS100D=y 165CONFIG_MACH_NAS100D=y
166CONFIG_MACH_DSMG600=y
124CONFIG_ARCH_IXDP4XX=y 167CONFIG_ARCH_IXDP4XX=y
125CONFIG_CPU_IXP46X=y 168CONFIG_CPU_IXP46X=y
126CONFIG_CPU_IXP43X=y 169CONFIG_CPU_IXP43X=y
127# CONFIG_MACH_GTWX5715 is not set 170CONFIG_MACH_GTWX5715=y
128 171
129# 172#
130# IXP4xx Options 173# IXP4xx Options
131# 174#
175CONFIG_DMABOUNCE=y
132# CONFIG_IXP4XX_INDIRECT_PCI is not set 176# CONFIG_IXP4XX_INDIRECT_PCI is not set
177CONFIG_IXP4XX_QMGR=y
178CONFIG_IXP4XX_NPE=y
179
180#
181# Boot options
182#
183
184#
185# Power management
186#
133 187
134# 188#
135# Processor Type 189# Processor Type
@@ -140,33 +194,40 @@ CONFIG_CPU_32v5=y
140CONFIG_CPU_ABRT_EV5T=y 194CONFIG_CPU_ABRT_EV5T=y
141CONFIG_CPU_CACHE_VIVT=y 195CONFIG_CPU_CACHE_VIVT=y
142CONFIG_CPU_TLB_V4WBI=y 196CONFIG_CPU_TLB_V4WBI=y
197CONFIG_CPU_CP15=y
198CONFIG_CPU_CP15_MMU=y
143 199
144# 200#
145# Processor Features 201# Processor Features
146# 202#
147# CONFIG_ARM_THUMB is not set 203# CONFIG_ARM_THUMB is not set
148CONFIG_CPU_BIG_ENDIAN=y 204CONFIG_CPU_BIG_ENDIAN=y
205# CONFIG_CPU_DCACHE_DISABLE is not set
206# CONFIG_OUTER_CACHE is not set
207# CONFIG_IWMMXT is not set
149CONFIG_XSCALE_PMU=y 208CONFIG_XSCALE_PMU=y
150CONFIG_DMABOUNCE=y
151 209
152# 210#
153# Bus support 211# Bus support
154# 212#
155CONFIG_ISA_DMA_API=y
156CONFIG_PCI=y 213CONFIG_PCI=y
157CONFIG_PCI_LEGACY_PROC=y 214CONFIG_PCI_SYSCALL=y
215# CONFIG_ARCH_SUPPORTS_MSI is not set
216CONFIG_PCI_LEGACY=y
158# CONFIG_PCI_DEBUG is not set 217# CONFIG_PCI_DEBUG is not set
159
160#
161# PCCARD (PCMCIA/CardBus) support
162#
163# CONFIG_PCCARD is not set 218# CONFIG_PCCARD is not set
164 219
165# 220#
166# Kernel Features 221# Kernel Features
167# 222#
223# CONFIG_TICK_ONESHOT is not set
224# CONFIG_NO_HZ is not set
225# CONFIG_HIGH_RES_TIMERS is not set
226CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
168# CONFIG_PREEMPT is not set 227# CONFIG_PREEMPT is not set
169# CONFIG_NO_IDLE_HZ is not set 228CONFIG_HZ=100
229CONFIG_AEABI=y
230CONFIG_OABI_COMPAT=y
170# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set 231# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
171CONFIG_SELECT_MEMORY_MODEL=y 232CONFIG_SELECT_MEMORY_MODEL=y
172CONFIG_FLATMEM_MANUAL=y 233CONFIG_FLATMEM_MANUAL=y
@@ -175,7 +236,12 @@ CONFIG_FLATMEM_MANUAL=y
175CONFIG_FLATMEM=y 236CONFIG_FLATMEM=y
176CONFIG_FLAT_NODE_MEM_MAP=y 237CONFIG_FLAT_NODE_MEM_MAP=y
177# CONFIG_SPARSEMEM_STATIC is not set 238# CONFIG_SPARSEMEM_STATIC is not set
239# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
178CONFIG_SPLIT_PTLOCK_CPUS=4096 240CONFIG_SPLIT_PTLOCK_CPUS=4096
241# CONFIG_RESOURCES_64BIT is not set
242CONFIG_ZONE_DMA_FLAG=1
243CONFIG_BOUNCE=y
244CONFIG_VIRT_TO_BUS=y
179CONFIG_ALIGNMENT_TRAP=y 245CONFIG_ALIGNMENT_TRAP=y
180 246
181# 247#
@@ -185,6 +251,7 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
185CONFIG_ZBOOT_ROM_BSS=0x0 251CONFIG_ZBOOT_ROM_BSS=0x0
186CONFIG_CMDLINE="console=ttyS0,115200 ip=bootp root=/dev/nfs" 252CONFIG_CMDLINE="console=ttyS0,115200 ip=bootp root=/dev/nfs"
187# CONFIG_XIP_KERNEL is not set 253# CONFIG_XIP_KERNEL is not set
254# CONFIG_KEXEC is not set
188 255
189# 256#
190# Floating point emulation 257# Floating point emulation
@@ -203,13 +270,12 @@ CONFIG_FPE_NWFPE=y
203CONFIG_BINFMT_ELF=y 270CONFIG_BINFMT_ELF=y
204# CONFIG_BINFMT_AOUT is not set 271# CONFIG_BINFMT_AOUT is not set
205# CONFIG_BINFMT_MISC is not set 272# CONFIG_BINFMT_MISC is not set
206# CONFIG_ARTHUR is not set
207 273
208# 274#
209# Power management options 275# Power management options
210# 276#
211# CONFIG_PM is not set 277# CONFIG_PM is not set
212# CONFIG_APM is not set 278CONFIG_SUSPEND_UP_POSSIBLE=y
213 279
214# 280#
215# Networking 281# Networking
@@ -219,11 +285,13 @@ CONFIG_NET=y
219# 285#
220# Networking options 286# Networking options
221# 287#
222CONFIG_PACKET=m 288CONFIG_PACKET=y
223CONFIG_PACKET_MMAP=y 289CONFIG_PACKET_MMAP=y
224CONFIG_UNIX=y 290CONFIG_UNIX=y
225CONFIG_XFRM=y 291CONFIG_XFRM=y
226# CONFIG_XFRM_USER is not set 292# CONFIG_XFRM_USER is not set
293# CONFIG_XFRM_SUB_POLICY is not set
294# CONFIG_XFRM_MIGRATE is not set
227# CONFIG_NET_KEY is not set 295# CONFIG_NET_KEY is not set
228CONFIG_INET=y 296CONFIG_INET=y
229CONFIG_IP_MULTICAST=y 297CONFIG_IP_MULTICAST=y
@@ -232,9 +300,7 @@ CONFIG_ASK_IP_FIB_HASH=y
232# CONFIG_IP_FIB_TRIE is not set 300# CONFIG_IP_FIB_TRIE is not set
233CONFIG_IP_FIB_HASH=y 301CONFIG_IP_FIB_HASH=y
234CONFIG_IP_MULTIPLE_TABLES=y 302CONFIG_IP_MULTIPLE_TABLES=y
235CONFIG_IP_ROUTE_FWMARK=y
236CONFIG_IP_ROUTE_MULTIPATH=y 303CONFIG_IP_ROUTE_MULTIPATH=y
237# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
238CONFIG_IP_ROUTE_VERBOSE=y 304CONFIG_IP_ROUTE_VERBOSE=y
239CONFIG_IP_PNP=y 305CONFIG_IP_PNP=y
240CONFIG_IP_PNP_DHCP=y 306CONFIG_IP_PNP_DHCP=y
@@ -251,15 +317,18 @@ CONFIG_SYN_COOKIES=y
251# CONFIG_INET_AH is not set 317# CONFIG_INET_AH is not set
252# CONFIG_INET_ESP is not set 318# CONFIG_INET_ESP is not set
253# CONFIG_INET_IPCOMP is not set 319# CONFIG_INET_IPCOMP is not set
254CONFIG_INET_TUNNEL=m 320# CONFIG_INET_XFRM_TUNNEL is not set
321# CONFIG_INET_TUNNEL is not set
322CONFIG_INET_XFRM_MODE_TRANSPORT=y
323CONFIG_INET_XFRM_MODE_TUNNEL=y
324CONFIG_INET_XFRM_MODE_BEET=y
325# CONFIG_INET_LRO is not set
255CONFIG_INET_DIAG=y 326CONFIG_INET_DIAG=y
256CONFIG_INET_TCP_DIAG=y 327CONFIG_INET_TCP_DIAG=y
257# CONFIG_TCP_CONG_ADVANCED is not set 328# CONFIG_TCP_CONG_ADVANCED is not set
258CONFIG_TCP_CONG_BIC=y 329CONFIG_TCP_CONG_CUBIC=y
259 330CONFIG_DEFAULT_TCP_CONG="cubic"
260# 331# CONFIG_TCP_MD5SIG is not set
261# IP: Virtual Server Configuration
262#
263CONFIG_IP_VS=m 332CONFIG_IP_VS=m
264CONFIG_IP_VS_DEBUG=y 333CONFIG_IP_VS_DEBUG=y
265CONFIG_IP_VS_TAB_BITS=12 334CONFIG_IP_VS_TAB_BITS=12
@@ -290,6 +359,9 @@ CONFIG_IP_VS_SH=m
290# IPVS application helper 359# IPVS application helper
291# 360#
292# CONFIG_IPV6 is not set 361# CONFIG_IPV6 is not set
362# CONFIG_INET6_XFRM_TUNNEL is not set
363# CONFIG_INET6_TUNNEL is not set
364# CONFIG_NETWORK_SECMARK is not set
293CONFIG_NETFILTER=y 365CONFIG_NETFILTER=y
294# CONFIG_NETFILTER_DEBUG is not set 366# CONFIG_NETFILTER_DEBUG is not set
295CONFIG_BRIDGE_NETFILTER=y 367CONFIG_BRIDGE_NETFILTER=y
@@ -298,70 +370,57 @@ CONFIG_BRIDGE_NETFILTER=y
298# Core Netfilter Configuration 370# Core Netfilter Configuration
299# 371#
300# CONFIG_NETFILTER_NETLINK is not set 372# CONFIG_NETFILTER_NETLINK is not set
373# CONFIG_NF_CONNTRACK_ENABLED is not set
374# CONFIG_NF_CONNTRACK is not set
375CONFIG_NETFILTER_XTABLES=m
376# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
377# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
378# CONFIG_NETFILTER_XT_TARGET_MARK is not set
379# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
380# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
381# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
382# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
383# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
384# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
385# CONFIG_NETFILTER_XT_MATCH_ESP is not set
386# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
387# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
388# CONFIG_NETFILTER_XT_MATCH_MAC is not set
389# CONFIG_NETFILTER_XT_MATCH_MARK is not set
390# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
391# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
392# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
393# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
394# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
395# CONFIG_NETFILTER_XT_MATCH_REALM is not set
396# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
397# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
398# CONFIG_NETFILTER_XT_MATCH_STRING is not set
399# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
400# CONFIG_NETFILTER_XT_MATCH_TIME is not set
401# CONFIG_NETFILTER_XT_MATCH_U32 is not set
402# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
301 403
302# 404#
303# IP: Netfilter Configuration 405# IP: Netfilter Configuration
304# 406#
305CONFIG_IP_NF_CONNTRACK=m
306# CONFIG_IP_NF_CT_ACCT is not set
307# CONFIG_IP_NF_CONNTRACK_MARK is not set
308# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
309# CONFIG_IP_NF_CT_PROTO_SCTP is not set
310CONFIG_IP_NF_FTP=m
311CONFIG_IP_NF_IRC=m
312# CONFIG_IP_NF_NETBIOS_NS is not set
313# CONFIG_IP_NF_TFTP is not set
314# CONFIG_IP_NF_AMANDA is not set
315# CONFIG_IP_NF_PPTP is not set
316CONFIG_IP_NF_QUEUE=m 407CONFIG_IP_NF_QUEUE=m
317CONFIG_IP_NF_IPTABLES=m 408CONFIG_IP_NF_IPTABLES=m
318CONFIG_IP_NF_MATCH_LIMIT=m
319# CONFIG_IP_NF_MATCH_IPRANGE is not set 409# CONFIG_IP_NF_MATCH_IPRANGE is not set
320CONFIG_IP_NF_MATCH_MAC=m
321# CONFIG_IP_NF_MATCH_PKTTYPE is not set
322CONFIG_IP_NF_MATCH_MARK=m
323CONFIG_IP_NF_MATCH_MULTIPORT=m
324CONFIG_IP_NF_MATCH_TOS=m 410CONFIG_IP_NF_MATCH_TOS=m
325# CONFIG_IP_NF_MATCH_RECENT is not set 411# CONFIG_IP_NF_MATCH_RECENT is not set
326# CONFIG_IP_NF_MATCH_ECN is not set 412# CONFIG_IP_NF_MATCH_ECN is not set
327# CONFIG_IP_NF_MATCH_DSCP is not set 413# CONFIG_IP_NF_MATCH_AH is not set
328CONFIG_IP_NF_MATCH_AH_ESP=m
329CONFIG_IP_NF_MATCH_LENGTH=m
330CONFIG_IP_NF_MATCH_TTL=m 414CONFIG_IP_NF_MATCH_TTL=m
331CONFIG_IP_NF_MATCH_TCPMSS=m
332# CONFIG_IP_NF_MATCH_HELPER is not set
333CONFIG_IP_NF_MATCH_STATE=m
334# CONFIG_IP_NF_MATCH_CONNTRACK is not set
335CONFIG_IP_NF_MATCH_OWNER=m 415CONFIG_IP_NF_MATCH_OWNER=m
336# CONFIG_IP_NF_MATCH_PHYSDEV is not set
337# CONFIG_IP_NF_MATCH_ADDRTYPE is not set 416# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
338# CONFIG_IP_NF_MATCH_REALM is not set
339# CONFIG_IP_NF_MATCH_SCTP is not set
340# CONFIG_IP_NF_MATCH_DCCP is not set
341# CONFIG_IP_NF_MATCH_COMMENT is not set
342# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
343# CONFIG_IP_NF_MATCH_STRING is not set
344CONFIG_IP_NF_FILTER=m 417CONFIG_IP_NF_FILTER=m
345CONFIG_IP_NF_TARGET_REJECT=m 418CONFIG_IP_NF_TARGET_REJECT=m
346CONFIG_IP_NF_TARGET_LOG=m 419CONFIG_IP_NF_TARGET_LOG=m
347CONFIG_IP_NF_TARGET_ULOG=m 420CONFIG_IP_NF_TARGET_ULOG=m
348CONFIG_IP_NF_TARGET_TCPMSS=m
349# CONFIG_IP_NF_TARGET_NFQUEUE is not set
350CONFIG_IP_NF_NAT=m
351CONFIG_IP_NF_NAT_NEEDED=y
352CONFIG_IP_NF_TARGET_MASQUERADE=m
353CONFIG_IP_NF_TARGET_REDIRECT=m
354# CONFIG_IP_NF_TARGET_NETMAP is not set
355# CONFIG_IP_NF_TARGET_SAME is not set
356CONFIG_IP_NF_NAT_SNMP_BASIC=m
357CONFIG_IP_NF_NAT_IRC=m
358CONFIG_IP_NF_NAT_FTP=m
359CONFIG_IP_NF_MANGLE=m 421CONFIG_IP_NF_MANGLE=m
360CONFIG_IP_NF_TARGET_TOS=m 422CONFIG_IP_NF_TARGET_TOS=m
361# CONFIG_IP_NF_TARGET_ECN is not set 423# CONFIG_IP_NF_TARGET_ECN is not set
362# CONFIG_IP_NF_TARGET_DSCP is not set
363CONFIG_IP_NF_TARGET_MARK=m
364# CONFIG_IP_NF_TARGET_CLASSIFY is not set
365# CONFIG_IP_NF_TARGET_TTL is not set 424# CONFIG_IP_NF_TARGET_TTL is not set
366# CONFIG_IP_NF_RAW is not set 425# CONFIG_IP_NF_RAW is not set
367CONFIG_IP_NF_ARPTABLES=m 426CONFIG_IP_NF_ARPTABLES=m
@@ -372,16 +431,9 @@ CONFIG_IP_NF_ARPFILTER=m
372# Bridge: Netfilter Configuration 431# Bridge: Netfilter Configuration
373# 432#
374# CONFIG_BRIDGE_NF_EBTABLES is not set 433# CONFIG_BRIDGE_NF_EBTABLES is not set
375
376#
377# DCCP Configuration (EXPERIMENTAL)
378#
379# CONFIG_IP_DCCP is not set 434# CONFIG_IP_DCCP is not set
380
381#
382# SCTP Configuration (EXPERIMENTAL)
383#
384# CONFIG_IP_SCTP is not set 435# CONFIG_IP_SCTP is not set
436# CONFIG_TIPC is not set
385CONFIG_ATM=y 437CONFIG_ATM=y
386CONFIG_ATM_CLIP=y 438CONFIG_ATM_CLIP=y
387# CONFIG_ATM_CLIP_NO_ICMP is not set 439# CONFIG_ATM_CLIP_NO_ICMP is not set
@@ -397,25 +449,17 @@ CONFIG_LLC=m
397CONFIG_IPX=m 449CONFIG_IPX=m
398# CONFIG_IPX_INTERN is not set 450# CONFIG_IPX_INTERN is not set
399CONFIG_ATALK=m 451CONFIG_ATALK=m
400CONFIG_DEV_APPLETALK=y 452CONFIG_DEV_APPLETALK=m
401CONFIG_IPDDP=m 453CONFIG_IPDDP=m
402CONFIG_IPDDP_ENCAP=y 454CONFIG_IPDDP_ENCAP=y
403CONFIG_IPDDP_DECAP=y 455CONFIG_IPDDP_DECAP=y
404CONFIG_X25=m 456CONFIG_X25=m
405CONFIG_LAPB=m 457CONFIG_LAPB=m
406# CONFIG_NET_DIVERT is not set
407CONFIG_ECONET=m 458CONFIG_ECONET=m
408CONFIG_ECONET_AUNUDP=y 459CONFIG_ECONET_AUNUDP=y
409CONFIG_ECONET_NATIVE=y 460CONFIG_ECONET_NATIVE=y
410CONFIG_WAN_ROUTER=m 461CONFIG_WAN_ROUTER=m
411
412#
413# QoS and/or fair queueing
414#
415CONFIG_NET_SCHED=y 462CONFIG_NET_SCHED=y
416CONFIG_NET_SCH_CLK_JIFFIES=y
417# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
418# CONFIG_NET_SCH_CLK_CPU is not set
419 463
420# 464#
421# Queueing/Scheduling 465# Queueing/Scheduling
@@ -425,6 +469,7 @@ CONFIG_NET_SCH_HTB=m
425# CONFIG_NET_SCH_HFSC is not set 469# CONFIG_NET_SCH_HFSC is not set
426# CONFIG_NET_SCH_ATM is not set 470# CONFIG_NET_SCH_ATM is not set
427CONFIG_NET_SCH_PRIO=m 471CONFIG_NET_SCH_PRIO=m
472# CONFIG_NET_SCH_RR is not set
428CONFIG_NET_SCH_RED=m 473CONFIG_NET_SCH_RED=m
429CONFIG_NET_SCH_SFQ=m 474CONFIG_NET_SCH_SFQ=m
430CONFIG_NET_SCH_TEQL=m 475CONFIG_NET_SCH_TEQL=m
@@ -449,10 +494,17 @@ CONFIG_NET_CLS_U32=m
449CONFIG_NET_CLS_RSVP=m 494CONFIG_NET_CLS_RSVP=m
450CONFIG_NET_CLS_RSVP6=m 495CONFIG_NET_CLS_RSVP6=m
451# CONFIG_NET_EMATCH is not set 496# CONFIG_NET_EMATCH is not set
452# CONFIG_NET_CLS_ACT is not set 497CONFIG_NET_CLS_ACT=y
498CONFIG_NET_ACT_POLICE=y
499# CONFIG_NET_ACT_GACT is not set
500# CONFIG_NET_ACT_MIRRED is not set
501# CONFIG_NET_ACT_IPT is not set
502# CONFIG_NET_ACT_NAT is not set
503# CONFIG_NET_ACT_PEDIT is not set
504# CONFIG_NET_ACT_SIMP is not set
453CONFIG_NET_CLS_POLICE=y 505CONFIG_NET_CLS_POLICE=y
454# CONFIG_NET_CLS_IND is not set 506# CONFIG_NET_CLS_IND is not set
455CONFIG_NET_ESTIMATOR=y 507CONFIG_NET_SCH_FIFO=y
456 508
457# 509#
458# Network testing 510# Network testing
@@ -461,7 +513,18 @@ CONFIG_NET_PKTGEN=m
461# CONFIG_HAMRADIO is not set 513# CONFIG_HAMRADIO is not set
462# CONFIG_IRDA is not set 514# CONFIG_IRDA is not set
463# CONFIG_BT is not set 515# CONFIG_BT is not set
516# CONFIG_AF_RXRPC is not set
517CONFIG_FIB_RULES=y
518
519#
520# Wireless
521#
522# CONFIG_CFG80211 is not set
523# CONFIG_WIRELESS_EXT is not set
524# CONFIG_MAC80211 is not set
464# CONFIG_IEEE80211 is not set 525# CONFIG_IEEE80211 is not set
526# CONFIG_RFKILL is not set
527# CONFIG_NET_9P is not set
465 528
466# 529#
467# Device Drivers 530# Device Drivers
@@ -470,19 +533,14 @@ CONFIG_NET_PKTGEN=m
470# 533#
471# Generic Driver Options 534# Generic Driver Options
472# 535#
536CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
473CONFIG_STANDALONE=y 537CONFIG_STANDALONE=y
474CONFIG_PREVENT_FIRMWARE_BUILD=y 538CONFIG_PREVENT_FIRMWARE_BUILD=y
475# CONFIG_FW_LOADER is not set 539CONFIG_FW_LOADER=y
476# CONFIG_DEBUG_DRIVER is not set 540# CONFIG_DEBUG_DRIVER is not set
477 541# CONFIG_DEBUG_DEVRES is not set
478# 542# CONFIG_SYS_HYPERVISOR is not set
479# Connector - unified userspace <-> kernelspace linker
480#
481# CONFIG_CONNECTOR is not set 543# CONFIG_CONNECTOR is not set
482
483#
484# Memory Technology Devices (MTD)
485#
486CONFIG_MTD=y 544CONFIG_MTD=y
487# CONFIG_MTD_DEBUG is not set 545# CONFIG_MTD_DEBUG is not set
488# CONFIG_MTD_CONCAT is not set 546# CONFIG_MTD_CONCAT is not set
@@ -498,11 +556,14 @@ CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
498# User Modules And Translation Layers 556# User Modules And Translation Layers
499# 557#
500CONFIG_MTD_CHAR=y 558CONFIG_MTD_CHAR=y
559CONFIG_MTD_BLKDEVS=y
501CONFIG_MTD_BLOCK=y 560CONFIG_MTD_BLOCK=y
502# CONFIG_FTL is not set 561# CONFIG_FTL is not set
503# CONFIG_NFTL is not set 562# CONFIG_NFTL is not set
504# CONFIG_INFTL is not set 563# CONFIG_INFTL is not set
505# CONFIG_RFD_FTL is not set 564# CONFIG_RFD_FTL is not set
565# CONFIG_SSFDC is not set
566# CONFIG_MTD_OOPS is not set
506 567
507# 568#
508# RAM/ROM/Flash chip drivers 569# RAM/ROM/Flash chip drivers
@@ -528,7 +589,6 @@ CONFIG_MTD_CFI_UTIL=y
528# CONFIG_MTD_RAM is not set 589# CONFIG_MTD_RAM is not set
529# CONFIG_MTD_ROM is not set 590# CONFIG_MTD_ROM is not set
530# CONFIG_MTD_ABSENT is not set 591# CONFIG_MTD_ABSENT is not set
531# CONFIG_MTD_XIP is not set
532 592
533# 593#
534# Mapping drivers for chip access 594# Mapping drivers for chip access
@@ -538,6 +598,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
538# CONFIG_MTD_ARM_INTEGRATOR is not set 598# CONFIG_MTD_ARM_INTEGRATOR is not set
539CONFIG_MTD_IXP4XX=y 599CONFIG_MTD_IXP4XX=y
540# CONFIG_MTD_PCI is not set 600# CONFIG_MTD_PCI is not set
601# CONFIG_MTD_INTEL_VR_NOR is not set
541# CONFIG_MTD_PLATRAM is not set 602# CONFIG_MTD_PLATRAM is not set
542 603
543# 604#
@@ -547,7 +608,6 @@ CONFIG_MTD_IXP4XX=y
547# CONFIG_MTD_SLRAM is not set 608# CONFIG_MTD_SLRAM is not set
548# CONFIG_MTD_PHRAM is not set 609# CONFIG_MTD_PHRAM is not set
549# CONFIG_MTD_MTDRAM is not set 610# CONFIG_MTD_MTDRAM is not set
550# CONFIG_MTD_BLKMTD is not set
551# CONFIG_MTD_BLOCK2MTD is not set 611# CONFIG_MTD_BLOCK2MTD is not set
552 612
553# 613#
@@ -556,33 +616,24 @@ CONFIG_MTD_IXP4XX=y
556# CONFIG_MTD_DOC2000 is not set 616# CONFIG_MTD_DOC2000 is not set
557# CONFIG_MTD_DOC2001 is not set 617# CONFIG_MTD_DOC2001 is not set
558# CONFIG_MTD_DOC2001PLUS is not set 618# CONFIG_MTD_DOC2001PLUS is not set
559
560#
561# NAND Flash Device Drivers
562#
563CONFIG_MTD_NAND=m 619CONFIG_MTD_NAND=m
564# CONFIG_MTD_NAND_VERIFY_WRITE is not set 620# CONFIG_MTD_NAND_VERIFY_WRITE is not set
621# CONFIG_MTD_NAND_ECC_SMC is not set
622# CONFIG_MTD_NAND_MUSEUM_IDS is not set
565CONFIG_MTD_NAND_IDS=m 623CONFIG_MTD_NAND_IDS=m
566# CONFIG_MTD_NAND_DISKONCHIP is not set 624# CONFIG_MTD_NAND_DISKONCHIP is not set
625# CONFIG_MTD_NAND_CAFE is not set
567# CONFIG_MTD_NAND_NANDSIM is not set 626# CONFIG_MTD_NAND_NANDSIM is not set
568 627# CONFIG_MTD_NAND_PLATFORM is not set
569# 628# CONFIG_MTD_ALAUDA is not set
570# OneNAND Flash Device Drivers
571#
572# CONFIG_MTD_ONENAND is not set 629# CONFIG_MTD_ONENAND is not set
573 630
574# 631#
575# Parallel port support 632# UBI - Unsorted block images
576# 633#
634# CONFIG_MTD_UBI is not set
577# CONFIG_PARPORT is not set 635# CONFIG_PARPORT is not set
578 636CONFIG_BLK_DEV=y
579#
580# Plug and Play support
581#
582
583#
584# Block devices
585#
586# CONFIG_BLK_CPQ_DA is not set 637# CONFIG_BLK_CPQ_DA is not set
587# CONFIG_BLK_CPQ_CISS_DA is not set 638# CONFIG_BLK_CPQ_CISS_DA is not set
588# CONFIG_BLK_DEV_DAC960 is not set 639# CONFIG_BLK_DEV_DAC960 is not set
@@ -592,17 +643,20 @@ CONFIG_BLK_DEV_LOOP=y
592# CONFIG_BLK_DEV_CRYPTOLOOP is not set 643# CONFIG_BLK_DEV_CRYPTOLOOP is not set
593# CONFIG_BLK_DEV_NBD is not set 644# CONFIG_BLK_DEV_NBD is not set
594# CONFIG_BLK_DEV_SX8 is not set 645# CONFIG_BLK_DEV_SX8 is not set
646# CONFIG_BLK_DEV_UB is not set
595CONFIG_BLK_DEV_RAM=y 647CONFIG_BLK_DEV_RAM=y
596CONFIG_BLK_DEV_RAM_COUNT=16 648CONFIG_BLK_DEV_RAM_COUNT=16
597CONFIG_BLK_DEV_RAM_SIZE=8192 649CONFIG_BLK_DEV_RAM_SIZE=8192
598CONFIG_BLK_DEV_INITRD=y 650CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
599# CONFIG_CDROM_PKTCDVD is not set 651# CONFIG_CDROM_PKTCDVD is not set
600# CONFIG_ATA_OVER_ETH is not set 652# CONFIG_ATA_OVER_ETH is not set
601 653CONFIG_MISC_DEVICES=y
602# 654# CONFIG_PHANTOM is not set
603# ATA/ATAPI/MFM/RLL support 655# CONFIG_EEPROM_93CX6 is not set
604# 656# CONFIG_SGI_IOC4 is not set
657# CONFIG_TIFM_CORE is not set
605CONFIG_IDE=y 658CONFIG_IDE=y
659CONFIG_IDE_MAX_HWIFS=4
606CONFIG_BLK_DEV_IDE=y 660CONFIG_BLK_DEV_IDE=y
607 661
608# 662#
@@ -614,24 +668,28 @@ CONFIG_BLK_DEV_IDEDISK=y
614# CONFIG_BLK_DEV_IDECD is not set 668# CONFIG_BLK_DEV_IDECD is not set
615# CONFIG_BLK_DEV_IDETAPE is not set 669# CONFIG_BLK_DEV_IDETAPE is not set
616# CONFIG_BLK_DEV_IDEFLOPPY is not set 670# CONFIG_BLK_DEV_IDEFLOPPY is not set
671# CONFIG_BLK_DEV_IDESCSI is not set
617# CONFIG_IDE_TASK_IOCTL is not set 672# CONFIG_IDE_TASK_IOCTL is not set
673CONFIG_IDE_PROC_FS=y
618 674
619# 675#
620# IDE chipset support/bugfixes 676# IDE chipset support/bugfixes
621# 677#
622CONFIG_IDE_GENERIC=y 678CONFIG_IDE_GENERIC=y
679# CONFIG_BLK_DEV_PLATFORM is not set
680
681#
682# PCI IDE chipsets support
683#
623CONFIG_BLK_DEV_IDEPCI=y 684CONFIG_BLK_DEV_IDEPCI=y
624# CONFIG_IDEPCI_SHARE_IRQ is not set 685# CONFIG_IDEPCI_SHARE_IRQ is not set
686CONFIG_IDEPCI_PCIBUS_ORDER=y
625# CONFIG_BLK_DEV_OFFBOARD is not set 687# CONFIG_BLK_DEV_OFFBOARD is not set
626# CONFIG_BLK_DEV_GENERIC is not set 688# CONFIG_BLK_DEV_GENERIC is not set
627# CONFIG_BLK_DEV_OPTI621 is not set 689# CONFIG_BLK_DEV_OPTI621 is not set
628# CONFIG_BLK_DEV_SL82C105 is not set
629CONFIG_BLK_DEV_IDEDMA_PCI=y 690CONFIG_BLK_DEV_IDEDMA_PCI=y
630# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
631# CONFIG_IDEDMA_PCI_AUTO is not set
632# CONFIG_BLK_DEV_AEC62XX is not set 691# CONFIG_BLK_DEV_AEC62XX is not set
633# CONFIG_BLK_DEV_ALI15X3 is not set 692# CONFIG_BLK_DEV_ALI15X3 is not set
634# CONFIG_BLK_DEV_AMD74XX is not set
635CONFIG_BLK_DEV_CMD64X=y 693CONFIG_BLK_DEV_CMD64X=y
636# CONFIG_BLK_DEV_TRIFLEX is not set 694# CONFIG_BLK_DEV_TRIFLEX is not set
637# CONFIG_BLK_DEV_CY82C693 is not set 695# CONFIG_BLK_DEV_CY82C693 is not set
@@ -639,93 +697,163 @@ CONFIG_BLK_DEV_CMD64X=y
639# CONFIG_BLK_DEV_CS5530 is not set 697# CONFIG_BLK_DEV_CS5530 is not set
640# CONFIG_BLK_DEV_HPT34X is not set 698# CONFIG_BLK_DEV_HPT34X is not set
641CONFIG_BLK_DEV_HPT366=y 699CONFIG_BLK_DEV_HPT366=y
700# CONFIG_BLK_DEV_JMICRON is not set
642# CONFIG_BLK_DEV_SC1200 is not set 701# CONFIG_BLK_DEV_SC1200 is not set
643# CONFIG_BLK_DEV_PIIX is not set 702# CONFIG_BLK_DEV_PIIX is not set
703# CONFIG_BLK_DEV_IT8213 is not set
644# CONFIG_BLK_DEV_IT821X is not set 704# CONFIG_BLK_DEV_IT821X is not set
645# CONFIG_BLK_DEV_NS87415 is not set 705# CONFIG_BLK_DEV_NS87415 is not set
646# CONFIG_BLK_DEV_PDC202XX_OLD is not set 706# CONFIG_BLK_DEV_PDC202XX_OLD is not set
647CONFIG_BLK_DEV_PDC202XX_NEW=y 707CONFIG_BLK_DEV_PDC202XX_NEW=y
648# CONFIG_PDC202XX_FORCE is not set
649# CONFIG_BLK_DEV_SVWKS is not set 708# CONFIG_BLK_DEV_SVWKS is not set
650# CONFIG_BLK_DEV_SIIMAGE is not set 709# CONFIG_BLK_DEV_SIIMAGE is not set
710# CONFIG_BLK_DEV_SL82C105 is not set
651# CONFIG_BLK_DEV_SLC90E66 is not set 711# CONFIG_BLK_DEV_SLC90E66 is not set
652# CONFIG_BLK_DEV_TRM290 is not set 712# CONFIG_BLK_DEV_TRM290 is not set
653# CONFIG_BLK_DEV_VIA82CXXX is not set 713# CONFIG_BLK_DEV_VIA82CXXX is not set
714# CONFIG_BLK_DEV_TC86C001 is not set
654# CONFIG_IDE_ARM is not set 715# CONFIG_IDE_ARM is not set
655CONFIG_BLK_DEV_IDEDMA=y 716CONFIG_BLK_DEV_IDEDMA=y
656# CONFIG_IDEDMA_IVB is not set 717CONFIG_IDE_ARCH_OBSOLETE_INIT=y
657# CONFIG_IDEDMA_AUTO is not set
658# CONFIG_BLK_DEV_HD is not set 718# CONFIG_BLK_DEV_HD is not set
659 719
660# 720#
661# SCSI device support 721# SCSI device support
662# 722#
663# CONFIG_RAID_ATTRS is not set 723# CONFIG_RAID_ATTRS is not set
664# CONFIG_SCSI is not set 724CONFIG_SCSI=y
665 725CONFIG_SCSI_DMA=y
666# 726# CONFIG_SCSI_TGT is not set
667# Multi-device support (RAID and LVM) 727# CONFIG_SCSI_NETLINK is not set
668# 728# CONFIG_SCSI_PROC_FS is not set
729
730#
731# SCSI support type (disk, tape, CD-ROM)
732#
733CONFIG_BLK_DEV_SD=y
734# CONFIG_CHR_DEV_ST is not set
735# CONFIG_CHR_DEV_OSST is not set
736# CONFIG_BLK_DEV_SR is not set
737# CONFIG_CHR_DEV_SG is not set
738# CONFIG_CHR_DEV_SCH is not set
739
740#
741# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
742#
743# CONFIG_SCSI_MULTI_LUN is not set
744# CONFIG_SCSI_CONSTANTS is not set
745# CONFIG_SCSI_LOGGING is not set
746# CONFIG_SCSI_SCAN_ASYNC is not set
747CONFIG_SCSI_WAIT_SCAN=m
748
749#
750# SCSI Transports
751#
752# CONFIG_SCSI_SPI_ATTRS is not set
753# CONFIG_SCSI_FC_ATTRS is not set
754# CONFIG_SCSI_ISCSI_ATTRS is not set
755# CONFIG_SCSI_SAS_LIBSAS is not set
756# CONFIG_SCSI_SRP_ATTRS is not set
757# CONFIG_SCSI_LOWLEVEL is not set
758CONFIG_ATA=y
759# CONFIG_ATA_NONSTANDARD is not set
760# CONFIG_SATA_AHCI is not set
761# CONFIG_SATA_SVW is not set
762# CONFIG_ATA_PIIX is not set
763# CONFIG_SATA_MV is not set
764# CONFIG_SATA_NV is not set
765# CONFIG_PDC_ADMA is not set
766# CONFIG_SATA_QSTOR is not set
767# CONFIG_SATA_PROMISE is not set
768# CONFIG_SATA_SX4 is not set
769# CONFIG_SATA_SIL is not set
770# CONFIG_SATA_SIL24 is not set
771# CONFIG_SATA_SIS is not set
772# CONFIG_SATA_ULI is not set
773# CONFIG_SATA_VIA is not set
774# CONFIG_SATA_VITESSE is not set
775# CONFIG_SATA_INIC162X is not set
776# CONFIG_PATA_ALI is not set
777# CONFIG_PATA_AMD is not set
778CONFIG_PATA_ARTOP=y
779# CONFIG_PATA_ATIIXP is not set
780# CONFIG_PATA_CMD640_PCI is not set
781# CONFIG_PATA_CMD64X is not set
782# CONFIG_PATA_CS5520 is not set
783# CONFIG_PATA_CS5530 is not set
784# CONFIG_PATA_CYPRESS is not set
785# CONFIG_PATA_EFAR is not set
786# CONFIG_ATA_GENERIC is not set
787# CONFIG_PATA_HPT366 is not set
788# CONFIG_PATA_HPT37X is not set
789# CONFIG_PATA_HPT3X2N is not set
790# CONFIG_PATA_HPT3X3 is not set
791# CONFIG_PATA_IT821X is not set
792# CONFIG_PATA_IT8213 is not set
793# CONFIG_PATA_JMICRON is not set
794# CONFIG_PATA_TRIFLEX is not set
795# CONFIG_PATA_MARVELL is not set
796# CONFIG_PATA_MPIIX is not set
797# CONFIG_PATA_OLDPIIX is not set
798# CONFIG_PATA_NETCELL is not set
799# CONFIG_PATA_NS87410 is not set
800# CONFIG_PATA_NS87415 is not set
801# CONFIG_PATA_OPTI is not set
802# CONFIG_PATA_OPTIDMA is not set
803# CONFIG_PATA_PDC_OLD is not set
804# CONFIG_PATA_RADISYS is not set
805# CONFIG_PATA_RZ1000 is not set
806# CONFIG_PATA_SC1200 is not set
807# CONFIG_PATA_SERVERWORKS is not set
808# CONFIG_PATA_PDC2027X is not set
809# CONFIG_PATA_SIL680 is not set
810# CONFIG_PATA_SIS is not set
811# CONFIG_PATA_VIA is not set
812# CONFIG_PATA_WINBOND is not set
813# CONFIG_PATA_PLATFORM is not set
814CONFIG_PATA_IXP4XX_CF=y
669# CONFIG_MD is not set 815# CONFIG_MD is not set
670
671#
672# Fusion MPT device support
673#
674# CONFIG_FUSION is not set 816# CONFIG_FUSION is not set
675 817
676# 818#
677# IEEE 1394 (FireWire) support 819# IEEE 1394 (FireWire) support
678# 820#
821# CONFIG_FIREWIRE is not set
679# CONFIG_IEEE1394 is not set 822# CONFIG_IEEE1394 is not set
680
681#
682# I2O device support
683#
684# CONFIG_I2O is not set 823# CONFIG_I2O is not set
685
686#
687# Network device support
688#
689CONFIG_NETDEVICES=y 824CONFIG_NETDEVICES=y
825# CONFIG_NETDEVICES_MULTIQUEUE is not set
826# CONFIG_IFB is not set
690CONFIG_DUMMY=y 827CONFIG_DUMMY=y
691# CONFIG_BONDING is not set 828# CONFIG_BONDING is not set
829# CONFIG_MACVLAN is not set
692# CONFIG_EQUALIZER is not set 830# CONFIG_EQUALIZER is not set
693# CONFIG_TUN is not set 831# CONFIG_TUN is not set
694 832# CONFIG_VETH is not set
695#
696# ARCnet devices
697#
698# CONFIG_ARCNET is not set 833# CONFIG_ARCNET is not set
699
700#
701# PHY device support
702#
703# CONFIG_PHYLIB is not set 834# CONFIG_PHYLIB is not set
704
705#
706# Ethernet (10 or 100Mbit)
707#
708CONFIG_NET_ETHERNET=y 835CONFIG_NET_ETHERNET=y
709CONFIG_MII=y 836CONFIG_MII=y
837CONFIG_IXP4XX_ETH=y
838# CONFIG_AX88796 is not set
710# CONFIG_HAPPYMEAL is not set 839# CONFIG_HAPPYMEAL is not set
711# CONFIG_SUNGEM is not set 840# CONFIG_SUNGEM is not set
712# CONFIG_CASSINI is not set 841# CONFIG_CASSINI is not set
713# CONFIG_NET_VENDOR_3COM is not set 842# CONFIG_NET_VENDOR_3COM is not set
714# CONFIG_SMC91X is not set 843# CONFIG_SMC91X is not set
715# CONFIG_DM9000 is not set 844# CONFIG_DM9000 is not set
716
717#
718# Tulip family network device support
719#
720# CONFIG_NET_TULIP is not set 845# CONFIG_NET_TULIP is not set
721# CONFIG_HP100 is not set 846# CONFIG_HP100 is not set
847# CONFIG_IBM_NEW_EMAC_ZMII is not set
848# CONFIG_IBM_NEW_EMAC_RGMII is not set
849# CONFIG_IBM_NEW_EMAC_TAH is not set
850# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
722CONFIG_NET_PCI=y 851CONFIG_NET_PCI=y
723# CONFIG_PCNET32 is not set 852# CONFIG_PCNET32 is not set
724# CONFIG_AMD8111_ETH is not set 853# CONFIG_AMD8111_ETH is not set
725# CONFIG_ADAPTEC_STARFIRE is not set 854# CONFIG_ADAPTEC_STARFIRE is not set
726# CONFIG_B44 is not set 855# CONFIG_B44 is not set
727# CONFIG_FORCEDETH is not set 856# CONFIG_FORCEDETH is not set
728# CONFIG_DGRS is not set
729CONFIG_EEPRO100=y 857CONFIG_EEPRO100=y
730# CONFIG_E100 is not set 858# CONFIG_E100 is not set
731# CONFIG_FEALNX is not set 859# CONFIG_FEALNX is not set
@@ -738,93 +866,76 @@ CONFIG_EEPRO100=y
738# CONFIG_SUNDANCE is not set 866# CONFIG_SUNDANCE is not set
739# CONFIG_TLAN is not set 867# CONFIG_TLAN is not set
740# CONFIG_VIA_RHINE is not set 868# CONFIG_VIA_RHINE is not set
741 869# CONFIG_SC92031 is not set
742# 870CONFIG_NETDEV_1000=y
743# Ethernet (1000 Mbit)
744#
745# CONFIG_ACENIC is not set 871# CONFIG_ACENIC is not set
746# CONFIG_DL2K is not set 872# CONFIG_DL2K is not set
747# CONFIG_E1000 is not set 873# CONFIG_E1000 is not set
874# CONFIG_E1000E is not set
875# CONFIG_IP1000 is not set
748# CONFIG_NS83820 is not set 876# CONFIG_NS83820 is not set
749# CONFIG_HAMACHI is not set 877# CONFIG_HAMACHI is not set
750# CONFIG_YELLOWFIN is not set 878# CONFIG_YELLOWFIN is not set
751# CONFIG_R8169 is not set 879# CONFIG_R8169 is not set
752# CONFIG_SIS190 is not set 880# CONFIG_SIS190 is not set
753# CONFIG_SKGE is not set 881# CONFIG_SKGE is not set
882# CONFIG_SKY2 is not set
754# CONFIG_SK98LIN is not set 883# CONFIG_SK98LIN is not set
755# CONFIG_VIA_VELOCITY is not set 884# CONFIG_VIA_VELOCITY is not set
756# CONFIG_TIGON3 is not set 885# CONFIG_TIGON3 is not set
757# CONFIG_BNX2 is not set 886# CONFIG_BNX2 is not set
758 887# CONFIG_QLA3XXX is not set
759# 888# CONFIG_ATL1 is not set
760# Ethernet (10000 Mbit) 889CONFIG_NETDEV_10000=y
761#
762# CONFIG_CHELSIO_T1 is not set 890# CONFIG_CHELSIO_T1 is not set
891# CONFIG_CHELSIO_T3 is not set
892# CONFIG_IXGBE is not set
763# CONFIG_IXGB is not set 893# CONFIG_IXGB is not set
764# CONFIG_S2IO is not set 894# CONFIG_S2IO is not set
765 895# CONFIG_MYRI10GE is not set
766# 896# CONFIG_NETXEN_NIC is not set
767# Token Ring devices 897# CONFIG_NIU is not set
768# 898# CONFIG_MLX4_CORE is not set
899# CONFIG_TEHUTI is not set
769# CONFIG_TR is not set 900# CONFIG_TR is not set
770 901
771# 902#
772# Wireless LAN (non-hamradio) 903# Wireless LAN
773#
774CONFIG_NET_RADIO=y
775
776#
777# Obsolete Wireless cards support (pre-802.11)
778#
779# CONFIG_STRIP is not set
780
781#
782# Wireless 802.11b ISA/PCI cards support
783#
784# CONFIG_AIRO is not set
785CONFIG_HERMES=y
786# CONFIG_PLX_HERMES is not set
787# CONFIG_TMD_HERMES is not set
788# CONFIG_NORTEL_HERMES is not set
789CONFIG_PCI_HERMES=y
790# CONFIG_ATMEL is not set
791
792#
793# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
794# 904#
795# CONFIG_PRISM54 is not set 905# CONFIG_WLAN_PRE80211 is not set
796# CONFIG_HOSTAP is not set 906# CONFIG_WLAN_80211 is not set
797CONFIG_NET_WIRELESS=y
798 907
799# 908#
800# Wan interfaces 909# USB Network Adapters
801# 910#
911# CONFIG_USB_CATC is not set
912# CONFIG_USB_KAWETH is not set
913# CONFIG_USB_PEGASUS is not set
914# CONFIG_USB_RTL8150 is not set
915# CONFIG_USB_USBNET is not set
802CONFIG_WAN=y 916CONFIG_WAN=y
803# CONFIG_DSCC4 is not set
804# CONFIG_LANMEDIA is not set 917# CONFIG_LANMEDIA is not set
805# CONFIG_SYNCLINK_SYNCPPP is not set
806CONFIG_HDLC=m 918CONFIG_HDLC=m
807CONFIG_HDLC_RAW=y 919CONFIG_HDLC_RAW=m
808# CONFIG_HDLC_RAW_ETH is not set 920# CONFIG_HDLC_RAW_ETH is not set
809CONFIG_HDLC_CISCO=y 921CONFIG_HDLC_CISCO=m
810CONFIG_HDLC_FR=y 922CONFIG_HDLC_FR=m
811CONFIG_HDLC_PPP=y 923CONFIG_HDLC_PPP=m
812CONFIG_HDLC_X25=y 924CONFIG_HDLC_X25=m
813# CONFIG_PCI200SYN is not set 925# CONFIG_PCI200SYN is not set
814# CONFIG_WANXL is not set 926# CONFIG_WANXL is not set
815# CONFIG_PC300 is not set 927# CONFIG_PC300 is not set
928# CONFIG_PC300TOO is not set
816# CONFIG_FARSYNC is not set 929# CONFIG_FARSYNC is not set
930# CONFIG_DSCC4 is not set
931# CONFIG_IXP4XX_HSS is not set
817CONFIG_DLCI=m 932CONFIG_DLCI=m
818CONFIG_DLCI_COUNT=24
819CONFIG_DLCI_MAX=8 933CONFIG_DLCI_MAX=8
820CONFIG_WAN_ROUTER_DRIVERS=y 934CONFIG_WAN_ROUTER_DRIVERS=m
821# CONFIG_CYCLADES_SYNC is not set 935# CONFIG_CYCLADES_SYNC is not set
822# CONFIG_LAPBETHER is not set 936# CONFIG_LAPBETHER is not set
823# CONFIG_X25_ASY is not set 937# CONFIG_X25_ASY is not set
824 938CONFIG_ATM_DRIVERS=y
825#
826# ATM drivers
827#
828# CONFIG_ATM_DUMMY is not set 939# CONFIG_ATM_DUMMY is not set
829CONFIG_ATM_TCP=m 940CONFIG_ATM_TCP=m
830# CONFIG_ATM_LANAI is not set 941# CONFIG_ATM_LANAI is not set
@@ -842,20 +953,19 @@ CONFIG_ATM_TCP=m
842# CONFIG_HIPPI is not set 953# CONFIG_HIPPI is not set
843# CONFIG_PPP is not set 954# CONFIG_PPP is not set
844# CONFIG_SLIP is not set 955# CONFIG_SLIP is not set
956# CONFIG_NET_FC is not set
845# CONFIG_SHAPER is not set 957# CONFIG_SHAPER is not set
846# CONFIG_NETCONSOLE is not set 958# CONFIG_NETCONSOLE is not set
847# CONFIG_NETPOLL is not set 959# CONFIG_NETPOLL is not set
848# CONFIG_NET_POLL_CONTROLLER is not set 960# CONFIG_NET_POLL_CONTROLLER is not set
849
850#
851# ISDN subsystem
852#
853# CONFIG_ISDN is not set 961# CONFIG_ISDN is not set
854 962
855# 963#
856# Input device support 964# Input device support
857# 965#
858CONFIG_INPUT=y 966CONFIG_INPUT=y
967# CONFIG_INPUT_FF_MEMLESS is not set
968# CONFIG_INPUT_POLLDEV is not set
859 969
860# 970#
861# Userland interfaces 971# Userland interfaces
@@ -865,7 +975,6 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y
865CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 975CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
866CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 976CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
867# CONFIG_INPUT_JOYDEV is not set 977# CONFIG_INPUT_JOYDEV is not set
868# CONFIG_INPUT_TSDEV is not set
869# CONFIG_INPUT_EVDEV is not set 978# CONFIG_INPUT_EVDEV is not set
870# CONFIG_INPUT_EVBUG is not set 979# CONFIG_INPUT_EVBUG is not set
871 980
@@ -875,8 +984,16 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
875# CONFIG_INPUT_KEYBOARD is not set 984# CONFIG_INPUT_KEYBOARD is not set
876# CONFIG_INPUT_MOUSE is not set 985# CONFIG_INPUT_MOUSE is not set
877# CONFIG_INPUT_JOYSTICK is not set 986# CONFIG_INPUT_JOYSTICK is not set
987# CONFIG_INPUT_TABLET is not set
878# CONFIG_INPUT_TOUCHSCREEN is not set 988# CONFIG_INPUT_TOUCHSCREEN is not set
879# CONFIG_INPUT_MISC is not set 989CONFIG_INPUT_MISC=y
990CONFIG_INPUT_IXP4XX_BEEPER=y
991# CONFIG_INPUT_ATI_REMOTE is not set
992# CONFIG_INPUT_ATI_REMOTE2 is not set
993# CONFIG_INPUT_KEYSPAN_REMOTE is not set
994# CONFIG_INPUT_POWERMATE is not set
995# CONFIG_INPUT_YEALINK is not set
996# CONFIG_INPUT_UINPUT is not set
880 997
881# 998#
882# Hardware I/O ports 999# Hardware I/O ports
@@ -895,7 +1012,9 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
895# 1012#
896CONFIG_SERIAL_8250=y 1013CONFIG_SERIAL_8250=y
897CONFIG_SERIAL_8250_CONSOLE=y 1014CONFIG_SERIAL_8250_CONSOLE=y
1015CONFIG_SERIAL_8250_PCI=y
898CONFIG_SERIAL_8250_NR_UARTS=2 1016CONFIG_SERIAL_8250_NR_UARTS=2
1017CONFIG_SERIAL_8250_RUNTIME_UARTS=2
899# CONFIG_SERIAL_8250_EXTENDED is not set 1018# CONFIG_SERIAL_8250_EXTENDED is not set
900 1019
901# 1020#
@@ -907,51 +1026,17 @@ CONFIG_SERIAL_CORE_CONSOLE=y
907CONFIG_UNIX98_PTYS=y 1026CONFIG_UNIX98_PTYS=y
908CONFIG_LEGACY_PTYS=y 1027CONFIG_LEGACY_PTYS=y
909CONFIG_LEGACY_PTY_COUNT=256 1028CONFIG_LEGACY_PTY_COUNT=256
910
911#
912# IPMI
913#
914# CONFIG_IPMI_HANDLER is not set 1029# CONFIG_IPMI_HANDLER is not set
915 1030CONFIG_HW_RANDOM=m
916# 1031CONFIG_HW_RANDOM_IXP4XX=m
917# Watchdog Cards
918#
919CONFIG_WATCHDOG=y
920# CONFIG_WATCHDOG_NOWAYOUT is not set
921
922#
923# Watchdog Device Drivers
924#
925# CONFIG_SOFT_WATCHDOG is not set
926CONFIG_IXP4XX_WATCHDOG=y
927
928#
929# PCI-based Watchdog Cards
930#
931# CONFIG_PCIPCWATCHDOG is not set
932# CONFIG_WDTPCI is not set
933# CONFIG_NVRAM is not set 1032# CONFIG_NVRAM is not set
934# CONFIG_RTC is not set
935# CONFIG_DTLK is not set
936# CONFIG_R3964 is not set 1033# CONFIG_R3964 is not set
937# CONFIG_APPLICOM is not set 1034# CONFIG_APPLICOM is not set
938
939#
940# Ftape, the floppy tape device driver
941#
942# CONFIG_DRM is not set
943# CONFIG_RAW_DRIVER is not set 1035# CONFIG_RAW_DRIVER is not set
944
945#
946# TPM devices
947#
948# CONFIG_TCG_TPM is not set 1036# CONFIG_TCG_TPM is not set
949# CONFIG_TELCLOCK is not set 1037CONFIG_DEVPORT=y
950
951#
952# I2C support
953#
954CONFIG_I2C=y 1038CONFIG_I2C=y
1039CONFIG_I2C_BOARDINFO=y
955CONFIG_I2C_CHARDEV=y 1040CONFIG_I2C_CHARDEV=y
956 1041
957# 1042#
@@ -969,57 +1054,68 @@ CONFIG_I2C_ALGOBIT=y
969# CONFIG_I2C_ALI15X3 is not set 1054# CONFIG_I2C_ALI15X3 is not set
970# CONFIG_I2C_AMD756 is not set 1055# CONFIG_I2C_AMD756 is not set
971# CONFIG_I2C_AMD8111 is not set 1056# CONFIG_I2C_AMD8111 is not set
1057# CONFIG_I2C_GPIO is not set
972# CONFIG_I2C_I801 is not set 1058# CONFIG_I2C_I801 is not set
973# CONFIG_I2C_I810 is not set 1059# CONFIG_I2C_I810 is not set
974# CONFIG_I2C_PIIX4 is not set 1060# CONFIG_I2C_PIIX4 is not set
975# CONFIG_I2C_IOP3XX is not set 1061# CONFIG_I2C_IOP3XX is not set
976CONFIG_I2C_IXP4XX=y 1062CONFIG_I2C_IXP4XX=y
977# CONFIG_I2C_NFORCE2 is not set 1063# CONFIG_I2C_NFORCE2 is not set
1064# CONFIG_I2C_OCORES is not set
978# CONFIG_I2C_PARPORT_LIGHT is not set 1065# CONFIG_I2C_PARPORT_LIGHT is not set
979# CONFIG_I2C_PROSAVAGE is not set 1066# CONFIG_I2C_PROSAVAGE is not set
980# CONFIG_I2C_SAVAGE4 is not set 1067# CONFIG_I2C_SAVAGE4 is not set
981# CONFIG_SCx200_ACB is not set 1068# CONFIG_I2C_SIMTEC is not set
982# CONFIG_I2C_SIS5595 is not set 1069# CONFIG_I2C_SIS5595 is not set
983# CONFIG_I2C_SIS630 is not set 1070# CONFIG_I2C_SIS630 is not set
984# CONFIG_I2C_SIS96X is not set 1071# CONFIG_I2C_SIS96X is not set
1072# CONFIG_I2C_TAOS_EVM is not set
985# CONFIG_I2C_STUB is not set 1073# CONFIG_I2C_STUB is not set
1074# CONFIG_I2C_TINY_USB is not set
986# CONFIG_I2C_VIA is not set 1075# CONFIG_I2C_VIA is not set
987# CONFIG_I2C_VIAPRO is not set 1076# CONFIG_I2C_VIAPRO is not set
988# CONFIG_I2C_VOODOO3 is not set 1077# CONFIG_I2C_VOODOO3 is not set
989# CONFIG_I2C_PCA_ISA is not set
990 1078
991# 1079#
992# Miscellaneous I2C Chip support 1080# Miscellaneous I2C Chip support
993# 1081#
994# CONFIG_SENSORS_DS1337 is not set 1082# CONFIG_SENSORS_DS1337 is not set
995# CONFIG_SENSORS_DS1374 is not set 1083# CONFIG_SENSORS_DS1374 is not set
1084# CONFIG_DS1682 is not set
996CONFIG_SENSORS_EEPROM=y 1085CONFIG_SENSORS_EEPROM=y
997# CONFIG_SENSORS_PCF8574 is not set 1086# CONFIG_SENSORS_PCF8574 is not set
998# CONFIG_SENSORS_PCA9539 is not set 1087# CONFIG_SENSORS_PCA9539 is not set
999# CONFIG_SENSORS_PCF8591 is not set 1088# CONFIG_SENSORS_PCF8591 is not set
1000# CONFIG_SENSORS_RTC8564 is not set
1001# CONFIG_SENSORS_MAX6875 is not set 1089# CONFIG_SENSORS_MAX6875 is not set
1002# CONFIG_RTC_X1205_I2C is not set 1090# CONFIG_SENSORS_TSL2550 is not set
1003# CONFIG_I2C_DEBUG_CORE is not set 1091# CONFIG_I2C_DEBUG_CORE is not set
1004# CONFIG_I2C_DEBUG_ALGO is not set 1092# CONFIG_I2C_DEBUG_ALGO is not set
1005# CONFIG_I2C_DEBUG_BUS is not set 1093# CONFIG_I2C_DEBUG_BUS is not set
1006# CONFIG_I2C_DEBUG_CHIP is not set 1094# CONFIG_I2C_DEBUG_CHIP is not set
1007 1095
1008# 1096#
1009# Hardware Monitoring support 1097# SPI support
1010# 1098#
1099# CONFIG_SPI is not set
1100# CONFIG_SPI_MASTER is not set
1101# CONFIG_W1 is not set
1102# CONFIG_POWER_SUPPLY is not set
1011CONFIG_HWMON=y 1103CONFIG_HWMON=y
1012# CONFIG_HWMON_VID is not set 1104# CONFIG_HWMON_VID is not set
1105# CONFIG_SENSORS_AD7418 is not set
1013# CONFIG_SENSORS_ADM1021 is not set 1106# CONFIG_SENSORS_ADM1021 is not set
1014# CONFIG_SENSORS_ADM1025 is not set 1107# CONFIG_SENSORS_ADM1025 is not set
1015# CONFIG_SENSORS_ADM1026 is not set 1108# CONFIG_SENSORS_ADM1026 is not set
1109# CONFIG_SENSORS_ADM1029 is not set
1016# CONFIG_SENSORS_ADM1031 is not set 1110# CONFIG_SENSORS_ADM1031 is not set
1017# CONFIG_SENSORS_ADM9240 is not set 1111# CONFIG_SENSORS_ADM9240 is not set
1018# CONFIG_SENSORS_ASB100 is not set 1112# CONFIG_SENSORS_ADT7470 is not set
1019# CONFIG_SENSORS_ATXP1 is not set 1113# CONFIG_SENSORS_ATXP1 is not set
1020# CONFIG_SENSORS_DS1621 is not set 1114# CONFIG_SENSORS_DS1621 is not set
1021# CONFIG_SENSORS_FSCHER is not set 1115# CONFIG_SENSORS_I5K_AMB is not set
1022# CONFIG_SENSORS_FSCPOS is not set 1116# CONFIG_SENSORS_F71805F is not set
1117# CONFIG_SENSORS_F71882FG is not set
1118# CONFIG_SENSORS_F75375S is not set
1023# CONFIG_SENSORS_GL518SM is not set 1119# CONFIG_SENSORS_GL518SM is not set
1024# CONFIG_SENSORS_GL520SM is not set 1120# CONFIG_SENSORS_GL520SM is not set
1025# CONFIG_SENSORS_IT87 is not set 1121# CONFIG_SENSORS_IT87 is not set
@@ -1033,67 +1129,268 @@ CONFIG_HWMON=y
1033# CONFIG_SENSORS_LM87 is not set 1129# CONFIG_SENSORS_LM87 is not set
1034# CONFIG_SENSORS_LM90 is not set 1130# CONFIG_SENSORS_LM90 is not set
1035# CONFIG_SENSORS_LM92 is not set 1131# CONFIG_SENSORS_LM92 is not set
1132# CONFIG_SENSORS_LM93 is not set
1036# CONFIG_SENSORS_MAX1619 is not set 1133# CONFIG_SENSORS_MAX1619 is not set
1134# CONFIG_SENSORS_MAX6650 is not set
1037# CONFIG_SENSORS_PC87360 is not set 1135# CONFIG_SENSORS_PC87360 is not set
1136# CONFIG_SENSORS_PC87427 is not set
1038# CONFIG_SENSORS_SIS5595 is not set 1137# CONFIG_SENSORS_SIS5595 is not set
1138# CONFIG_SENSORS_DME1737 is not set
1039# CONFIG_SENSORS_SMSC47M1 is not set 1139# CONFIG_SENSORS_SMSC47M1 is not set
1140# CONFIG_SENSORS_SMSC47M192 is not set
1040# CONFIG_SENSORS_SMSC47B397 is not set 1141# CONFIG_SENSORS_SMSC47B397 is not set
1142# CONFIG_SENSORS_THMC50 is not set
1041# CONFIG_SENSORS_VIA686A is not set 1143# CONFIG_SENSORS_VIA686A is not set
1144# CONFIG_SENSORS_VT1211 is not set
1145# CONFIG_SENSORS_VT8231 is not set
1042# CONFIG_SENSORS_W83781D is not set 1146# CONFIG_SENSORS_W83781D is not set
1147# CONFIG_SENSORS_W83791D is not set
1043# CONFIG_SENSORS_W83792D is not set 1148# CONFIG_SENSORS_W83792D is not set
1149# CONFIG_SENSORS_W83793 is not set
1044# CONFIG_SENSORS_W83L785TS is not set 1150# CONFIG_SENSORS_W83L785TS is not set
1045# CONFIG_SENSORS_W83627HF is not set 1151# CONFIG_SENSORS_W83627HF is not set
1046# CONFIG_SENSORS_W83627EHF is not set 1152# CONFIG_SENSORS_W83627EHF is not set
1047# CONFIG_HWMON_DEBUG_CHIP is not set 1153# CONFIG_HWMON_DEBUG_CHIP is not set
1154CONFIG_WATCHDOG=y
1155# CONFIG_WATCHDOG_NOWAYOUT is not set
1048 1156
1049# 1157#
1050# Misc devices 1158# Watchdog Device Drivers
1051# 1159#
1160# CONFIG_SOFT_WATCHDOG is not set
1161CONFIG_IXP4XX_WATCHDOG=y
1052 1162
1053# 1163#
1054# Multimedia Capabilities Port drivers 1164# PCI-based Watchdog Cards
1055# 1165#
1166# CONFIG_PCIPCWATCHDOG is not set
1167# CONFIG_WDTPCI is not set
1056 1168
1057# 1169#
1058# Multimedia devices 1170# USB-based Watchdog Cards
1059# 1171#
1060# CONFIG_VIDEO_DEV is not set 1172# CONFIG_USBPCWATCHDOG is not set
1061 1173
1062# 1174#
1063# Digital Video Broadcasting Devices 1175# Sonics Silicon Backplane
1064# 1176#
1065# CONFIG_DVB is not set 1177CONFIG_SSB_POSSIBLE=y
1178# CONFIG_SSB is not set
1179
1180#
1181# Multifunction device drivers
1182#
1183# CONFIG_MFD_SM501 is not set
1184
1185#
1186# Multimedia devices
1187#
1188# CONFIG_VIDEO_DEV is not set
1189# CONFIG_DVB_CORE is not set
1190CONFIG_DAB=y
1191# CONFIG_USB_DABUSB is not set
1066 1192
1067# 1193#
1068# Graphics support 1194# Graphics support
1069# 1195#
1196# CONFIG_DRM is not set
1197# CONFIG_VGASTATE is not set
1198# CONFIG_VIDEO_OUTPUT_CONTROL is not set
1070# CONFIG_FB is not set 1199# CONFIG_FB is not set
1200# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
1201
1202#
1203# Display device support
1204#
1205# CONFIG_DISPLAY_SUPPORT is not set
1071 1206
1072# 1207#
1073# Sound 1208# Sound
1074# 1209#
1075# CONFIG_SOUND is not set 1210# CONFIG_SOUND is not set
1211CONFIG_HID_SUPPORT=y
1212CONFIG_HID=y
1213# CONFIG_HID_DEBUG is not set
1214# CONFIG_HIDRAW is not set
1076 1215
1077# 1216#
1078# USB support 1217# USB Input Devices
1079# 1218#
1219CONFIG_USB_HID=y
1220# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1221# CONFIG_HID_FF is not set
1222# CONFIG_USB_HIDDEV is not set
1223CONFIG_USB_SUPPORT=y
1080CONFIG_USB_ARCH_HAS_HCD=y 1224CONFIG_USB_ARCH_HAS_HCD=y
1081CONFIG_USB_ARCH_HAS_OHCI=y 1225CONFIG_USB_ARCH_HAS_OHCI=y
1082# CONFIG_USB is not set 1226CONFIG_USB_ARCH_HAS_EHCI=y
1227CONFIG_USB=y
1228# CONFIG_USB_DEBUG is not set
1229
1230#
1231# Miscellaneous USB options
1232#
1233CONFIG_USB_DEVICEFS=y
1234# CONFIG_USB_DEVICE_CLASS is not set
1235# CONFIG_USB_DYNAMIC_MINORS is not set
1236# CONFIG_USB_OTG is not set
1237
1238#
1239# USB Host Controller Drivers
1240#
1241CONFIG_USB_EHCI_HCD=y
1242# CONFIG_USB_EHCI_SPLIT_ISO is not set
1243# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
1244# CONFIG_USB_EHCI_TT_NEWSCHED is not set
1245# CONFIG_USB_ISP116X_HCD is not set
1246CONFIG_USB_OHCI_HCD=y
1247# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1248# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1249CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1250CONFIG_USB_UHCI_HCD=y
1251# CONFIG_USB_SL811_HCD is not set
1252# CONFIG_USB_R8A66597_HCD is not set
1253
1254#
1255# USB Device Class drivers
1256#
1257# CONFIG_USB_ACM is not set
1258# CONFIG_USB_PRINTER is not set
1083 1259
1084# 1260#
1085# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' 1261# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1086# 1262#
1087 1263
1088# 1264#
1265# may also be needed; see USB_STORAGE Help for more information
1266#
1267CONFIG_USB_STORAGE=y
1268# CONFIG_USB_STORAGE_DEBUG is not set
1269# CONFIG_USB_STORAGE_DATAFAB is not set
1270# CONFIG_USB_STORAGE_FREECOM is not set
1271# CONFIG_USB_STORAGE_ISD200 is not set
1272# CONFIG_USB_STORAGE_DPCM is not set
1273# CONFIG_USB_STORAGE_USBAT is not set
1274# CONFIG_USB_STORAGE_SDDR09 is not set
1275# CONFIG_USB_STORAGE_SDDR55 is not set
1276# CONFIG_USB_STORAGE_JUMPSHOT is not set
1277# CONFIG_USB_STORAGE_ALAUDA is not set
1278# CONFIG_USB_STORAGE_KARMA is not set
1279# CONFIG_USB_LIBUSUAL is not set
1280
1281#
1282# USB Imaging devices
1283#
1284# CONFIG_USB_MDC800 is not set
1285# CONFIG_USB_MICROTEK is not set
1286# CONFIG_USB_MON is not set
1287
1288#
1289# USB port drivers
1290#
1291
1292#
1293# USB Serial Converter support
1294#
1295# CONFIG_USB_SERIAL is not set
1296
1297#
1298# USB Miscellaneous drivers
1299#
1300# CONFIG_USB_EMI62 is not set
1301# CONFIG_USB_EMI26 is not set
1302# CONFIG_USB_ADUTUX is not set
1303# CONFIG_USB_AUERSWALD is not set
1304# CONFIG_USB_RIO500 is not set
1305# CONFIG_USB_LEGOTOWER is not set
1306# CONFIG_USB_LCD is not set
1307# CONFIG_USB_BERRY_CHARGE is not set
1308# CONFIG_USB_LED is not set
1309# CONFIG_USB_CYPRESS_CY7C63 is not set
1310# CONFIG_USB_CYTHERM is not set
1311# CONFIG_USB_PHIDGET is not set
1312# CONFIG_USB_IDMOUSE is not set
1313# CONFIG_USB_FTDI_ELAN is not set
1314# CONFIG_USB_APPLEDISPLAY is not set
1315# CONFIG_USB_SISUSBVGA is not set
1316# CONFIG_USB_LD is not set
1317# CONFIG_USB_TRANCEVIBRATOR is not set
1318# CONFIG_USB_IOWARRIOR is not set
1319# CONFIG_USB_TEST is not set
1320
1321#
1322# USB DSL modem support
1323#
1324# CONFIG_USB_ATM is not set
1325
1326#
1089# USB Gadget Support 1327# USB Gadget Support
1090# 1328#
1091# CONFIG_USB_GADGET is not set 1329# CONFIG_USB_GADGET is not set
1330# CONFIG_MMC is not set
1331CONFIG_NEW_LEDS=y
1332CONFIG_LEDS_CLASS=y
1092 1333
1093# 1334#
1094# MMC/SD Card support 1335# LED drivers
1336#
1337# CONFIG_LEDS_IXP4XX is not set
1338CONFIG_LEDS_GPIO=y
1339
1340#
1341# LED Triggers
1342#
1343CONFIG_LEDS_TRIGGERS=y
1344CONFIG_LEDS_TRIGGER_TIMER=y
1345CONFIG_LEDS_TRIGGER_IDE_DISK=y
1346CONFIG_LEDS_TRIGGER_HEARTBEAT=y
1347CONFIG_RTC_LIB=y
1348CONFIG_RTC_CLASS=y
1349CONFIG_RTC_HCTOSYS=y
1350CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1351# CONFIG_RTC_DEBUG is not set
1352
1353#
1354# RTC interfaces
1355#
1356CONFIG_RTC_INTF_SYSFS=y
1357CONFIG_RTC_INTF_PROC=y
1358CONFIG_RTC_INTF_DEV=y
1359# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1360# CONFIG_RTC_DRV_TEST is not set
1361
1362#
1363# I2C RTC drivers
1364#
1365# CONFIG_RTC_DRV_DS1307 is not set
1366# CONFIG_RTC_DRV_DS1374 is not set
1367# CONFIG_RTC_DRV_DS1672 is not set
1368# CONFIG_RTC_DRV_MAX6900 is not set
1369# CONFIG_RTC_DRV_RS5C372 is not set
1370# CONFIG_RTC_DRV_ISL1208 is not set
1371CONFIG_RTC_DRV_X1205=y
1372CONFIG_RTC_DRV_PCF8563=y
1373# CONFIG_RTC_DRV_PCF8583 is not set
1374# CONFIG_RTC_DRV_M41T80 is not set
1375
1376#
1377# SPI RTC drivers
1378#
1379
1380#
1381# Platform RTC drivers
1382#
1383# CONFIG_RTC_DRV_CMOS is not set
1384# CONFIG_RTC_DRV_DS1553 is not set
1385# CONFIG_RTC_DRV_STK17TA8 is not set
1386# CONFIG_RTC_DRV_DS1742 is not set
1387# CONFIG_RTC_DRV_M48T86 is not set
1388# CONFIG_RTC_DRV_M48T59 is not set
1389# CONFIG_RTC_DRV_V3020 is not set
1390
1391#
1392# on-CPU RTC drivers
1095# 1393#
1096# CONFIG_MMC is not set
1097 1394
1098# 1395#
1099# File systems 1396# File systems
@@ -1107,16 +1404,19 @@ CONFIG_EXT3_FS=y
1107CONFIG_EXT3_FS_XATTR=y 1404CONFIG_EXT3_FS_XATTR=y
1108CONFIG_EXT3_FS_POSIX_ACL=y 1405CONFIG_EXT3_FS_POSIX_ACL=y
1109# CONFIG_EXT3_FS_SECURITY is not set 1406# CONFIG_EXT3_FS_SECURITY is not set
1407# CONFIG_EXT4DEV_FS is not set
1110CONFIG_JBD=y 1408CONFIG_JBD=y
1111# CONFIG_JBD_DEBUG is not set
1112CONFIG_FS_MBCACHE=y 1409CONFIG_FS_MBCACHE=y
1113# CONFIG_REISERFS_FS is not set 1410# CONFIG_REISERFS_FS is not set
1114# CONFIG_JFS_FS is not set 1411# CONFIG_JFS_FS is not set
1115CONFIG_FS_POSIX_ACL=y 1412CONFIG_FS_POSIX_ACL=y
1116# CONFIG_XFS_FS is not set 1413# CONFIG_XFS_FS is not set
1414# CONFIG_GFS2_FS is not set
1415# CONFIG_OCFS2_FS is not set
1117# CONFIG_MINIX_FS is not set 1416# CONFIG_MINIX_FS is not set
1118# CONFIG_ROMFS_FS is not set 1417# CONFIG_ROMFS_FS is not set
1119CONFIG_INOTIFY=y 1418CONFIG_INOTIFY=y
1419CONFIG_INOTIFY_USER=y
1120# CONFIG_QUOTA is not set 1420# CONFIG_QUOTA is not set
1121CONFIG_DNOTIFY=y 1421CONFIG_DNOTIFY=y
1122# CONFIG_AUTOFS_FS is not set 1422# CONFIG_AUTOFS_FS is not set
@@ -1140,11 +1440,12 @@ CONFIG_DNOTIFY=y
1140# Pseudo filesystems 1440# Pseudo filesystems
1141# 1441#
1142CONFIG_PROC_FS=y 1442CONFIG_PROC_FS=y
1443CONFIG_PROC_SYSCTL=y
1143CONFIG_SYSFS=y 1444CONFIG_SYSFS=y
1144CONFIG_TMPFS=y 1445CONFIG_TMPFS=y
1446# CONFIG_TMPFS_POSIX_ACL is not set
1145# CONFIG_HUGETLB_PAGE is not set 1447# CONFIG_HUGETLB_PAGE is not set
1146CONFIG_RAMFS=y 1448# CONFIG_CONFIGFS_FS is not set
1147# CONFIG_RELAYFS_FS is not set
1148 1449
1149# 1450#
1150# Miscellaneous filesystems 1451# Miscellaneous filesystems
@@ -1156,13 +1457,15 @@ CONFIG_RAMFS=y
1156# CONFIG_BEFS_FS is not set 1457# CONFIG_BEFS_FS is not set
1157# CONFIG_BFS_FS is not set 1458# CONFIG_BFS_FS is not set
1158# CONFIG_EFS_FS is not set 1459# CONFIG_EFS_FS is not set
1159# CONFIG_JFFS_FS is not set
1160CONFIG_JFFS2_FS=y 1460CONFIG_JFFS2_FS=y
1161CONFIG_JFFS2_FS_DEBUG=0 1461CONFIG_JFFS2_FS_DEBUG=0
1162CONFIG_JFFS2_FS_WRITEBUFFER=y 1462CONFIG_JFFS2_FS_WRITEBUFFER=y
1463# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
1163# CONFIG_JFFS2_SUMMARY is not set 1464# CONFIG_JFFS2_SUMMARY is not set
1465# CONFIG_JFFS2_FS_XATTR is not set
1164# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set 1466# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1165CONFIG_JFFS2_ZLIB=y 1467CONFIG_JFFS2_ZLIB=y
1468# CONFIG_JFFS2_LZO is not set
1166CONFIG_JFFS2_RTIME=y 1469CONFIG_JFFS2_RTIME=y
1167# CONFIG_JFFS2_RUBIN is not set 1470# CONFIG_JFFS2_RUBIN is not set
1168# CONFIG_CRAMFS is not set 1471# CONFIG_CRAMFS is not set
@@ -1171,10 +1474,7 @@ CONFIG_JFFS2_RTIME=y
1171# CONFIG_QNX4FS_FS is not set 1474# CONFIG_QNX4FS_FS is not set
1172# CONFIG_SYSV_FS is not set 1475# CONFIG_SYSV_FS is not set
1173# CONFIG_UFS_FS is not set 1476# CONFIG_UFS_FS is not set
1174 1477CONFIG_NETWORK_FILESYSTEMS=y
1175#
1176# Network File Systems
1177#
1178CONFIG_NFS_FS=y 1478CONFIG_NFS_FS=y
1179CONFIG_NFS_V3=y 1479CONFIG_NFS_V3=y
1180# CONFIG_NFS_V3_ACL is not set 1480# CONFIG_NFS_V3_ACL is not set
@@ -1186,6 +1486,7 @@ CONFIG_LOCKD=y
1186CONFIG_LOCKD_V4=y 1486CONFIG_LOCKD_V4=y
1187CONFIG_NFS_COMMON=y 1487CONFIG_NFS_COMMON=y
1188CONFIG_SUNRPC=y 1488CONFIG_SUNRPC=y
1489# CONFIG_SUNRPC_BIND34 is not set
1189# CONFIG_RPCSEC_GSS_KRB5 is not set 1490# CONFIG_RPCSEC_GSS_KRB5 is not set
1190# CONFIG_RPCSEC_GSS_SPKM3 is not set 1491# CONFIG_RPCSEC_GSS_SPKM3 is not set
1191# CONFIG_SMB_FS is not set 1492# CONFIG_SMB_FS is not set
@@ -1193,7 +1494,6 @@ CONFIG_SUNRPC=y
1193# CONFIG_NCP_FS is not set 1494# CONFIG_NCP_FS is not set
1194# CONFIG_CODA_FS is not set 1495# CONFIG_CODA_FS is not set
1195# CONFIG_AFS_FS is not set 1496# CONFIG_AFS_FS is not set
1196# CONFIG_9P_FS is not set
1197 1497
1198# 1498#
1199# Partition Types 1499# Partition Types
@@ -1213,37 +1513,53 @@ CONFIG_MSDOS_PARTITION=y
1213# CONFIG_SGI_PARTITION is not set 1513# CONFIG_SGI_PARTITION is not set
1214# CONFIG_ULTRIX_PARTITION is not set 1514# CONFIG_ULTRIX_PARTITION is not set
1215# CONFIG_SUN_PARTITION is not set 1515# CONFIG_SUN_PARTITION is not set
1516# CONFIG_KARMA_PARTITION is not set
1216# CONFIG_EFI_PARTITION is not set 1517# CONFIG_EFI_PARTITION is not set
1217 1518# CONFIG_SYSV68_PARTITION is not set
1218#
1219# Native Language Support
1220#
1221# CONFIG_NLS is not set 1519# CONFIG_NLS is not set
1222 1520# CONFIG_DLM is not set
1223# 1521CONFIG_INSTRUMENTATION=y
1224# Profiling support
1225#
1226# CONFIG_PROFILING is not set 1522# CONFIG_PROFILING is not set
1523# CONFIG_MARKERS is not set
1227 1524
1228# 1525#
1229# Kernel hacking 1526# Kernel hacking
1230# 1527#
1231# CONFIG_PRINTK_TIME is not set 1528# CONFIG_PRINTK_TIME is not set
1232CONFIG_DEBUG_KERNEL=y 1529CONFIG_ENABLE_WARN_DEPRECATED=y
1530CONFIG_ENABLE_MUST_CHECK=y
1233CONFIG_MAGIC_SYSRQ=y 1531CONFIG_MAGIC_SYSRQ=y
1234CONFIG_LOG_BUF_SHIFT=14 1532# CONFIG_UNUSED_SYMBOLS is not set
1533# CONFIG_DEBUG_FS is not set
1534# CONFIG_HEADERS_CHECK is not set
1535CONFIG_DEBUG_KERNEL=y
1536# CONFIG_DEBUG_SHIRQ is not set
1235CONFIG_DETECT_SOFTLOCKUP=y 1537CONFIG_DETECT_SOFTLOCKUP=y
1538CONFIG_SCHED_DEBUG=y
1236# CONFIG_SCHEDSTATS is not set 1539# CONFIG_SCHEDSTATS is not set
1237# CONFIG_DEBUG_SLAB is not set 1540# CONFIG_TIMER_STATS is not set
1541# CONFIG_SLUB_DEBUG_ON is not set
1542# CONFIG_DEBUG_RT_MUTEXES is not set
1543# CONFIG_RT_MUTEX_TESTER is not set
1238# CONFIG_DEBUG_SPINLOCK is not set 1544# CONFIG_DEBUG_SPINLOCK is not set
1545# CONFIG_DEBUG_MUTEXES is not set
1546# CONFIG_DEBUG_LOCK_ALLOC is not set
1547# CONFIG_PROVE_LOCKING is not set
1548# CONFIG_LOCK_STAT is not set
1239# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1549# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1550# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1240# CONFIG_DEBUG_KOBJECT is not set 1551# CONFIG_DEBUG_KOBJECT is not set
1241CONFIG_DEBUG_BUGVERBOSE=y 1552CONFIG_DEBUG_BUGVERBOSE=y
1242# CONFIG_DEBUG_INFO is not set 1553# CONFIG_DEBUG_INFO is not set
1243# CONFIG_DEBUG_FS is not set
1244# CONFIG_DEBUG_VM is not set 1554# CONFIG_DEBUG_VM is not set
1555# CONFIG_DEBUG_LIST is not set
1556# CONFIG_DEBUG_SG is not set
1245CONFIG_FRAME_POINTER=y 1557CONFIG_FRAME_POINTER=y
1558CONFIG_FORCED_INLINING=y
1559# CONFIG_BOOT_PRINTK_DELAY is not set
1246# CONFIG_RCU_TORTURE_TEST is not set 1560# CONFIG_RCU_TORTURE_TEST is not set
1561# CONFIG_FAULT_INJECTION is not set
1562# CONFIG_SAMPLES is not set
1247# CONFIG_DEBUG_USER is not set 1563# CONFIG_DEBUG_USER is not set
1248CONFIG_DEBUG_ERRORS=y 1564CONFIG_DEBUG_ERRORS=y
1249CONFIG_DEBUG_LL=y 1565CONFIG_DEBUG_LL=y
@@ -1254,22 +1570,22 @@ CONFIG_DEBUG_LL=y
1254# 1570#
1255# CONFIG_KEYS is not set 1571# CONFIG_KEYS is not set
1256# CONFIG_SECURITY is not set 1572# CONFIG_SECURITY is not set
1257 1573# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1258#
1259# Cryptographic options
1260#
1261# CONFIG_CRYPTO is not set 1574# CONFIG_CRYPTO is not set
1262 1575
1263# 1576#
1264# Hardware crypto devices
1265#
1266
1267#
1268# Library routines 1577# Library routines
1269# 1578#
1579CONFIG_BITREVERSE=y
1270# CONFIG_CRC_CCITT is not set 1580# CONFIG_CRC_CCITT is not set
1271# CONFIG_CRC16 is not set 1581# CONFIG_CRC16 is not set
1582# CONFIG_CRC_ITU_T is not set
1272CONFIG_CRC32=y 1583CONFIG_CRC32=y
1584# CONFIG_CRC7 is not set
1273# CONFIG_LIBCRC32C is not set 1585# CONFIG_LIBCRC32C is not set
1274CONFIG_ZLIB_INFLATE=y 1586CONFIG_ZLIB_INFLATE=y
1275CONFIG_ZLIB_DEFLATE=y 1587CONFIG_ZLIB_DEFLATE=y
1588CONFIG_PLIST=y
1589CONFIG_HAS_IOMEM=y
1590CONFIG_HAS_IOPORT=y
1591CONFIG_HAS_DMA=y
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index faa761921153..00d44c6fbfe9 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_PCI) += bios32.o isa.o
20obj-$(CONFIG_SMP) += smp.o 20obj-$(CONFIG_SMP) += smp.o
21obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 21obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
22obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o 22obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o
23obj-$(CONFIG_ATAGS_PROC) += atags.o
23obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o 24obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
24 25
25obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o 26obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c
new file mode 100644
index 000000000000..e2e934c38080
--- /dev/null
+++ b/arch/arm/kernel/atags.c
@@ -0,0 +1,86 @@
1#include <linux/slab.h>
2#include <linux/kexec.h>
3#include <linux/proc_fs.h>
4#include <asm/setup.h>
5#include <asm/types.h>
6#include <asm/page.h>
7
8struct buffer {
9 size_t size;
10 char *data;
11};
12static struct buffer tags_buffer;
13
14static int
15read_buffer(char* page, char** start, off_t off, int count,
16 int* eof, void* data)
17{
18 struct buffer *buffer = (struct buffer *)data;
19
20 if (off >= buffer->size) {
21 *eof = 1;
22 return 0;
23 }
24
25 count = min((int) (buffer->size - off), count);
26
27 memcpy(page, &buffer->data[off], count);
28
29 return count;
30}
31
32
33static int
34create_proc_entries(void)
35{
36 struct proc_dir_entry* tags_entry;
37
38 tags_entry = create_proc_read_entry("atags", 0400, &proc_root, read_buffer, &tags_buffer);
39 if (!tags_entry)
40 return -ENOMEM;
41
42 return 0;
43}
44
45
46static char __initdata atags_copy_buf[KEXEC_BOOT_PARAMS_SIZE];
47static char __initdata *atags_copy;
48
49void __init save_atags(const struct tag *tags)
50{
51 atags_copy = atags_copy_buf;
52 memcpy(atags_copy, tags, KEXEC_BOOT_PARAMS_SIZE);
53}
54
55
56static int __init init_atags_procfs(void)
57{
58 struct tag *tag;
59 int error;
60
61 if (!atags_copy) {
62 printk(KERN_WARNING "Exporting ATAGs: No saved tags found\n");
63 return -EIO;
64 }
65
66 for (tag = (struct tag *) atags_copy; tag->hdr.size; tag = tag_next(tag))
67 ;
68
69 tags_buffer.size = ((char *) tag - atags_copy) + sizeof(tag->hdr);
70 tags_buffer.data = kmalloc(tags_buffer.size, GFP_KERNEL);
71 if (tags_buffer.data == NULL)
72 return -ENOMEM;
73 memcpy(tags_buffer.data, atags_copy, tags_buffer.size);
74
75 error = create_proc_entries();
76 if (error) {
77 printk(KERN_ERR "Exporting ATAGs: not enough memory\n");
78 kfree(tags_buffer.data);
79 tags_buffer.size = 0;
80 tags_buffer.data = NULL;
81 }
82
83 return error;
84}
85
86arch_initcall(init_atags_procfs);
diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h
new file mode 100644
index 000000000000..e5f028d214a1
--- /dev/null
+++ b/arch/arm/kernel/atags.h
@@ -0,0 +1,5 @@
1#ifdef CONFIG_ATAGS_PROC
2extern void save_atags(struct tag *tags);
3#else
4static inline void save_atags(struct tag *tags) { }
5#endif
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index cecf658e3625..283e14fff993 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -359,7 +359,7 @@
359 CALL(sys_kexec_load) 359 CALL(sys_kexec_load)
360 CALL(sys_utimensat) 360 CALL(sys_utimensat)
361 CALL(sys_signalfd) 361 CALL(sys_signalfd)
362/* 350 */ CALL(sys_timerfd) 362/* 350 */ CALL(sys_ni_syscall)
363 CALL(sys_eventfd) 363 CALL(sys_eventfd)
364 CALL(sys_fallocate) 364 CALL(sys_fallocate)
365#ifndef syscalls_counted 365#ifndef syscalls_counted
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 863c66454f2b..db8f54a3451f 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -21,6 +21,7 @@ extern void setup_mm_for_reboot(char mode);
21extern unsigned long kexec_start_address; 21extern unsigned long kexec_start_address;
22extern unsigned long kexec_indirection_page; 22extern unsigned long kexec_indirection_page;
23extern unsigned long kexec_mach_type; 23extern unsigned long kexec_mach_type;
24extern unsigned long kexec_boot_atags;
24 25
25/* 26/*
26 * Provide a dummy crash_notes definition while crash dump arrives to arm. 27 * Provide a dummy crash_notes definition while crash dump arrives to arm.
@@ -62,6 +63,7 @@ void machine_kexec(struct kimage *image)
62 kexec_start_address = image->start; 63 kexec_start_address = image->start;
63 kexec_indirection_page = page_list; 64 kexec_indirection_page = page_list;
64 kexec_mach_type = machine_arch_type; 65 kexec_mach_type = machine_arch_type;
66 kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
65 67
66 /* copy our kernel relocation code to the control code page */ 68 /* copy our kernel relocation code to the control code page */
67 memcpy(reboot_code_buffer, 69 memcpy(reboot_code_buffer,
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
index 062c111c572f..61930eb09029 100644
--- a/arch/arm/kernel/relocate_kernel.S
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -7,23 +7,6 @@
7 .globl relocate_new_kernel 7 .globl relocate_new_kernel
8relocate_new_kernel: 8relocate_new_kernel:
9 9
10 /* Move boot params back to where the kernel expects them */
11
12 ldr r0,kexec_boot_params_address
13 teq r0,#0
14 beq 8f
15
16 ldr r1,kexec_boot_params_copy
17 mov r6,#KEXEC_BOOT_PARAMS_SIZE/4
187:
19 ldr r5,[r1],#4
20 str r5,[r0],#4
21 subs r6,r6,#1
22 bne 7b
23
248:
25 /* Boot params moved, now go on with the kernel */
26
27 ldr r0,kexec_indirection_page 10 ldr r0,kexec_indirection_page
28 ldr r1,kexec_start_address 11 ldr r1,kexec_start_address
29 12
@@ -67,7 +50,7 @@ relocate_new_kernel:
67 mov lr,r1 50 mov lr,r1
68 mov r0,#0 51 mov r0,#0
69 ldr r1,kexec_mach_type 52 ldr r1,kexec_mach_type
70 ldr r2,kexec_boot_params_address 53 ldr r2,kexec_boot_atags
71 mov pc,lr 54 mov pc,lr
72 55
73 .globl kexec_start_address 56 .globl kexec_start_address
@@ -82,14 +65,9 @@ kexec_indirection_page:
82kexec_mach_type: 65kexec_mach_type:
83 .long 0x0 66 .long 0x0
84 67
85 /* phy addr where new kernel will expect to find boot params */ 68 /* phy addr of the atags for the new kernel */
86 .globl kexec_boot_params_address 69 .globl kexec_boot_atags
87kexec_boot_params_address: 70kexec_boot_atags:
88 .long 0x0
89
90 /* phy addr where old kernel put a copy of orig boot params */
91 .globl kexec_boot_params_copy
92kexec_boot_params_copy:
93 .long 0x0 71 .long 0x0
94 72
95relocate_new_kernel_end: 73relocate_new_kernel_end:
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index bf56eb337df1..d3941a7b0455 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -24,7 +24,6 @@
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/smp.h> 25#include <linux/smp.h>
26#include <linux/fs.h> 26#include <linux/fs.h>
27#include <linux/kexec.h>
28 27
29#include <asm/cpu.h> 28#include <asm/cpu.h>
30#include <asm/elf.h> 29#include <asm/elf.h>
@@ -39,6 +38,7 @@
39#include <asm/mach/time.h> 38#include <asm/mach/time.h>
40 39
41#include "compat.h" 40#include "compat.h"
41#include "atags.h"
42 42
43#ifndef MEM_SIZE 43#ifndef MEM_SIZE
44#define MEM_SIZE (16*1024*1024) 44#define MEM_SIZE (16*1024*1024)
@@ -62,6 +62,7 @@ extern int root_mountflags;
62extern void _stext, _text, _etext, __data_start, _edata, _end; 62extern void _stext, _text, _etext, __data_start, _edata, _end;
63 63
64unsigned int processor_id; 64unsigned int processor_id;
65EXPORT_SYMBOL(processor_id);
65unsigned int __machine_arch_type; 66unsigned int __machine_arch_type;
66EXPORT_SYMBOL(__machine_arch_type); 67EXPORT_SYMBOL(__machine_arch_type);
67 68
@@ -784,23 +785,6 @@ static int __init customize_machine(void)
784} 785}
785arch_initcall(customize_machine); 786arch_initcall(customize_machine);
786 787
787#ifdef CONFIG_KEXEC
788
789/* Physical addr of where the boot params should be for this machine */
790extern unsigned long kexec_boot_params_address;
791
792/* Physical addr of the buffer into which the boot params are copied */
793extern unsigned long kexec_boot_params_copy;
794
795/* Pointer to the boot params buffer, for manipulation and display */
796unsigned long kexec_boot_params;
797EXPORT_SYMBOL(kexec_boot_params);
798
799/* The buffer itself - make sure it is sized correctly */
800static unsigned long kexec_boot_params_buf[(KEXEC_BOOT_PARAMS_SIZE + 3) / 4];
801
802#endif
803
804void __init setup_arch(char **cmdline_p) 788void __init setup_arch(char **cmdline_p)
805{ 789{
806 struct tag *tags = (struct tag *)&init_tags; 790 struct tag *tags = (struct tag *)&init_tags;
@@ -819,18 +803,6 @@ void __init setup_arch(char **cmdline_p)
819 else if (mdesc->boot_params) 803 else if (mdesc->boot_params)
820 tags = phys_to_virt(mdesc->boot_params); 804 tags = phys_to_virt(mdesc->boot_params);
821 805
822#ifdef CONFIG_KEXEC
823 kexec_boot_params_copy = virt_to_phys(kexec_boot_params_buf);
824 kexec_boot_params = (unsigned long)kexec_boot_params_buf;
825 if (__atags_pointer) {
826 kexec_boot_params_address = __atags_pointer;
827 memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
828 } else if (mdesc->boot_params) {
829 kexec_boot_params_address = mdesc->boot_params;
830 memcpy((void *)kexec_boot_params, tags, KEXEC_BOOT_PARAMS_SIZE);
831 }
832#endif
833
834 /* 806 /*
835 * If we have the old style parameters, convert them to 807 * If we have the old style parameters, convert them to
836 * a tag list. 808 * a tag list.
@@ -846,6 +818,7 @@ void __init setup_arch(char **cmdline_p)
846 if (tags->hdr.tag == ATAG_CORE) { 818 if (tags->hdr.tag == ATAG_CORE) {
847 if (meminfo.nr_banks != 0) 819 if (meminfo.nr_banks != 0)
848 squash_mem_tags(tags); 820 squash_mem_tags(tags);
821 save_atags(tags);
849 parse_tags(tags); 822 parse_tags(tags);
850 } 823 }
851 824
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index eafbb2b05eb8..eefae1de334c 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -150,7 +150,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
150 secondary_data.pgdir = 0; 150 secondary_data.pgdir = 0;
151 151
152 *pmd_offset(pgd, PHYS_OFFSET) = __pmd(0); 152 *pmd_offset(pgd, PHYS_OFFSET) = __pmd(0);
153 pgd_free(pgd); 153 pgd_free(&init_mm, pgd);
154 154
155 if (ret) { 155 if (ret) {
156 printk(KERN_CRIT "CPU%u: processor failed to boot\n", cpu); 156 printk(KERN_CRIT "CPU%u: processor failed to boot\n", cpu);
@@ -290,6 +290,11 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
290 local_irq_enable(); 290 local_irq_enable();
291 local_fiq_enable(); 291 local_fiq_enable();
292 292
293 /*
294 * Setup local timer for this CPU.
295 */
296 local_timer_setup(cpu);
297
293 calibrate_delay(); 298 calibrate_delay();
294 299
295 smp_store_cpu_info(cpu); 300 smp_store_cpu_info(cpu);
@@ -300,11 +305,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
300 cpu_set(cpu, cpu_online_map); 305 cpu_set(cpu, cpu_online_map);
301 306
302 /* 307 /*
303 * Setup local timer for this CPU.
304 */
305 local_timer_setup(cpu);
306
307 /*
308 * OK, it's off to the idle thread for us 308 * OK, it's off to the idle thread for us
309 */ 309 */
310 cpu_idle(); 310 cpu_idle();
@@ -454,6 +454,27 @@ int smp_call_function(void (*func)(void *info), void *info, int retry,
454} 454}
455EXPORT_SYMBOL_GPL(smp_call_function); 455EXPORT_SYMBOL_GPL(smp_call_function);
456 456
457int smp_call_function_single(int cpu, void (*func)(void *info), void *info,
458 int retry, int wait)
459{
460 /* prevent preemption and reschedule on another processor */
461 int current_cpu = get_cpu();
462 int ret = 0;
463
464 if (cpu == current_cpu) {
465 local_irq_disable();
466 func(info);
467 local_irq_enable();
468 } else
469 ret = smp_call_function_on_cpu(func, info, retry, wait,
470 cpumask_of_cpu(cpu));
471
472 put_cpu();
473
474 return ret;
475}
476EXPORT_SYMBOL_GPL(smp_call_function_single);
477
457void show_ipi_list(struct seq_file *p) 478void show_ipi_list(struct seq_file *p)
458{ 479{
459 unsigned int cpu; 480 unsigned int cpu;
@@ -481,8 +502,7 @@ void show_local_irqs(struct seq_file *p)
481static void ipi_timer(void) 502static void ipi_timer(void)
482{ 503{
483 irq_enter(); 504 irq_enter();
484 profile_tick(CPU_PROFILING); 505 local_timer_interrupt();
485 update_process_times(user_mode(get_irq_regs()));
486 irq_exit(); 506 irq_exit();
487} 507}
488 508
@@ -621,6 +641,11 @@ void smp_send_timer(void)
621 send_ipi_message(mask, IPI_TIMER); 641 send_ipi_message(mask, IPI_TIMER);
622} 642}
623 643
644void smp_timer_broadcast(cpumask_t mask)
645{
646 send_ipi_message(mask, IPI_TIMER);
647}
648
624void smp_send_stop(void) 649void smp_send_stop(void)
625{ 650{
626 cpumask_t mask = cpu_online_map; 651 cpumask_t mask = cpu_online_map;
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 5b0422cdde76..074dcd5d9a7e 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -253,6 +253,36 @@ config AT91_TIMER_HZ
253 system clock (of at least several MHz), rounding is less of a 253 system clock (of at least several MHz), rounding is less of a
254 problem so it can be safer to use a decimal values like 100. 254 problem so it can be safer to use a decimal values like 100.
255 255
256choice
257 prompt "Select a UART for early kernel messages"
258
259config AT91_EARLY_DBGU
260 bool "DBGU"
261
262config AT91_EARLY_USART0
263 bool "USART0"
264
265config AT91_EARLY_USART1
266 bool "USART1"
267
268config AT91_EARLY_USART2
269 bool "USART2"
270 depends on ! ARCH_AT91X40
271
272config AT91_EARLY_USART3
273 bool "USART3"
274 depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260)
275
276config AT91_EARLY_USART4
277 bool "USART4"
278 depends on ARCH_AT91SAM9260
279
280config AT91_EARLY_USART5
281 bool "USART5"
282 depends on ARCH_AT91SAM9260
283
284endchoice
285
256endmenu 286endmenu
257 287
258endif 288endif
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index 5c090c9442f5..e38d23770992 100644
--- a/arch/arm/mach-at91/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -49,8 +49,6 @@ static irqreturn_t at91sam926x_timer_interrupt(int irq, void *dev_id)
49 volatile long nr_ticks; 49 volatile long nr_ticks;
50 50
51 if (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS) { /* This is a shared interrupt */ 51 if (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS) { /* This is a shared interrupt */
52 write_seqlock(&xtime_lock);
53
54 /* Get number to ticks performed before interrupt and clear PIT interrupt */ 52 /* Get number to ticks performed before interrupt and clear PIT interrupt */
55 nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR)); 53 nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
56 do { 54 do {
@@ -58,7 +56,6 @@ static irqreturn_t at91sam926x_timer_interrupt(int irq, void *dev_id)
58 nr_ticks--; 56 nr_ticks--;
59 } while (nr_ticks); 57 } while (nr_ticks);
60 58
61 write_sequnlock(&xtime_lock);
62 return IRQ_HANDLED; 59 return IRQ_HANDLED;
63 } else 60 } else
64 return IRQ_NONE; /* not handled */ 61 return IRQ_NONE; /* not handled */
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index b5daf7f5e011..7b9ce7a336b0 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -47,6 +47,9 @@ extern void at91_irq_resume(void);
47#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ 47#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */
48 48
49struct at91_gpio_bank { 49struct at91_gpio_bank {
50 unsigned chipbase; /* bank's first GPIO number */
51 void __iomem *regbase; /* base of register bank */
52 struct at91_gpio_bank *next; /* bank sharing same IRQ/clock/... */
50 unsigned short id; /* peripheral ID */ 53 unsigned short id; /* peripheral ID */
51 unsigned long offset; /* offset from system peripheral base */ 54 unsigned long offset; /* offset from system peripheral base */
52 struct clk *clock; /* associated clock */ 55 struct clk *clock; /* associated clock */
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 6aeddd68d8af..f629c2b5f0c5 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -33,12 +33,10 @@ static int gpio_banks;
33 33
34static inline void __iomem *pin_to_controller(unsigned pin) 34static inline void __iomem *pin_to_controller(unsigned pin)
35{ 35{
36 void __iomem *sys_base = (void __iomem *) AT91_VA_BASE_SYS;
37
38 pin -= PIN_BASE; 36 pin -= PIN_BASE;
39 pin /= 32; 37 pin /= 32;
40 if (likely(pin < gpio_banks)) 38 if (likely(pin < gpio_banks))
41 return sys_base + gpio[pin].offset; 39 return gpio[pin].regbase;
42 40
43 return NULL; 41 return NULL;
44} 42}
@@ -294,11 +292,11 @@ void at91_gpio_suspend(void)
294 int i; 292 int i;
295 293
296 for (i = 0; i < gpio_banks; i++) { 294 for (i = 0; i < gpio_banks; i++) {
297 u32 pio = gpio[i].offset; 295 void __iomem *pio = gpio[i].regbase;
298 296
299 backups[i] = at91_sys_read(pio + PIO_IMR); 297 backups[i] = __raw_readl(pio + PIO_IMR);
300 at91_sys_write(pio + PIO_IDR, backups[i]); 298 __raw_writel(backups[i], pio + PIO_IDR);
301 at91_sys_write(pio + PIO_IER, wakeups[i]); 299 __raw_writel(wakeups[i], pio + PIO_IER);
302 300
303 if (!wakeups[i]) 301 if (!wakeups[i])
304 clk_disable(gpio[i].clock); 302 clk_disable(gpio[i].clock);
@@ -315,13 +313,13 @@ void at91_gpio_resume(void)
315 int i; 313 int i;
316 314
317 for (i = 0; i < gpio_banks; i++) { 315 for (i = 0; i < gpio_banks; i++) {
318 u32 pio = gpio[i].offset; 316 void __iomem *pio = gpio[i].regbase;
319 317
320 if (!wakeups[i]) 318 if (!wakeups[i])
321 clk_enable(gpio[i].clock); 319 clk_enable(gpio[i].clock);
322 320
323 at91_sys_write(pio + PIO_IDR, wakeups[i]); 321 __raw_writel(wakeups[i], pio + PIO_IDR);
324 at91_sys_write(pio + PIO_IER, backups[i]); 322 __raw_writel(backups[i], pio + PIO_IER);
325 } 323 }
326} 324}
327 325
@@ -361,7 +359,13 @@ static void gpio_irq_unmask(unsigned pin)
361 359
362static int gpio_irq_type(unsigned pin, unsigned type) 360static int gpio_irq_type(unsigned pin, unsigned type)
363{ 361{
364 return (type == IRQT_BOTHEDGE) ? 0 : -EINVAL; 362 switch (type) {
363 case IRQ_TYPE_NONE:
364 case IRQ_TYPE_EDGE_BOTH:
365 return 0;
366 default:
367 return -EINVAL;
368 }
365} 369}
366 370
367static struct irq_chip gpio_irqchip = { 371static struct irq_chip gpio_irqchip = {
@@ -376,20 +380,30 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
376{ 380{
377 unsigned pin; 381 unsigned pin;
378 struct irq_desc *gpio; 382 struct irq_desc *gpio;
383 struct at91_gpio_bank *bank;
379 void __iomem *pio; 384 void __iomem *pio;
380 u32 isr; 385 u32 isr;
381 386
382 pio = get_irq_chip_data(irq); 387 bank = get_irq_chip_data(irq);
388 pio = bank->regbase;
383 389
384 /* temporarily mask (level sensitive) parent IRQ */ 390 /* temporarily mask (level sensitive) parent IRQ */
385 desc->chip->ack(irq); 391 desc->chip->ack(irq);
386 for (;;) { 392 for (;;) {
387 /* reading ISR acks the pending (edge triggered) GPIO interrupt */ 393 /* Reading ISR acks pending (edge triggered) GPIO interrupts.
394 * When there none are pending, we're finished unless we need
395 * to process multiple banks (like ID_PIOCDE on sam9263).
396 */
388 isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR); 397 isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR);
389 if (!isr) 398 if (!isr) {
390 break; 399 if (!bank->next)
400 break;
401 bank = bank->next;
402 pio = bank->regbase;
403 continue;
404 }
391 405
392 pin = (unsigned) get_irq_data(irq); 406 pin = bank->chipbase;
393 gpio = &irq_desc[pin]; 407 gpio = &irq_desc[pin];
394 408
395 while (isr) { 409 while (isr) {
@@ -481,24 +495,21 @@ postcore_initcall(at91_gpio_debugfs_init);
481 */ 495 */
482void __init at91_gpio_irq_setup(void) 496void __init at91_gpio_irq_setup(void)
483{ 497{
484 unsigned pioc, pin; 498 unsigned pioc, pin;
499 struct at91_gpio_bank *this, *prev;
485 500
486 for (pioc = 0, pin = PIN_BASE; 501 for (pioc = 0, pin = PIN_BASE, this = gpio, prev = NULL;
487 pioc < gpio_banks; 502 pioc++ < gpio_banks;
488 pioc++) { 503 prev = this, this++) {
489 void __iomem *controller; 504 unsigned id = this->id;
490 unsigned id = gpio[pioc].id;
491 unsigned i; 505 unsigned i;
492 506
493 clk_enable(gpio[pioc].clock); /* enable PIO controller's clock */ 507 /* enable PIO controller's clock */
494 508 clk_enable(this->clock);
495 controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset;
496 __raw_writel(~0, controller + PIO_IDR);
497 509
498 set_irq_data(id, (void *) pin); 510 __raw_writel(~0, this->regbase + PIO_IDR);
499 set_irq_chip_data(id, controller);
500 511
501 for (i = 0; i < 32; i++, pin++) { 512 for (i = 0, pin = this->chipbase; i < 32; i++, pin++) {
502 /* 513 /*
503 * Can use the "simple" and not "edge" handler since it's 514 * Can use the "simple" and not "edge" handler since it's
504 * shorter, and the AIC handles interrupts sanely. 515 * shorter, and the AIC handles interrupts sanely.
@@ -508,6 +519,14 @@ void __init at91_gpio_irq_setup(void)
508 set_irq_flags(pin, IRQF_VALID); 519 set_irq_flags(pin, IRQF_VALID);
509 } 520 }
510 521
522 /* The toplevel handler handles one bank of GPIOs, except
523 * AT91SAM9263_ID_PIOCDE handles three... PIOC is first in
524 * the list, so we only set up that handler.
525 */
526 if (prev && prev->next == this)
527 continue;
528
529 set_irq_chip_data(id, this);
511 set_irq_chained_handler(id, gpio_irq_handler); 530 set_irq_chained_handler(id, gpio_irq_handler);
512 } 531 }
513 pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); 532 pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks);
@@ -518,8 +537,20 @@ void __init at91_gpio_irq_setup(void)
518 */ 537 */
519void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) 538void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
520{ 539{
540 unsigned i;
541 struct at91_gpio_bank *last;
542
521 BUG_ON(nr_banks > MAX_GPIO_BANKS); 543 BUG_ON(nr_banks > MAX_GPIO_BANKS);
522 544
523 gpio = data; 545 gpio = data;
524 gpio_banks = nr_banks; 546 gpio_banks = nr_banks;
547
548 for (i = 0, last = NULL; i < nr_banks; i++, last = data, data++) {
549 data->chipbase = PIN_BASE + i * 32;
550 data->regbase = data->offset + (void __iomem *)AT91_VA_BASE_SYS;
551
552 /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
553 if (last && last->id == data->id)
554 last->next = data;
555 }
525} 556}
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 61b2dfcb89d6..e774447c0592 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -189,6 +189,20 @@ config IXP4XX_INDIRECT_PCI
189 need to use the indirect method instead. If you don't know 189 need to use the indirect method instead. If you don't know
190 what you need, leave this option unselected. 190 what you need, leave this option unselected.
191 191
192config IXP4XX_QMGR
193 tristate "IXP4xx Queue Manager support"
194 help
195 This driver supports IXP4xx built-in hardware queue manager
196 and is automatically selected by Ethernet and HSS drivers.
197
198config IXP4XX_NPE
199 tristate "IXP4xx Network Processor Engine support"
200 select HOTPLUG
201 select FW_LOADER
202 help
203 This driver supports IXP4xx built-in network coprocessors
204 and is automatically selected by Ethernet and HSS drivers.
205
192endmenu 206endmenu
193 207
194endif 208endif
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index 77e00ade5585..c1956882c48b 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -23,10 +23,12 @@ obj-$(CONFIG_MACH_AVILA) += avila-setup.o
23obj-$(CONFIG_MACH_IXDPG425) += coyote-setup.o 23obj-$(CONFIG_MACH_IXDPG425) += coyote-setup.o
24obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o 24obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o
25obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o 25obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o
26obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o nslu2-power.o 26obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o
27obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o nas100d-power.o 27obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o
28obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o dsmg600-power.o 28obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o
29obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o 29obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o
30obj-$(CONFIG_MACH_WG302V2) += wg302v2-setup.o 30obj-$(CONFIG_MACH_WG302V2) += wg302v2-setup.o
31 31
32obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o 32obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o
33obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx_qmgr.o
34obj-$(CONFIG_IXP4XX_NPE) += ixp4xx_npe.o
diff --git a/arch/arm/mach-ixp4xx/dsmg600-power.c b/arch/arm/mach-ixp4xx/dsmg600-power.c
deleted file mode 100644
index 34717872d076..000000000000
--- a/arch/arm/mach-ixp4xx/dsmg600-power.c
+++ /dev/null
@@ -1,125 +0,0 @@
1/*
2 * arch/arm/mach-ixp4xx/dsmg600-power.c
3 *
4 * DSM-G600 Power/Reset driver
5 * Author: Michael Westerhof <mwester@dls.net>
6 *
7 * Based on nslu2-power.c
8 * Copyright (C) 2005 Tower Technologies
9 * Author: Alessandro Zummo <a.zummo@towertech.it>
10 *
11 * which was based on nslu2-io.c
12 * Copyright (C) 2004 Karen Spearel
13 *
14 * Maintainers: http://www.nslu2-linux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/reboot.h>
24#include <linux/interrupt.h>
25#include <linux/irq.h>
26#include <linux/jiffies.h>
27#include <linux/timer.h>
28
29#include <asm/mach-types.h>
30
31extern void ctrl_alt_del(void);
32
33/* This is used to make sure the power-button pusher is serious. The button
34 * must be held until the value of this counter reaches zero.
35 */
36static volatile int power_button_countdown;
37
38/* Must hold the button down for at least this many counts to be processed */
39#define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */
40
41static void dsmg600_power_handler(unsigned long data);
42static DEFINE_TIMER(dsmg600_power_timer, dsmg600_power_handler, 0, 0);
43
44static void dsmg600_power_handler(unsigned long data)
45{
46 /* This routine is called twice per second to check the
47 * state of the power button.
48 */
49
50 if (*IXP4XX_GPIO_GPINR & DSMG600_PB_BM) {
51
52 /* IO Pin is 1 (button pushed) */
53 if (power_button_countdown == 0) {
54 /* Signal init to do the ctrlaltdel action, this will bypass
55 * init if it hasn't started and do a kernel_restart.
56 */
57 ctrl_alt_del();
58
59 /* Change the state of the power LED to "blink" */
60 gpio_line_set(DSMG600_LED_PWR_GPIO, IXP4XX_GPIO_LOW);
61 }
62 power_button_countdown--;
63
64 } else {
65 power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
66 }
67
68 mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500));
69}
70
71static irqreturn_t dsmg600_reset_handler(int irq, void *dev_id)
72{
73 /* This is the paper-clip reset, it shuts the machine down directly. */
74 machine_power_off();
75
76 return IRQ_HANDLED;
77}
78
79static int __init dsmg600_power_init(void)
80{
81 if (!(machine_is_dsmg600()))
82 return 0;
83
84 if (request_irq(DSMG600_RB_IRQ, &dsmg600_reset_handler,
85 IRQF_DISABLED | IRQF_TRIGGER_LOW, "DSM-G600 reset button",
86 NULL) < 0) {
87
88 printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
89 DSMG600_RB_IRQ);
90
91 return -EIO;
92 }
93
94 /* The power button on the D-Link DSM-G600 is on GPIO 15, but
95 * it cannot handle interrupts on that GPIO line. So we'll
96 * have to poll it with a kernel timer.
97 */
98
99 /* Make sure that the power button GPIO is set up as an input */
100 gpio_line_config(DSMG600_PB_GPIO, IXP4XX_GPIO_IN);
101
102 /* Set the initial value for the power button IRQ handler */
103 power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
104
105 mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500));
106
107 return 0;
108}
109
110static void __exit dsmg600_power_exit(void)
111{
112 if (!(machine_is_dsmg600()))
113 return;
114
115 del_timer_sync(&dsmg600_power_timer);
116
117 free_irq(DSMG600_RB_IRQ, NULL);
118}
119
120module_init(dsmg600_power_init);
121module_exit(dsmg600_power_exit);
122
123MODULE_AUTHOR("Michael Westerhof <mwester@dls.net>");
124MODULE_DESCRIPTION("DSM-G600 Power/Reset driver");
125MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
index c473d408aa7c..688659668bdf 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-setup.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -1,25 +1,37 @@
1/* 1/*
2 * DSM-G600 board-setup 2 * DSM-G600 board-setup
3 * 3 *
4 * Copyright (C) 2008 Rod Whitby <rod@whitby.id.au>
4 * Copyright (C) 2006 Tower Technologies 5 * Copyright (C) 2006 Tower Technologies
5 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 * 6 *
7 * based ixdp425-setup.c: 7 * based on ixdp425-setup.c:
8 * Copyright (C) 2003-2004 MontaVista Software, Inc. 8 * Copyright (C) 2003-2004 MontaVista Software, Inc.
9 * based on nslu2-power.c:
10 * Copyright (C) 2005 Tower Technologies
11 * based on nslu2-io.c:
12 * Copyright (C) 2004 Karen Spearel
9 * 13 *
10 * Author: Alessandro Zummo <a.zummo@towertech.it> 14 * Author: Alessandro Zummo <a.zummo@towertech.it>
15 * Author: Michael Westerhof <mwester@dls.net>
16 * Author: Rod Whitby <rod@whitby.id.au>
11 * Maintainers: http://www.nslu2-linux.org/ 17 * Maintainers: http://www.nslu2-linux.org/
12 */ 18 */
13 19
14#include <linux/kernel.h> 20#include <linux/irq.h>
21#include <linux/jiffies.h>
22#include <linux/timer.h>
15#include <linux/serial.h> 23#include <linux/serial.h>
16#include <linux/serial_8250.h> 24#include <linux/serial_8250.h>
25#include <linux/leds.h>
26#include <linux/reboot.h>
27#include <linux/i2c.h>
17#include <linux/i2c-gpio.h> 28#include <linux/i2c-gpio.h>
18 29
19#include <asm/mach-types.h> 30#include <asm/mach-types.h>
20#include <asm/mach/arch.h> 31#include <asm/mach/arch.h>
21#include <asm/mach/flash.h> 32#include <asm/mach/flash.h>
22#include <asm/mach/time.h> 33#include <asm/mach/time.h>
34#include <asm/gpio.h>
23 35
24static struct flash_platform_data dsmg600_flash_data = { 36static struct flash_platform_data dsmg600_flash_data = {
25 .map_name = "cfi_probe", 37 .map_name = "cfi_probe",
@@ -51,29 +63,34 @@ static struct platform_device dsmg600_i2c_gpio = {
51 }, 63 },
52}; 64};
53 65
54#ifdef CONFIG_LEDS_CLASS 66static struct i2c_board_info __initdata dsmg600_i2c_board_info [] = {
55static struct resource dsmg600_led_resources[] = { 67 {
68 I2C_BOARD_INFO("rtc-pcf8563", 0x51),
69 },
70};
71
72static struct gpio_led dsmg600_led_pins[] = {
56 { 73 {
57 .name = "power", 74 .name = "power",
58 .start = DSMG600_LED_PWR_GPIO, 75 .gpio = DSMG600_LED_PWR_GPIO,
59 .end = DSMG600_LED_PWR_GPIO,
60 .flags = IXP4XX_GPIO_HIGH,
61 }, 76 },
62 { 77 {
63 .name = "wlan", 78 .name = "wlan",
64 .start = DSMG600_LED_WLAN_GPIO, 79 .gpio = DSMG600_LED_WLAN_GPIO,
65 .end = DSMG600_LED_WLAN_GPIO, 80 .active_low = true,
66 .flags = IXP4XX_GPIO_LOW,
67 }, 81 },
68}; 82};
69 83
84static struct gpio_led_platform_data dsmg600_led_data = {
85 .num_leds = ARRAY_SIZE(dsmg600_led_pins),
86 .leds = dsmg600_led_pins,
87};
88
70static struct platform_device dsmg600_leds = { 89static struct platform_device dsmg600_leds = {
71 .name = "IXP4XX-GPIO-LED", 90 .name = "leds-gpio",
72 .id = -1, 91 .id = -1,
73 .num_resources = ARRAY_SIZE(dsmg600_led_resources), 92 .dev.platform_data = &dsmg600_led_data,
74 .resource = dsmg600_led_resources,
75}; 93};
76#endif
77 94
78static struct resource dsmg600_uart_resources[] = { 95static struct resource dsmg600_uart_resources[] = {
79 { 96 {
@@ -121,6 +138,7 @@ static struct platform_device dsmg600_uart = {
121static struct platform_device *dsmg600_devices[] __initdata = { 138static struct platform_device *dsmg600_devices[] __initdata = {
122 &dsmg600_i2c_gpio, 139 &dsmg600_i2c_gpio,
123 &dsmg600_flash, 140 &dsmg600_flash,
141 &dsmg600_leds,
124}; 142};
125 143
126static void dsmg600_power_off(void) 144static void dsmg600_power_off(void)
@@ -132,6 +150,57 @@ static void dsmg600_power_off(void)
132 gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH); 150 gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH);
133} 151}
134 152
153/* This is used to make sure the power-button pusher is serious. The button
154 * must be held until the value of this counter reaches zero.
155 */
156static int power_button_countdown;
157
158/* Must hold the button down for at least this many counts to be processed */
159#define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */
160
161static void dsmg600_power_handler(unsigned long data);
162static DEFINE_TIMER(dsmg600_power_timer, dsmg600_power_handler, 0, 0);
163
164static void dsmg600_power_handler(unsigned long data)
165{
166 /* This routine is called twice per second to check the
167 * state of the power button.
168 */
169
170 if (gpio_get_value(DSMG600_PB_GPIO)) {
171
172 /* IO Pin is 1 (button pushed) */
173 if (power_button_countdown > 0)
174 power_button_countdown--;
175
176 } else {
177
178 /* Done on button release, to allow for auto-power-on mods. */
179 if (power_button_countdown == 0) {
180 /* Signal init to do the ctrlaltdel action,
181 * this will bypass init if it hasn't started
182 * and do a kernel_restart.
183 */
184 ctrl_alt_del();
185
186 /* Change the state of the power LED to "blink" */
187 gpio_line_set(DSMG600_LED_PWR_GPIO, IXP4XX_GPIO_LOW);
188 } else {
189 power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
190 }
191 }
192
193 mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500));
194}
195
196static irqreturn_t dsmg600_reset_handler(int irq, void *dev_id)
197{
198 /* This is the paper-clip reset, it shuts the machine down directly. */
199 machine_power_off();
200
201 return IRQ_HANDLED;
202}
203
135static void __init dsmg600_timer_init(void) 204static void __init dsmg600_timer_init(void)
136{ 205{
137 /* The xtal on this machine is non-standard. */ 206 /* The xtal on this machine is non-standard. */
@@ -156,7 +225,8 @@ static void __init dsmg600_init(void)
156 dsmg600_flash_resource.end = 225 dsmg600_flash_resource.end =
157 IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; 226 IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
158 227
159 pm_power_off = dsmg600_power_off; 228 i2c_register_board_info(0, dsmg600_i2c_board_info,
229 ARRAY_SIZE(dsmg600_i2c_board_info));
160 230
161 /* The UART is required on the DSM-G600 (Redboot cannot use the 231 /* The UART is required on the DSM-G600 (Redboot cannot use the
162 * NIC) -- do it here so that it does *not* get removed if 232 * NIC) -- do it here so that it does *not* get removed if
@@ -166,10 +236,28 @@ static void __init dsmg600_init(void)
166 236
167 platform_add_devices(dsmg600_devices, ARRAY_SIZE(dsmg600_devices)); 237 platform_add_devices(dsmg600_devices, ARRAY_SIZE(dsmg600_devices));
168 238
169#ifdef CONFIG_LEDS_CLASS 239 pm_power_off = dsmg600_power_off;
170 /* We don't care whether or not this works. */ 240
171 (void)platform_device_register(&dsmg600_leds); 241 if (request_irq(gpio_to_irq(DSMG600_RB_GPIO), &dsmg600_reset_handler,
172#endif 242 IRQF_DISABLED | IRQF_TRIGGER_LOW,
243 "DSM-G600 reset button", NULL) < 0) {
244
245 printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
246 gpio_to_irq(DSMG600_RB_GPIO));
247 }
248
249 /* The power button on the D-Link DSM-G600 is on GPIO 15, but
250 * it cannot handle interrupts on that GPIO line. So we'll
251 * have to poll it with a kernel timer.
252 */
253
254 /* Make sure that the power button GPIO is set up as an input */
255 gpio_line_config(DSMG600_PB_GPIO, IXP4XX_GPIO_IN);
256
257 /* Set the initial value for the power button IRQ handler */
258 power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
259
260 mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500));
173} 261}
174 262
175MACHINE_START(DSMG600, "D-Link DSM-G600 RevA") 263MACHINE_START(DSMG600, "D-Link DSM-G600 RevA")
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index e89070da28bf..44584afb34a3 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -177,6 +177,31 @@ static struct platform_device ixdp425_uart = {
177 .resource = ixdp425_uart_resources 177 .resource = ixdp425_uart_resources
178}; 178};
179 179
180/* Built-in 10/100 Ethernet MAC interfaces */
181static struct eth_plat_info ixdp425_plat_eth[] = {
182 {
183 .phy = 0,
184 .rxq = 3,
185 .txreadyq = 20,
186 }, {
187 .phy = 1,
188 .rxq = 4,
189 .txreadyq = 21,
190 }
191};
192
193static struct platform_device ixdp425_eth[] = {
194 {
195 .name = "ixp4xx_eth",
196 .id = IXP4XX_ETH_NPEB,
197 .dev.platform_data = ixdp425_plat_eth,
198 }, {
199 .name = "ixp4xx_eth",
200 .id = IXP4XX_ETH_NPEC,
201 .dev.platform_data = ixdp425_plat_eth + 1,
202 }
203};
204
180static struct platform_device *ixdp425_devices[] __initdata = { 205static struct platform_device *ixdp425_devices[] __initdata = {
181 &ixdp425_i2c_gpio, 206 &ixdp425_i2c_gpio,
182 &ixdp425_flash, 207 &ixdp425_flash,
@@ -184,7 +209,9 @@ static struct platform_device *ixdp425_devices[] __initdata = {
184 defined(CONFIG_MTD_NAND_PLATFORM_MODULE) 209 defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
185 &ixdp425_flash_nand, 210 &ixdp425_flash_nand,
186#endif 211#endif
187 &ixdp425_uart 212 &ixdp425_uart,
213 &ixdp425_eth[0],
214 &ixdp425_eth[1],
188}; 215};
189 216
190static void __init ixdp425_init(void) 217static void __init ixdp425_init(void)
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_npe.c b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
new file mode 100644
index 000000000000..83c137ec582c
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
@@ -0,0 +1,741 @@
1/*
2 * Intel IXP4xx Network Processor Engine driver for Linux
3 *
4 * Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License
8 * as published by the Free Software Foundation.
9 *
10 * The code is based on publicly available information:
11 * - Intel IXP4xx Developer's Manual and other e-papers
12 * - Intel IXP400 Access Library Software (BSD license)
13 * - previous works by Christian Hohnstaedt <chohnstaedt@innominate.com>
14 * Thanks, Christian.
15 */
16
17#include <linux/delay.h>
18#include <linux/dma-mapping.h>
19#include <linux/firmware.h>
20#include <linux/io.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <asm/arch/npe.h>
25
26#define DEBUG_MSG 0
27#define DEBUG_FW 0
28
29#define NPE_COUNT 3
30#define MAX_RETRIES 1000 /* microseconds */
31#define NPE_42X_DATA_SIZE 0x800 /* in dwords */
32#define NPE_46X_DATA_SIZE 0x1000
33#define NPE_A_42X_INSTR_SIZE 0x1000
34#define NPE_B_AND_C_42X_INSTR_SIZE 0x800
35#define NPE_46X_INSTR_SIZE 0x1000
36#define REGS_SIZE 0x1000
37
38#define NPE_PHYS_REG 32
39
40#define FW_MAGIC 0xFEEDF00D
41#define FW_BLOCK_TYPE_INSTR 0x0
42#define FW_BLOCK_TYPE_DATA 0x1
43#define FW_BLOCK_TYPE_EOF 0xF
44
45/* NPE exec status (read) and command (write) */
46#define CMD_NPE_STEP 0x01
47#define CMD_NPE_START 0x02
48#define CMD_NPE_STOP 0x03
49#define CMD_NPE_CLR_PIPE 0x04
50#define CMD_CLR_PROFILE_CNT 0x0C
51#define CMD_RD_INS_MEM 0x10 /* instruction memory */
52#define CMD_WR_INS_MEM 0x11
53#define CMD_RD_DATA_MEM 0x12 /* data memory */
54#define CMD_WR_DATA_MEM 0x13
55#define CMD_RD_ECS_REG 0x14 /* exec access register */
56#define CMD_WR_ECS_REG 0x15
57
58#define STAT_RUN 0x80000000
59#define STAT_STOP 0x40000000
60#define STAT_CLEAR 0x20000000
61#define STAT_ECS_K 0x00800000 /* pipeline clean */
62
63#define NPE_STEVT 0x1B
64#define NPE_STARTPC 0x1C
65#define NPE_REGMAP 0x1E
66#define NPE_CINDEX 0x1F
67
68#define INSTR_WR_REG_SHORT 0x0000C000
69#define INSTR_WR_REG_BYTE 0x00004000
70#define INSTR_RD_FIFO 0x0F888220
71#define INSTR_RESET_MBOX 0x0FAC8210
72
73#define ECS_BG_CTXT_REG_0 0x00 /* Background Executing Context */
74#define ECS_BG_CTXT_REG_1 0x01 /* Stack level */
75#define ECS_BG_CTXT_REG_2 0x02
76#define ECS_PRI_1_CTXT_REG_0 0x04 /* Priority 1 Executing Context */
77#define ECS_PRI_1_CTXT_REG_1 0x05 /* Stack level */
78#define ECS_PRI_1_CTXT_REG_2 0x06
79#define ECS_PRI_2_CTXT_REG_0 0x08 /* Priority 2 Executing Context */
80#define ECS_PRI_2_CTXT_REG_1 0x09 /* Stack level */
81#define ECS_PRI_2_CTXT_REG_2 0x0A
82#define ECS_DBG_CTXT_REG_0 0x0C /* Debug Executing Context */
83#define ECS_DBG_CTXT_REG_1 0x0D /* Stack level */
84#define ECS_DBG_CTXT_REG_2 0x0E
85#define ECS_INSTRUCT_REG 0x11 /* NPE Instruction Register */
86
87#define ECS_REG_0_ACTIVE 0x80000000 /* all levels */
88#define ECS_REG_0_NEXTPC_MASK 0x1FFF0000 /* BG/PRI1/PRI2 levels */
89#define ECS_REG_0_LDUR_BITS 8
90#define ECS_REG_0_LDUR_MASK 0x00000700 /* all levels */
91#define ECS_REG_1_CCTXT_BITS 16
92#define ECS_REG_1_CCTXT_MASK 0x000F0000 /* all levels */
93#define ECS_REG_1_SELCTXT_BITS 0
94#define ECS_REG_1_SELCTXT_MASK 0x0000000F /* all levels */
95#define ECS_DBG_REG_2_IF 0x00100000 /* debug level */
96#define ECS_DBG_REG_2_IE 0x00080000 /* debug level */
97
98/* NPE watchpoint_fifo register bit */
99#define WFIFO_VALID 0x80000000
100
101/* NPE messaging_status register bit definitions */
102#define MSGSTAT_OFNE 0x00010000 /* OutFifoNotEmpty */
103#define MSGSTAT_IFNF 0x00020000 /* InFifoNotFull */
104#define MSGSTAT_OFNF 0x00040000 /* OutFifoNotFull */
105#define MSGSTAT_IFNE 0x00080000 /* InFifoNotEmpty */
106#define MSGSTAT_MBINT 0x00100000 /* Mailbox interrupt */
107#define MSGSTAT_IFINT 0x00200000 /* InFifo interrupt */
108#define MSGSTAT_OFINT 0x00400000 /* OutFifo interrupt */
109#define MSGSTAT_WFINT 0x00800000 /* WatchFifo interrupt */
110
111/* NPE messaging_control register bit definitions */
112#define MSGCTL_OUT_FIFO 0x00010000 /* enable output FIFO */
113#define MSGCTL_IN_FIFO 0x00020000 /* enable input FIFO */
114#define MSGCTL_OUT_FIFO_WRITE 0x01000000 /* enable FIFO + WRITE */
115#define MSGCTL_IN_FIFO_WRITE 0x02000000
116
117/* NPE mailbox_status value for reset */
118#define RESET_MBOX_STAT 0x0000F0F0
119
120const char *npe_names[] = { "NPE-A", "NPE-B", "NPE-C" };
121
122#define print_npe(pri, npe, fmt, ...) \
123 printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__)
124
125#if DEBUG_MSG
126#define debug_msg(npe, fmt, ...) \
127 print_npe(KERN_DEBUG, npe, fmt, ## __VA_ARGS__)
128#else
129#define debug_msg(npe, fmt, ...)
130#endif
131
132static struct {
133 u32 reg, val;
134} ecs_reset[] = {
135 { ECS_BG_CTXT_REG_0, 0xA0000000 },
136 { ECS_BG_CTXT_REG_1, 0x01000000 },
137 { ECS_BG_CTXT_REG_2, 0x00008000 },
138 { ECS_PRI_1_CTXT_REG_0, 0x20000080 },
139 { ECS_PRI_1_CTXT_REG_1, 0x01000000 },
140 { ECS_PRI_1_CTXT_REG_2, 0x00008000 },
141 { ECS_PRI_2_CTXT_REG_0, 0x20000080 },
142 { ECS_PRI_2_CTXT_REG_1, 0x01000000 },
143 { ECS_PRI_2_CTXT_REG_2, 0x00008000 },
144 { ECS_DBG_CTXT_REG_0, 0x20000000 },
145 { ECS_DBG_CTXT_REG_1, 0x00000000 },
146 { ECS_DBG_CTXT_REG_2, 0x001E0000 },
147 { ECS_INSTRUCT_REG, 0x1003C00F },
148};
149
150static struct npe npe_tab[NPE_COUNT] = {
151 {
152 .id = 0,
153 .regs = (struct npe_regs __iomem *)IXP4XX_NPEA_BASE_VIRT,
154 .regs_phys = IXP4XX_NPEA_BASE_PHYS,
155 }, {
156 .id = 1,
157 .regs = (struct npe_regs __iomem *)IXP4XX_NPEB_BASE_VIRT,
158 .regs_phys = IXP4XX_NPEB_BASE_PHYS,
159 }, {
160 .id = 2,
161 .regs = (struct npe_regs __iomem *)IXP4XX_NPEC_BASE_VIRT,
162 .regs_phys = IXP4XX_NPEC_BASE_PHYS,
163 }
164};
165
166int npe_running(struct npe *npe)
167{
168 return (__raw_readl(&npe->regs->exec_status_cmd) & STAT_RUN) != 0;
169}
170
171static void npe_cmd_write(struct npe *npe, u32 addr, int cmd, u32 data)
172{
173 __raw_writel(data, &npe->regs->exec_data);
174 __raw_writel(addr, &npe->regs->exec_addr);
175 __raw_writel(cmd, &npe->regs->exec_status_cmd);
176}
177
178static u32 npe_cmd_read(struct npe *npe, u32 addr, int cmd)
179{
180 __raw_writel(addr, &npe->regs->exec_addr);
181 __raw_writel(cmd, &npe->regs->exec_status_cmd);
182 /* Iintroduce extra read cycles after issuing read command to NPE
183 so that we read the register after the NPE has updated it.
184 This is to overcome race condition between XScale and NPE */
185 __raw_readl(&npe->regs->exec_data);
186 __raw_readl(&npe->regs->exec_data);
187 return __raw_readl(&npe->regs->exec_data);
188}
189
190static void npe_clear_active(struct npe *npe, u32 reg)
191{
192 u32 val = npe_cmd_read(npe, reg, CMD_RD_ECS_REG);
193 npe_cmd_write(npe, reg, CMD_WR_ECS_REG, val & ~ECS_REG_0_ACTIVE);
194}
195
196static void npe_start(struct npe *npe)
197{
198 /* ensure only Background Context Stack Level is active */
199 npe_clear_active(npe, ECS_PRI_1_CTXT_REG_0);
200 npe_clear_active(npe, ECS_PRI_2_CTXT_REG_0);
201 npe_clear_active(npe, ECS_DBG_CTXT_REG_0);
202
203 __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
204 __raw_writel(CMD_NPE_START, &npe->regs->exec_status_cmd);
205}
206
207static void npe_stop(struct npe *npe)
208{
209 __raw_writel(CMD_NPE_STOP, &npe->regs->exec_status_cmd);
210 __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd); /*FIXME?*/
211}
212
213static int __must_check npe_debug_instr(struct npe *npe, u32 instr, u32 ctx,
214 u32 ldur)
215{
216 u32 wc;
217 int i;
218
219 /* set the Active bit, and the LDUR, in the debug level */
220 npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG,
221 ECS_REG_0_ACTIVE | (ldur << ECS_REG_0_LDUR_BITS));
222
223 /* set CCTXT at ECS DEBUG L3 to specify in which context to execute
224 the instruction, and set SELCTXT at ECS DEBUG Level to specify
225 which context store to access.
226 Debug ECS Level Reg 1 has form 0x000n000n, where n = context number
227 */
228 npe_cmd_write(npe, ECS_DBG_CTXT_REG_1, CMD_WR_ECS_REG,
229 (ctx << ECS_REG_1_CCTXT_BITS) |
230 (ctx << ECS_REG_1_SELCTXT_BITS));
231
232 /* clear the pipeline */
233 __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
234
235 /* load NPE instruction into the instruction register */
236 npe_cmd_write(npe, ECS_INSTRUCT_REG, CMD_WR_ECS_REG, instr);
237
238 /* we need this value later to wait for completion of NPE execution
239 step */
240 wc = __raw_readl(&npe->regs->watch_count);
241
242 /* issue a Step One command via the Execution Control register */
243 __raw_writel(CMD_NPE_STEP, &npe->regs->exec_status_cmd);
244
245 /* Watch Count register increments when NPE completes an instruction */
246 for (i = 0; i < MAX_RETRIES; i++) {
247 if (wc != __raw_readl(&npe->regs->watch_count))
248 return 0;
249 udelay(1);
250 }
251
252 print_npe(KERN_ERR, npe, "reset: npe_debug_instr(): timeout\n");
253 return -ETIMEDOUT;
254}
255
256static int __must_check npe_logical_reg_write8(struct npe *npe, u32 addr,
257 u8 val, u32 ctx)
258{
259 /* here we build the NPE assembler instruction: mov8 d0, #0 */
260 u32 instr = INSTR_WR_REG_BYTE | /* OpCode */
261 addr << 9 | /* base Operand */
262 (val & 0x1F) << 4 | /* lower 5 bits to immediate data */
263 (val & ~0x1F) << (18 - 5);/* higher 3 bits to CoProc instr. */
264 return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
265}
266
267static int __must_check npe_logical_reg_write16(struct npe *npe, u32 addr,
268 u16 val, u32 ctx)
269{
270 /* here we build the NPE assembler instruction: mov16 d0, #0 */
271 u32 instr = INSTR_WR_REG_SHORT | /* OpCode */
272 addr << 9 | /* base Operand */
273 (val & 0x1F) << 4 | /* lower 5 bits to immediate data */
274 (val & ~0x1F) << (18 - 5);/* higher 11 bits to CoProc instr. */
275 return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
276}
277
278static int __must_check npe_logical_reg_write32(struct npe *npe, u32 addr,
279 u32 val, u32 ctx)
280{
281 /* write in 16 bit steps first the high and then the low value */
282 if (npe_logical_reg_write16(npe, addr, val >> 16, ctx))
283 return -ETIMEDOUT;
284 return npe_logical_reg_write16(npe, addr + 2, val & 0xFFFF, ctx);
285}
286
287static int npe_reset(struct npe *npe)
288{
289 u32 val, ctl, exec_count, ctx_reg2;
290 int i;
291
292 ctl = (__raw_readl(&npe->regs->messaging_control) | 0x3F000000) &
293 0x3F3FFFFF;
294
295 /* disable parity interrupt */
296 __raw_writel(ctl & 0x3F00FFFF, &npe->regs->messaging_control);
297
298 /* pre exec - debug instruction */
299 /* turn off the halt bit by clearing Execution Count register. */
300 exec_count = __raw_readl(&npe->regs->exec_count);
301 __raw_writel(0, &npe->regs->exec_count);
302 /* ensure that IF and IE are on (temporarily), so that we don't end up
303 stepping forever */
304 ctx_reg2 = npe_cmd_read(npe, ECS_DBG_CTXT_REG_2, CMD_RD_ECS_REG);
305 npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2 |
306 ECS_DBG_REG_2_IF | ECS_DBG_REG_2_IE);
307
308 /* clear the FIFOs */
309 while (__raw_readl(&npe->regs->watchpoint_fifo) & WFIFO_VALID)
310 ;
311 while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE)
312 /* read from the outFIFO until empty */
313 print_npe(KERN_DEBUG, npe, "npe_reset: read FIFO = 0x%X\n",
314 __raw_readl(&npe->regs->in_out_fifo));
315
316 while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)
317 /* step execution of the NPE intruction to read inFIFO using
318 the Debug Executing Context stack */
319 if (npe_debug_instr(npe, INSTR_RD_FIFO, 0, 0))
320 return -ETIMEDOUT;
321
322 /* reset the mailbox reg from the XScale side */
323 __raw_writel(RESET_MBOX_STAT, &npe->regs->mailbox_status);
324 /* from NPE side */
325 if (npe_debug_instr(npe, INSTR_RESET_MBOX, 0, 0))
326 return -ETIMEDOUT;
327
328 /* Reset the physical registers in the NPE register file */
329 for (val = 0; val < NPE_PHYS_REG; val++) {
330 if (npe_logical_reg_write16(npe, NPE_REGMAP, val >> 1, 0))
331 return -ETIMEDOUT;
332 /* address is either 0 or 4 */
333 if (npe_logical_reg_write32(npe, (val & 1) * 4, 0, 0))
334 return -ETIMEDOUT;
335 }
336
337 /* Reset the context store = each context's Context Store registers */
338
339 /* Context 0 has no STARTPC. Instead, this value is used to set NextPC
340 for Background ECS, to set where NPE starts executing code */
341 val = npe_cmd_read(npe, ECS_BG_CTXT_REG_0, CMD_RD_ECS_REG);
342 val &= ~ECS_REG_0_NEXTPC_MASK;
343 val |= (0 /* NextPC */ << 16) & ECS_REG_0_NEXTPC_MASK;
344 npe_cmd_write(npe, ECS_BG_CTXT_REG_0, CMD_WR_ECS_REG, val);
345
346 for (i = 0; i < 16; i++) {
347 if (i) { /* Context 0 has no STEVT nor STARTPC */
348 /* STEVT = off, 0x80 */
349 if (npe_logical_reg_write8(npe, NPE_STEVT, 0x80, i))
350 return -ETIMEDOUT;
351 if (npe_logical_reg_write16(npe, NPE_STARTPC, 0, i))
352 return -ETIMEDOUT;
353 }
354 /* REGMAP = d0->p0, d8->p2, d16->p4 */
355 if (npe_logical_reg_write16(npe, NPE_REGMAP, 0x820, i))
356 return -ETIMEDOUT;
357 if (npe_logical_reg_write8(npe, NPE_CINDEX, 0, i))
358 return -ETIMEDOUT;
359 }
360
361 /* post exec */
362 /* clear active bit in debug level */
363 npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG, 0);
364 /* clear the pipeline */
365 __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
366 /* restore previous values */
367 __raw_writel(exec_count, &npe->regs->exec_count);
368 npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2);
369
370 /* write reset values to Execution Context Stack registers */
371 for (val = 0; val < ARRAY_SIZE(ecs_reset); val++)
372 npe_cmd_write(npe, ecs_reset[val].reg, CMD_WR_ECS_REG,
373 ecs_reset[val].val);
374
375 /* clear the profile counter */
376 __raw_writel(CMD_CLR_PROFILE_CNT, &npe->regs->exec_status_cmd);
377
378 __raw_writel(0, &npe->regs->exec_count);
379 __raw_writel(0, &npe->regs->action_points[0]);
380 __raw_writel(0, &npe->regs->action_points[1]);
381 __raw_writel(0, &npe->regs->action_points[2]);
382 __raw_writel(0, &npe->regs->action_points[3]);
383 __raw_writel(0, &npe->regs->watch_count);
384
385 val = ixp4xx_read_feature_bits();
386 /* reset the NPE */
387 ixp4xx_write_feature_bits(val &
388 ~(IXP4XX_FEATURE_RESET_NPEA << npe->id));
389 for (i = 0; i < MAX_RETRIES; i++) {
390 if (!(ixp4xx_read_feature_bits() &
391 (IXP4XX_FEATURE_RESET_NPEA << npe->id)))
392 break; /* reset completed */
393 udelay(1);
394 }
395 if (i == MAX_RETRIES)
396 return -ETIMEDOUT;
397
398 /* deassert reset */
399 ixp4xx_write_feature_bits(val |
400 (IXP4XX_FEATURE_RESET_NPEA << npe->id));
401 for (i = 0; i < MAX_RETRIES; i++) {
402 if (ixp4xx_read_feature_bits() &
403 (IXP4XX_FEATURE_RESET_NPEA << npe->id))
404 break; /* NPE is back alive */
405 udelay(1);
406 }
407 if (i == MAX_RETRIES)
408 return -ETIMEDOUT;
409
410 npe_stop(npe);
411
412 /* restore NPE configuration bus Control Register - parity settings */
413 __raw_writel(ctl, &npe->regs->messaging_control);
414 return 0;
415}
416
417
418int npe_send_message(struct npe *npe, const void *msg, const char *what)
419{
420 const u32 *send = msg;
421 int cycles = 0;
422
423 debug_msg(npe, "Trying to send message %s [%08X:%08X]\n",
424 what, send[0], send[1]);
425
426 if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE) {
427 debug_msg(npe, "NPE input FIFO not empty\n");
428 return -EIO;
429 }
430
431 __raw_writel(send[0], &npe->regs->in_out_fifo);
432
433 if (!(__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNF)) {
434 debug_msg(npe, "NPE input FIFO full\n");
435 return -EIO;
436 }
437
438 __raw_writel(send[1], &npe->regs->in_out_fifo);
439
440 while ((cycles < MAX_RETRIES) &&
441 (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)) {
442 udelay(1);
443 cycles++;
444 }
445
446 if (cycles == MAX_RETRIES) {
447 debug_msg(npe, "Timeout sending message\n");
448 return -ETIMEDOUT;
449 }
450
451 debug_msg(npe, "Sending a message took %i cycles\n", cycles);
452 return 0;
453}
454
455int npe_recv_message(struct npe *npe, void *msg, const char *what)
456{
457 u32 *recv = msg;
458 int cycles = 0, cnt = 0;
459
460 debug_msg(npe, "Trying to receive message %s\n", what);
461
462 while (cycles < MAX_RETRIES) {
463 if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE) {
464 recv[cnt++] = __raw_readl(&npe->regs->in_out_fifo);
465 if (cnt == 2)
466 break;
467 } else {
468 udelay(1);
469 cycles++;
470 }
471 }
472
473 switch(cnt) {
474 case 1:
475 debug_msg(npe, "Received [%08X]\n", recv[0]);
476 break;
477 case 2:
478 debug_msg(npe, "Received [%08X:%08X]\n", recv[0], recv[1]);
479 break;
480 }
481
482 if (cycles == MAX_RETRIES) {
483 debug_msg(npe, "Timeout waiting for message\n");
484 return -ETIMEDOUT;
485 }
486
487 debug_msg(npe, "Receiving a message took %i cycles\n", cycles);
488 return 0;
489}
490
491int npe_send_recv_message(struct npe *npe, void *msg, const char *what)
492{
493 int result;
494 u32 *send = msg, recv[2];
495
496 if ((result = npe_send_message(npe, msg, what)) != 0)
497 return result;
498 if ((result = npe_recv_message(npe, recv, what)) != 0)
499 return result;
500
501 if ((recv[0] != send[0]) || (recv[1] != send[1])) {
502 debug_msg(npe, "Message %s: unexpected message received\n",
503 what);
504 return -EIO;
505 }
506 return 0;
507}
508
509
510int npe_load_firmware(struct npe *npe, const char *name, struct device *dev)
511{
512 const struct firmware *fw_entry;
513
514 struct dl_block {
515 u32 type;
516 u32 offset;
517 } *blk;
518
519 struct dl_image {
520 u32 magic;
521 u32 id;
522 u32 size;
523 union {
524 u32 data[0];
525 struct dl_block blocks[0];
526 };
527 } *image;
528
529 struct dl_codeblock {
530 u32 npe_addr;
531 u32 size;
532 u32 data[0];
533 } *cb;
534
535 int i, j, err, data_size, instr_size, blocks, table_end;
536 u32 cmd;
537
538 if ((err = request_firmware(&fw_entry, name, dev)) != 0)
539 return err;
540
541 err = -EINVAL;
542 if (fw_entry->size < sizeof(struct dl_image)) {
543 print_npe(KERN_ERR, npe, "incomplete firmware file\n");
544 goto err;
545 }
546 image = (struct dl_image*)fw_entry->data;
547
548#if DEBUG_FW
549 print_npe(KERN_DEBUG, npe, "firmware: %08X %08X %08X (0x%X bytes)\n",
550 image->magic, image->id, image->size, image->size * 4);
551#endif
552
553 if (image->magic == swab32(FW_MAGIC)) { /* swapped file */
554 image->id = swab32(image->id);
555 image->size = swab32(image->size);
556 } else if (image->magic != FW_MAGIC) {
557 print_npe(KERN_ERR, npe, "bad firmware file magic: 0x%X\n",
558 image->magic);
559 goto err;
560 }
561 if ((image->size * 4 + sizeof(struct dl_image)) != fw_entry->size) {
562 print_npe(KERN_ERR, npe,
563 "inconsistent size of firmware file\n");
564 goto err;
565 }
566 if (((image->id >> 24) & 0xF /* NPE ID */) != npe->id) {
567 print_npe(KERN_ERR, npe, "firmware file NPE ID mismatch\n");
568 goto err;
569 }
570 if (image->magic == swab32(FW_MAGIC))
571 for (i = 0; i < image->size; i++)
572 image->data[i] = swab32(image->data[i]);
573
574 if (!cpu_is_ixp46x() && ((image->id >> 28) & 0xF /* device ID */)) {
575 print_npe(KERN_INFO, npe, "IXP46x firmware ignored on "
576 "IXP42x\n");
577 goto err;
578 }
579
580 if (npe_running(npe)) {
581 print_npe(KERN_INFO, npe, "unable to load firmware, NPE is "
582 "already running\n");
583 err = -EBUSY;
584 goto err;
585 }
586#if 0
587 npe_stop(npe);
588 npe_reset(npe);
589#endif
590
591 print_npe(KERN_INFO, npe, "firmware functionality 0x%X, "
592 "revision 0x%X:%X\n", (image->id >> 16) & 0xFF,
593 (image->id >> 8) & 0xFF, image->id & 0xFF);
594
595 if (!cpu_is_ixp46x()) {
596 if (!npe->id)
597 instr_size = NPE_A_42X_INSTR_SIZE;
598 else
599 instr_size = NPE_B_AND_C_42X_INSTR_SIZE;
600 data_size = NPE_42X_DATA_SIZE;
601 } else {
602 instr_size = NPE_46X_INSTR_SIZE;
603 data_size = NPE_46X_DATA_SIZE;
604 }
605
606 for (blocks = 0; blocks * sizeof(struct dl_block) / 4 < image->size;
607 blocks++)
608 if (image->blocks[blocks].type == FW_BLOCK_TYPE_EOF)
609 break;
610 if (blocks * sizeof(struct dl_block) / 4 >= image->size) {
611 print_npe(KERN_INFO, npe, "firmware EOF block marker not "
612 "found\n");
613 goto err;
614 }
615
616#if DEBUG_FW
617 print_npe(KERN_DEBUG, npe, "%i firmware blocks found\n", blocks);
618#endif
619
620 table_end = blocks * sizeof(struct dl_block) / 4 + 1 /* EOF marker */;
621 for (i = 0, blk = image->blocks; i < blocks; i++, blk++) {
622 if (blk->offset > image->size - sizeof(struct dl_codeblock) / 4
623 || blk->offset < table_end) {
624 print_npe(KERN_INFO, npe, "invalid offset 0x%X of "
625 "firmware block #%i\n", blk->offset, i);
626 goto err;
627 }
628
629 cb = (struct dl_codeblock*)&image->data[blk->offset];
630 if (blk->type == FW_BLOCK_TYPE_INSTR) {
631 if (cb->npe_addr + cb->size > instr_size)
632 goto too_big;
633 cmd = CMD_WR_INS_MEM;
634 } else if (blk->type == FW_BLOCK_TYPE_DATA) {
635 if (cb->npe_addr + cb->size > data_size)
636 goto too_big;
637 cmd = CMD_WR_DATA_MEM;
638 } else {
639 print_npe(KERN_INFO, npe, "invalid firmware block #%i "
640 "type 0x%X\n", i, blk->type);
641 goto err;
642 }
643 if (blk->offset + sizeof(*cb) / 4 + cb->size > image->size) {
644 print_npe(KERN_INFO, npe, "firmware block #%i doesn't "
645 "fit in firmware image: type %c, start 0x%X,"
646 " length 0x%X\n", i,
647 blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
648 cb->npe_addr, cb->size);
649 goto err;
650 }
651
652 for (j = 0; j < cb->size; j++)
653 npe_cmd_write(npe, cb->npe_addr + j, cmd, cb->data[j]);
654 }
655
656 npe_start(npe);
657 if (!npe_running(npe))
658 print_npe(KERN_ERR, npe, "unable to start\n");
659 release_firmware(fw_entry);
660 return 0;
661
662too_big:
663 print_npe(KERN_INFO, npe, "firmware block #%i doesn't fit in NPE "
664 "memory: type %c, start 0x%X, length 0x%X\n", i,
665 blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
666 cb->npe_addr, cb->size);
667err:
668 release_firmware(fw_entry);
669 return err;
670}
671
672
673struct npe *npe_request(int id)
674{
675 if (id < NPE_COUNT)
676 if (npe_tab[id].valid)
677 if (try_module_get(THIS_MODULE))
678 return &npe_tab[id];
679 return NULL;
680}
681
682void npe_release(struct npe *npe)
683{
684 module_put(THIS_MODULE);
685}
686
687
688static int __init npe_init_module(void)
689{
690
691 int i, found = 0;
692
693 for (i = 0; i < NPE_COUNT; i++) {
694 struct npe *npe = &npe_tab[i];
695 if (!(ixp4xx_read_feature_bits() &
696 (IXP4XX_FEATURE_RESET_NPEA << i)))
697 continue; /* NPE already disabled or not present */
698 if (!(npe->mem_res = request_mem_region(npe->regs_phys,
699 REGS_SIZE,
700 npe_name(npe)))) {
701 print_npe(KERN_ERR, npe,
702 "failed to request memory region\n");
703 continue;
704 }
705
706 if (npe_reset(npe))
707 continue;
708 npe->valid = 1;
709 found++;
710 }
711
712 if (!found)
713 return -ENOSYS;
714 return 0;
715}
716
717static void __exit npe_cleanup_module(void)
718{
719 int i;
720
721 for (i = 0; i < NPE_COUNT; i++)
722 if (npe_tab[i].mem_res) {
723 npe_reset(&npe_tab[i]);
724 release_resource(npe_tab[i].mem_res);
725 }
726}
727
728module_init(npe_init_module);
729module_exit(npe_cleanup_module);
730
731MODULE_AUTHOR("Krzysztof Halasa");
732MODULE_LICENSE("GPL v2");
733
734EXPORT_SYMBOL(npe_names);
735EXPORT_SYMBOL(npe_running);
736EXPORT_SYMBOL(npe_request);
737EXPORT_SYMBOL(npe_release);
738EXPORT_SYMBOL(npe_load_firmware);
739EXPORT_SYMBOL(npe_send_message);
740EXPORT_SYMBOL(npe_recv_message);
741EXPORT_SYMBOL(npe_send_recv_message);
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
new file mode 100644
index 000000000000..e83301325301
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
@@ -0,0 +1,274 @@
1/*
2 * Intel IXP4xx Queue Manager driver for Linux
3 *
4 * Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License
8 * as published by the Free Software Foundation.
9 */
10
11#include <linux/ioport.h>
12#include <linux/interrupt.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <asm/arch/qmgr.h>
16
17#define DEBUG 0
18
19struct qmgr_regs __iomem *qmgr_regs;
20static struct resource *mem_res;
21static spinlock_t qmgr_lock;
22static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
23static void (*irq_handlers[HALF_QUEUES])(void *pdev);
24static void *irq_pdevs[HALF_QUEUES];
25
26void qmgr_set_irq(unsigned int queue, int src,
27 void (*handler)(void *pdev), void *pdev)
28{
29 u32 __iomem *reg = &qmgr_regs->irqsrc[queue / 8]; /* 8 queues / u32 */
30 int bit = (queue % 8) * 4; /* 3 bits + 1 reserved bit per queue */
31 unsigned long flags;
32
33 src &= 7;
34 spin_lock_irqsave(&qmgr_lock, flags);
35 __raw_writel((__raw_readl(reg) & ~(7 << bit)) | (src << bit), reg);
36 irq_handlers[queue] = handler;
37 irq_pdevs[queue] = pdev;
38 spin_unlock_irqrestore(&qmgr_lock, flags);
39}
40
41
42static irqreturn_t qmgr_irq1(int irq, void *pdev)
43{
44 int i;
45 u32 val = __raw_readl(&qmgr_regs->irqstat[0]);
46 __raw_writel(val, &qmgr_regs->irqstat[0]); /* ACK */
47
48 for (i = 0; i < HALF_QUEUES; i++)
49 if (val & (1 << i))
50 irq_handlers[i](irq_pdevs[i]);
51
52 return val ? IRQ_HANDLED : 0;
53}
54
55
56void qmgr_enable_irq(unsigned int queue)
57{
58 unsigned long flags;
59
60 spin_lock_irqsave(&qmgr_lock, flags);
61 __raw_writel(__raw_readl(&qmgr_regs->irqen[0]) | (1 << queue),
62 &qmgr_regs->irqen[0]);
63 spin_unlock_irqrestore(&qmgr_lock, flags);
64}
65
66void qmgr_disable_irq(unsigned int queue)
67{
68 unsigned long flags;
69
70 spin_lock_irqsave(&qmgr_lock, flags);
71 __raw_writel(__raw_readl(&qmgr_regs->irqen[0]) & ~(1 << queue),
72 &qmgr_regs->irqen[0]);
73 spin_unlock_irqrestore(&qmgr_lock, flags);
74}
75
76static inline void shift_mask(u32 *mask)
77{
78 mask[3] = mask[3] << 1 | mask[2] >> 31;
79 mask[2] = mask[2] << 1 | mask[1] >> 31;
80 mask[1] = mask[1] << 1 | mask[0] >> 31;
81 mask[0] <<= 1;
82}
83
84int qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
85 unsigned int nearly_empty_watermark,
86 unsigned int nearly_full_watermark)
87{
88 u32 cfg, addr = 0, mask[4]; /* in 16-dwords */
89 int err;
90
91 if (queue >= HALF_QUEUES)
92 return -ERANGE;
93
94 if ((nearly_empty_watermark | nearly_full_watermark) & ~7)
95 return -EINVAL;
96
97 switch (len) {
98 case 16:
99 cfg = 0 << 24;
100 mask[0] = 0x1;
101 break;
102 case 32:
103 cfg = 1 << 24;
104 mask[0] = 0x3;
105 break;
106 case 64:
107 cfg = 2 << 24;
108 mask[0] = 0xF;
109 break;
110 case 128:
111 cfg = 3 << 24;
112 mask[0] = 0xFF;
113 break;
114 default:
115 return -EINVAL;
116 }
117
118 cfg |= nearly_empty_watermark << 26;
119 cfg |= nearly_full_watermark << 29;
120 len /= 16; /* in 16-dwords: 1, 2, 4 or 8 */
121 mask[1] = mask[2] = mask[3] = 0;
122
123 if (!try_module_get(THIS_MODULE))
124 return -ENODEV;
125
126 spin_lock_irq(&qmgr_lock);
127 if (__raw_readl(&qmgr_regs->sram[queue])) {
128 err = -EBUSY;
129 goto err;
130 }
131
132 while (1) {
133 if (!(used_sram_bitmap[0] & mask[0]) &&
134 !(used_sram_bitmap[1] & mask[1]) &&
135 !(used_sram_bitmap[2] & mask[2]) &&
136 !(used_sram_bitmap[3] & mask[3]))
137 break; /* found free space */
138
139 addr++;
140 shift_mask(mask);
141 if (addr + len > ARRAY_SIZE(qmgr_regs->sram)) {
142 printk(KERN_ERR "qmgr: no free SRAM space for"
143 " queue %i\n", queue);
144 err = -ENOMEM;
145 goto err;
146 }
147 }
148
149 used_sram_bitmap[0] |= mask[0];
150 used_sram_bitmap[1] |= mask[1];
151 used_sram_bitmap[2] |= mask[2];
152 used_sram_bitmap[3] |= mask[3];
153 __raw_writel(cfg | (addr << 14), &qmgr_regs->sram[queue]);
154 spin_unlock_irq(&qmgr_lock);
155
156#if DEBUG
157 printk(KERN_DEBUG "qmgr: requested queue %i, addr = 0x%02X\n",
158 queue, addr);
159#endif
160 return 0;
161
162err:
163 spin_unlock_irq(&qmgr_lock);
164 module_put(THIS_MODULE);
165 return err;
166}
167
168void qmgr_release_queue(unsigned int queue)
169{
170 u32 cfg, addr, mask[4];
171
172 BUG_ON(queue >= HALF_QUEUES); /* not in valid range */
173
174 spin_lock_irq(&qmgr_lock);
175 cfg = __raw_readl(&qmgr_regs->sram[queue]);
176 addr = (cfg >> 14) & 0xFF;
177
178 BUG_ON(!addr); /* not requested */
179
180 switch ((cfg >> 24) & 3) {
181 case 0: mask[0] = 0x1; break;
182 case 1: mask[0] = 0x3; break;
183 case 2: mask[0] = 0xF; break;
184 case 3: mask[0] = 0xFF; break;
185 }
186
187 while (addr--)
188 shift_mask(mask);
189
190 __raw_writel(0, &qmgr_regs->sram[queue]);
191
192 used_sram_bitmap[0] &= ~mask[0];
193 used_sram_bitmap[1] &= ~mask[1];
194 used_sram_bitmap[2] &= ~mask[2];
195 used_sram_bitmap[3] &= ~mask[3];
196 irq_handlers[queue] = NULL; /* catch IRQ bugs */
197 spin_unlock_irq(&qmgr_lock);
198
199 module_put(THIS_MODULE);
200#if DEBUG
201 printk(KERN_DEBUG "qmgr: released queue %i\n", queue);
202#endif
203}
204
205static int qmgr_init(void)
206{
207 int i, err;
208 mem_res = request_mem_region(IXP4XX_QMGR_BASE_PHYS,
209 IXP4XX_QMGR_REGION_SIZE,
210 "IXP4xx Queue Manager");
211 if (mem_res == NULL)
212 return -EBUSY;
213
214 qmgr_regs = ioremap(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
215 if (qmgr_regs == NULL) {
216 err = -ENOMEM;
217 goto error_map;
218 }
219
220 /* reset qmgr registers */
221 for (i = 0; i < 4; i++) {
222 __raw_writel(0x33333333, &qmgr_regs->stat1[i]);
223 __raw_writel(0, &qmgr_regs->irqsrc[i]);
224 }
225 for (i = 0; i < 2; i++) {
226 __raw_writel(0, &qmgr_regs->stat2[i]);
227 __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[i]); /* clear */
228 __raw_writel(0, &qmgr_regs->irqen[i]);
229 }
230
231 for (i = 0; i < QUEUES; i++)
232 __raw_writel(0, &qmgr_regs->sram[i]);
233
234 err = request_irq(IRQ_IXP4XX_QM1, qmgr_irq1, 0,
235 "IXP4xx Queue Manager", NULL);
236 if (err) {
237 printk(KERN_ERR "qmgr: failed to request IRQ%i\n",
238 IRQ_IXP4XX_QM1);
239 goto error_irq;
240 }
241
242 used_sram_bitmap[0] = 0xF; /* 4 first pages reserved for config */
243 spin_lock_init(&qmgr_lock);
244
245 printk(KERN_INFO "IXP4xx Queue Manager initialized.\n");
246 return 0;
247
248error_irq:
249 iounmap(qmgr_regs);
250error_map:
251 release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
252 return err;
253}
254
255static void qmgr_remove(void)
256{
257 free_irq(IRQ_IXP4XX_QM1, NULL);
258 synchronize_irq(IRQ_IXP4XX_QM1);
259 iounmap(qmgr_regs);
260 release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
261}
262
263module_init(qmgr_init);
264module_exit(qmgr_remove);
265
266MODULE_LICENSE("GPL v2");
267MODULE_AUTHOR("Krzysztof Halasa");
268
269EXPORT_SYMBOL(qmgr_regs);
270EXPORT_SYMBOL(qmgr_set_irq);
271EXPORT_SYMBOL(qmgr_enable_irq);
272EXPORT_SYMBOL(qmgr_disable_irq);
273EXPORT_SYMBOL(qmgr_request_queue);
274EXPORT_SYMBOL(qmgr_release_queue);
diff --git a/arch/arm/mach-ixp4xx/nas100d-power.c b/arch/arm/mach-ixp4xx/nas100d-power.c
deleted file mode 100644
index 29aa98d3a7fa..000000000000
--- a/arch/arm/mach-ixp4xx/nas100d-power.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * arch/arm/mach-ixp4xx/nas100d-power.c
3 *
4 * NAS 100d Power/Reset driver
5 *
6 * Copyright (C) 2005 Tower Technologies
7 *
8 * based on nas100d-io.c
9 * Copyright (C) 2004 Karen Spearel
10 *
11 * Author: Alessandro Zummo <a.zummo@towertech.it>
12 * Maintainers: http://www.nslu2-linux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 */
19
20#include <linux/interrupt.h>
21#include <linux/irq.h>
22#include <linux/module.h>
23#include <linux/reboot.h>
24
25#include <asm/mach-types.h>
26
27static irqreturn_t nas100d_reset_handler(int irq, void *dev_id)
28{
29 /* Signal init to do the ctrlaltdel action, this will bypass init if
30 * it hasn't started and do a kernel_restart.
31 */
32 ctrl_alt_del();
33
34 return IRQ_HANDLED;
35}
36
37static int __init nas100d_power_init(void)
38{
39 if (!(machine_is_nas100d()))
40 return 0;
41
42 set_irq_type(NAS100D_RB_IRQ, IRQT_LOW);
43
44 if (request_irq(NAS100D_RB_IRQ, &nas100d_reset_handler,
45 IRQF_DISABLED, "NAS100D reset button", NULL) < 0) {
46
47 printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
48 NAS100D_RB_IRQ);
49
50 return -EIO;
51 }
52
53 return 0;
54}
55
56static void __exit nas100d_power_exit(void)
57{
58 if (!(machine_is_nas100d()))
59 return;
60
61 free_irq(NAS100D_RB_IRQ, NULL);
62}
63
64module_init(nas100d_power_init);
65module_exit(nas100d_power_exit);
66
67MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
68MODULE_DESCRIPTION("NAS100D Power/Reset driver");
69MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
index 54d884fb2517..4cecae84837b 100644
--- a/arch/arm/mach-ixp4xx/nas100d-setup.c
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -3,8 +3,14 @@
3 * 3 *
4 * NAS 100d board-setup 4 * NAS 100d board-setup
5 * 5 *
6 * based ixdp425-setup.c: 6 * Copyright (C) 2008 Rod Whitby <rod@whitby.id.au>
7 *
8 * based on ixdp425-setup.c:
7 * Copyright (C) 2003-2004 MontaVista Software, Inc. 9 * Copyright (C) 2003-2004 MontaVista Software, Inc.
10 * based on nas100d-power.c:
11 * Copyright (C) 2005 Tower Technologies
12 * based on nas100d-io.c
13 * Copyright (C) 2004 Karen Spearel
8 * 14 *
9 * Author: Alessandro Zummo <a.zummo@towertech.it> 15 * Author: Alessandro Zummo <a.zummo@towertech.it>
10 * Author: Rod Whitby <rod@whitby.id.au> 16 * Author: Rod Whitby <rod@whitby.id.au>
@@ -12,15 +18,22 @@
12 * 18 *
13 */ 19 */
14 20
15#include <linux/kernel.h> 21#include <linux/if_ether.h>
22#include <linux/irq.h>
23#include <linux/jiffies.h>
24#include <linux/timer.h>
16#include <linux/serial.h> 25#include <linux/serial.h>
17#include <linux/serial_8250.h> 26#include <linux/serial_8250.h>
18#include <linux/leds.h> 27#include <linux/leds.h>
28#include <linux/reboot.h>
29#include <linux/i2c.h>
19#include <linux/i2c-gpio.h> 30#include <linux/i2c-gpio.h>
20 31
21#include <asm/mach-types.h> 32#include <asm/mach-types.h>
22#include <asm/mach/arch.h> 33#include <asm/mach/arch.h>
23#include <asm/mach/flash.h> 34#include <asm/mach/flash.h>
35#include <asm/io.h>
36#include <asm/gpio.h>
24 37
25static struct flash_platform_data nas100d_flash_data = { 38static struct flash_platform_data nas100d_flash_data = {
26 .map_name = "cfi_probe", 39 .map_name = "cfi_probe",
@@ -39,35 +52,40 @@ static struct platform_device nas100d_flash = {
39 .resource = &nas100d_flash_resource, 52 .resource = &nas100d_flash_resource,
40}; 53};
41 54
42#ifdef CONFIG_LEDS_IXP4XX 55static struct i2c_board_info __initdata nas100d_i2c_board_info [] = {
43static struct resource nas100d_led_resources[] = { 56 {
57 I2C_BOARD_INFO("rtc-pcf8563", 0x51),
58 },
59};
60
61static struct gpio_led nas100d_led_pins[] = {
44 { 62 {
45 .name = "wlan", /* green led */ 63 .name = "wlan", /* green led */
46 .start = 0, 64 .gpio = NAS100D_LED_WLAN_GPIO,
47 .end = 0, 65 .active_low = true,
48 .flags = IXP4XX_GPIO_LOW,
49 }, 66 },
50 { 67 {
51 .name = "ready", /* blue power led (off is flashing!) */ 68 .name = "power", /* blue power led (off=flashing) */
52 .start = 15, 69 .gpio = NAS100D_LED_PWR_GPIO,
53 .end = 15, 70 .active_low = true,
54 .flags = IXP4XX_GPIO_LOW,
55 }, 71 },
56 { 72 {
57 .name = "disk", /* yellow led */ 73 .name = "disk", /* yellow led */
58 .start = 3, 74 .gpio = NAS100D_LED_DISK_GPIO,
59 .end = 3, 75 .active_low = true,
60 .flags = IXP4XX_GPIO_LOW,
61 }, 76 },
62}; 77};
63 78
79static struct gpio_led_platform_data nas100d_led_data = {
80 .num_leds = ARRAY_SIZE(nas100d_led_pins),
81 .leds = nas100d_led_pins,
82};
83
64static struct platform_device nas100d_leds = { 84static struct platform_device nas100d_leds = {
65 .name = "IXP4XX-GPIO-LED", 85 .name = "leds-gpio",
66 .id = -1, 86 .id = -1,
67 .num_resources = ARRAY_SIZE(nas100d_led_resources), 87 .dev.platform_data = &nas100d_led_data,
68 .resource = nas100d_led_resources,
69}; 88};
70#endif
71 89
72static struct i2c_gpio_platform_data nas100d_i2c_gpio_data = { 90static struct i2c_gpio_platform_data nas100d_i2c_gpio_data = {
73 .sda_pin = NAS100D_SDA_PIN, 91 .sda_pin = NAS100D_SDA_PIN,
@@ -125,12 +143,28 @@ static struct platform_device nas100d_uart = {
125 .resource = nas100d_uart_resources, 143 .resource = nas100d_uart_resources,
126}; 144};
127 145
146/* Built-in 10/100 Ethernet MAC interfaces */
147static struct eth_plat_info nas100d_plat_eth[] = {
148 {
149 .phy = 0,
150 .rxq = 3,
151 .txreadyq = 20,
152 }
153};
154
155static struct platform_device nas100d_eth[] = {
156 {
157 .name = "ixp4xx_eth",
158 .id = IXP4XX_ETH_NPEB,
159 .dev.platform_data = nas100d_plat_eth,
160 }
161};
162
128static struct platform_device *nas100d_devices[] __initdata = { 163static struct platform_device *nas100d_devices[] __initdata = {
129 &nas100d_i2c_gpio, 164 &nas100d_i2c_gpio,
130 &nas100d_flash, 165 &nas100d_flash,
131#ifdef CONFIG_LEDS_IXP4XX
132 &nas100d_leds, 166 &nas100d_leds,
133#endif 167 &nas100d_eth[0],
134}; 168};
135 169
136static void nas100d_power_off(void) 170static void nas100d_power_off(void)
@@ -144,8 +178,63 @@ static void nas100d_power_off(void)
144 gpio_line_set(NAS100D_PO_GPIO, IXP4XX_GPIO_HIGH); 178 gpio_line_set(NAS100D_PO_GPIO, IXP4XX_GPIO_HIGH);
145} 179}
146 180
181/* This is used to make sure the power-button pusher is serious. The button
182 * must be held until the value of this counter reaches zero.
183 */
184static int power_button_countdown;
185
186/* Must hold the button down for at least this many counts to be processed */
187#define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */
188
189static void nas100d_power_handler(unsigned long data);
190static DEFINE_TIMER(nas100d_power_timer, nas100d_power_handler, 0, 0);
191
192static void nas100d_power_handler(unsigned long data)
193{
194 /* This routine is called twice per second to check the
195 * state of the power button.
196 */
197
198 if (gpio_get_value(NAS100D_PB_GPIO)) {
199
200 /* IO Pin is 1 (button pushed) */
201 if (power_button_countdown > 0)
202 power_button_countdown--;
203
204 } else {
205
206 /* Done on button release, to allow for auto-power-on mods. */
207 if (power_button_countdown == 0) {
208 /* Signal init to do the ctrlaltdel action,
209 * this will bypass init if it hasn't started
210 * and do a kernel_restart.
211 */
212 ctrl_alt_del();
213
214 /* Change the state of the power LED to "blink" */
215 gpio_line_set(NAS100D_LED_PWR_GPIO, IXP4XX_GPIO_LOW);
216 } else {
217 power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
218 }
219 }
220
221 mod_timer(&nas100d_power_timer, jiffies + msecs_to_jiffies(500));
222}
223
224static irqreturn_t nas100d_reset_handler(int irq, void *dev_id)
225{
226 /* This is the paper-clip reset, it shuts the machine down directly. */
227 machine_power_off();
228
229 return IRQ_HANDLED;
230}
231
147static void __init nas100d_init(void) 232static void __init nas100d_init(void)
148{ 233{
234 DECLARE_MAC_BUF(mac_buf);
235 uint8_t __iomem *f;
236 int i;
237
149 ixp4xx_sys_init(); 238 ixp4xx_sys_init();
150 239
151 /* gpio 14 and 15 are _not_ clocks */ 240 /* gpio 14 and 15 are _not_ clocks */
@@ -155,7 +244,8 @@ static void __init nas100d_init(void)
155 nas100d_flash_resource.end = 244 nas100d_flash_resource.end =
156 IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; 245 IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
157 246
158 pm_power_off = nas100d_power_off; 247 i2c_register_board_info(0, nas100d_i2c_board_info,
248 ARRAY_SIZE(nas100d_i2c_board_info));
159 249
160 /* 250 /*
161 * This is only useful on a modified machine, but it is valuable 251 * This is only useful on a modified machine, but it is valuable
@@ -165,6 +255,48 @@ static void __init nas100d_init(void)
165 (void)platform_device_register(&nas100d_uart); 255 (void)platform_device_register(&nas100d_uart);
166 256
167 platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices)); 257 platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices));
258
259 pm_power_off = nas100d_power_off;
260
261 if (request_irq(gpio_to_irq(NAS100D_RB_GPIO), &nas100d_reset_handler,
262 IRQF_DISABLED | IRQF_TRIGGER_LOW,
263 "NAS100D reset button", NULL) < 0) {
264
265 printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
266 gpio_to_irq(NAS100D_RB_GPIO));
267 }
268
269 /* The power button on the Iomega NAS100d is on GPIO 14, but
270 * it cannot handle interrupts on that GPIO line. So we'll
271 * have to poll it with a kernel timer.
272 */
273
274 /* Make sure that the power button GPIO is set up as an input */
275 gpio_line_config(NAS100D_PB_GPIO, IXP4XX_GPIO_IN);
276
277 /* Set the initial value for the power button IRQ handler */
278 power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
279
280 mod_timer(&nas100d_power_timer, jiffies + msecs_to_jiffies(500));
281
282 /*
283 * Map in a portion of the flash and read the MAC address.
284 * Since it is stored in BE in the flash itself, we need to
285 * byteswap it if we're in LE mode.
286 */
287 f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x1000000);
288 if (f) {
289 for (i = 0; i < 6; i++)
290#ifdef __ARMEB__
291 nas100d_plat_eth[0].hwaddr[i] = readb(f + 0xFC0FD8 + i);
292#else
293 nas100d_plat_eth[0].hwaddr[i] = readb(f + 0xFC0FD8 + (i^3));
294#endif
295 iounmap(f);
296 }
297 printk(KERN_INFO "NAS100D: Using MAC address %s for port 0\n",
298 print_mac(mac_buf, nas100d_plat_eth[0].hwaddr));
299
168} 300}
169 301
170MACHINE_START(NAS100D, "Iomega NAS 100d") 302MACHINE_START(NAS100D, "Iomega NAS 100d")
diff --git a/arch/arm/mach-ixp4xx/nslu2-power.c b/arch/arm/mach-ixp4xx/nslu2-power.c
deleted file mode 100644
index 6f10dc208320..000000000000
--- a/arch/arm/mach-ixp4xx/nslu2-power.c
+++ /dev/null
@@ -1,91 +0,0 @@
1/*
2 * arch/arm/mach-ixp4xx/nslu2-power.c
3 *
4 * NSLU2 Power/Reset driver
5 *
6 * Copyright (C) 2005 Tower Technologies
7 *
8 * based on nslu2-io.c
9 * Copyright (C) 2004 Karen Spearel
10 *
11 * Author: Alessandro Zummo <a.zummo@towertech.it>
12 * Maintainers: http://www.nslu2-linux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 */
19
20#include <linux/module.h>
21#include <linux/reboot.h>
22#include <linux/irq.h>
23#include <linux/interrupt.h>
24
25#include <asm/mach-types.h>
26
27static irqreturn_t nslu2_power_handler(int irq, void *dev_id)
28{
29 /* Signal init to do the ctrlaltdel action, this will bypass init if
30 * it hasn't started and do a kernel_restart.
31 */
32 ctrl_alt_del();
33
34 return IRQ_HANDLED;
35}
36
37static irqreturn_t nslu2_reset_handler(int irq, void *dev_id)
38{
39 /* This is the paper-clip reset, it shuts the machine down directly.
40 */
41 machine_power_off();
42
43 return IRQ_HANDLED;
44}
45
46static int __init nslu2_power_init(void)
47{
48 if (!(machine_is_nslu2()))
49 return 0;
50
51 *IXP4XX_GPIO_GPISR = 0x20400000; /* read the 2 irqs to clr */
52
53 set_irq_type(NSLU2_RB_IRQ, IRQT_LOW);
54 set_irq_type(NSLU2_PB_IRQ, IRQT_HIGH);
55
56 if (request_irq(NSLU2_RB_IRQ, &nslu2_reset_handler,
57 IRQF_DISABLED, "NSLU2 reset button", NULL) < 0) {
58
59 printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
60 NSLU2_RB_IRQ);
61
62 return -EIO;
63 }
64
65 if (request_irq(NSLU2_PB_IRQ, &nslu2_power_handler,
66 IRQF_DISABLED, "NSLU2 power button", NULL) < 0) {
67
68 printk(KERN_DEBUG "Power Button IRQ %d not available\n",
69 NSLU2_PB_IRQ);
70
71 return -EIO;
72 }
73
74 return 0;
75}
76
77static void __exit nslu2_power_exit(void)
78{
79 if (!(machine_is_nslu2()))
80 return;
81
82 free_irq(NSLU2_RB_IRQ, NULL);
83 free_irq(NSLU2_PB_IRQ, NULL);
84}
85
86module_init(nslu2_power_init);
87module_exit(nslu2_power_exit);
88
89MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
90MODULE_DESCRIPTION("NSLU2 Power/Reset driver");
91MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
index 77277d27fcc5..acaebcbce53a 100644
--- a/arch/arm/mach-ixp4xx/nslu2-setup.c
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -3,27 +3,35 @@
3 * 3 *
4 * NSLU2 board-setup 4 * NSLU2 board-setup
5 * 5 *
6 * based ixdp425-setup.c: 6 * Copyright (C) 2008 Rod Whitby <rod@whitby.id.au>
7 *
8 * based on ixdp425-setup.c:
7 * Copyright (C) 2003-2004 MontaVista Software, Inc. 9 * Copyright (C) 2003-2004 MontaVista Software, Inc.
10 * based on nslu2-power.c:
11 * Copyright (C) 2005 Tower Technologies
8 * 12 *
9 * Author: Mark Rakes <mrakes at mac.com> 13 * Author: Mark Rakes <mrakes at mac.com>
10 * Author: Rod Whitby <rod@whitby.id.au> 14 * Author: Rod Whitby <rod@whitby.id.au>
15 * Author: Alessandro Zummo <a.zummo@towertech.it>
11 * Maintainers: http://www.nslu2-linux.org/ 16 * Maintainers: http://www.nslu2-linux.org/
12 * 17 *
13 * Fixed missing init_time in MACHINE_START kas11 10/22/04
14 * Changed to conform to new style __init ixdp425 kas11 10/22/04
15 */ 18 */
16 19
17#include <linux/kernel.h> 20#include <linux/if_ether.h>
21#include <linux/irq.h>
18#include <linux/serial.h> 22#include <linux/serial.h>
19#include <linux/serial_8250.h> 23#include <linux/serial_8250.h>
20#include <linux/leds.h> 24#include <linux/leds.h>
25#include <linux/reboot.h>
26#include <linux/i2c.h>
21#include <linux/i2c-gpio.h> 27#include <linux/i2c-gpio.h>
22 28
23#include <asm/mach-types.h> 29#include <asm/mach-types.h>
24#include <asm/mach/arch.h> 30#include <asm/mach/arch.h>
25#include <asm/mach/flash.h> 31#include <asm/mach/flash.h>
26#include <asm/mach/time.h> 32#include <asm/mach/time.h>
33#include <asm/io.h>
34#include <asm/gpio.h>
27 35
28static struct flash_platform_data nslu2_flash_data = { 36static struct flash_platform_data nslu2_flash_data = {
29 .map_name = "cfi_probe", 37 .map_name = "cfi_probe",
@@ -47,41 +55,43 @@ static struct i2c_gpio_platform_data nslu2_i2c_gpio_data = {
47 .scl_pin = NSLU2_SCL_PIN, 55 .scl_pin = NSLU2_SCL_PIN,
48}; 56};
49 57
50#ifdef CONFIG_LEDS_IXP4XX 58static struct i2c_board_info __initdata nslu2_i2c_board_info [] = {
51static struct resource nslu2_led_resources[] = { 59 {
60 I2C_BOARD_INFO("rtc-x1205", 0x6f),
61 },
62};
63
64static struct gpio_led nslu2_led_pins[] = {
52 { 65 {
53 .name = "ready", /* green led */ 66 .name = "ready", /* green led */
54 .start = NSLU2_LED_GRN_GPIO, 67 .gpio = NSLU2_LED_GRN_GPIO,
55 .end = NSLU2_LED_GRN_GPIO,
56 .flags = IXP4XX_GPIO_HIGH,
57 }, 68 },
58 { 69 {
59 .name = "status", /* red led */ 70 .name = "status", /* red led */
60 .start = NSLU2_LED_RED_GPIO, 71 .gpio = NSLU2_LED_RED_GPIO,
61 .end = NSLU2_LED_RED_GPIO,
62 .flags = IXP4XX_GPIO_HIGH,
63 }, 72 },
64 { 73 {
65 .name = "disk-1", 74 .name = "disk-1",
66 .start = NSLU2_LED_DISK1_GPIO, 75 .gpio = NSLU2_LED_DISK1_GPIO,
67 .end = NSLU2_LED_DISK1_GPIO, 76 .active_low = true,
68 .flags = IXP4XX_GPIO_LOW,
69 }, 77 },
70 { 78 {
71 .name = "disk-2", 79 .name = "disk-2",
72 .start = NSLU2_LED_DISK2_GPIO, 80 .gpio = NSLU2_LED_DISK2_GPIO,
73 .end = NSLU2_LED_DISK2_GPIO, 81 .active_low = true,
74 .flags = IXP4XX_GPIO_LOW,
75 }, 82 },
76}; 83};
77 84
85static struct gpio_led_platform_data nslu2_led_data = {
86 .num_leds = ARRAY_SIZE(nslu2_led_pins),
87 .leds = nslu2_led_pins,
88};
89
78static struct platform_device nslu2_leds = { 90static struct platform_device nslu2_leds = {
79 .name = "IXP4XX-GPIO-LED", 91 .name = "leds-gpio",
80 .id = -1, 92 .id = -1,
81 .num_resources = ARRAY_SIZE(nslu2_led_resources), 93 .dev.platform_data = &nslu2_led_data,
82 .resource = nslu2_led_resources,
83}; 94};
84#endif
85 95
86static struct platform_device nslu2_i2c_gpio = { 96static struct platform_device nslu2_i2c_gpio = {
87 .name = "i2c-gpio", 97 .name = "i2c-gpio",
@@ -140,13 +150,29 @@ static struct platform_device nslu2_uart = {
140 .resource = nslu2_uart_resources, 150 .resource = nslu2_uart_resources,
141}; 151};
142 152
153/* Built-in 10/100 Ethernet MAC interfaces */
154static struct eth_plat_info nslu2_plat_eth[] = {
155 {
156 .phy = 1,
157 .rxq = 3,
158 .txreadyq = 20,
159 }
160};
161
162static struct platform_device nslu2_eth[] = {
163 {
164 .name = "ixp4xx_eth",
165 .id = IXP4XX_ETH_NPEB,
166 .dev.platform_data = nslu2_plat_eth,
167 }
168};
169
143static struct platform_device *nslu2_devices[] __initdata = { 170static struct platform_device *nslu2_devices[] __initdata = {
144 &nslu2_i2c_gpio, 171 &nslu2_i2c_gpio,
145 &nslu2_flash, 172 &nslu2_flash,
146 &nslu2_beeper, 173 &nslu2_beeper,
147#ifdef CONFIG_LEDS_IXP4XX
148 &nslu2_leds, 174 &nslu2_leds,
149#endif 175 &nslu2_eth[0],
150}; 176};
151 177
152static void nslu2_power_off(void) 178static void nslu2_power_off(void)
@@ -160,6 +186,25 @@ static void nslu2_power_off(void)
160 gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH); 186 gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH);
161} 187}
162 188
189static irqreturn_t nslu2_power_handler(int irq, void *dev_id)
190{
191 /* Signal init to do the ctrlaltdel action, this will bypass init if
192 * it hasn't started and do a kernel_restart.
193 */
194 ctrl_alt_del();
195
196 return IRQ_HANDLED;
197}
198
199static irqreturn_t nslu2_reset_handler(int irq, void *dev_id)
200{
201 /* This is the paper-clip reset, it shuts the machine down directly.
202 */
203 machine_power_off();
204
205 return IRQ_HANDLED;
206}
207
163static void __init nslu2_timer_init(void) 208static void __init nslu2_timer_init(void)
164{ 209{
165 /* The xtal on this machine is non-standard. */ 210 /* The xtal on this machine is non-standard. */
@@ -175,13 +220,18 @@ static struct sys_timer nslu2_timer = {
175 220
176static void __init nslu2_init(void) 221static void __init nslu2_init(void)
177{ 222{
223 DECLARE_MAC_BUF(mac_buf);
224 uint8_t __iomem *f;
225 int i;
226
178 ixp4xx_sys_init(); 227 ixp4xx_sys_init();
179 228
180 nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); 229 nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
181 nslu2_flash_resource.end = 230 nslu2_flash_resource.end =
182 IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; 231 IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
183 232
184 pm_power_off = nslu2_power_off; 233 i2c_register_board_info(0, nslu2_i2c_board_info,
234 ARRAY_SIZE(nslu2_i2c_board_info));
185 235
186 /* 236 /*
187 * This is only useful on a modified machine, but it is valuable 237 * This is only useful on a modified machine, but it is valuable
@@ -191,6 +241,43 @@ static void __init nslu2_init(void)
191 (void)platform_device_register(&nslu2_uart); 241 (void)platform_device_register(&nslu2_uart);
192 242
193 platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices)); 243 platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices));
244
245 pm_power_off = nslu2_power_off;
246
247 if (request_irq(gpio_to_irq(NSLU2_RB_GPIO), &nslu2_reset_handler,
248 IRQF_DISABLED | IRQF_TRIGGER_LOW,
249 "NSLU2 reset button", NULL) < 0) {
250
251 printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
252 gpio_to_irq(NSLU2_RB_GPIO));
253 }
254
255 if (request_irq(gpio_to_irq(NSLU2_PB_GPIO), &nslu2_power_handler,
256 IRQF_DISABLED | IRQF_TRIGGER_HIGH,
257 "NSLU2 power button", NULL) < 0) {
258
259 printk(KERN_DEBUG "Power Button IRQ %d not available\n",
260 gpio_to_irq(NSLU2_PB_GPIO));
261 }
262
263 /*
264 * Map in a portion of the flash and read the MAC address.
265 * Since it is stored in BE in the flash itself, we need to
266 * byteswap it if we're in LE mode.
267 */
268 f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x40000);
269 if (f) {
270 for (i = 0; i < 6; i++)
271#ifdef __ARMEB__
272 nslu2_plat_eth[0].hwaddr[i] = readb(f + 0x3FFB0 + i);
273#else
274 nslu2_plat_eth[0].hwaddr[i] = readb(f + 0x3FFB0 + (i^3));
275#endif
276 iounmap(f);
277 }
278 printk(KERN_INFO "NSLU2: Using MAC address %s for port 0\n",
279 print_mac(mac_buf, nslu2_plat_eth[0].hwaddr));
280
194} 281}
195 282
196MACHINE_START(NSLU2, "Linksys NSLU2") 283MACHINE_START(NSLU2, "Linksys NSLU2")
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index b5c916c0747d..6e0c4f5b5ae6 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -3,10 +3,11 @@
3# 3#
4 4
5# Common support (must be linked before board specific support) 5# Common support (must be linked before board specific support)
6obj-y += clock.o devices.o generic.o irq.o dma.o time.o 6obj-y += clock.o devices.o generic.o irq.o dma.o \
7 time.o gpio.o
7obj-$(CONFIG_PXA25x) += pxa25x.o 8obj-$(CONFIG_PXA25x) += pxa25x.o
8obj-$(CONFIG_PXA27x) += pxa27x.o 9obj-$(CONFIG_PXA27x) += pxa27x.o
9obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o 10obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o smemc.o
10obj-$(CONFIG_CPU_PXA300) += pxa300.o 11obj-$(CONFIG_CPU_PXA300) += pxa300.o
11obj-$(CONFIG_CPU_PXA320) += pxa320.o 12obj-$(CONFIG_CPU_PXA320) += pxa320.o
12 13
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
index 28cfd71c032d..6012177a29a3 100644
--- a/arch/arm/mach-pxa/cm-x270.c
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -29,6 +29,7 @@
29#include <asm/mach/map.h> 29#include <asm/mach/map.h>
30 30
31#include <asm/arch/pxa-regs.h> 31#include <asm/arch/pxa-regs.h>
32#include <asm/arch/pxa2xx-regs.h>
32#include <asm/arch/pxafb.h> 33#include <asm/arch/pxafb.h>
33#include <asm/arch/ohci.h> 34#include <asm/arch/ohci.h>
34#include <asm/arch/mmc.h> 35#include <asm/arch/mmc.h>
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 50ff453ad370..bfccb80ac8ef 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -10,6 +10,7 @@
10#include <asm/arch/mmc.h> 10#include <asm/arch/mmc.h>
11#include <asm/arch/irda.h> 11#include <asm/arch/irda.h>
12#include <asm/arch/i2c.h> 12#include <asm/arch/i2c.h>
13#include <asm/arch/ohci.h>
13 14
14#include "devices.h" 15#include "devices.h"
15 16
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 698aeec52961..80721c610d41 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -23,6 +23,7 @@
23#include <linux/ioport.h> 23#include <linux/ioport.h>
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/string.h> 25#include <linux/string.h>
26#include <linux/sysdev.h>
26 27
27#include <asm/hardware.h> 28#include <asm/hardware.h>
28#include <asm/irq.h> 29#include <asm/irq.h>
@@ -31,7 +32,6 @@
31#include <asm/mach/map.h> 32#include <asm/mach/map.h>
32 33
33#include <asm/arch/pxa-regs.h> 34#include <asm/arch/pxa-regs.h>
34#include <asm/arch/gpio.h>
35 35
36#include "generic.h" 36#include "generic.h"
37 37
@@ -66,97 +66,6 @@ unsigned int get_memclk_frequency_10khz(void)
66EXPORT_SYMBOL(get_memclk_frequency_10khz); 66EXPORT_SYMBOL(get_memclk_frequency_10khz);
67 67
68/* 68/*
69 * Handy function to set GPIO alternate functions
70 */
71int pxa_last_gpio;
72
73int pxa_gpio_mode(int gpio_mode)
74{
75 unsigned long flags;
76 int gpio = gpio_mode & GPIO_MD_MASK_NR;
77 int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
78 int gafr;
79
80 if (gpio > pxa_last_gpio)
81 return -EINVAL;
82
83 local_irq_save(flags);
84 if (gpio_mode & GPIO_DFLT_LOW)
85 GPCR(gpio) = GPIO_bit(gpio);
86 else if (gpio_mode & GPIO_DFLT_HIGH)
87 GPSR(gpio) = GPIO_bit(gpio);
88 if (gpio_mode & GPIO_MD_MASK_DIR)
89 GPDR(gpio) |= GPIO_bit(gpio);
90 else
91 GPDR(gpio) &= ~GPIO_bit(gpio);
92 gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
93 GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
94 local_irq_restore(flags);
95
96 return 0;
97}
98
99EXPORT_SYMBOL(pxa_gpio_mode);
100
101int gpio_direction_input(unsigned gpio)
102{
103 unsigned long flags;
104 u32 mask;
105
106 if (gpio > pxa_last_gpio)
107 return -EINVAL;
108
109 mask = GPIO_bit(gpio);
110 local_irq_save(flags);
111 GPDR(gpio) &= ~mask;
112 local_irq_restore(flags);
113
114 return 0;
115}
116EXPORT_SYMBOL(gpio_direction_input);
117
118int gpio_direction_output(unsigned gpio, int value)
119{
120 unsigned long flags;
121 u32 mask;
122
123 if (gpio > pxa_last_gpio)
124 return -EINVAL;
125
126 mask = GPIO_bit(gpio);
127 local_irq_save(flags);
128 if (value)
129 GPSR(gpio) = mask;
130 else
131 GPCR(gpio) = mask;
132 GPDR(gpio) |= mask;
133 local_irq_restore(flags);
134
135 return 0;
136}
137EXPORT_SYMBOL(gpio_direction_output);
138
139/*
140 * Return GPIO level
141 */
142int pxa_gpio_get_value(unsigned gpio)
143{
144 return __gpio_get_value(gpio);
145}
146
147EXPORT_SYMBOL(pxa_gpio_get_value);
148
149/*
150 * Set output GPIO level
151 */
152void pxa_gpio_set_value(unsigned gpio, int value)
153{
154 __gpio_set_value(gpio, value);
155}
156
157EXPORT_SYMBOL(pxa_gpio_set_value);
158
159/*
160 * Routine to safely enable or disable a clock in the CKEN 69 * Routine to safely enable or disable a clock in the CKEN
161 */ 70 */
162void __pxa_set_cken(int clock, int enable) 71void __pxa_set_cken(int clock, int enable)
@@ -171,7 +80,6 @@ void __pxa_set_cken(int clock, int enable)
171 80
172 local_irq_restore(flags); 81 local_irq_restore(flags);
173} 82}
174
175EXPORT_SYMBOL(__pxa_set_cken); 83EXPORT_SYMBOL(__pxa_set_cken);
176 84
177/* 85/*
@@ -226,3 +134,59 @@ void __init pxa_map_io(void)
226 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc)); 134 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
227 get_clk_frequency_khz(1); 135 get_clk_frequency_khz(1);
228} 136}
137
138#ifdef CONFIG_PM
139
140static unsigned long saved_gplr[4];
141static unsigned long saved_gpdr[4];
142static unsigned long saved_grer[4];
143static unsigned long saved_gfer[4];
144
145static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state)
146{
147 int i, gpio;
148
149 for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) {
150 saved_gplr[i] = GPLR(gpio);
151 saved_gpdr[i] = GPDR(gpio);
152 saved_grer[i] = GRER(gpio);
153 saved_gfer[i] = GFER(gpio);
154
155 /* Clear GPIO transition detect bits */
156 GEDR(gpio) = GEDR(gpio);
157 }
158 return 0;
159}
160
161static int pxa_gpio_resume(struct sys_device *dev)
162{
163 int i, gpio;
164
165 for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) {
166 /* restore level with set/clear */
167 GPSR(gpio) = saved_gplr[i];
168 GPCR(gpio) = ~saved_gplr[i];
169
170 GRER(gpio) = saved_grer[i];
171 GFER(gpio) = saved_gfer[i];
172 GPDR(gpio) = saved_gpdr[i];
173 }
174 return 0;
175}
176#else
177#define pxa_gpio_suspend NULL
178#define pxa_gpio_resume NULL
179#endif
180
181struct sysdev_class pxa_gpio_sysclass = {
182 .name = "gpio",
183 .suspend = pxa_gpio_suspend,
184 .resume = pxa_gpio_resume,
185};
186
187static int __init pxa_gpio_init(void)
188{
189 return sysdev_class_register(&pxa_gpio_sysclass);
190}
191
192core_initcall(pxa_gpio_init);
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index b30f240a16c7..b3d10b0e52a0 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -16,6 +16,7 @@ extern void __init pxa_init_irq_low(void);
16extern void __init pxa_init_irq_high(void); 16extern void __init pxa_init_irq_high(void);
17extern void __init pxa_init_irq_gpio(int gpio_nr); 17extern void __init pxa_init_irq_gpio(int gpio_nr);
18extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)); 18extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int));
19extern void __init pxa_init_gpio(int gpio_nr);
19extern void __init pxa25x_init_irq(void); 20extern void __init pxa25x_init_irq(void);
20extern void __init pxa27x_init_irq(void); 21extern void __init pxa27x_init_irq(void);
21extern void __init pxa3xx_init_irq(void); 22extern void __init pxa3xx_init_irq(void);
@@ -52,3 +53,6 @@ extern unsigned pxa3xx_get_memclk_frequency_10khz(void);
52#define pxa3xx_get_clk_frequency_khz(x) (0) 53#define pxa3xx_get_clk_frequency_khz(x) (0)
53#define pxa3xx_get_memclk_frequency_10khz() (0) 54#define pxa3xx_get_memclk_frequency_10khz() (0)
54#endif 55#endif
56
57extern struct sysdev_class pxa_irq_sysclass;
58extern struct sysdev_class pxa_gpio_sysclass;
diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c
new file mode 100644
index 000000000000..8638dd7dd076
--- /dev/null
+++ b/arch/arm/mach-pxa/gpio.c
@@ -0,0 +1,197 @@
1/*
2 * linux/arch/arm/mach-pxa/gpio.c
3 *
4 * Generic PXA GPIO handling
5 *
6 * Author: Nicolas Pitre
7 * Created: Jun 15, 2001
8 * Copyright: MontaVista Software Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/init.h>
16#include <linux/module.h>
17
18#include <asm/gpio.h>
19#include <asm/hardware.h>
20#include <asm/io.h>
21#include <asm/arch/pxa-regs.h>
22
23#include "generic.h"
24
25
26struct pxa_gpio_chip {
27 struct gpio_chip chip;
28 void __iomem *regbase;
29};
30
31int pxa_last_gpio;
32
33/*
34 * Configure pins for GPIO or other functions
35 */
36int pxa_gpio_mode(int gpio_mode)
37{
38 unsigned long flags;
39 int gpio = gpio_mode & GPIO_MD_MASK_NR;
40 int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
41 int gafr;
42
43 if (gpio > pxa_last_gpio)
44 return -EINVAL;
45
46 local_irq_save(flags);
47 if (gpio_mode & GPIO_DFLT_LOW)
48 GPCR(gpio) = GPIO_bit(gpio);
49 else if (gpio_mode & GPIO_DFLT_HIGH)
50 GPSR(gpio) = GPIO_bit(gpio);
51 if (gpio_mode & GPIO_MD_MASK_DIR)
52 GPDR(gpio) |= GPIO_bit(gpio);
53 else
54 GPDR(gpio) &= ~GPIO_bit(gpio);
55 gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
56 GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
57 local_irq_restore(flags);
58
59 return 0;
60}
61EXPORT_SYMBOL(pxa_gpio_mode);
62
63static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
64{
65 unsigned long flags;
66 u32 mask = 1 << offset;
67 u32 value;
68 struct pxa_gpio_chip *pxa;
69 void __iomem *gpdr;
70
71 pxa = container_of(chip, struct pxa_gpio_chip, chip);
72 gpdr = pxa->regbase + GPDR_OFFSET;
73 local_irq_save(flags);
74 value = __raw_readl(gpdr);
75 value &= ~mask;
76 __raw_writel(value, gpdr);
77 local_irq_restore(flags);
78
79 return 0;
80}
81
82static int pxa_gpio_direction_output(struct gpio_chip *chip,
83 unsigned offset, int value)
84{
85 unsigned long flags;
86 u32 mask = 1 << offset;
87 u32 tmp;
88 struct pxa_gpio_chip *pxa;
89 void __iomem *gpdr;
90
91 pxa = container_of(chip, struct pxa_gpio_chip, chip);
92 __raw_writel(mask,
93 pxa->regbase + (value ? GPSR_OFFSET : GPCR_OFFSET));
94 gpdr = pxa->regbase + GPDR_OFFSET;
95 local_irq_save(flags);
96 tmp = __raw_readl(gpdr);
97 tmp |= mask;
98 __raw_writel(tmp, gpdr);
99 local_irq_restore(flags);
100
101 return 0;
102}
103
104/*
105 * Return GPIO level
106 */
107static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
108{
109 u32 mask = 1 << offset;
110 struct pxa_gpio_chip *pxa;
111
112 pxa = container_of(chip, struct pxa_gpio_chip, chip);
113 return __raw_readl(pxa->regbase + GPLR_OFFSET) & mask;
114}
115
116/*
117 * Set output GPIO level
118 */
119static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
120{
121 u32 mask = 1 << offset;
122 struct pxa_gpio_chip *pxa;
123
124 pxa = container_of(chip, struct pxa_gpio_chip, chip);
125
126 if (value)
127 __raw_writel(mask, pxa->regbase + GPSR_OFFSET);
128 else
129 __raw_writel(mask, pxa->regbase + GPCR_OFFSET);
130}
131
132static struct pxa_gpio_chip pxa_gpio_chip[] = {
133 [0] = {
134 .regbase = GPIO0_BASE,
135 .chip = {
136 .label = "gpio-0",
137 .direction_input = pxa_gpio_direction_input,
138 .direction_output = pxa_gpio_direction_output,
139 .get = pxa_gpio_get,
140 .set = pxa_gpio_set,
141 .base = 0,
142 .ngpio = 32,
143 },
144 },
145 [1] = {
146 .regbase = GPIO1_BASE,
147 .chip = {
148 .label = "gpio-1",
149 .direction_input = pxa_gpio_direction_input,
150 .direction_output = pxa_gpio_direction_output,
151 .get = pxa_gpio_get,
152 .set = pxa_gpio_set,
153 .base = 32,
154 .ngpio = 32,
155 },
156 },
157 [2] = {
158 .regbase = GPIO2_BASE,
159 .chip = {
160 .label = "gpio-2",
161 .direction_input = pxa_gpio_direction_input,
162 .direction_output = pxa_gpio_direction_output,
163 .get = pxa_gpio_get,
164 .set = pxa_gpio_set,
165 .base = 64,
166 .ngpio = 32, /* 21 for PXA25x */
167 },
168 },
169#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
170 [3] = {
171 .regbase = GPIO3_BASE,
172 .chip = {
173 .label = "gpio-3",
174 .direction_input = pxa_gpio_direction_input,
175 .direction_output = pxa_gpio_direction_output,
176 .get = pxa_gpio_get,
177 .set = pxa_gpio_set,
178 .base = 96,
179 .ngpio = 32,
180 },
181 },
182#endif
183};
184
185void __init pxa_init_gpio(int gpio_nr)
186{
187 int i;
188
189 /* add a GPIO chip for each register bank.
190 * the last PXA25x register only contains 21 GPIOs
191 */
192 for (i = 0; i < gpio_nr; i += 32) {
193 if (i+32 > gpio_nr)
194 pxa_gpio_chip[i/32].chip.ngpio = gpio_nr - i;
195 gpiochip_add(&pxa_gpio_chip[i/32].chip);
196 }
197}
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 07acb45b16ea..36c6a68beca2 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/sysdev.h>
18 19
19#include <asm/hardware.h> 20#include <asm/hardware.h>
20#include <asm/irq.h> 21#include <asm/irq.h>
@@ -310,6 +311,8 @@ void __init pxa_init_irq_gpio(int gpio_nr)
310 /* Install handler for GPIO>=2 edge detect interrupts */ 311 /* Install handler for GPIO>=2 edge detect interrupts */
311 set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low); 312 set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low);
312 set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler); 313 set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);
314
315 pxa_init_gpio(gpio_nr);
313} 316}
314 317
315void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)) 318void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int))
@@ -321,3 +324,64 @@ void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int))
321 pxa_low_gpio_chip.set_wake = set_wake; 324 pxa_low_gpio_chip.set_wake = set_wake;
322 pxa_muxed_gpio_chip.set_wake = set_wake; 325 pxa_muxed_gpio_chip.set_wake = set_wake;
323} 326}
327
328#ifdef CONFIG_PM
329static unsigned long saved_icmr[2];
330
331static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
332{
333 switch (dev->id) {
334 case 0:
335 saved_icmr[0] = ICMR;
336 ICMR = 0;
337 break;
338#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
339 case 1:
340 saved_icmr[1] = ICMR2;
341 ICMR2 = 0;
342 break;
343#endif
344 default:
345 return -EINVAL;
346 }
347
348 return 0;
349}
350
351static int pxa_irq_resume(struct sys_device *dev)
352{
353 switch (dev->id) {
354 case 0:
355 ICMR = saved_icmr[0];
356 ICLR = 0;
357 ICCR = 1;
358 break;
359#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
360 case 1:
361 ICMR2 = saved_icmr[1];
362 ICLR2 = 0;
363 break;
364#endif
365 default:
366 return -EINVAL;
367 }
368
369 return 0;
370}
371#else
372#define pxa_irq_suspend NULL
373#define pxa_irq_resume NULL
374#endif
375
376struct sysdev_class pxa_irq_sysclass = {
377 .name = "irq",
378 .suspend = pxa_irq_suspend,
379 .resume = pxa_irq_resume,
380};
381
382static int __init pxa_irq_init(void)
383{
384 return sysdev_class_register(&pxa_irq_sysclass);
385}
386
387core_initcall(pxa_irq_init);
diff --git a/arch/arm/mach-pxa/mfp.c b/arch/arm/mach-pxa/mfp.c
index ec1b2d8f61c4..f5809adce298 100644
--- a/arch/arm/mach-pxa/mfp.c
+++ b/arch/arm/mach-pxa/mfp.c
@@ -22,6 +22,7 @@
22#include <asm/hardware.h> 22#include <asm/hardware.h>
23#include <asm/arch/mfp.h> 23#include <asm/arch/mfp.h>
24#include <asm/arch/mfp-pxa3xx.h> 24#include <asm/arch/mfp-pxa3xx.h>
25#include <asm/arch/pxa3xx-regs.h>
25 26
26/* mfp_spin_lock is used to ensure that MFP register configuration 27/* mfp_spin_lock is used to ensure that MFP register configuration
27 * (most likely a read-modify-write operation) is atomic, and that 28 * (most likely a read-modify-write operation) is atomic, and that
@@ -223,11 +224,19 @@ static int pxa3xx_mfp_resume(struct sys_device *d)
223 struct pxa3xx_mfp_pin *p = &mfp_table[pin]; 224 struct pxa3xx_mfp_pin *p = &mfp_table[pin];
224 __mfp_config_run(p); 225 __mfp_config_run(p);
225 } 226 }
227
228 /* clear RDH bit when MFP settings are restored
229 *
230 * NOTE: the last 3 bits DxS are write-1-to-clear so carefully
231 * preserve them here in case they will be referenced later
232 */
233 ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
234
226 return 0; 235 return 0;
227} 236}
228 237
229static struct sysdev_class mfp_sysclass = { 238static struct sysdev_class mfp_sysclass = {
230 set_kset_name("mfp"), 239 .name = "mfp",
231 .suspend = pxa3xx_mfp_suspend, 240 .suspend = pxa3xx_mfp_suspend,
232 .resume = pxa3xx_mfp_resume, 241 .resume = pxa3xx_mfp_resume,
233}; 242};
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c
index 540c3bba5f9a..c14696b9979d 100644
--- a/arch/arm/mach-pxa/pcm027.c
+++ b/arch/arm/mach-pxa/pcm027.c
@@ -29,6 +29,7 @@
29#include <asm/mach/arch.h> 29#include <asm/mach/arch.h>
30#include <asm/arch/hardware.h> 30#include <asm/arch/hardware.h>
31#include <asm/arch/pxa-regs.h> 31#include <asm/arch/pxa-regs.h>
32#include <asm/arch/pxa2xx-regs.h>
32#include <asm/arch/pxa2xx_spi.h> 33#include <asm/arch/pxa2xx_spi.h>
33#include <asm/arch/pcm027.h> 34#include <asm/arch/pcm027.h>
34#include "generic.h" 35#include "generic.h"
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index dd54496083cb..209eabf0ed3e 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -164,7 +164,7 @@ static struct resource poodlets_resources[] = {
164 }, 164 },
165}; 165};
166 166
167static unsigned long poodle_get_hsync_len(void) 167static unsigned long poodle_get_hsync_invperiod(void)
168{ 168{
169 return 0; 169 return 0;
170} 170}
@@ -174,9 +174,9 @@ static void poodle_null_hsync(void)
174} 174}
175 175
176static struct corgits_machinfo poodle_ts_machinfo = { 176static struct corgits_machinfo poodle_ts_machinfo = {
177 .get_hsync_len = poodle_get_hsync_len, 177 .get_hsync_invperiod = poodle_get_hsync_invperiod,
178 .put_hsync = poodle_null_hsync, 178 .put_hsync = poodle_null_hsync,
179 .wait_hsync = poodle_null_hsync, 179 .wait_hsync = poodle_null_hsync,
180}; 180};
181 181
182static struct platform_device poodle_ts_device = { 182static struct platform_device poodle_ts_device = {
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index ddd05bf78e02..599e53fcc2c5 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -21,6 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/suspend.h> 23#include <linux/suspend.h>
24#include <linux/sysdev.h>
24 25
25#include <asm/hardware.h> 26#include <asm/hardware.h>
26#include <asm/arch/irqs.h> 27#include <asm/arch/irqs.h>
@@ -141,11 +142,6 @@ static struct clk pxa25x_clks[] = {
141#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x 142#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
142#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] 143#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
143 144
144#define RESTORE_GPLEVEL(n) do { \
145 GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \
146 GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \
147} while (0)
148
149/* 145/*
150 * List of global PXA peripheral registers to preserve. 146 * List of global PXA peripheral registers to preserve.
151 * More ones like CP and general purpose register values are preserved 147 * More ones like CP and general purpose register values are preserved
@@ -153,10 +149,6 @@ static struct clk pxa25x_clks[] = {
153 */ 149 */
154enum { SLEEP_SAVE_START = 0, 150enum { SLEEP_SAVE_START = 0,
155 151
156 SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2,
157 SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2,
158 SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2,
159 SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2,
160 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, 152 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2,
161 153
162 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, 154 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
@@ -165,7 +157,6 @@ enum { SLEEP_SAVE_START = 0,
165 157
166 SLEEP_SAVE_PSTR, 158 SLEEP_SAVE_PSTR,
167 159
168 SLEEP_SAVE_ICMR,
169 SLEEP_SAVE_CKEN, 160 SLEEP_SAVE_CKEN,
170 161
171 SLEEP_SAVE_SIZE 162 SLEEP_SAVE_SIZE
@@ -174,17 +165,12 @@ enum { SLEEP_SAVE_START = 0,
174 165
175static void pxa25x_cpu_pm_save(unsigned long *sleep_save) 166static void pxa25x_cpu_pm_save(unsigned long *sleep_save)
176{ 167{
177 SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2);
178 SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
179 SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
180 SAVE(GFER0); SAVE(GFER1); SAVE(GFER2);
181 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); 168 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2);
182 169
183 SAVE(GAFR0_L); SAVE(GAFR0_U); 170 SAVE(GAFR0_L); SAVE(GAFR0_U);
184 SAVE(GAFR1_L); SAVE(GAFR1_U); 171 SAVE(GAFR1_L); SAVE(GAFR1_U);
185 SAVE(GAFR2_L); SAVE(GAFR2_U); 172 SAVE(GAFR2_L); SAVE(GAFR2_U);
186 173
187 SAVE(ICMR); ICMR = 0;
188 SAVE(CKEN); 174 SAVE(CKEN);
189 SAVE(PSTR); 175 SAVE(PSTR);
190 176
@@ -198,22 +184,14 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
198 PSPR = 0; 184 PSPR = 0;
199 185
200 /* restore registers */ 186 /* restore registers */
201 RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2);
202 RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
203 RESTORE(GAFR0_L); RESTORE(GAFR0_U); 187 RESTORE(GAFR0_L); RESTORE(GAFR0_U);
204 RESTORE(GAFR1_L); RESTORE(GAFR1_U); 188 RESTORE(GAFR1_L); RESTORE(GAFR1_U);
205 RESTORE(GAFR2_L); RESTORE(GAFR2_U); 189 RESTORE(GAFR2_L); RESTORE(GAFR2_U);
206 RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2);
207 RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2);
208 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); 190 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
209 191
210 PSSR = PSSR_RDH | PSSR_PH; 192 PSSR = PSSR_RDH | PSSR_PH;
211 193
212 RESTORE(CKEN); 194 RESTORE(CKEN);
213
214 ICLR = 0;
215 ICCR = 1;
216 RESTORE(ICMR);
217 RESTORE(PSTR); 195 RESTORE(PSTR);
218} 196}
219 197
@@ -304,9 +282,17 @@ static struct platform_device *pxa25x_devices[] __initdata = {
304 &pxa25x_device_assp, 282 &pxa25x_device_assp,
305}; 283};
306 284
285static struct sys_device pxa25x_sysdev[] = {
286 {
287 .cls = &pxa_irq_sysclass,
288 }, {
289 .cls = &pxa_gpio_sysclass,
290 },
291};
292
307static int __init pxa25x_init(void) 293static int __init pxa25x_init(void)
308{ 294{
309 int ret = 0; 295 int i, ret = 0;
310 296
311 /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ 297 /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
312 if (cpu_is_pxa25x()) 298 if (cpu_is_pxa25x())
@@ -320,9 +306,18 @@ static int __init pxa25x_init(void)
320 306
321 pxa25x_init_pm(); 307 pxa25x_init_pm();
322 308
309 for (i = 0; i < ARRAY_SIZE(pxa25x_sysdev); i++) {
310 ret = sysdev_register(&pxa25x_sysdev[i]);
311 if (ret)
312 pr_err("failed to register sysdev[%d]\n", i);
313 }
314
323 ret = platform_add_devices(pxa25x_devices, 315 ret = platform_add_devices(pxa25x_devices,
324 ARRAY_SIZE(pxa25x_devices)); 316 ARRAY_SIZE(pxa25x_devices));
317 if (ret)
318 return ret;
325 } 319 }
320
326 /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ 321 /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
327 if (cpu_is_pxa25x()) 322 if (cpu_is_pxa25x())
328 ret = platform_device_register(&pxa_device_hwuart); 323 ret = platform_device_register(&pxa_device_hwuart);
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 96cf274ec7cb..46a951c3e5a0 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/suspend.h> 17#include <linux/suspend.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/sysdev.h>
19 20
20#include <asm/hardware.h> 21#include <asm/hardware.h>
21#include <asm/irq.h> 22#include <asm/irq.h>
@@ -171,11 +172,6 @@ static struct clk pxa27x_clks[] = {
171#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x 172#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
172#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] 173#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
173 174
174#define RESTORE_GPLEVEL(n) do { \
175 GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \
176 GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \
177} while (0)
178
179/* 175/*
180 * List of global PXA peripheral registers to preserve. 176 * List of global PXA peripheral registers to preserve.
181 * More ones like CP and general purpose register values are preserved 177 * More ones like CP and general purpose register values are preserved
@@ -183,10 +179,6 @@ static struct clk pxa27x_clks[] = {
183 */ 179 */
184enum { SLEEP_SAVE_START = 0, 180enum { SLEEP_SAVE_START = 0,
185 181
186 SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3,
187 SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3,
188 SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3,
189 SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3,
190 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3, 182 SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
191 183
192 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, 184 SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
@@ -196,7 +188,6 @@ enum { SLEEP_SAVE_START = 0,
196 188
197 SLEEP_SAVE_PSTR, 189 SLEEP_SAVE_PSTR,
198 190
199 SLEEP_SAVE_ICMR,
200 SLEEP_SAVE_CKEN, 191 SLEEP_SAVE_CKEN,
201 192
202 SLEEP_SAVE_MDREFR, 193 SLEEP_SAVE_MDREFR,
@@ -208,10 +199,6 @@ enum { SLEEP_SAVE_START = 0,
208 199
209void pxa27x_cpu_pm_save(unsigned long *sleep_save) 200void pxa27x_cpu_pm_save(unsigned long *sleep_save)
210{ 201{
211 SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); SAVE(GPLR3);
212 SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); SAVE(GPDR3);
213 SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); SAVE(GRER3);
214 SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); SAVE(GFER3);
215 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3); 202 SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3);
216 203
217 SAVE(GAFR0_L); SAVE(GAFR0_U); 204 SAVE(GAFR0_L); SAVE(GAFR0_U);
@@ -223,12 +210,8 @@ void pxa27x_cpu_pm_save(unsigned long *sleep_save)
223 SAVE(PWER); SAVE(PCFR); SAVE(PRER); 210 SAVE(PWER); SAVE(PCFR); SAVE(PRER);
224 SAVE(PFER); SAVE(PKWR); 211 SAVE(PFER); SAVE(PKWR);
225 212
226 SAVE(ICMR); ICMR = 0;
227 SAVE(CKEN); 213 SAVE(CKEN);
228 SAVE(PSTR); 214 SAVE(PSTR);
229
230 /* Clear GPIO transition detect bits */
231 GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; GEDR3 = GEDR3;
232} 215}
233 216
234void pxa27x_cpu_pm_restore(unsigned long *sleep_save) 217void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
@@ -237,15 +220,10 @@ void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
237 PSPR = 0; 220 PSPR = 0;
238 221
239 /* restore registers */ 222 /* restore registers */
240 RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1);
241 RESTORE_GPLEVEL(2); RESTORE_GPLEVEL(3);
242 RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); RESTORE(GPDR3);
243 RESTORE(GAFR0_L); RESTORE(GAFR0_U); 223 RESTORE(GAFR0_L); RESTORE(GAFR0_U);
244 RESTORE(GAFR1_L); RESTORE(GAFR1_U); 224 RESTORE(GAFR1_L); RESTORE(GAFR1_U);
245 RESTORE(GAFR2_L); RESTORE(GAFR2_U); 225 RESTORE(GAFR2_L); RESTORE(GAFR2_U);
246 RESTORE(GAFR3_L); RESTORE(GAFR3_U); 226 RESTORE(GAFR3_L); RESTORE(GAFR3_U);
247 RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); RESTORE(GRER3);
248 RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); RESTORE(GFER3);
249 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3); 227 RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3);
250 228
251 RESTORE(MDREFR); 229 RESTORE(MDREFR);
@@ -256,9 +234,6 @@ void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
256 234
257 RESTORE(CKEN); 235 RESTORE(CKEN);
258 236
259 ICLR = 0;
260 ICCR = 1;
261 RESTORE(ICMR);
262 RESTORE(PSTR); 237 RESTORE(PSTR);
263} 238}
264 239
@@ -409,9 +384,22 @@ static struct platform_device *devices[] __initdata = {
409 &pxa27x_device_ssp3, 384 &pxa27x_device_ssp3,
410}; 385};
411 386
387static struct sys_device pxa27x_sysdev[] = {
388 {
389 .id = 0,
390 .cls = &pxa_irq_sysclass,
391 }, {
392 .id = 1,
393 .cls = &pxa_irq_sysclass,
394 }, {
395 .cls = &pxa_gpio_sysclass,
396 },
397};
398
412static int __init pxa27x_init(void) 399static int __init pxa27x_init(void)
413{ 400{
414 int ret = 0; 401 int i, ret = 0;
402
415 if (cpu_is_pxa27x()) { 403 if (cpu_is_pxa27x()) {
416 clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks)); 404 clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks));
417 405
@@ -420,8 +408,15 @@ static int __init pxa27x_init(void)
420 408
421 pxa27x_init_pm(); 409 pxa27x_init_pm();
422 410
411 for (i = 0; i < ARRAY_SIZE(pxa27x_sysdev); i++) {
412 ret = sysdev_register(&pxa27x_sysdev[i]);
413 if (ret)
414 pr_err("failed to register sysdev[%d]\n", i);
415 }
416
423 ret = platform_add_devices(devices, ARRAY_SIZE(devices)); 417 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
424 } 418 }
419
425 return ret; 420 return ret;
426} 421}
427 422
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 5cbf057a1b32..e47e67c11afe 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -20,6 +20,7 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/irq.h> 21#include <linux/irq.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/sysdev.h>
23 24
24#include <asm/hardware.h> 25#include <asm/hardware.h>
25#include <asm/arch/pxa3xx-regs.h> 26#include <asm/arch/pxa3xx-regs.h>
@@ -39,6 +40,7 @@
39#define RO_CLK 60000000 40#define RO_CLK 60000000
40 41
41#define ACCR_D0CS (1 << 26) 42#define ACCR_D0CS (1 << 26)
43#define ACCR_PCCE (1 << 11)
42 44
43/* crystal frequency to static memory controller multiplier (SMCFS) */ 45/* crystal frequency to static memory controller multiplier (SMCFS) */
44static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, }; 46static unsigned char smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
@@ -203,7 +205,6 @@ static struct clk pxa3xx_clks[] = {
203}; 205};
204 206
205#ifdef CONFIG_PM 207#ifdef CONFIG_PM
206#define SLEEP_SAVE_SIZE 4
207 208
208#define ISRAM_START 0x5c000000 209#define ISRAM_START 0x5c000000
209#define ISRAM_SIZE SZ_256K 210#define ISRAM_SIZE SZ_256K
@@ -211,25 +212,29 @@ static struct clk pxa3xx_clks[] = {
211static void __iomem *sram; 212static void __iomem *sram;
212static unsigned long wakeup_src; 213static unsigned long wakeup_src;
213 214
214static void pxa3xx_cpu_pm_save(unsigned long *sleep_save) 215#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
215{ 216#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
216 pr_debug("PM: CKENA=%08x CKENB=%08x\n", CKENA, CKENB);
217 217
218 if (CKENA & (1 << CKEN_USBH)) { 218enum { SLEEP_SAVE_START = 0,
219 printk(KERN_ERR "PM: USB host clock not stopped?\n"); 219 SLEEP_SAVE_CKENA,
220 CKENA &= ~(1 << CKEN_USBH); 220 SLEEP_SAVE_CKENB,
221 } 221 SLEEP_SAVE_ACCR,
222// CKENA |= 1 << (CKEN_ISC & 31);
223 222
224 /* 223 SLEEP_SAVE_SIZE,
225 * Low power modes require the HSIO2 clock to be enabled. 224};
226 */ 225
227 CKENB |= 1 << (CKEN_HSIO2 & 31); 226static void pxa3xx_cpu_pm_save(unsigned long *sleep_save)
227{
228 SAVE(CKENA);
229 SAVE(CKENB);
230 SAVE(ACCR);
228} 231}
229 232
230static void pxa3xx_cpu_pm_restore(unsigned long *sleep_save) 233static void pxa3xx_cpu_pm_restore(unsigned long *sleep_save)
231{ 234{
232 CKENB &= ~(1 << (CKEN_HSIO2 & 31)); 235 RESTORE(ACCR);
236 RESTORE(CKENA);
237 RESTORE(CKENB);
233} 238}
234 239
235/* 240/*
@@ -265,6 +270,46 @@ static void pxa3xx_cpu_standby(unsigned int pwrmode)
265 printk("PM: AD2D0SR=%08x ASCR=%08x\n", AD2D0SR, ASCR); 270 printk("PM: AD2D0SR=%08x ASCR=%08x\n", AD2D0SR, ASCR);
266} 271}
267 272
273/*
274 * NOTE: currently, the OBM (OEM Boot Module) binary comes along with
275 * PXA3xx development kits assumes that the resuming process continues
276 * with the address stored within the first 4 bytes of SDRAM. The PSPR
277 * register is used privately by BootROM and OBM, and _must_ be set to
278 * 0x5c014000 for the moment.
279 */
280static void pxa3xx_cpu_pm_suspend(void)
281{
282 volatile unsigned long *p = (volatile void *)0xc0000000;
283 unsigned long saved_data = *p;
284
285 extern void pxa3xx_cpu_suspend(void);
286 extern void pxa3xx_cpu_resume(void);
287
288 /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */
289 CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM);
290 CKENB |= 1 << (CKEN_HSIO2 & 0x1f);
291
292 /* clear and setup wakeup source */
293 AD3SR = ~0;
294 AD3ER = wakeup_src;
295 ASCR = ASCR;
296 ARSR = ARSR;
297
298 PCFR |= (1u << 13); /* L1_DIS */
299 PCFR &= ~((1u << 12) | (1u << 1)); /* L0_EN | SL_ROD */
300
301 PSPR = 0x5c014000;
302
303 /* overwrite with the resume address */
304 *p = virt_to_phys(pxa3xx_cpu_resume);
305
306 pxa3xx_cpu_suspend();
307
308 *p = saved_data;
309
310 AD3ER = 0;
311}
312
268static void pxa3xx_cpu_pm_enter(suspend_state_t state) 313static void pxa3xx_cpu_pm_enter(suspend_state_t state)
269{ 314{
270 /* 315 /*
@@ -279,6 +324,7 @@ static void pxa3xx_cpu_pm_enter(suspend_state_t state)
279 break; 324 break;
280 325
281 case PM_SUSPEND_MEM: 326 case PM_SUSPEND_MEM:
327 pxa3xx_cpu_pm_suspend();
282 break; 328 break;
283 } 329 }
284} 330}
@@ -452,9 +498,21 @@ static struct platform_device *devices[] __initdata = {
452 &pxa3xx_device_ssp4, 498 &pxa3xx_device_ssp4,
453}; 499};
454 500
501static struct sys_device pxa3xx_sysdev[] = {
502 {
503 .id = 0,
504 .cls = &pxa_irq_sysclass,
505 }, {
506 .id = 1,
507 .cls = &pxa_irq_sysclass,
508 }, {
509 .cls = &pxa_gpio_sysclass,
510 },
511};
512
455static int __init pxa3xx_init(void) 513static int __init pxa3xx_init(void)
456{ 514{
457 int ret = 0; 515 int i, ret = 0;
458 516
459 if (cpu_is_pxa3xx()) { 517 if (cpu_is_pxa3xx()) {
460 clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks)); 518 clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks));
@@ -464,9 +522,16 @@ static int __init pxa3xx_init(void)
464 522
465 pxa3xx_init_pm(); 523 pxa3xx_init_pm();
466 524
467 return platform_add_devices(devices, ARRAY_SIZE(devices)); 525 for (i = 0; i < ARRAY_SIZE(pxa3xx_sysdev); i++) {
526 ret = sysdev_register(&pxa3xx_sysdev[i]);
527 if (ret)
528 pr_err("failed to register sysdev[%d]\n", i);
529 }
530
531 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
468 } 532 }
469 return 0; 533
534 return ret;
470} 535}
471 536
472subsys_initcall(pxa3xx_init); 537subsys_initcall(pxa3xx_init);
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index 14bb4a93ea52..784716eb7fc5 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -50,6 +50,108 @@ pxa_cpu_save_sp:
50 str r0, [r1] 50 str r0, [r1]
51 ldr pc, [sp], #4 51 ldr pc, [sp], #4
52 52
53#ifdef CONFIG_PXA3xx
54/*
55 * pxa3xx_cpu_suspend() - forces CPU into sleep state (S2D3C4)
56 *
57 * NOTE: unfortunately, pxa_cpu_save_cp can not be reused here since
58 * the auxiliary control register address is different between pxa3xx
59 * and pxa{25x,27x}
60 */
61
62ENTRY(pxa3xx_cpu_suspend)
63
64#ifndef CONFIG_IWMMXT
65 mra r2, r3, acc0
66#endif
67 stmfd sp!, {r2 - r12, lr} @ save registers on stack
68
69 mrc p14, 0, r3, c6, c0, 0 @ clock configuration, for turbo mode
70 mrc p15, 0, r4, c15, c1, 0 @ CP access reg
71 mrc p15, 0, r5, c13, c0, 0 @ PID
72 mrc p15, 0, r6, c3, c0, 0 @ domain ID
73 mrc p15, 0, r7, c2, c0, 0 @ translation table base addr
74 mrc p15, 0, r8, c1, c0, 1 @ auxiliary control reg
75 mrc p15, 0, r9, c1, c0, 0 @ control reg
76
77 bic r3, r3, #2 @ clear frequency change bit
78
79 @ store them plus current virtual stack ptr on stack
80 mov r10, sp
81 stmfd sp!, {r3 - r10}
82
83 @ store physical address of stack pointer
84 mov r0, sp
85 bl sleep_phys_sp
86 ldr r1, =sleep_save_sp
87 str r0, [r1]
88
89 @ clean data cache
90 bl xsc3_flush_kern_cache_all
91
92 mov r0, #0x06 @ S2D3C4 mode
93 mcr p14, 0, r0, c7, c0, 0 @ enter sleep
94
9520: b 20b @ waiting for sleep
96
97 .data
98 .align 5
99/*
100 * pxa3xx_cpu_resume
101 */
102
103ENTRY(pxa3xx_cpu_resume)
104
105 mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
106 msr cpsr_c, r0
107
108 ldr r0, sleep_save_sp @ stack phys addr
109 ldmfd r0, {r3 - r9, sp} @ CP regs + virt stack ptr
110
111 mov r1, #0
112 mcr p15, 0, r1, c7, c7, 0 @ invalidate I & D caches, BTB
113 mcr p15, 0, r1, c7, c10, 4 @ drain write (&fill) buffer
114 mcr p15, 0, r1, c7, c5, 4 @ flush prefetch buffer
115 mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
116
117 mcr p14, 0, r3, c6, c0, 0 @ clock configuration, turbo mode.
118 mcr p15, 0, r4, c15, c1, 0 @ CP access reg
119 mcr p15, 0, r5, c13, c0, 0 @ PID
120 mcr p15, 0, r6, c3, c0, 0 @ domain ID
121 mcr p15, 0, r7, c2, c0, 0 @ translation table base addr
122 mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg
123
124 @ temporarily map resume_turn_on_mmu into the page table,
125 @ otherwise prefetch abort occurs after MMU is turned on
126 mov r1, r7
127 bic r1, r1, #0x00ff
128 bic r1, r1, #0x3f00
129 ldr r2, =0x542e
130
131 adr r3, resume_turn_on_mmu
132 mov r3, r3, lsr #20
133 orr r4, r2, r3, lsl #20
134 ldr r5, [r1, r3, lsl #2]
135 str r4, [r1, r3, lsl #2]
136
137 @ Mapping page table address in the page table
138 mov r6, r1, lsr #20
139 orr r7, r2, r6, lsl #20
140 ldr r8, [r1, r6, lsl #2]
141 str r7, [r1, r6, lsl #2]
142
143 ldr r2, =pxa3xx_resume_after_mmu @ absolute virtual address
144 b resume_turn_on_mmu @ cache align execution
145
146 .text
147pxa3xx_resume_after_mmu:
148 /* restore the temporary mapping */
149 str r5, [r1, r3, lsl #2]
150 str r8, [r1, r6, lsl #2]
151 b resume_after_mmu
152
153#endif /* CONFIG_PXA3xx */
154
53#ifdef CONFIG_PXA27x 155#ifdef CONFIG_PXA27x
54/* 156/*
55 * pxa27x_cpu_suspend() 157 * pxa27x_cpu_suspend()
diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c
new file mode 100644
index 000000000000..ad346addc028
--- /dev/null
+++ b/arch/arm/mach-pxa/smemc.c
@@ -0,0 +1,88 @@
1/*
2 * Static Memory Controller
3 */
4
5#include <linux/module.h>
6#include <linux/kernel.h>
7#include <linux/init.h>
8#include <linux/io.h>
9#include <linux/sysdev.h>
10
11#define SMEMC_PHYS_BASE (0x4A000000)
12#define SMEMC_PHYS_SIZE (0x90)
13
14#define MSC0 (0x08) /* Static Memory Controller Register 0 */
15#define MSC1 (0x0C) /* Static Memory Controller Register 1 */
16#define SXCNFG (0x1C) /* Synchronous Static Memory Control Register */
17#define MEMCLKCFG (0x68) /* Clock Configuration */
18#define CSADRCFG0 (0x80) /* Address Configuration Register for CS0 */
19#define CSADRCFG1 (0x84) /* Address Configuration Register for CS1 */
20#define CSADRCFG2 (0x88) /* Address Configuration Register for CS2 */
21#define CSADRCFG3 (0x8C) /* Address Configuration Register for CS3 */
22
23#ifdef CONFIG_PM
24static void __iomem *smemc_mmio_base;
25
26static unsigned long msc[2];
27static unsigned long sxcnfg, memclkcfg;
28static unsigned long csadrcfg[4];
29
30static int pxa3xx_smemc_suspend(struct sys_device *dev, pm_message_t state)
31{
32 msc[0] = __raw_readl(smemc_mmio_base + MSC0);
33 msc[1] = __raw_readl(smemc_mmio_base + MSC1);
34 sxcnfg = __raw_readl(smemc_mmio_base + SXCNFG);
35 memclkcfg = __raw_readl(smemc_mmio_base + MEMCLKCFG);
36 csadrcfg[0] = __raw_readl(smemc_mmio_base + CSADRCFG0);
37 csadrcfg[1] = __raw_readl(smemc_mmio_base + CSADRCFG1);
38 csadrcfg[2] = __raw_readl(smemc_mmio_base + CSADRCFG2);
39 csadrcfg[3] = __raw_readl(smemc_mmio_base + CSADRCFG3);
40
41 return 0;
42}
43
44static int pxa3xx_smemc_resume(struct sys_device *dev)
45{
46 __raw_writel(msc[0], smemc_mmio_base + MSC0);
47 __raw_writel(msc[1], smemc_mmio_base + MSC1);
48 __raw_writel(sxcnfg, smemc_mmio_base + SXCNFG);
49 __raw_writel(memclkcfg, smemc_mmio_base + MEMCLKCFG);
50 __raw_writel(csadrcfg[0], smemc_mmio_base + CSADRCFG0);
51 __raw_writel(csadrcfg[1], smemc_mmio_base + CSADRCFG1);
52 __raw_writel(csadrcfg[2], smemc_mmio_base + CSADRCFG2);
53 __raw_writel(csadrcfg[3], smemc_mmio_base + CSADRCFG3);
54
55 return 0;
56}
57
58static struct sysdev_class smemc_sysclass = {
59 .name = "smemc",
60 .suspend = pxa3xx_smemc_suspend,
61 .resume = pxa3xx_smemc_resume,
62};
63
64static struct sys_device smemc_sysdev = {
65 .id = 0,
66 .cls = &smemc_sysclass,
67};
68
69static int __init smemc_init(void)
70{
71 int ret = 0;
72
73 if (cpu_is_pxa3xx()) {
74 smemc_mmio_base = ioremap(SMEMC_PHYS_BASE, SMEMC_PHYS_SIZE);
75 if (smemc_mmio_base == NULL)
76 return -ENODEV;
77
78 ret = sysdev_class_register(&smemc_sysclass);
79 if (ret)
80 return ret;
81
82 ret = sysdev_register(&smemc_sysdev);
83 }
84
85 return ret;
86}
87subsys_initcall(smemc_init);
88#endif
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 5078edeadf96..9e7773fca01c 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -36,6 +36,7 @@
36#include <asm/mach/irq.h> 36#include <asm/mach/irq.h>
37 37
38#include <asm/arch/pxa-regs.h> 38#include <asm/arch/pxa-regs.h>
39#include <asm/arch/pxa2xx-regs.h>
39#include <asm/arch/irda.h> 40#include <asm/arch/irda.h>
40#include <asm/arch/mmc.h> 41#include <asm/arch/mmc.h>
41#include <asm/arch/ohci.h> 42#include <asm/arch/ohci.h>
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 1a9c844ac7eb..9b26fa5edad6 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -29,6 +29,7 @@
29#include <asm/irq.h> 29#include <asm/irq.h>
30#include <asm/system.h> 30#include <asm/system.h>
31#include <asm/arch/pxa-regs.h> 31#include <asm/arch/pxa-regs.h>
32#include <asm/arch/pxa2xx-regs.h>
32#include <asm/arch/irda.h> 33#include <asm/arch/irda.h>
33#include <asm/arch/mmc.h> 34#include <asm/arch/mmc.h>
34#include <asm/arch/udc.h> 35#include <asm/arch/udc.h>
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index 35156ca39df7..39b3bb7f1020 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -7,24 +7,21 @@ config MACH_REALVIEW_EB
7 help 7 help
8 Include support for the ARM(R) RealView Emulation Baseboard platform. 8 Include support for the ARM(R) RealView Emulation Baseboard platform.
9 9
10config REALVIEW_MPCORE 10config REALVIEW_EB_ARM11MP
11 bool "Support MPcore tile" 11 bool "Support ARM11MPCore tile"
12 depends on MACH_REALVIEW_EB 12 depends on MACH_REALVIEW_EB
13 select CACHE_L2X0 13 select CACHE_L2X0
14 help 14 help
15 Enable support for the MPCore tile on the Realview platform. 15 Enable support for the ARM11MPCore tile on the Realview platform.
16 Since there are device address and interrupt differences, a
17 kernel built with this option enabled is not compatible with
18 other tiles.
19 16
20config REALVIEW_MPCORE_REVB 17config REALVIEW_EB_ARM11MP_REVB
21 bool "Support MPcore RevB tile" 18 bool "Support ARM11MPCore RevB tile"
22 depends on REALVIEW_MPCORE 19 depends on REALVIEW_EB_ARM11MP
23 default n 20 default n
24 help 21 help
25 Enable support for the MPCore RevB tile on the Realview platform. 22 Enable support for the ARM11MPCore RevB tile on the Realview
26 Since there are device address differences, a 23 platform. Since there are device address differences, a
27 kernel built with this option enabled is not compatible with 24 kernel built with this option enabled is not compatible with
28 other tiles. 25 other revisions of the ARM11MPCore tile.
29 26
30endmenu 27endmenu
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
index 36e76ba937fc..ca1e390c3c28 100644
--- a/arch/arm/mach-realview/Makefile
+++ b/arch/arm/mach-realview/Makefile
@@ -4,6 +4,5 @@
4 4
5obj-y := core.o clock.o 5obj-y := core.o clock.o
6obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o 6obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o
7obj-$(CONFIG_SMP) += platsmp.o headsmp.o 7obj-$(CONFIG_SMP) += platsmp.o headsmp.o localtimer.o
8obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 8obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
9obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 61d70218f1e8..98aefc9f4df3 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -25,6 +25,8 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/amba/bus.h> 26#include <linux/amba/bus.h>
27#include <linux/amba/clcd.h> 27#include <linux/amba/clcd.h>
28#include <linux/clocksource.h>
29#include <linux/clockchips.h>
28 30
29#include <asm/system.h> 31#include <asm/system.h>
30#include <asm/hardware.h> 32#include <asm/hardware.h>
@@ -37,7 +39,6 @@
37#include <asm/mach/arch.h> 39#include <asm/mach/arch.h>
38#include <asm/mach/flash.h> 40#include <asm/mach/flash.h>
39#include <asm/mach/irq.h> 41#include <asm/mach/irq.h>
40#include <asm/mach/time.h>
41#include <asm/mach/map.h> 42#include <asm/mach/map.h>
42#include <asm/mach/mmc.h> 43#include <asm/mach/mmc.h>
43 44
@@ -48,6 +49,9 @@
48 49
49#define REALVIEW_REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET) 50#define REALVIEW_REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
50 51
52/* used by entry-macro.S */
53void __iomem *gic_cpu_base_addr;
54
51/* 55/*
52 * This is the RealView sched_clock implementation. This has 56 * This is the RealView sched_clock implementation. This has
53 * a resolution of 41.7ns, and a maximum value of about 179s. 57 * a resolution of 41.7ns, and a maximum value of about 179s.
@@ -121,26 +125,6 @@ struct platform_device realview_flash_device = {
121 .resource = &realview_flash_resource, 125 .resource = &realview_flash_resource,
122}; 126};
123 127
124static struct resource realview_smc91x_resources[] = {
125 [0] = {
126 .start = REALVIEW_ETH_BASE,
127 .end = REALVIEW_ETH_BASE + SZ_64K - 1,
128 .flags = IORESOURCE_MEM,
129 },
130 [1] = {
131 .start = IRQ_ETH,
132 .end = IRQ_ETH,
133 .flags = IORESOURCE_IRQ,
134 },
135};
136
137struct platform_device realview_smc91x_device = {
138 .name = "smc91x",
139 .id = 0,
140 .num_resources = ARRAY_SIZE(realview_smc91x_resources),
141 .resource = realview_smc91x_resources,
142};
143
144static struct resource realview_i2c_resource = { 128static struct resource realview_i2c_resource = {
145 .start = REALVIEW_I2C_BASE, 129 .start = REALVIEW_I2C_BASE,
146 .end = REALVIEW_I2C_BASE + SZ_4K - 1, 130 .end = REALVIEW_I2C_BASE + SZ_4K - 1,
@@ -484,45 +468,64 @@ void realview_leds_event(led_event_t ledevt)
484#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) 468#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
485#endif 469#endif
486 470
487/* 471static void timer_set_mode(enum clock_event_mode mode,
488 * Returns number of ms since last clock interrupt. Note that interrupts 472 struct clock_event_device *clk)
489 * will have been disabled by do_gettimeoffset()
490 */
491static unsigned long realview_gettimeoffset(void)
492{ 473{
493 unsigned long ticks1, ticks2, status; 474 unsigned long ctrl;
494 475
495 /* 476 switch(mode) {
496 * Get the current number of ticks. Note that there is a race 477 case CLOCK_EVT_MODE_PERIODIC:
497 * condition between us reading the timer and checking for 478 writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
498 * an interrupt. We get around this by ensuring that the
499 * counter has not reloaded between our two reads.
500 */
501 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
502 do {
503 ticks1 = ticks2;
504 status = __raw_readl(__io_address(REALVIEW_GIC_DIST_BASE + GIC_DIST_PENDING_SET)
505 + ((IRQ_TIMERINT0_1 >> 5) << 2));
506 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
507 } while (ticks2 > ticks1);
508 479
509 /* 480 ctrl = TIMER_CTRL_PERIODIC;
510 * Number of ticks since last interrupt. 481 ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE;
511 */ 482 break;
512 ticks1 = TIMER_RELOAD - ticks2; 483 case CLOCK_EVT_MODE_ONESHOT:
484 /* period set, and timer enabled in 'next_event' hook */
485 ctrl = TIMER_CTRL_ONESHOT;
486 ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE;
487 break;
488 case CLOCK_EVT_MODE_UNUSED:
489 case CLOCK_EVT_MODE_SHUTDOWN:
490 default:
491 ctrl = 0;
492 }
513 493
514 /* 494 writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL);
515 * Interrupt pending? If so, we've reloaded once already. 495}
516 *
517 * FIXME: Need to check this is effectively timer 0 that expires
518 */
519 if (status & IRQMASK_TIMERINT0_1)
520 ticks1 += TIMER_RELOAD;
521 496
522 /* 497static int timer_set_next_event(unsigned long evt,
523 * Convert the ticks to usecs 498 struct clock_event_device *unused)
524 */ 499{
525 return TICKS2USECS(ticks1); 500 unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL);
501
502 writel(evt, TIMER0_VA_BASE + TIMER_LOAD);
503 writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL);
504
505 return 0;
506}
507
508static struct clock_event_device timer0_clockevent = {
509 .name = "timer0",
510 .shift = 32,
511 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
512 .set_mode = timer_set_mode,
513 .set_next_event = timer_set_next_event,
514 .rating = 300,
515 .cpumask = CPU_MASK_ALL,
516};
517
518static void __init realview_clockevents_init(unsigned int timer_irq)
519{
520 timer0_clockevent.irq = timer_irq;
521 timer0_clockevent.mult =
522 div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
523 timer0_clockevent.max_delta_ns =
524 clockevent_delta2ns(0xffffffff, &timer0_clockevent);
525 timer0_clockevent.min_delta_ns =
526 clockevent_delta2ns(0xf, &timer0_clockevent);
527
528 clockevents_register_device(&timer0_clockevent);
526} 529}
527 530
528/* 531/*
@@ -530,15 +533,12 @@ static unsigned long realview_gettimeoffset(void)
530 */ 533 */
531static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) 534static irqreturn_t realview_timer_interrupt(int irq, void *dev_id)
532{ 535{
533 // ...clear the interrupt 536 struct clock_event_device *evt = &timer0_clockevent;
537
538 /* clear the interrupt */
534 writel(1, TIMER0_VA_BASE + TIMER_INTCLR); 539 writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
535 540
536 timer_tick(); 541 evt->event_handler(evt);
537
538#if defined(CONFIG_SMP) && !defined(CONFIG_LOCAL_TIMERS)
539 smp_send_timer();
540 update_process_times(user_mode(get_irq_regs()));
541#endif
542 542
543 return IRQ_HANDLED; 543 return IRQ_HANDLED;
544} 544}
@@ -549,13 +549,49 @@ static struct irqaction realview_timer_irq = {
549 .handler = realview_timer_interrupt, 549 .handler = realview_timer_interrupt,
550}; 550};
551 551
552static cycle_t realview_get_cycles(void)
553{
554 return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
555}
556
557static struct clocksource clocksource_realview = {
558 .name = "timer3",
559 .rating = 200,
560 .read = realview_get_cycles,
561 .mask = CLOCKSOURCE_MASK(32),
562 .shift = 20,
563 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
564};
565
566static void __init realview_clocksource_init(void)
567{
568 /* setup timer 0 as free-running clocksource */
569 writel(0, TIMER3_VA_BASE + TIMER_CTRL);
570 writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD);
571 writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE);
572 writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
573 TIMER3_VA_BASE + TIMER_CTRL);
574
575 clocksource_realview.mult =
576 clocksource_khz2mult(1000, clocksource_realview.shift);
577 clocksource_register(&clocksource_realview);
578}
579
552/* 580/*
553 * Set up timer interrupt, and return the current time in seconds. 581 * Set up the clock source and clock events devices
554 */ 582 */
555static void __init realview_timer_init(void) 583void __init realview_timer_init(unsigned int timer_irq)
556{ 584{
557 u32 val; 585 u32 val;
558 586
587#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
588 /*
589 * The dummy clock device has to be registered before the main device
590 * so that the latter will broadcast the clock events
591 */
592 local_timer_setup(smp_processor_id());
593#endif
594
559 /* 595 /*
560 * set clock frequency: 596 * set clock frequency:
561 * REALVIEW_REFCLK is 32KHz 597 * REALVIEW_REFCLK is 32KHz
@@ -576,18 +612,11 @@ static void __init realview_timer_init(void)
576 writel(0, TIMER2_VA_BASE + TIMER_CTRL); 612 writel(0, TIMER2_VA_BASE + TIMER_CTRL);
577 writel(0, TIMER3_VA_BASE + TIMER_CTRL); 613 writel(0, TIMER3_VA_BASE + TIMER_CTRL);
578 614
579 writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
580 writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE);
581 writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC |
582 TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL);
583
584 /* 615 /*
585 * Make irqs happen for the system timer 616 * Make irqs happen for the system timer
586 */ 617 */
587 setup_irq(IRQ_TIMERINT0_1, &realview_timer_irq); 618 setup_irq(timer_irq, &realview_timer_irq);
588}
589 619
590struct sys_timer realview_timer = { 620 realview_clocksource_init();
591 .init = realview_timer_init, 621 realview_clockevents_init(timer_irq);
592 .offset = realview_gettimeoffset, 622}
593};
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index 2b53420f9c1b..492a14c0d604 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -27,8 +27,6 @@
27#include <asm/leds.h> 27#include <asm/leds.h>
28#include <asm/io.h> 28#include <asm/io.h>
29 29
30extern struct sys_timer realview_timer;
31
32#define AMBA_DEVICE(name,busid,base,plat) \ 30#define AMBA_DEVICE(name,busid,base,plat) \
33static struct amba_device name##_device = { \ 31static struct amba_device name##_device = { \
34 .dev = { \ 32 .dev = { \
@@ -38,7 +36,7 @@ static struct amba_device name##_device = { \
38 }, \ 36 }, \
39 .res = { \ 37 .res = { \
40 .start = REALVIEW_##base##_BASE, \ 38 .start = REALVIEW_##base##_BASE, \
41 .end = (REALVIEW_##base##_BASE) + SZ_4K - 1,\ 39 .end = (REALVIEW_##base##_BASE) + SZ_4K - 1, \
42 .flags = IORESOURCE_MEM, \ 40 .flags = IORESOURCE_MEM, \
43 }, \ 41 }, \
44 .dma_mask = ~0, \ 42 .dma_mask = ~0, \
@@ -46,74 +44,19 @@ static struct amba_device name##_device = { \
46 /* .dma = base##_DMA,*/ \ 44 /* .dma = base##_DMA,*/ \
47} 45}
48 46
49/*
50 * These devices are connected via the core APB bridge
51 */
52#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ }
53#define GPIO2_DMA { 0, 0 }
54#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ }
55#define GPIO3_DMA { 0, 0 }
56
57#define AACI_IRQ { IRQ_AACI, NO_IRQ }
58#define AACI_DMA { 0x80, 0x81 }
59#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_MMCI0B }
60#define MMCI0_DMA { 0x84, 0 }
61#define KMI0_IRQ { IRQ_KMI0, NO_IRQ }
62#define KMI0_DMA { 0, 0 }
63#define KMI1_IRQ { IRQ_KMI1, NO_IRQ }
64#define KMI1_DMA { 0, 0 }
65
66/*
67 * These devices are connected directly to the multi-layer AHB switch
68 */
69#define SMC_IRQ { NO_IRQ, NO_IRQ }
70#define SMC_DMA { 0, 0 }
71#define MPMC_IRQ { NO_IRQ, NO_IRQ }
72#define MPMC_DMA { 0, 0 }
73#define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ }
74#define CLCD_DMA { 0, 0 }
75#define DMAC_IRQ { IRQ_DMAINT, NO_IRQ }
76#define DMAC_DMA { 0, 0 }
77
78/*
79 * These devices are connected via the core APB bridge
80 */
81#define SCTL_IRQ { NO_IRQ, NO_IRQ }
82#define SCTL_DMA { 0, 0 }
83#define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ }
84#define WATCHDOG_DMA { 0, 0 }
85#define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ }
86#define GPIO0_DMA { 0, 0 }
87#define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ }
88#define GPIO1_DMA { 0, 0 }
89#define RTC_IRQ { IRQ_RTCINT, NO_IRQ }
90#define RTC_DMA { 0, 0 }
91
92/*
93 * These devices are connected via the DMA APB bridge
94 */
95#define SCI_IRQ { IRQ_SCIINT, NO_IRQ }
96#define SCI_DMA { 7, 6 }
97#define UART0_IRQ { IRQ_UARTINT0, NO_IRQ }
98#define UART0_DMA { 15, 14 }
99#define UART1_IRQ { IRQ_UARTINT1, NO_IRQ }
100#define UART1_DMA { 13, 12 }
101#define UART2_IRQ { IRQ_UARTINT2, NO_IRQ }
102#define UART2_DMA { 11, 10 }
103#define UART3_IRQ { IRQ_UART3, NO_IRQ }
104#define UART3_DMA { 0x86, 0x87 }
105#define SSP_IRQ { IRQ_SSPINT, NO_IRQ }
106#define SSP_DMA { 9, 8 }
107
108
109extern struct platform_device realview_flash_device; 47extern struct platform_device realview_flash_device;
110extern struct platform_device realview_smc91x_device;
111extern struct platform_device realview_i2c_device; 48extern struct platform_device realview_i2c_device;
112extern struct mmc_platform_data realview_mmc0_plat_data; 49extern struct mmc_platform_data realview_mmc0_plat_data;
113extern struct mmc_platform_data realview_mmc1_plat_data; 50extern struct mmc_platform_data realview_mmc1_plat_data;
114extern struct clk realview_clcd_clk; 51extern struct clk realview_clcd_clk;
115extern struct clcd_board clcd_plat_data; 52extern struct clcd_board clcd_plat_data;
53extern void __iomem *gic_cpu_base_addr;
54#ifdef CONFIG_LOCAL_TIMERS
55extern void __iomem *twd_base_addr;
56extern unsigned int twd_size;
57#endif
116 58
117extern void realview_leds_event(led_event_t ledevt); 59extern void realview_leds_event(led_event_t ledevt);
60extern void realview_timer_init(unsigned int timer_irq);
118 61
119#endif 62#endif
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c
index c7bdf04ab094..50604360479f 100644
--- a/arch/arm/mach-realview/localtimer.c
+++ b/arch/arm/mach-realview/localtimer.c
@@ -14,19 +14,75 @@
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/smp.h> 15#include <linux/smp.h>
16#include <linux/jiffies.h> 16#include <linux/jiffies.h>
17#include <linux/percpu.h>
18#include <linux/clockchips.h>
19#include <linux/irq.h>
17 20
18#include <asm/mach/time.h>
19#include <asm/hardware/arm_twd.h> 21#include <asm/hardware/arm_twd.h>
20#include <asm/hardware/gic.h> 22#include <asm/hardware/gic.h>
21#include <asm/hardware.h> 23#include <asm/hardware.h>
22#include <asm/io.h> 24#include <asm/io.h>
23#include <asm/irq.h> 25#include <asm/irq.h>
24 26
25#define TWD_BASE(cpu) (__io_address(REALVIEW_TWD_BASE) + \ 27static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
26 ((cpu) * REALVIEW_TWD_SIZE)) 28
29/*
30 * Used on SMP for either the local timer or IPI_TIMER
31 */
32void local_timer_interrupt(void)
33{
34 struct clock_event_device *clk = &__get_cpu_var(local_clockevent);
35
36 clk->event_handler(clk);
37}
38
39#ifdef CONFIG_LOCAL_TIMERS
40
41#define TWD_BASE(cpu) (twd_base_addr + (cpu) * twd_size)
42
43/* set up by the platform code */
44void __iomem *twd_base_addr;
45unsigned int twd_size;
27 46
28static unsigned long mpcore_timer_rate; 47static unsigned long mpcore_timer_rate;
29 48
49static void local_timer_set_mode(enum clock_event_mode mode,
50 struct clock_event_device *clk)
51{
52 void __iomem *base = TWD_BASE(smp_processor_id());
53 unsigned long ctrl;
54
55 switch(mode) {
56 case CLOCK_EVT_MODE_PERIODIC:
57 /* timer load already set up */
58 ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE
59 | TWD_TIMER_CONTROL_PERIODIC;
60 break;
61 case CLOCK_EVT_MODE_ONESHOT:
62 /* period set, and timer enabled in 'next_event' hook */
63 ctrl = TWD_TIMER_CONTROL_IT_ENABLE | TWD_TIMER_CONTROL_ONESHOT;
64 break;
65 case CLOCK_EVT_MODE_UNUSED:
66 case CLOCK_EVT_MODE_SHUTDOWN:
67 default:
68 ctrl = 0;
69 }
70
71 __raw_writel(ctrl, base + TWD_TIMER_CONTROL);
72}
73
74static int local_timer_set_next_event(unsigned long evt,
75 struct clock_event_device *unused)
76{
77 void __iomem *base = TWD_BASE(smp_processor_id());
78 unsigned long ctrl = __raw_readl(base + TWD_TIMER_CONTROL);
79
80 __raw_writel(evt, base + TWD_TIMER_COUNTER);
81 __raw_writel(ctrl | TWD_TIMER_CONTROL_ENABLE, base + TWD_TIMER_CONTROL);
82
83 return 0;
84}
85
30/* 86/*
31 * local_timer_ack: checks for a local timer interrupt. 87 * local_timer_ack: checks for a local timer interrupt.
32 * 88 *
@@ -45,12 +101,11 @@ int local_timer_ack(void)
45 return 0; 101 return 0;
46} 102}
47 103
48void __cpuinit local_timer_setup(unsigned int cpu) 104static void __cpuinit twd_calibrate_rate(unsigned int cpu)
49{ 105{
50 void __iomem *base = TWD_BASE(cpu); 106 void __iomem *base = TWD_BASE(cpu);
51 unsigned int load, offset; 107 unsigned long load, count;
52 u64 waitjiffies; 108 u64 waitjiffies;
53 unsigned int count;
54 109
55 /* 110 /*
56 * If this is the first time round, we need to work out how fast 111 * If this is the first time round, we need to work out how fast
@@ -88,36 +143,36 @@ void __cpuinit local_timer_setup(unsigned int cpu)
88 load = mpcore_timer_rate / HZ; 143 load = mpcore_timer_rate / HZ;
89 144
90 __raw_writel(load, base + TWD_TIMER_LOAD); 145 __raw_writel(load, base + TWD_TIMER_LOAD);
91 __raw_writel(0x7, base + TWD_TIMER_CONTROL); 146}
92
93 /*
94 * Now maneuver our local tick into the right part of the jiffy.
95 * Start by working out where within the tick our local timer
96 * interrupt should go.
97 */
98 offset = ((mpcore_timer_rate / HZ) / (NR_CPUS + 1)) * (cpu + 1);
99
100 /*
101 * gettimeoffset() will return a number of us since the last tick.
102 * Convert this number of us to a local timer tick count.
103 * Be careful of integer overflow whilst keeping maximum precision.
104 *
105 * with HZ=100 and 1MHz (fpga) ~ 1GHz processor:
106 * load = 1 ~ 10,000
107 * mpcore_timer_rate/10000 = 100 ~ 100,000
108 *
109 * so the multiply value will be less than 10^9 always.
110 */
111 load = (system_timer->offset() * (mpcore_timer_rate / 10000)) / 100;
112
113 /* Add on our offset to get the load value */
114 load = (load + offset) % (mpcore_timer_rate / HZ);
115 147
116 __raw_writel(load, base + TWD_TIMER_COUNTER); 148/*
149 * Setup the local clock events for a CPU.
150 */
151void __cpuinit local_timer_setup(unsigned int cpu)
152{
153 struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
154 unsigned long flags;
155
156 twd_calibrate_rate(cpu);
157
158 clk->name = "local_timer";
159 clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
160 clk->rating = 350;
161 clk->set_mode = local_timer_set_mode;
162 clk->set_next_event = local_timer_set_next_event;
163 clk->irq = IRQ_LOCALTIMER;
164 clk->cpumask = cpumask_of_cpu(cpu);
165 clk->shift = 20;
166 clk->mult = div_sc(mpcore_timer_rate, NSEC_PER_SEC, clk->shift);
167 clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
168 clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
117 169
118 /* Make sure our local interrupt controller has this enabled */ 170 /* Make sure our local interrupt controller has this enabled */
119 __raw_writel(1 << IRQ_LOCALTIMER, 171 local_irq_save(flags);
120 __io_address(REALVIEW_GIC_DIST_BASE) + GIC_DIST_ENABLE_SET); 172 get_irq_chip(IRQ_LOCALTIMER)->unmask(IRQ_LOCALTIMER);
173 local_irq_restore(flags);
174
175 clockevents_register_device(clk);
121} 176}
122 177
123/* 178/*
@@ -127,3 +182,26 @@ void __cpuexit local_timer_stop(unsigned int cpu)
127{ 182{
128 __raw_writel(0, TWD_BASE(cpu) + TWD_TIMER_CONTROL); 183 __raw_writel(0, TWD_BASE(cpu) + TWD_TIMER_CONTROL);
129} 184}
185
186#else /* CONFIG_LOCAL_TIMERS */
187
188static void dummy_timer_set_mode(enum clock_event_mode mode,
189 struct clock_event_device *clk)
190{
191}
192
193void __cpuinit local_timer_setup(unsigned int cpu)
194{
195 struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
196
197 clk->name = "dummy_timer";
198 clk->features = CLOCK_EVT_FEAT_DUMMY;
199 clk->rating = 200;
200 clk->set_mode = dummy_timer_set_mode;
201 clk->broadcast = smp_timer_broadcast;
202 clk->cpumask = cpumask_of_cpu(cpu);
203
204 clockevents_register_device(clk);
205}
206
207#endif /* !CONFIG_LOCAL_TIMERS */
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index fce3596f9950..de2b7159557d 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -18,6 +18,7 @@
18#include <asm/hardware/arm_scu.h> 18#include <asm/hardware/arm_scu.h>
19#include <asm/hardware.h> 19#include <asm/hardware.h>
20#include <asm/io.h> 20#include <asm/io.h>
21#include <asm/mach-types.h>
21 22
22extern void realview_secondary_startup(void); 23extern void realview_secondary_startup(void);
23 24
@@ -31,9 +32,13 @@ static unsigned int __init get_core_count(void)
31{ 32{
32 unsigned int ncores; 33 unsigned int ncores;
33 34
34 ncores = __raw_readl(__io_address(REALVIEW_MPCORE_SCU_BASE) + SCU_CONFIG); 35 if (machine_is_realview_eb() && core_tile_eb11mp()) {
36 ncores = __raw_readl(__io_address(REALVIEW_EB11MP_SCU_BASE) + SCU_CONFIG);
37 ncores = (ncores & 0x03) + 1;
38 } else
39 ncores = 1;
35 40
36 return (ncores & 0x03) + 1; 41 return ncores;
37} 42}
38 43
39static DEFINE_SPINLOCK(boot_lock); 44static DEFINE_SPINLOCK(boot_lock);
@@ -52,7 +57,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
52 * core (e.g. timer irq), then they will not have been enabled 57 * core (e.g. timer irq), then they will not have been enabled
53 * for us: do so 58 * for us: do so
54 */ 59 */
55 gic_cpu_init(0, __io_address(REALVIEW_GIC_CPU_BASE)); 60 gic_cpu_init(0, __io_address(REALVIEW_EB11MP_GIC_CPU_BASE));
56 61
57 /* 62 /*
58 * let the primary processor know we're out of the 63 * let the primary processor know we're out of the
@@ -187,10 +192,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
187 if (max_cpus > ncores) 192 if (max_cpus > ncores)
188 max_cpus = ncores; 193 max_cpus = ncores;
189 194
195#ifdef CONFIG_LOCAL_TIMERS
190 /* 196 /*
191 * Enable the local timer for primary CPU 197 * Enable the local timer for primary CPU. If the device is
198 * dummy (!CONFIG_LOCAL_TIMERS), it was already registers in
199 * realview_timer_init
192 */ 200 */
193 local_timer_setup(cpu); 201 if (machine_is_realview_eb() && core_tile_eb11mp())
202 local_timer_setup(cpu);
203#endif
194 204
195 /* 205 /*
196 * Initialise the present map, which describes the set of CPUs 206 * Initialise the present map, which describes the set of CPUs
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index ecec2f85c4cd..60d9eb810246 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -36,7 +36,9 @@
36#include <asm/mach/arch.h> 36#include <asm/mach/arch.h>
37#include <asm/mach/map.h> 37#include <asm/mach/map.h>
38#include <asm/mach/mmc.h> 38#include <asm/mach/mmc.h>
39#include <asm/mach/time.h>
39 40
41#include <asm/arch/board-eb.h>
40#include <asm/arch/irqs.h> 42#include <asm/arch/irqs.h>
41 43
42#include "core.h" 44#include "core.h"
@@ -58,26 +60,7 @@ static struct map_desc realview_eb_io_desc[] __initdata = {
58 .pfn = __phys_to_pfn(REALVIEW_GIC_DIST_BASE), 60 .pfn = __phys_to_pfn(REALVIEW_GIC_DIST_BASE),
59 .length = SZ_4K, 61 .length = SZ_4K,
60 .type = MT_DEVICE, 62 .type = MT_DEVICE,
61 },
62#ifdef CONFIG_REALVIEW_MPCORE
63 {
64 .virtual = IO_ADDRESS(REALVIEW_GIC1_CPU_BASE),
65 .pfn = __phys_to_pfn(REALVIEW_GIC1_CPU_BASE),
66 .length = SZ_4K,
67 .type = MT_DEVICE,
68 }, { 63 }, {
69 .virtual = IO_ADDRESS(REALVIEW_GIC1_DIST_BASE),
70 .pfn = __phys_to_pfn(REALVIEW_GIC1_DIST_BASE),
71 .length = SZ_4K,
72 .type = MT_DEVICE,
73 }, {
74 .virtual = IO_ADDRESS(REALVIEW_MPCORE_L220_BASE),
75 .pfn = __phys_to_pfn(REALVIEW_MPCORE_L220_BASE),
76 .length = SZ_8K,
77 .type = MT_DEVICE,
78 },
79#endif
80 {
81 .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE), 64 .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE),
82 .pfn = __phys_to_pfn(REALVIEW_SCTL_BASE), 65 .pfn = __phys_to_pfn(REALVIEW_SCTL_BASE),
83 .length = SZ_4K, 66 .length = SZ_4K,
@@ -103,11 +86,95 @@ static struct map_desc realview_eb_io_desc[] __initdata = {
103#endif 86#endif
104}; 87};
105 88
89static struct map_desc realview_eb11mp_io_desc[] __initdata = {
90 {
91 .virtual = IO_ADDRESS(REALVIEW_EB11MP_GIC_CPU_BASE),
92 .pfn = __phys_to_pfn(REALVIEW_EB11MP_GIC_CPU_BASE),
93 .length = SZ_4K,
94 .type = MT_DEVICE,
95 }, {
96 .virtual = IO_ADDRESS(REALVIEW_EB11MP_GIC_DIST_BASE),
97 .pfn = __phys_to_pfn(REALVIEW_EB11MP_GIC_DIST_BASE),
98 .length = SZ_4K,
99 .type = MT_DEVICE,
100 }, {
101 .virtual = IO_ADDRESS(REALVIEW_EB11MP_L220_BASE),
102 .pfn = __phys_to_pfn(REALVIEW_EB11MP_L220_BASE),
103 .length = SZ_8K,
104 .type = MT_DEVICE,
105 }
106};
107
106static void __init realview_eb_map_io(void) 108static void __init realview_eb_map_io(void)
107{ 109{
108 iotable_init(realview_eb_io_desc, ARRAY_SIZE(realview_eb_io_desc)); 110 iotable_init(realview_eb_io_desc, ARRAY_SIZE(realview_eb_io_desc));
111 if (core_tile_eb11mp())
112 iotable_init(realview_eb11mp_io_desc, ARRAY_SIZE(realview_eb11mp_io_desc));
109} 113}
110 114
115/*
116 * RealView EB AMBA devices
117 */
118
119/*
120 * These devices are connected via the core APB bridge
121 */
122#define GPIO2_IRQ { IRQ_EB_GPIO2, NO_IRQ }
123#define GPIO2_DMA { 0, 0 }
124#define GPIO3_IRQ { IRQ_EB_GPIO3, NO_IRQ }
125#define GPIO3_DMA { 0, 0 }
126
127#define AACI_IRQ { IRQ_EB_AACI, NO_IRQ }
128#define AACI_DMA { 0x80, 0x81 }
129#define MMCI0_IRQ { IRQ_EB_MMCI0A, IRQ_EB_MMCI0B }
130#define MMCI0_DMA { 0x84, 0 }
131#define KMI0_IRQ { IRQ_EB_KMI0, NO_IRQ }
132#define KMI0_DMA { 0, 0 }
133#define KMI1_IRQ { IRQ_EB_KMI1, NO_IRQ }
134#define KMI1_DMA { 0, 0 }
135
136/*
137 * These devices are connected directly to the multi-layer AHB switch
138 */
139#define SMC_IRQ { NO_IRQ, NO_IRQ }
140#define SMC_DMA { 0, 0 }
141#define MPMC_IRQ { NO_IRQ, NO_IRQ }
142#define MPMC_DMA { 0, 0 }
143#define CLCD_IRQ { IRQ_EB_CLCD, NO_IRQ }
144#define CLCD_DMA { 0, 0 }
145#define DMAC_IRQ { IRQ_EB_DMA, NO_IRQ }
146#define DMAC_DMA { 0, 0 }
147
148/*
149 * These devices are connected via the core APB bridge
150 */
151#define SCTL_IRQ { NO_IRQ, NO_IRQ }
152#define SCTL_DMA { 0, 0 }
153#define WATCHDOG_IRQ { IRQ_EB_WDOG, NO_IRQ }
154#define WATCHDOG_DMA { 0, 0 }
155#define GPIO0_IRQ { IRQ_EB_GPIO0, NO_IRQ }
156#define GPIO0_DMA { 0, 0 }
157#define GPIO1_IRQ { IRQ_EB_GPIO1, NO_IRQ }
158#define GPIO1_DMA { 0, 0 }
159#define RTC_IRQ { IRQ_EB_RTC, NO_IRQ }
160#define RTC_DMA { 0, 0 }
161
162/*
163 * These devices are connected via the DMA APB bridge
164 */
165#define SCI_IRQ { IRQ_EB_SCI, NO_IRQ }
166#define SCI_DMA { 7, 6 }
167#define UART0_IRQ { IRQ_EB_UART0, NO_IRQ }
168#define UART0_DMA { 15, 14 }
169#define UART1_IRQ { IRQ_EB_UART1, NO_IRQ }
170#define UART1_DMA { 13, 12 }
171#define UART2_IRQ { IRQ_EB_UART2, NO_IRQ }
172#define UART2_DMA { 11, 10 }
173#define UART3_IRQ { IRQ_EB_UART3, NO_IRQ }
174#define UART3_DMA { 0x86, 0x87 }
175#define SSP_IRQ { IRQ_EB_SSP, NO_IRQ }
176#define SSP_DMA { 9, 8 }
177
111/* FPGA Primecells */ 178/* FPGA Primecells */
112AMBA_DEVICE(aaci, "fpga:04", AACI, NULL); 179AMBA_DEVICE(aaci, "fpga:04", AACI, NULL);
113AMBA_DEVICE(mmc0, "fpga:05", MMCI0, &realview_mmc0_plat_data); 180AMBA_DEVICE(mmc0, "fpga:05", MMCI0, &realview_mmc0_plat_data);
@@ -153,38 +220,127 @@ static struct amba_device *amba_devs[] __initdata = {
153 &kmi1_device, 220 &kmi1_device,
154}; 221};
155 222
223/*
224 * RealView EB platform devices
225 */
226
227static struct resource realview_eb_smc91x_resources[] = {
228 [0] = {
229 .start = REALVIEW_ETH_BASE,
230 .end = REALVIEW_ETH_BASE + SZ_64K - 1,
231 .flags = IORESOURCE_MEM,
232 },
233 [1] = {
234 .start = IRQ_EB_ETH,
235 .end = IRQ_EB_ETH,
236 .flags = IORESOURCE_IRQ,
237 },
238};
239
240static struct platform_device realview_eb_smc91x_device = {
241 .name = "smc91x",
242 .id = 0,
243 .num_resources = ARRAY_SIZE(realview_eb_smc91x_resources),
244 .resource = realview_eb_smc91x_resources,
245};
246
156static void __init gic_init_irq(void) 247static void __init gic_init_irq(void)
157{ 248{
158#ifdef CONFIG_REALVIEW_MPCORE 249 if (core_tile_eb11mp()) {
159 unsigned int pldctrl; 250 unsigned int pldctrl;
160 writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK)); 251
161 pldctrl = readl(__io_address(REALVIEW_SYS_BASE) + REALVIEW_MPCORE_SYS_PLD_CTRL1); 252 /* new irq mode */
162 pldctrl |= 0x00800000; /* New irq mode */ 253 writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK));
163 writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + REALVIEW_MPCORE_SYS_PLD_CTRL1); 254 pldctrl = readl(__io_address(REALVIEW_SYS_BASE) + REALVIEW_EB11MP_SYS_PLD_CTRL1);
164 writel(0x00000000, __io_address(REALVIEW_SYS_LOCK)); 255 pldctrl |= 0x00800000;
256 writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + REALVIEW_EB11MP_SYS_PLD_CTRL1);
257 writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
258
259 /* core tile GIC, primary */
260 gic_cpu_base_addr = __io_address(REALVIEW_EB11MP_GIC_CPU_BASE);
261 gic_dist_init(0, __io_address(REALVIEW_EB11MP_GIC_DIST_BASE), 29);
262 gic_cpu_init(0, gic_cpu_base_addr);
263
264#ifndef CONFIG_REALVIEW_EB_ARM11MP_REVB
265 /* board GIC, secondary */
266 gic_dist_init(1, __io_address(REALVIEW_GIC_DIST_BASE), 64);
267 gic_cpu_init(1, __io_address(REALVIEW_GIC_CPU_BASE));
268 gic_cascade_irq(1, IRQ_EB11MP_EB_IRQ1);
165#endif 269#endif
166 gic_dist_init(0, __io_address(REALVIEW_GIC_DIST_BASE), 29); 270 } else {
167 gic_cpu_init(0, __io_address(REALVIEW_GIC_CPU_BASE)); 271 /* board GIC, primary */
168#if defined(CONFIG_REALVIEW_MPCORE) && !defined(CONFIG_REALVIEW_MPCORE_REVB) 272 gic_cpu_base_addr = __io_address(REALVIEW_GIC_CPU_BASE);
169 gic_dist_init(1, __io_address(REALVIEW_GIC1_DIST_BASE), 64); 273 gic_dist_init(0, __io_address(REALVIEW_GIC_DIST_BASE), 29);
170 gic_cpu_init(1, __io_address(REALVIEW_GIC1_CPU_BASE)); 274 gic_cpu_init(0, gic_cpu_base_addr);
171 gic_cascade_irq(1, IRQ_EB_IRQ1); 275 }
276}
277
278/*
279 * Fix up the IRQ numbers for the RealView EB/ARM11MPCore tile
280 */
281static void realview_eb11mp_fixup(void)
282{
283 /* AMBA devices */
284 dmac_device.irq[0] = IRQ_EB11MP_DMA;
285 uart0_device.irq[0] = IRQ_EB11MP_UART0;
286 uart1_device.irq[0] = IRQ_EB11MP_UART1;
287 uart2_device.irq[0] = IRQ_EB11MP_UART2;
288 uart3_device.irq[0] = IRQ_EB11MP_UART3;
289 clcd_device.irq[0] = IRQ_EB11MP_CLCD;
290 wdog_device.irq[0] = IRQ_EB11MP_WDOG;
291 gpio0_device.irq[0] = IRQ_EB11MP_GPIO0;
292 gpio1_device.irq[0] = IRQ_EB11MP_GPIO1;
293 gpio2_device.irq[0] = IRQ_EB11MP_GPIO2;
294 rtc_device.irq[0] = IRQ_EB11MP_RTC;
295 sci0_device.irq[0] = IRQ_EB11MP_SCI;
296 ssp0_device.irq[0] = IRQ_EB11MP_SSP;
297 aaci_device.irq[0] = IRQ_EB11MP_AACI;
298 mmc0_device.irq[0] = IRQ_EB11MP_MMCI0A;
299 mmc0_device.irq[1] = IRQ_EB11MP_MMCI0B;
300 kmi0_device.irq[0] = IRQ_EB11MP_KMI0;
301 kmi1_device.irq[0] = IRQ_EB11MP_KMI1;
302
303 /* platform devices */
304 realview_eb_smc91x_resources[1].start = IRQ_EB11MP_ETH;
305 realview_eb_smc91x_resources[1].end = IRQ_EB11MP_ETH;
306}
307
308static void __init realview_eb_timer_init(void)
309{
310 unsigned int timer_irq;
311
312 if (core_tile_eb11mp()) {
313#ifdef CONFIG_LOCAL_TIMERS
314 twd_base_addr = __io_address(REALVIEW_EB11MP_TWD_BASE);
315 twd_size = REALVIEW_EB11MP_TWD_SIZE;
172#endif 316#endif
317 timer_irq = IRQ_EB11MP_TIMER0_1;
318 } else
319 timer_irq = IRQ_EB_TIMER0_1;
320
321 realview_timer_init(timer_irq);
173} 322}
174 323
324static struct sys_timer realview_eb_timer = {
325 .init = realview_eb_timer_init,
326};
327
175static void __init realview_eb_init(void) 328static void __init realview_eb_init(void)
176{ 329{
177 int i; 330 int i;
178 331
179#ifdef CONFIG_REALVIEW_MPCORE 332 if (core_tile_eb11mp()) {
180 /* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled 333 realview_eb11mp_fixup();
181 * Bits: .... ...0 0111 1001 0000 .... .... .... */ 334
182 l2x0_init(__io_address(REALVIEW_MPCORE_L220_BASE), 0x00790000, 0xfe000fff); 335 /* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
183#endif 336 * Bits: .... ...0 0111 1001 0000 .... .... .... */
337 l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
338 }
339
184 clk_register(&realview_clcd_clk); 340 clk_register(&realview_clcd_clk);
185 341
186 platform_device_register(&realview_flash_device); 342 platform_device_register(&realview_flash_device);
187 platform_device_register(&realview_smc91x_device); 343 platform_device_register(&realview_eb_smc91x_device);
188 platform_device_register(&realview_i2c_device); 344 platform_device_register(&realview_i2c_device);
189 345
190 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { 346 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
@@ -204,6 +360,6 @@ MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
204 .boot_params = 0x00000100, 360 .boot_params = 0x00000100,
205 .map_io = realview_eb_map_io, 361 .map_io = realview_eb_map_io,
206 .init_irq = gic_init_irq, 362 .init_irq = gic_init_irq,
207 .timer = &realview_timer, 363 .timer = &realview_eb_timer,
208 .init_machine = realview_eb_init, 364 .init_machine = realview_eb_init,
209MACHINE_END 365MACHINE_END
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 9e13c8358ea7..5c84c604ed86 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -470,7 +470,7 @@ void __init sa1110_mb_disable(void)
470 * If the system is going to use the SA-1111 DMA engines, set up 470 * If the system is going to use the SA-1111 DMA engines, set up
471 * the memory bus request/grant pins. 471 * the memory bus request/grant pins.
472 */ 472 */
473void __init sa1110_mb_enable(void) 473void __devinit sa1110_mb_enable(void)
474{ 474{
475 unsigned long flags; 475 unsigned long flags;
476 476
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 75952779ce19..303a7ff6bfd2 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -162,7 +162,7 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
162 * Free the page table, if there was one. 162 * Free the page table, if there was one.
163 */ 163 */
164 if ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_TABLE) 164 if ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_TABLE)
165 pte_free_kernel(pmd_page_vaddr(pmd)); 165 pte_free_kernel(&init_mm, pmd_page_vaddr(pmd));
166 } 166 }
167 167
168 addr += PGDIR_SIZE; 168 addr += PGDIR_SIZE;
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index 50b9aed6000d..500c9610ab30 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -65,14 +65,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
65 return new_pgd; 65 return new_pgd;
66 66
67no_pte: 67no_pte:
68 pmd_free(new_pmd); 68 pmd_free(mm, new_pmd);
69no_pmd: 69no_pmd:
70 free_pages((unsigned long)new_pgd, 2); 70 free_pages((unsigned long)new_pgd, 2);
71no_pgd: 71no_pgd:
72 return NULL; 72 return NULL;
73} 73}
74 74
75void free_pgd_slow(pgd_t *pgd) 75void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd)
76{ 76{
77 pmd_t *pmd; 77 pmd_t *pmd;
78 struct page *pte; 78 struct page *pte;
@@ -94,8 +94,8 @@ void free_pgd_slow(pgd_t *pgd)
94 pmd_clear(pmd); 94 pmd_clear(pmd);
95 dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE); 95 dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE);
96 pte_lock_deinit(pte); 96 pte_lock_deinit(pte);
97 pte_free(pte); 97 pte_free(mm, pte);
98 pmd_free(pmd); 98 pmd_free(mm, pmd);
99free: 99free:
100 free_pages((unsigned long) pgd, 2); 100 free_pages((unsigned long) pgd, 2);
101} 101}
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
index ba3d21d8fba3..6fe481ff4fdf 100644
--- a/arch/arm/plat-iop/time.c
+++ b/arch/arm/plat-iop/time.c
@@ -57,8 +57,6 @@ unsigned long iop_gettimeoffset(void)
57static irqreturn_t 57static irqreturn_t
58iop_timer_interrupt(int irq, void *dev_id) 58iop_timer_interrupt(int irq, void *dev_id)
59{ 59{
60 write_seqlock(&xtime_lock);
61
62 write_tisr(1); 60 write_tisr(1);
63 61
64 while ((signed long)(next_jiffy_time - read_tcr1()) 62 while ((signed long)(next_jiffy_time - read_tcr1())
@@ -67,8 +65,6 @@ iop_timer_interrupt(int irq, void *dev_id)
67 next_jiffy_time -= ticks_per_jiffy; 65 next_jiffy_time -= ticks_per_jiffy;
68 } 66 }
69 67
70 write_sequnlock(&xtime_lock);
71
72 return IRQ_HANDLED; 68 return IRQ_HANDLED;
73} 69}
74 70
diff --git a/arch/arm/plat-s3c24xx/time.c b/arch/arm/plat-s3c24xx/time.c
index 2ec1daaa0e53..766473b3f98b 100644
--- a/arch/arm/plat-s3c24xx/time.c
+++ b/arch/arm/plat-s3c24xx/time.c
@@ -130,9 +130,7 @@ static unsigned long s3c2410_gettimeoffset (void)
130static irqreturn_t 130static irqreturn_t
131s3c2410_timer_interrupt(int irq, void *dev_id) 131s3c2410_timer_interrupt(int irq, void *dev_id)
132{ 132{
133 write_seqlock(&xtime_lock);
134 timer_tick(); 133 timer_tick();
135 write_sequnlock(&xtime_lock);
136 return IRQ_HANDLED; 134 return IRQ_HANDLED;
137} 135}
138 136
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index c816f29154c9..28e0caf4156c 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -82,6 +82,7 @@ config PLATFORM_AT32AP
82 select SUBARCH_AVR32B 82 select SUBARCH_AVR32B
83 select MMU 83 select MMU
84 select PERFORMANCE_COUNTERS 84 select PERFORMANCE_COUNTERS
85 select HAVE_GPIO_LIB
85 86
86# 87#
87# CPU types 88# CPU types
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c
index d61a02da898c..38a8fa31c0b5 100644
--- a/arch/avr32/mach-at32ap/pio.c
+++ b/arch/avr32/mach-at32ap/pio.c
@@ -24,11 +24,11 @@
24#define MAX_NR_PIO_DEVICES 8 24#define MAX_NR_PIO_DEVICES 8
25 25
26struct pio_device { 26struct pio_device {
27 struct gpio_chip chip;
27 void __iomem *regs; 28 void __iomem *regs;
28 const struct platform_device *pdev; 29 const struct platform_device *pdev;
29 struct clk *clk; 30 struct clk *clk;
30 u32 pinmux_mask; 31 u32 pinmux_mask;
31 u32 gpio_mask;
32 char name[8]; 32 char name[8];
33}; 33};
34 34
@@ -64,7 +64,8 @@ void __init at32_select_periph(unsigned int pin, unsigned int periph,
64 goto fail; 64 goto fail;
65 } 65 }
66 66
67 if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) { 67 if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask)
68 || gpiochip_is_requested(&pio->chip, pin_index))) {
68 printk("%s: pin %u is busy\n", pio->name, pin_index); 69 printk("%s: pin %u is busy\n", pio->name, pin_index);
69 goto fail; 70 goto fail;
70 } 71 }
@@ -79,9 +80,6 @@ void __init at32_select_periph(unsigned int pin, unsigned int periph,
79 if (!(flags & AT32_GPIOF_PULLUP)) 80 if (!(flags & AT32_GPIOF_PULLUP))
80 pio_writel(pio, PUDR, mask); 81 pio_writel(pio, PUDR, mask);
81 82
82 /* gpio_request NOT allowed */
83 set_bit(pin_index, &pio->gpio_mask);
84
85 return; 83 return;
86 84
87fail: 85fail:
@@ -130,9 +128,6 @@ void __init at32_select_gpio(unsigned int pin, unsigned long flags)
130 128
131 pio_writel(pio, PER, mask); 129 pio_writel(pio, PER, mask);
132 130
133 /* gpio_request now allowed */
134 clear_bit(pin_index, &pio->gpio_mask);
135
136 return; 131 return;
137 132
138fail: 133fail:
@@ -166,96 +161,50 @@ fail:
166 161
167/* GPIO API */ 162/* GPIO API */
168 163
169int gpio_request(unsigned int gpio, const char *label) 164static int direction_input(struct gpio_chip *chip, unsigned offset)
170{ 165{
171 struct pio_device *pio; 166 struct pio_device *pio = container_of(chip, struct pio_device, chip);
172 unsigned int pin; 167 u32 mask = 1 << offset;
173
174 pio = gpio_to_pio(gpio);
175 if (!pio)
176 return -ENODEV;
177 168
178 pin = gpio & 0x1f; 169 if (!(pio_readl(pio, PSR) & mask))
179 if (test_and_set_bit(pin, &pio->gpio_mask)) 170 return -EINVAL;
180 return -EBUSY;
181 171
172 pio_writel(pio, ODR, mask);
182 return 0; 173 return 0;
183} 174}
184EXPORT_SYMBOL(gpio_request);
185 175
186void gpio_free(unsigned int gpio) 176static int gpio_get(struct gpio_chip *chip, unsigned offset)
187{ 177{
188 struct pio_device *pio; 178 struct pio_device *pio = container_of(chip, struct pio_device, chip);
189 unsigned int pin;
190 179
191 pio = gpio_to_pio(gpio); 180 return (pio_readl(pio, PDSR) >> offset) & 1;
192 if (!pio) {
193 printk(KERN_ERR
194 "gpio: attempted to free invalid pin %u\n", gpio);
195 return;
196 }
197
198 pin = gpio & 0x1f;
199 if (!test_and_clear_bit(pin, &pio->gpio_mask))
200 printk(KERN_ERR "gpio: freeing free or non-gpio pin %s-%u\n",
201 pio->name, pin);
202} 181}
203EXPORT_SYMBOL(gpio_free);
204 182
205int gpio_direction_input(unsigned int gpio) 183static void gpio_set(struct gpio_chip *chip, unsigned offset, int value);
206{
207 struct pio_device *pio;
208 unsigned int pin;
209
210 pio = gpio_to_pio(gpio);
211 if (!pio)
212 return -ENODEV;
213
214 pin = gpio & 0x1f;
215 pio_writel(pio, ODR, 1 << pin);
216
217 return 0;
218}
219EXPORT_SYMBOL(gpio_direction_input);
220 184
221int gpio_direction_output(unsigned int gpio, int value) 185static int direction_output(struct gpio_chip *chip, unsigned offset, int value)
222{ 186{
223 struct pio_device *pio; 187 struct pio_device *pio = container_of(chip, struct pio_device, chip);
224 unsigned int pin; 188 u32 mask = 1 << offset;
225
226 pio = gpio_to_pio(gpio);
227 if (!pio)
228 return -ENODEV;
229 189
230 gpio_set_value(gpio, value); 190 if (!(pio_readl(pio, PSR) & mask))
231 191 return -EINVAL;
232 pin = gpio & 0x1f;
233 pio_writel(pio, OER, 1 << pin);
234 192
193 gpio_set(chip, offset, value);
194 pio_writel(pio, OER, mask);
235 return 0; 195 return 0;
236} 196}
237EXPORT_SYMBOL(gpio_direction_output);
238 197
239int gpio_get_value(unsigned int gpio) 198static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)
240{ 199{
241 struct pio_device *pio = &pio_dev[gpio >> 5]; 200 struct pio_device *pio = container_of(chip, struct pio_device, chip);
201 u32 mask = 1 << offset;
242 202
243 return (pio_readl(pio, PDSR) >> (gpio & 0x1f)) & 1;
244}
245EXPORT_SYMBOL(gpio_get_value);
246
247void gpio_set_value(unsigned int gpio, int value)
248{
249 struct pio_device *pio = &pio_dev[gpio >> 5];
250 u32 mask;
251
252 mask = 1 << (gpio & 0x1f);
253 if (value) 203 if (value)
254 pio_writel(pio, SODR, mask); 204 pio_writel(pio, SODR, mask);
255 else 205 else
256 pio_writel(pio, CODR, mask); 206 pio_writel(pio, CODR, mask);
257} 207}
258EXPORT_SYMBOL(gpio_set_value);
259 208
260/*--------------------------------------------------------------------------*/ 209/*--------------------------------------------------------------------------*/
261 210
@@ -339,6 +288,63 @@ gpio_irq_setup(struct pio_device *pio, int irq, int gpio_irq)
339 288
340/*--------------------------------------------------------------------------*/ 289/*--------------------------------------------------------------------------*/
341 290
291#ifdef CONFIG_DEBUG_FS
292
293#include <linux/seq_file.h>
294
295/*
296 * This shows more info than the generic gpio dump code:
297 * pullups, deglitching, open drain drive.
298 */
299static void pio_bank_show(struct seq_file *s, struct gpio_chip *chip)
300{
301 struct pio_device *pio = container_of(chip, struct pio_device, chip);
302 u32 psr, osr, imr, pdsr, pusr, ifsr, mdsr;
303 unsigned i;
304 u32 mask;
305 char bank;
306
307 psr = pio_readl(pio, PSR);
308 osr = pio_readl(pio, OSR);
309 imr = pio_readl(pio, IMR);
310 pdsr = pio_readl(pio, PDSR);
311 pusr = pio_readl(pio, PUSR);
312 ifsr = pio_readl(pio, IFSR);
313 mdsr = pio_readl(pio, MDSR);
314
315 bank = 'A' + pio->pdev->id;
316
317 for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
318 const char *label;
319
320 label = gpiochip_is_requested(chip, i);
321 if (!label)
322 continue;
323
324 seq_printf(s, " gpio-%-3d P%c%-2d (%-12s) %s %s %s",
325 chip->base + i, bank, i,
326 label,
327 (osr & mask) ? "out" : "in ",
328 (mask & pdsr) ? "hi" : "lo",
329 (mask & pusr) ? " " : "up");
330 if (ifsr & mask)
331 seq_printf(s, " deglitch");
332 if ((osr & mdsr) & mask)
333 seq_printf(s, " open-drain");
334 if (imr & mask)
335 seq_printf(s, " irq-%d edge-both",
336 gpio_to_irq(chip->base + i));
337 seq_printf(s, "\n");
338 }
339}
340
341#else
342#define pio_bank_show NULL
343#endif
344
345
346/*--------------------------------------------------------------------------*/
347
342static int __init pio_probe(struct platform_device *pdev) 348static int __init pio_probe(struct platform_device *pdev)
343{ 349{
344 struct pio_device *pio = NULL; 350 struct pio_device *pio = NULL;
@@ -349,6 +355,18 @@ static int __init pio_probe(struct platform_device *pdev)
349 pio = &pio_dev[pdev->id]; 355 pio = &pio_dev[pdev->id];
350 BUG_ON(!pio->regs); 356 BUG_ON(!pio->regs);
351 357
358 pio->chip.label = pio->name;
359 pio->chip.base = pdev->id * 32;
360 pio->chip.ngpio = 32;
361
362 pio->chip.direction_input = direction_input;
363 pio->chip.get = gpio_get;
364 pio->chip.direction_output = direction_output;
365 pio->chip.set = gpio_set;
366 pio->chip.dbg_show = pio_bank_show;
367
368 gpiochip_add(&pio->chip);
369
352 gpio_irq_setup(pio, irq, gpio_irq_base); 370 gpio_irq_setup(pio, irq, gpio_irq_base);
353 371
354 platform_set_drvdata(pdev, pio); 372 platform_set_drvdata(pdev, pio);
@@ -406,12 +424,6 @@ void __init at32_init_pio(struct platform_device *pdev)
406 pio->pdev = pdev; 424 pio->pdev = pdev;
407 pio->regs = ioremap(regs->start, regs->end - regs->start + 1); 425 pio->regs = ioremap(regs->start, regs->end - regs->start + 1);
408 426
409 /*
410 * request_gpio() is only valid for pins that have been
411 * explicitly configured as GPIO and not previously requested
412 */
413 pio->gpio_mask = ~0UL;
414
415 /* start with irqs disabled and acked */ 427 /* start with irqs disabled and acked */
416 pio_writel(pio, IDR, ~0UL); 428 pio_writel(pio, IDR, ~0UL);
417 (void) pio_readl(pio, ISR); 429 (void) pio_readl(pio, ISR);
diff --git a/arch/avr32/mach-at32ap/pio.h b/arch/avr32/mach-at32ap/pio.h
index 50fa3aca32c5..7795116a483a 100644
--- a/arch/avr32/mach-at32ap/pio.h
+++ b/arch/avr32/mach-at32ap/pio.h
@@ -19,7 +19,7 @@
19#define PIO_OSR 0x0018 19#define PIO_OSR 0x0018
20#define PIO_IFER 0x0020 20#define PIO_IFER 0x0020
21#define PIO_IFDR 0x0024 21#define PIO_IFDR 0x0024
22#define PIO_ISFR 0x0028 22#define PIO_IFSR 0x0028
23#define PIO_SODR 0x0030 23#define PIO_SODR 0x0030
24#define PIO_CODR 0x0034 24#define PIO_CODR 0x0034
25#define PIO_ODSR 0x0038 25#define PIO_ODSR 0x0038
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 56ff51bc8c21..fdd9bf43361e 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -1373,7 +1373,7 @@ ENTRY(_sys_call_table)
1373 .long _sys_epoll_pwait 1373 .long _sys_epoll_pwait
1374 .long _sys_utimensat 1374 .long _sys_utimensat
1375 .long _sys_signalfd 1375 .long _sys_signalfd
1376 .long _sys_timerfd 1376 .long _sys_ni_syscall
1377 .long _sys_eventfd /* 350 */ 1377 .long _sys_eventfd /* 350 */
1378 .long _sys_pread64 1378 .long _sys_pread64
1379 .long _sys_pwrite64 1379 .long _sys_pwrite64
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 7f0be4cd5e9a..27b082ac7f11 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -150,6 +150,7 @@ config ETRAX_FLASH_BUSWIDTH
150 Width in bytes of the Flash bus (1, 2 or 4). Is usually 2. 150 Width in bytes of the Flash bus (1, 2 or 4). Is usually 2.
151 151
152source arch/cris/arch-v10/Kconfig 152source arch/cris/arch-v10/Kconfig
153source arch/cris/arch-v32/Kconfig
153 154
154endmenu 155endmenu
155 156
@@ -157,8 +158,8 @@ source "net/Kconfig"
157 158
158# bring in ETRAX built-in drivers 159# bring in ETRAX built-in drivers
159menu "Drivers for built-in interfaces" 160menu "Drivers for built-in interfaces"
160# arch/cris/arch is a symlink to correct arch (arch-v10 or arch-v32) 161source arch/cris/arch-v10/drivers/Kconfig
161source arch/cris/arch/drivers/Kconfig 162source arch/cris/arch-v32/drivers/Kconfig
162 163
163endmenu 164endmenu
164 165
diff --git a/arch/cris/arch-v10/Kconfig b/arch/cris/arch-v10/Kconfig
index f1ce6f64401d..1d61faec77cd 100644
--- a/arch/cris/arch-v10/Kconfig
+++ b/arch/cris/arch-v10/Kconfig
@@ -1,3 +1,5 @@
1if ETRAX_ARCH_V10
2
1# ETRAX 100LX v1 has a MMU "feature" requiring a low mapping 3# ETRAX 100LX v1 has a MMU "feature" requiring a low mapping
2config CRIS_LOW_MAP 4config CRIS_LOW_MAP
3 bool 5 bool
@@ -451,3 +453,5 @@ config ETRAX_POWERBUTTON_BIT
451 default "25" 453 default "25"
452 help 454 help
453 Configure where power button is connected. 455 Configure where power button is connected.
456
457endif
diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig
index e3c0f2928149..96740ef497d4 100644
--- a/arch/cris/arch-v10/drivers/Kconfig
+++ b/arch/cris/arch-v10/drivers/Kconfig
@@ -1,3 +1,5 @@
1if ETRAX_ARCH_V10
2
1config ETRAX_ETHERNET 3config ETRAX_ETHERNET
2 bool "Ethernet support" 4 bool "Ethernet support"
3 depends on ETRAX_ARCH_V10 5 depends on ETRAX_ARCH_V10
@@ -806,3 +808,5 @@ config ETRAX_DS1302_TRICKLE_CHARGE
806 1 = 2kohm, 2 = 4kohm, 3 = 4kohm 808 1 = 2kohm, 2 = 4kohm, 3 = 4kohm
807 4 = 1 diode, 8 = 2 diodes 809 4 = 1 diode, 8 = 2 diodes
808 Allowed values are (increasing current): 0, 11, 10, 9, 7, 6, 5 810 Allowed values are (increasing current): 0, 11, 10, 9, 7, 6, 5
811
812endif
diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S
index ec62c951fa3c..d1361dc119e2 100644
--- a/arch/cris/arch-v10/kernel/entry.S
+++ b/arch/cris/arch-v10/kernel/entry.S
@@ -1167,7 +1167,7 @@ sys_call_table:
1167 .long sys_epoll_pwait 1167 .long sys_epoll_pwait
1168 .long sys_utimensat /* 320 */ 1168 .long sys_utimensat /* 320 */
1169 .long sys_signalfd 1169 .long sys_signalfd
1170 .long sys_timerfd 1170 .long sys_ni_syscall
1171 .long sys_eventfd 1171 .long sys_eventfd
1172 .long sys_fallocate 1172 .long sys_fallocate
1173 1173
diff --git a/arch/cris/arch-v32/Kconfig b/arch/cris/arch-v32/Kconfig
index 4f79d8ed3e1c..d8acaa920e1c 100644
--- a/arch/cris/arch-v32/Kconfig
+++ b/arch/cris/arch-v32/Kconfig
@@ -1,3 +1,5 @@
1if ETRAX_ARCH_V32
2
1config ETRAX_DRAM_VIRTUAL_BASE 3config ETRAX_DRAM_VIRTUAL_BASE
2 hex 4 hex
3 depends on ETRAX_ARCH_V32 5 depends on ETRAX_ARCH_V32
@@ -294,3 +296,5 @@ config ETRAX_DEF_GIO_PE_OUT
294 help 296 help
295 Configures the initial data for the general port E bits. Most 297 Configures the initial data for the general port E bits. Most
296 products should use 00000 here. 298 products should use 00000 here.
299
300endif
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig
index 9bccb5e2a960..c329cce2a0c3 100644
--- a/arch/cris/arch-v32/drivers/Kconfig
+++ b/arch/cris/arch-v32/drivers/Kconfig
@@ -1,3 +1,5 @@
1if ETRAX_ARCH_V32
2
1config ETRAX_ETHERNET 3config ETRAX_ETHERNET
2 bool "Ethernet support" 4 bool "Ethernet support"
3 depends on ETRAX_ARCH_V32 5 depends on ETRAX_ARCH_V32
@@ -610,3 +612,5 @@ config ETRAX_STREAMCOPROC
610 help 612 help
611 This option enables a driver for the stream co-processor 613 This option enables a driver for the stream co-processor
612 for cryptographic operations. 614 for cryptographic operations.
615
616endif
diff --git a/arch/cris/arch-v32/drivers/pci/dma.c b/arch/cris/arch-v32/drivers/pci/dma.c
index 66f9500fbc02..e0364654fc44 100644
--- a/arch/cris/arch-v32/drivers/pci/dma.c
+++ b/arch/cris/arch-v32/drivers/pci/dma.c
@@ -93,7 +93,7 @@ int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
93 93
94 dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); 94 dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
95 if (!dev->dma_mem) 95 if (!dev->dma_mem)
96 goto out; 96 goto iounmap_out;
97 dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); 97 dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
98 if (!dev->dma_mem->bitmap) 98 if (!dev->dma_mem->bitmap)
99 goto free1_out; 99 goto free1_out;
@@ -110,6 +110,8 @@ int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
110 110
111 free1_out: 111 free1_out:
112 kfree(dev->dma_mem); 112 kfree(dev->dma_mem);
113 iounmap_out:
114 iounmap(mem_base);
113 out: 115 out:
114 return 0; 116 return 0;
115} 117}
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index bf0468cbe713..96f7d70f4473 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -138,6 +138,15 @@ config UCPAGE_OFFSET_C0000000
138 138
139endchoice 139endchoice
140 140
141config PAGE_OFFSET
142 hex
143 default 0x20000000 if UCPAGE_OFFSET_20000000
144 default 0x40000000 if UCPAGE_OFFSET_40000000
145 default 0x60000000 if UCPAGE_OFFSET_60000000
146 default 0x80000000 if UCPAGE_OFFSET_80000000
147 default 0xA0000000 if UCPAGE_OFFSET_A0000000
148 default 0xC0000000
149
141config PROTECT_KERNEL 150config PROTECT_KERNEL
142 bool "Protect core kernel against userspace" 151 bool "Protect core kernel against userspace"
143 depends on !MMU 152 depends on !MMU
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index f42b328b1dd0..ef7527b8b0c7 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -13,7 +13,7 @@ ENTRY(_start)
13 13
14jiffies = jiffies_64 + 4; 14jiffies = jiffies_64 + 4;
15 15
16__page_offset = 0xc0000000; /* start of area covered by struct pages */ 16__page_offset = CONFIG_PAGE_OFFSET; /* start of area covered by struct pages */
17__kernel_image_start = __page_offset; /* address at which kernel image resides */ 17__kernel_image_start = __page_offset; /* address at which kernel image resides */
18 18
19SECTIONS 19SECTIONS
diff --git a/arch/frv/mm/mmu-context.c b/arch/frv/mm/mmu-context.c
index 1530a4111e6d..81757d55a5b5 100644
--- a/arch/frv/mm/mmu-context.c
+++ b/arch/frv/mm/mmu-context.c
@@ -181,7 +181,7 @@ int cxn_pin_by_pid(pid_t pid)
181 181
182 /* get a handle on the mm_struct */ 182 /* get a handle on the mm_struct */
183 read_lock(&tasklist_lock); 183 read_lock(&tasklist_lock);
184 tsk = find_task_by_pid(pid); 184 tsk = find_task_by_vpid(pid);
185 if (tsk) { 185 if (tsk) {
186 ret = -EINVAL; 186 ret = -EINVAL;
187 187
diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c
index 7787c3cc52c6..1a2e5c8d03a9 100644
--- a/arch/frv/mm/pgalloc.c
+++ b/arch/frv/mm/pgalloc.c
@@ -140,7 +140,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
140 return pgd; 140 return pgd;
141} 141}
142 142
143void pgd_free(pgd_t *pgd) 143void pgd_free(struct mm_struct *mm, pgd_t *pgd)
144{ 144{
145 /* in the non-PAE case, clear_page_tables() clears user pgd entries */ 145 /* in the non-PAE case, clear_page_tables() clears user pgd entries */
146 quicklist_free(0, pgd_dtor, pgd); 146 quicklist_free(0, pgd_dtor, pgd);
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 8c0ae4f20f7e..a94445422cc6 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -1265,7 +1265,7 @@ sba_fill_pdir(
1265 * the sglist do both. 1265 * the sglist do both.
1266 */ 1266 */
1267static SBA_INLINE int 1267static SBA_INLINE int
1268sba_coalesce_chunks( struct ioc *ioc, 1268sba_coalesce_chunks(struct ioc *ioc, struct device *dev,
1269 struct scatterlist *startsg, 1269 struct scatterlist *startsg,
1270 int nents) 1270 int nents)
1271{ 1271{
@@ -1275,6 +1275,7 @@ sba_coalesce_chunks( struct ioc *ioc,
1275 struct scatterlist *dma_sg; /* next DMA stream head */ 1275 struct scatterlist *dma_sg; /* next DMA stream head */
1276 unsigned long dma_offset, dma_len; /* start/len of DMA stream */ 1276 unsigned long dma_offset, dma_len; /* start/len of DMA stream */
1277 int n_mappings = 0; 1277 int n_mappings = 0;
1278 unsigned int max_seg_size = dma_get_max_seg_size(dev);
1278 1279
1279 while (nents > 0) { 1280 while (nents > 0) {
1280 unsigned long vaddr = (unsigned long) sba_sg_address(startsg); 1281 unsigned long vaddr = (unsigned long) sba_sg_address(startsg);
@@ -1314,6 +1315,9 @@ sba_coalesce_chunks( struct ioc *ioc,
1314 > DMA_CHUNK_SIZE) 1315 > DMA_CHUNK_SIZE)
1315 break; 1316 break;
1316 1317
1318 if (dma_len + startsg->length > max_seg_size)
1319 break;
1320
1317 /* 1321 /*
1318 ** Then look for virtually contiguous blocks. 1322 ** Then look for virtually contiguous blocks.
1319 ** 1323 **
@@ -1441,7 +1445,7 @@ int sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, int di
1441 ** w/o this association, we wouldn't have coherent DMA! 1445 ** w/o this association, we wouldn't have coherent DMA!
1442 ** Access to the virtual address is what forces a two pass algorithm. 1446 ** Access to the virtual address is what forces a two pass algorithm.
1443 */ 1447 */
1444 coalesced = sba_coalesce_chunks(ioc, sglist, nents); 1448 coalesced = sba_coalesce_chunks(ioc, dev, sglist, nents);
1445 1449
1446 /* 1450 /*
1447 ** Program the I/O Pdir 1451 ** Program the I/O Pdir
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index c36f43c94600..f5d3efbfbeda 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1586,7 +1586,7 @@ sys_call_table:
1586 data8 sys_epoll_pwait // 1305 1586 data8 sys_epoll_pwait // 1305
1587 data8 sys_utimensat 1587 data8 sys_utimensat
1588 data8 sys_signalfd 1588 data8 sys_signalfd
1589 data8 sys_timerfd 1589 data8 sys_ni_syscall
1590 data8 sys_eventfd 1590 data8 sys_eventfd
1591 1591
1592 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls 1592 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
diff --git a/arch/m32r/boot/compressed/m32r_sio.c b/arch/m32r/boot/compressed/m32r_sio.c
index ee3c8be12fa0..01d877c6868f 100644
--- a/arch/m32r/boot/compressed/m32r_sio.c
+++ b/arch/m32r/boot/compressed/m32r_sio.c
@@ -17,7 +17,7 @@ static int puts(const char *s)
17 return 0; 17 return 0;
18} 18}
19 19
20#if defined(CONFIG_PLAT_M32700UT_Alpha) || defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) 20#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT)
21#include <asm/m32r.h> 21#include <asm/m32r.h>
22#include <asm/io.h> 22#include <asm/io.h>
23 23
@@ -52,7 +52,7 @@ static void putc(char c)
52 } 52 }
53 *BOOT_SIO0TXB = c; 53 *BOOT_SIO0TXB = c;
54} 54}
55#else /* !(CONFIG_PLAT_M32700UT_Alpha) && !(CONFIG_PLAT_M32700UT) */ 55#else /* !(CONFIG_PLAT_M32700UT) */
56#if defined(CONFIG_PLAT_MAPPI2) 56#if defined(CONFIG_PLAT_MAPPI2)
57#define SIO0STS (volatile unsigned short *)(0xa0efd000 + 14) 57#define SIO0STS (volatile unsigned short *)(0xa0efd000 + 14)
58#define SIO0TXB (volatile unsigned short *)(0xa0efd000 + 30) 58#define SIO0TXB (volatile unsigned short *)(0xa0efd000 + 30)
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 8236e42ef711..ffabd01c45eb 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -577,20 +577,6 @@ config MAC_HID
577 depends on INPUT_ADBHID 577 depends on INPUT_ADBHID
578 default y 578 default y
579 579
580config MAC_ADBKEYCODES
581 bool "Support for ADB raw keycodes"
582 depends on INPUT_ADBHID
583 help
584 This provides support for sending raw ADB keycodes to console
585 devices. This is the default up to 2.4.0, but in future this may be
586 phased out in favor of generic Linux keycodes. If you say Y here,
587 you can dynamically switch via the
588 /proc/sys/dev/mac_hid/keyboard_sends_linux_keycodes
589 sysctl and with the "keyboard_sends_linux_keycodes=" kernel
590 argument.
591
592 If unsure, say Y here.
593
594config ADB_KEYBOARD 580config ADB_KEYBOARD
595 bool "Support for ADB keyboard (old driver)" 581 bool "Support for ADB keyboard (old driver)"
596 depends on MAC && !INPUT_ADBHID 582 depends on MAC && !INPUT_ADBHID
diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile
index 4a1bd44ff162..2cba605cb59d 100644
--- a/arch/m68k/Makefile
+++ b/arch/m68k/Makefile
@@ -13,16 +13,15 @@
13# Copyright (C) 1994 by Hamish Macdonald 13# Copyright (C) 1994 by Hamish Macdonald
14# 14#
15 15
16# test for cross compiling
17COMPILE_ARCH = $(shell uname -m)
18
19# override top level makefile 16# override top level makefile
20AS += -m68020 17AS += -m68020
21LDFLAGS := -m m68kelf 18LDFLAGS := -m m68kelf
22LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds 19LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds
23ifneq ($(COMPILE_ARCH),$(ARCH)) 20ifneq ($(SUBARCH),$(ARCH))
24 # prefix for cross-compiling binaries 21 ifeq ($(CROSS_COMPILE),)
25 CROSS_COMPILE = m68k-linux-gnu- 22 CROSS_COMPILE := $(call cc-cross-prefix, \
23 m68k-linux-gnu- m68k-linux- m68k-unknown-linux-gnu-)
24 endif
26endif 25endif
27 26
28ifdef CONFIG_SUN3 27ifdef CONFIG_SUN3
diff --git a/arch/m68k/amiga/Makefile b/arch/m68k/amiga/Makefile
index 8b415651edee..6a0d7650f980 100644
--- a/arch/m68k/amiga/Makefile
+++ b/arch/m68k/amiga/Makefile
@@ -2,6 +2,6 @@
2# Makefile for Linux arch/m68k/amiga source directory 2# Makefile for Linux arch/m68k/amiga source directory
3# 3#
4 4
5obj-y := config.o amiints.o cia.o chipram.o amisound.o amiga_ksyms.o 5obj-y := config.o amiints.o cia.o chipram.o amisound.o
6 6
7obj-$(CONFIG_AMIGA_PCMCIA) += pcmcia.o 7obj-$(CONFIG_AMIGA_PCMCIA) += pcmcia.o
diff --git a/arch/m68k/amiga/amiga_ksyms.c b/arch/m68k/amiga/amiga_ksyms.c
deleted file mode 100644
index 7fdcf6bf3ada..000000000000
--- a/arch/m68k/amiga/amiga_ksyms.c
+++ /dev/null
@@ -1,33 +0,0 @@
1#include <linux/module.h>
2#include <linux/types.h>
3#include <asm/ptrace.h>
4#include <asm/amigahw.h>
5#include <asm/amigaints.h>
6#include <asm/amipcmcia.h>
7
8extern volatile u_short amiga_audio_min_period;
9extern u_short amiga_audio_period;
10
11/*
12 * Add things here when you find the need for it.
13 */
14EXPORT_SYMBOL(amiga_model);
15EXPORT_SYMBOL(amiga_chipset);
16EXPORT_SYMBOL(amiga_hw_present);
17EXPORT_SYMBOL(amiga_eclock);
18EXPORT_SYMBOL(amiga_colorclock);
19EXPORT_SYMBOL(amiga_chip_alloc);
20EXPORT_SYMBOL(amiga_chip_free);
21EXPORT_SYMBOL(amiga_chip_avail);
22EXPORT_SYMBOL(amiga_chip_size);
23EXPORT_SYMBOL(amiga_audio_period);
24EXPORT_SYMBOL(amiga_audio_min_period);
25
26#ifdef CONFIG_AMIGA_PCMCIA
27 EXPORT_SYMBOL(pcmcia_reset);
28 EXPORT_SYMBOL(pcmcia_copy_tuple);
29 EXPORT_SYMBOL(pcmcia_program_voltage);
30 EXPORT_SYMBOL(pcmcia_access_speed);
31 EXPORT_SYMBOL(pcmcia_write_enable);
32 EXPORT_SYMBOL(pcmcia_write_disable);
33#endif
diff --git a/arch/m68k/amiga/amisound.c b/arch/m68k/amiga/amisound.c
index 1f5bfb584297..61e5c54625ae 100644
--- a/arch/m68k/amiga/amisound.c
+++ b/arch/m68k/amiga/amisound.c
@@ -12,6 +12,7 @@
12#include <linux/timer.h> 12#include <linux/timer.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/string.h> 14#include <linux/string.h>
15#include <linux/module.h>
15 16
16#include <asm/system.h> 17#include <asm/system.h>
17#include <asm/amigahw.h> 18#include <asm/amigahw.h>
@@ -21,7 +22,7 @@ static const signed char sine_data[] = {
21 0, 39, 75, 103, 121, 127, 121, 103, 75, 39, 22 0, 39, 75, 103, 121, 127, 121, 103, 75, 39,
22 0, -39, -75, -103, -121, -127, -121, -103, -75, -39 23 0, -39, -75, -103, -121, -127, -121, -103, -75, -39
23}; 24};
24#define DATA_SIZE (sizeof(sine_data)/sizeof(sine_data[0])) 25#define DATA_SIZE ARRAY_SIZE(sine_data)
25 26
26#define custom amiga_custom 27#define custom amiga_custom
27 28
@@ -31,6 +32,7 @@ static const signed char sine_data[] = {
31 */ 32 */
32 33
33volatile unsigned short amiga_audio_min_period = 124; /* Default for pre-OCS */ 34volatile unsigned short amiga_audio_min_period = 124; /* Default for pre-OCS */
35EXPORT_SYMBOL(amiga_audio_min_period);
34 36
35#define MAX_PERIOD (65535) 37#define MAX_PERIOD (65535)
36 38
@@ -40,6 +42,7 @@ volatile unsigned short amiga_audio_min_period = 124; /* Default for pre-OCS */
40 */ 42 */
41 43
42unsigned short amiga_audio_period = MAX_PERIOD; 44unsigned short amiga_audio_period = MAX_PERIOD;
45EXPORT_SYMBOL(amiga_audio_period);
43 46
44static unsigned long clock_constant; 47static unsigned long clock_constant;
45 48
diff --git a/arch/m68k/amiga/chipram.c b/arch/m68k/amiga/chipram.c
index fa015d801617..d10726f9038b 100644
--- a/arch/m68k/amiga/chipram.c
+++ b/arch/m68k/amiga/chipram.c
@@ -13,10 +13,13 @@
13#include <linux/ioport.h> 13#include <linux/ioport.h>
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/string.h> 15#include <linux/string.h>
16#include <linux/module.h>
17
16#include <asm/page.h> 18#include <asm/page.h>
17#include <asm/amigahw.h> 19#include <asm/amigahw.h>
18 20
19unsigned long amiga_chip_size; 21unsigned long amiga_chip_size;
22EXPORT_SYMBOL(amiga_chip_size);
20 23
21static struct resource chipram_res = { 24static struct resource chipram_res = {
22 .name = "Chip RAM", .start = CHIP_PHYSADDR 25 .name = "Chip RAM", .start = CHIP_PHYSADDR
@@ -67,6 +70,7 @@ void *amiga_chip_alloc(unsigned long size, const char *name)
67#endif 70#endif
68 return (void *)ZTWO_VADDR(res->start); 71 return (void *)ZTWO_VADDR(res->start);
69} 72}
73EXPORT_SYMBOL(amiga_chip_alloc);
70 74
71 75
72 /* 76 /*
@@ -120,6 +124,7 @@ void amiga_chip_free(void *ptr)
120 } 124 }
121 printk("amiga_chip_free: trying to free nonexistent region at %p\n", ptr); 125 printk("amiga_chip_free: trying to free nonexistent region at %p\n", ptr);
122} 126}
127EXPORT_SYMBOL(amiga_chip_free);
123 128
124 129
125unsigned long amiga_chip_avail(void) 130unsigned long amiga_chip_avail(void)
@@ -129,3 +134,5 @@ unsigned long amiga_chip_avail(void)
129#endif 134#endif
130 return chipavail; 135 return chipavail;
131} 136}
137EXPORT_SYMBOL(amiga_chip_avail);
138
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
index 35748531327d..50f5daab46b7 100644
--- a/arch/m68k/amiga/config.c
+++ b/arch/m68k/amiga/config.c
@@ -23,6 +23,7 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/zorro.h> 25#include <linux/zorro.h>
26#include <linux/module.h>
26 27
27#include <asm/bootinfo.h> 28#include <asm/bootinfo.h>
28#include <asm/setup.h> 29#include <asm/setup.h>
@@ -36,13 +37,24 @@
36#include <asm/io.h> 37#include <asm/io.h>
37 38
38unsigned long amiga_model; 39unsigned long amiga_model;
40EXPORT_SYMBOL(amiga_model);
41
39unsigned long amiga_eclock; 42unsigned long amiga_eclock;
43EXPORT_SYMBOL(amiga_eclock);
44
40unsigned long amiga_masterclock; 45unsigned long amiga_masterclock;
46
41unsigned long amiga_colorclock; 47unsigned long amiga_colorclock;
48EXPORT_SYMBOL(amiga_colorclock);
49
42unsigned long amiga_chipset; 50unsigned long amiga_chipset;
51EXPORT_SYMBOL(amiga_chipset);
52
43unsigned char amiga_vblank; 53unsigned char amiga_vblank;
44unsigned char amiga_psfreq; 54unsigned char amiga_psfreq;
55
45struct amiga_hw_present amiga_hw_present; 56struct amiga_hw_present amiga_hw_present;
57EXPORT_SYMBOL(amiga_hw_present);
46 58
47static char s_a500[] __initdata = "A500"; 59static char s_a500[] __initdata = "A500";
48static char s_a500p[] __initdata = "A500+"; 60static char s_a500p[] __initdata = "A500+";
diff --git a/arch/m68k/amiga/pcmcia.c b/arch/m68k/amiga/pcmcia.c
index 186662ca1a89..7106f0c3639b 100644
--- a/arch/m68k/amiga/pcmcia.c
+++ b/arch/m68k/amiga/pcmcia.c
@@ -15,6 +15,8 @@
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/jiffies.h> 16#include <linux/jiffies.h>
17#include <linux/timer.h> 17#include <linux/timer.h>
18#include <linux/module.h>
19
18#include <asm/amigayle.h> 20#include <asm/amigayle.h>
19#include <asm/amipcmcia.h> 21#include <asm/amipcmcia.h>
20 22
@@ -30,6 +32,7 @@ void pcmcia_reset(void)
30 while (time_before(jiffies, reset_start_time + 1*HZ/100)); 32 while (time_before(jiffies, reset_start_time + 1*HZ/100));
31 b = gayle_reset; 33 b = gayle_reset;
32} 34}
35EXPORT_SYMBOL(pcmcia_reset);
33 36
34 37
35/* copy a tuple, including tuple header. return nb bytes copied */ 38/* copy a tuple, including tuple header. return nb bytes copied */
@@ -61,6 +64,7 @@ int pcmcia_copy_tuple(unsigned char tuple_id, void *tuple, int max_len)
61 64
62 return 0; 65 return 0;
63} 66}
67EXPORT_SYMBOL(pcmcia_copy_tuple);
64 68
65void pcmcia_program_voltage(int voltage) 69void pcmcia_program_voltage(int voltage)
66{ 70{
@@ -84,6 +88,7 @@ void pcmcia_program_voltage(int voltage)
84 gayle.config = cfg_byte; 88 gayle.config = cfg_byte;
85 89
86} 90}
91EXPORT_SYMBOL(pcmcia_program_voltage);
87 92
88void pcmcia_access_speed(int speed) 93void pcmcia_access_speed(int speed)
89{ 94{
@@ -101,13 +106,17 @@ void pcmcia_access_speed(int speed)
101 cfg_byte = (cfg_byte & 0xf3) | s; 106 cfg_byte = (cfg_byte & 0xf3) | s;
102 gayle.config = cfg_byte; 107 gayle.config = cfg_byte;
103} 108}
109EXPORT_SYMBOL(pcmcia_access_speed);
104 110
105void pcmcia_write_enable(void) 111void pcmcia_write_enable(void)
106{ 112{
107 gayle.cardstatus = GAYLE_CS_WR|GAYLE_CS_DA; 113 gayle.cardstatus = GAYLE_CS_WR|GAYLE_CS_DA;
108} 114}
115EXPORT_SYMBOL(pcmcia_write_enable);
109 116
110void pcmcia_write_disable(void) 117void pcmcia_write_disable(void)
111{ 118{
112 gayle.cardstatus = 0; 119 gayle.cardstatus = 0;
113} 120}
121EXPORT_SYMBOL(pcmcia_write_disable);
122
diff --git a/arch/m68k/atari/Makefile b/arch/m68k/atari/Makefile
index 2cb86191f0aa..2cd905efe63a 100644
--- a/arch/m68k/atari/Makefile
+++ b/arch/m68k/atari/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5obj-y := config.o time.o debug.o ataints.o stdma.o \ 5obj-y := config.o time.o debug.o ataints.o stdma.o \
6 atasound.o stram.o atari_ksyms.o 6 atasound.o stram.o
7 7
8ifeq ($(CONFIG_PCI),y) 8ifeq ($(CONFIG_PCI),y)
9obj-$(CONFIG_HADES) += hades-pci.o 9obj-$(CONFIG_HADES) += hades-pci.o
diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index b85ca22024c1..b45593a60bdd 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -40,6 +40,7 @@
40#include <linux/kernel_stat.h> 40#include <linux/kernel_stat.h>
41#include <linux/init.h> 41#include <linux/init.h>
42#include <linux/seq_file.h> 42#include <linux/seq_file.h>
43#include <linux/module.h>
43 44
44#include <asm/system.h> 45#include <asm/system.h>
45#include <asm/traps.h> 46#include <asm/traps.h>
@@ -446,6 +447,7 @@ unsigned long atari_register_vme_int(void)
446 free_vme_vec_bitmap |= 1 << i; 447 free_vme_vec_bitmap |= 1 << i;
447 return VME_SOURCE_BASE + i; 448 return VME_SOURCE_BASE + i;
448} 449}
450EXPORT_SYMBOL(atari_register_vme_int);
449 451
450 452
451void atari_unregister_vme_int(unsigned long irq) 453void atari_unregister_vme_int(unsigned long irq)
@@ -455,5 +457,6 @@ void atari_unregister_vme_int(unsigned long irq)
455 free_vme_vec_bitmap &= ~(1 << irq); 457 free_vme_vec_bitmap &= ~(1 << irq);
456 } 458 }
457} 459}
460EXPORT_SYMBOL(atari_unregister_vme_int);
458 461
459 462
diff --git a/arch/m68k/atari/atari_ksyms.c b/arch/m68k/atari/atari_ksyms.c
deleted file mode 100644
index a04757151538..000000000000
--- a/arch/m68k/atari/atari_ksyms.c
+++ /dev/null
@@ -1,35 +0,0 @@
1#include <linux/module.h>
2
3#include <asm/ptrace.h>
4#include <asm/traps.h>
5#include <asm/atarihw.h>
6#include <asm/atariints.h>
7#include <asm/atarikb.h>
8#include <asm/atari_joystick.h>
9#include <asm/atari_stdma.h>
10#include <asm/atari_stram.h>
11
12extern void atari_microwire_cmd( int cmd );
13extern int atari_MFP_init_done;
14extern int atari_SCC_init_done;
15extern int atari_SCC_reset_done;
16
17EXPORT_SYMBOL(atari_mch_cookie);
18EXPORT_SYMBOL(atari_mch_type);
19EXPORT_SYMBOL(atari_hw_present);
20EXPORT_SYMBOL(atari_switches);
21EXPORT_SYMBOL(atari_dont_touch_floppy_select);
22EXPORT_SYMBOL(atari_register_vme_int);
23EXPORT_SYMBOL(atari_unregister_vme_int);
24EXPORT_SYMBOL(stdma_lock);
25EXPORT_SYMBOL(stdma_release);
26EXPORT_SYMBOL(stdma_others_waiting);
27EXPORT_SYMBOL(stdma_islocked);
28EXPORT_SYMBOL(atari_stram_alloc);
29EXPORT_SYMBOL(atari_stram_free);
30
31EXPORT_SYMBOL(atari_MFP_init_done);
32EXPORT_SYMBOL(atari_SCC_init_done);
33EXPORT_SYMBOL(atari_SCC_reset_done);
34
35EXPORT_SYMBOL(atari_microwire_cmd);
diff --git a/arch/m68k/atari/atasound.c b/arch/m68k/atari/atasound.c
index ee04250eb56b..d266fe89c125 100644
--- a/arch/m68k/atari/atasound.c
+++ b/arch/m68k/atari/atasound.c
@@ -22,6 +22,7 @@
22#include <linux/fcntl.h> 22#include <linux/fcntl.h>
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/mm.h> 24#include <linux/mm.h>
25#include <linux/module.h>
25 26
26#include <asm/atarihw.h> 27#include <asm/atarihw.h>
27#include <asm/system.h> 28#include <asm/system.h>
@@ -43,6 +44,7 @@ void atari_microwire_cmd (int cmd)
43 while( tt_microwire.mask != 0x7ff) 44 while( tt_microwire.mask != 0x7ff)
44 ; 45 ;
45} 46}
47EXPORT_SYMBOL(atari_microwire_cmd);
46 48
47 49
48/* PSG base frequency */ 50/* PSG base frequency */
diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index e40e5dcaa347..5945e1505558 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -31,6 +31,7 @@
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/ioport.h> 32#include <linux/ioport.h>
33#include <linux/vt_kern.h> 33#include <linux/vt_kern.h>
34#include <linux/module.h>
34 35
35#include <asm/bootinfo.h> 36#include <asm/bootinfo.h>
36#include <asm/setup.h> 37#include <asm/setup.h>
@@ -43,10 +44,20 @@
43#include <asm/io.h> 44#include <asm/io.h>
44 45
45u_long atari_mch_cookie; 46u_long atari_mch_cookie;
47EXPORT_SYMBOL(atari_mch_cookie);
48
46u_long atari_mch_type; 49u_long atari_mch_type;
50EXPORT_SYMBOL(atari_mch_type);
51
47struct atari_hw_present atari_hw_present; 52struct atari_hw_present atari_hw_present;
53EXPORT_SYMBOL(atari_hw_present);
54
48u_long atari_switches; 55u_long atari_switches;
56EXPORT_SYMBOL(atari_switches);
57
49int atari_dont_touch_floppy_select; 58int atari_dont_touch_floppy_select;
59EXPORT_SYMBOL(atari_dont_touch_floppy_select);
60
50int atari_rtc_year_offset; 61int atari_rtc_year_offset;
51 62
52/* local function prototypes */ 63/* local function prototypes */
diff --git a/arch/m68k/atari/debug.c b/arch/m68k/atari/debug.c
index fbeed8c8ecbc..043ddbc61c7b 100644
--- a/arch/m68k/atari/debug.c
+++ b/arch/m68k/atari/debug.c
@@ -15,17 +15,23 @@
15#include <linux/console.h> 15#include <linux/console.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/module.h>
18 19
19#include <asm/atarihw.h> 20#include <asm/atarihw.h>
20#include <asm/atariints.h> 21#include <asm/atariints.h>
21 22
22/* Flag that Modem1 port is already initialized and used */ 23/* Flag that Modem1 port is already initialized and used */
23int atari_MFP_init_done; 24int atari_MFP_init_done;
25EXPORT_SYMBOL(atari_MFP_init_done);
26
24/* Flag that Modem1 port is already initialized and used */ 27/* Flag that Modem1 port is already initialized and used */
25int atari_SCC_init_done; 28int atari_SCC_init_done;
29EXPORT_SYMBOL(atari_SCC_init_done);
30
26/* Can be set somewhere, if a SCC master reset has already be done and should 31/* Can be set somewhere, if a SCC master reset has already be done and should
27 * not be repeated; used by kgdb */ 32 * not be repeated; used by kgdb */
28int atari_SCC_reset_done; 33int atari_SCC_reset_done;
34EXPORT_SYMBOL(atari_SCC_reset_done);
29 35
30static struct console atari_console_driver = { 36static struct console atari_console_driver = {
31 .name = "debug", 37 .name = "debug",
diff --git a/arch/m68k/atari/hades-pci.c b/arch/m68k/atari/hades-pci.c
index bee2b1443e36..2bbabc008708 100644
--- a/arch/m68k/atari/hades-pci.c
+++ b/arch/m68k/atari/hades-pci.c
@@ -376,8 +376,8 @@ struct pci_bus_info * __init init_hades_pci(void)
376 */ 376 */
377 377
378 bus = kzalloc(sizeof(struct pci_bus_info), GFP_KERNEL); 378 bus = kzalloc(sizeof(struct pci_bus_info), GFP_KERNEL);
379 if (!bus) 379 if (unlikely(!bus))
380 return NULL; 380 goto iounmap_base_virt;
381 381
382 /* 382 /*
383 * Claim resources. The m68k has no separate I/O space, both 383 * Claim resources. The m68k has no separate I/O space, both
@@ -385,43 +385,25 @@ struct pci_bus_info * __init init_hades_pci(void)
385 * the I/O resources are requested in memory space as well. 385 * the I/O resources are requested in memory space as well.
386 */ 386 */
387 387
388 if (request_resource(&iomem_resource, &config_space) != 0) 388 if (unlikely(request_resource(&iomem_resource, &config_space) != 0))
389 { 389 goto free_bus;
390 kfree(bus);
391 return NULL;
392 }
393 390
394 if (request_resource(&iomem_resource, &io_space) != 0) 391 if (unlikely(request_resource(&iomem_resource, &io_space) != 0))
395 { 392 goto release_config_space;
396 release_resource(&config_space);
397 kfree(bus);
398 return NULL;
399 }
400 393
401 bus->mem_space.start = HADES_MEM_BASE; 394 bus->mem_space.start = HADES_MEM_BASE;
402 bus->mem_space.end = HADES_MEM_BASE + HADES_MEM_SIZE - 1; 395 bus->mem_space.end = HADES_MEM_BASE + HADES_MEM_SIZE - 1;
403 bus->mem_space.name = pci_mem_name; 396 bus->mem_space.name = pci_mem_name;
404#if 1 397#if 1
405 if (request_resource(&iomem_resource, &bus->mem_space) != 0) 398 if (unlikely(request_resource(&iomem_resource, &bus->mem_space) != 0))
406 { 399 goto release_io_space;
407 release_resource(&io_space);
408 release_resource(&config_space);
409 kfree(bus);
410 return NULL;
411 }
412#endif 400#endif
413 bus->io_space.start = pci_io_base_virt; 401 bus->io_space.start = pci_io_base_virt;
414 bus->io_space.end = pci_io_base_virt + HADES_VIRT_IO_SIZE - 1; 402 bus->io_space.end = pci_io_base_virt + HADES_VIRT_IO_SIZE - 1;
415 bus->io_space.name = pci_io_name; 403 bus->io_space.name = pci_io_name;
416#if 1 404#if 1
417 if (request_resource(&ioport_resource, &bus->io_space) != 0) 405 if (unlikely(request_resource(&ioport_resource, &bus->io_space) != 0))
418 { 406 goto release_bus_mem_space;
419 release_resource(&bus->mem_space);
420 release_resource(&io_space);
421 release_resource(&config_space);
422 kfree(bus);
423 return NULL;
424 }
425#endif 407#endif
426 /* 408 /*
427 * Set hardware dependent functions. 409 * Set hardware dependent functions.
@@ -438,5 +420,21 @@ struct pci_bus_info * __init init_hades_pci(void)
438 tt_mfp.active_edge &= ~0x27; 420 tt_mfp.active_edge &= ~0x27;
439 421
440 return bus; 422 return bus;
423
424release_bus_mem_space:
425 release_resource(&bus->mem_space);
426release_io_space:
427 release_resource(&io_space);
428release_config_space:
429 release_resource(&config_space);
430free_bus:
431 kfree(bus);
432iounmap_base_virt:
433 iounmap((void *)pci_io_base_virt);
434
435 for (i = 0; i < N_SLOTS; i++)
436 iounmap((void *)pci_conf_base_virt[i]);
437
438 return NULL;
441} 439}
442#endif 440#endif
diff --git a/arch/m68k/atari/stdma.c b/arch/m68k/atari/stdma.c
index ab3fd5202b24..d1bd029a34ac 100644
--- a/arch/m68k/atari/stdma.c
+++ b/arch/m68k/atari/stdma.c
@@ -35,6 +35,7 @@
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/wait.h> 37#include <linux/wait.h>
38#include <linux/module.h>
38 39
39#include <asm/atari_stdma.h> 40#include <asm/atari_stdma.h>
40#include <asm/atariints.h> 41#include <asm/atariints.h>
@@ -91,6 +92,7 @@ void stdma_lock(irq_handler_t handler, void *data)
91 stdma_isr_data = data; 92 stdma_isr_data = data;
92 local_irq_restore(flags); 93 local_irq_restore(flags);
93} 94}
95EXPORT_SYMBOL(stdma_lock);
94 96
95 97
96/* 98/*
@@ -117,6 +119,7 @@ void stdma_release(void)
117 119
118 local_irq_restore(flags); 120 local_irq_restore(flags);
119} 121}
122EXPORT_SYMBOL(stdma_release);
120 123
121 124
122/* 125/*
@@ -134,6 +137,7 @@ int stdma_others_waiting(void)
134{ 137{
135 return waitqueue_active(&stdma_wait); 138 return waitqueue_active(&stdma_wait);
136} 139}
140EXPORT_SYMBOL(stdma_others_waiting);
137 141
138 142
139/* 143/*
@@ -155,6 +159,7 @@ int stdma_islocked(void)
155{ 159{
156 return stdma_locked; 160 return stdma_locked;
157} 161}
162EXPORT_SYMBOL(stdma_islocked);
158 163
159 164
160/* 165/*
diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
index bf4588cbe371..8dda6515887a 100644
--- a/arch/m68k/atari/stram.c
+++ b/arch/m68k/atari/stram.c
@@ -20,6 +20,7 @@
20#include <linux/bootmem.h> 20#include <linux/bootmem.h>
21#include <linux/mount.h> 21#include <linux/mount.h>
22#include <linux/blkdev.h> 22#include <linux/blkdev.h>
23#include <linux/module.h>
23 24
24#include <asm/setup.h> 25#include <asm/setup.h>
25#include <asm/machdep.h> 26#include <asm/machdep.h>
@@ -208,6 +209,7 @@ void *atari_stram_alloc(long size, const char *owner)
208 } 209 }
209 return( addr ); 210 return( addr );
210} 211}
212EXPORT_SYMBOL(atari_stram_alloc);
211 213
212void atari_stram_free( void *addr ) 214void atari_stram_free( void *addr )
213 215
@@ -237,6 +239,7 @@ void atari_stram_free( void *addr )
237 printk( KERN_ERR "atari_stram_free: cannot free block at %p " 239 printk( KERN_ERR "atari_stram_free: cannot free block at %p "
238 "(called from %p)\n", addr, __builtin_return_address(0) ); 240 "(called from %p)\n", addr, __builtin_return_address(0) );
239} 241}
242EXPORT_SYMBOL(atari_stram_free);
240 243
241 244
242/* ------------------------------------------------------------------------ */ 245/* ------------------------------------------------------------------------ */
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index 15b80abfe94a..ff9dffa5b860 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -678,7 +678,6 @@ CONFIG_LOGO_MAC_CLUT224=y
678# 678#
679CONFIG_MAC_SCC=y 679CONFIG_MAC_SCC=y
680CONFIG_MAC_HID=y 680CONFIG_MAC_HID=y
681CONFIG_MAC_ADBKEYCODES=y
682CONFIG_SERIAL_CONSOLE=y 681CONFIG_SERIAL_CONSOLE=y
683 682
684# 683#
diff --git a/arch/m68k/hp300/Makefile b/arch/m68k/hp300/Makefile
index 288b9c67c9bf..96d4244c82fd 100644
--- a/arch/m68k/hp300/Makefile
+++ b/arch/m68k/hp300/Makefile
@@ -2,4 +2,4 @@
2# Makefile for Linux arch/m68k/hp300 source directory 2# Makefile for Linux arch/m68k/hp300 source directory
3# 3#
4 4
5obj-y := ksyms.o config.o time.o reboot.o 5obj-y := config.o time.o reboot.o
diff --git a/arch/m68k/hp300/ksyms.c b/arch/m68k/hp300/ksyms.c
deleted file mode 100644
index 8202830763d1..000000000000
--- a/arch/m68k/hp300/ksyms.c
+++ /dev/null
@@ -1,9 +0,0 @@
1/*
2 * linux/arch/m68k/hp300/ksyms.c
3 *
4 * Copyright (C) 1998 Philip Blundell <philb@gnu.org>
5 *
6 * This file contains the HP300-specific kernel symbols. None yet. :-)
7 */
8
9#include <linux/module.h>
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 918f5dbeaef6..6dfa3b3c0e2a 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -742,7 +742,7 @@ sys_call_table:
742 .long sys_epoll_pwait /* 315 */ 742 .long sys_epoll_pwait /* 315 */
743 .long sys_utimensat 743 .long sys_utimensat
744 .long sys_signalfd 744 .long sys_signalfd
745 .long sys_timerfd 745 .long sys_ni_syscall
746 .long sys_eventfd 746 .long sys_eventfd
747 .long sys_fallocate /* 320 */ 747 .long sys_fallocate /* 320 */
748 748
diff --git a/arch/m68k/mac/Makefile b/arch/m68k/mac/Makefile
index 995a09d912f5..1d265ba365ad 100644
--- a/arch/m68k/mac/Makefile
+++ b/arch/m68k/mac/Makefile
@@ -3,4 +3,4 @@
3# 3#
4 4
5obj-y := config.o bootparse.o macints.o iop.o via.o oss.o psc.o \ 5obj-y := config.o bootparse.o macints.o iop.o via.o oss.o psc.o \
6 baboon.o macboing.o debug.o misc.o mac_ksyms.o 6 baboon.o macboing.o debug.o misc.o
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 01b468b9392e..735a49b4b936 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -58,8 +58,6 @@ extern struct mem_info m68k_memory[NUM_MEMINFO];
58 58
59extern struct mem_info m68k_ramdisk; 59extern struct mem_info m68k_ramdisk;
60 60
61extern char m68k_command_line[CL_SIZE];
62
63void *mac_env; /* Loaded by the boot asm */ 61void *mac_env; /* Loaded by the boot asm */
64 62
65/* The phys. video addr. - might be bogus on some machines */ 63/* The phys. video addr. - might be bogus on some machines */
diff --git a/arch/m68k/mac/mac_ksyms.c b/arch/m68k/mac/mac_ksyms.c
deleted file mode 100644
index 6e37ceb0f3b5..000000000000
--- a/arch/m68k/mac/mac_ksyms.c
+++ /dev/null
@@ -1,8 +0,0 @@
1#include <linux/module.h>
2#include <asm/ptrace.h>
3#include <asm/traps.h>
4
5/* Says whether we're using A/UX interrupts or not */
6extern int via_alt_mapping;
7
8EXPORT_SYMBOL(via_alt_mapping);
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index 8df270e950fa..fa485df4160e 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -28,6 +28,7 @@
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/ide.h> 30#include <linux/ide.h>
31#include <linux/module.h>
31 32
32#include <asm/bootinfo.h> 33#include <asm/bootinfo.h>
33#include <asm/macintosh.h> 34#include <asm/macintosh.h>
@@ -41,7 +42,9 @@ volatile __u8 *via1, *via2;
41/* See note in mac_via.h about how this is possibly not useful */ 42/* See note in mac_via.h about how this is possibly not useful */
42volatile long *via_memory_bogon=(long *)&via_memory_bogon; 43volatile long *via_memory_bogon=(long *)&via_memory_bogon;
43#endif 44#endif
44int rbv_present, via_alt_mapping; 45int rbv_present;
46int via_alt_mapping;
47EXPORT_SYMBOL(via_alt_mapping);
45__u8 rbv_clear; 48__u8 rbv_clear;
46 49
47/* 50/*
diff --git a/arch/m68k/mvme16x/Makefile b/arch/m68k/mvme16x/Makefile
index 950e82f21640..edb3f6e6ee6a 100644
--- a/arch/m68k/mvme16x/Makefile
+++ b/arch/m68k/mvme16x/Makefile
@@ -2,4 +2,4 @@
2# Makefile for Linux arch/m68k/mvme16x source directory 2# Makefile for Linux arch/m68k/mvme16x source directory
3# 3#
4 4
5obj-y := config.o rtc.o mvme16x_ksyms.o 5obj-y := config.o rtc.o
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
index daa785161401..24cbc3030454 100644
--- a/arch/m68k/mvme16x/config.c
+++ b/arch/m68k/mvme16x/config.c
@@ -25,6 +25,7 @@
25#include <linux/genhd.h> 25#include <linux/genhd.h>
26#include <linux/rtc.h> 26#include <linux/rtc.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/module.h>
28 29
29#include <asm/bootinfo.h> 30#include <asm/bootinfo.h>
30#include <asm/system.h> 31#include <asm/system.h>
@@ -58,6 +59,7 @@ static irq_handler_t tick_handler;
58 59
59 60
60unsigned short mvme16x_config; 61unsigned short mvme16x_config;
62EXPORT_SYMBOL(mvme16x_config);
61 63
62 64
63int mvme16x_parse_bootinfo(const struct bi_record *bi) 65int mvme16x_parse_bootinfo(const struct bi_record *bi)
diff --git a/arch/m68k/mvme16x/mvme16x_ksyms.c b/arch/m68k/mvme16x/mvme16x_ksyms.c
deleted file mode 100644
index 4a8a3634bb47..000000000000
--- a/arch/m68k/mvme16x/mvme16x_ksyms.c
+++ /dev/null
@@ -1,6 +0,0 @@
1#include <linux/module.h>
2#include <linux/types.h>
3#include <asm/ptrace.h>
4#include <asm/mvme16xhw.h>
5
6EXPORT_SYMBOL(mvme16x_config);
diff --git a/arch/m68knommu/Kconfig.debug b/arch/m68knommu/Kconfig.debug
index 9ff47bd09aee..ed6d9a83bfdb 100644
--- a/arch/m68knommu/Kconfig.debug
+++ b/arch/m68knommu/Kconfig.debug
@@ -21,13 +21,6 @@ config BOOTPARAM_STRING
21 default 'console=ttyS0,19200' 21 default 'console=ttyS0,19200'
22 depends on BOOTPARAM 22 depends on BOOTPARAM
23 23
24config DUMPTOFLASH
25 bool "Panic/Dump to FLASH"
26 depends on COLDFIRE
27 help
28 Dump any panic of trap output into a flash memory segment
29 for later analysis.
30
31config NO_KERNEL_MSG 24config NO_KERNEL_MSG
32 bool "Suppress Kernel BUG Messages" 25 bool "Suppress Kernel BUG Messages"
33 help 26 help
diff --git a/arch/m68knommu/defconfig b/arch/m68knommu/defconfig
index 5a0ecaaee3b0..648113075f97 100644
--- a/arch/m68knommu/defconfig
+++ b/arch/m68knommu/defconfig
@@ -597,7 +597,6 @@ CONFIG_MSDOS_PARTITION=y
597# CONFIG_FULLDEBUG is not set 597# CONFIG_FULLDEBUG is not set
598# CONFIG_HIGHPROFILE is not set 598# CONFIG_HIGHPROFILE is not set
599# CONFIG_BOOTPARAM is not set 599# CONFIG_BOOTPARAM is not set
600# CONFIG_DUMPTOFLASH is not set
601# CONFIG_NO_KERNEL_MSG is not set 600# CONFIG_NO_KERNEL_MSG is not set
602# CONFIG_BDM_DISABLE is not set 601# CONFIG_BDM_DISABLE is not set
603 602
diff --git a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68knommu/kernel/m68k_ksyms.c
index f795062aba1e..53fad1490282 100644
--- a/arch/m68knommu/kernel/m68k_ksyms.c
+++ b/arch/m68knommu/kernel/m68k_ksyms.c
@@ -24,14 +24,6 @@ extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
24EXPORT_SYMBOL(__ioremap); 24EXPORT_SYMBOL(__ioremap);
25EXPORT_SYMBOL(iounmap); 25EXPORT_SYMBOL(iounmap);
26EXPORT_SYMBOL(dump_fpu); 26EXPORT_SYMBOL(dump_fpu);
27EXPORT_SYMBOL(strnlen);
28EXPORT_SYMBOL(strrchr);
29EXPORT_SYMBOL(strstr);
30EXPORT_SYMBOL(strchr);
31EXPORT_SYMBOL(strcat);
32EXPORT_SYMBOL(strlen);
33EXPORT_SYMBOL(strcmp);
34EXPORT_SYMBOL(strncmp);
35 27
36EXPORT_SYMBOL(ip_fast_csum); 28EXPORT_SYMBOL(ip_fast_csum);
37 29
@@ -46,9 +38,6 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck);
46 it's OK to leave it out of version control. */ 38 it's OK to leave it out of version control. */
47EXPORT_SYMBOL(memcpy); 39EXPORT_SYMBOL(memcpy);
48EXPORT_SYMBOL(memset); 40EXPORT_SYMBOL(memset);
49EXPORT_SYMBOL(memcmp);
50EXPORT_SYMBOL(memscan);
51EXPORT_SYMBOL(memmove);
52 41
53EXPORT_SYMBOL(__down_failed); 42EXPORT_SYMBOL(__down_failed);
54EXPORT_SYMBOL(__down_failed_interruptible); 43EXPORT_SYMBOL(__down_failed_interruptible);
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index 332345d7675d..81507c53d4a9 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -64,9 +64,6 @@ void (*mach_power_off)(void);
64#ifdef CONFIG_M68VZ328 64#ifdef CONFIG_M68VZ328
65 #define CPU "MC68VZ328" 65 #define CPU "MC68VZ328"
66#endif 66#endif
67#ifdef CONFIG_M68332
68 #define CPU "MC68332"
69#endif
70#ifdef CONFIG_M68360 67#ifdef CONFIG_M68360
71 #define CPU "MC68360" 68 #define CPU "MC68360"
72#endif 69#endif
diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S
index 9620093514bc..1b02b8820068 100644
--- a/arch/m68knommu/kernel/syscalltable.S
+++ b/arch/m68knommu/kernel/syscalltable.S
@@ -336,7 +336,7 @@ ENTRY(sys_call_table)
336 .long sys_epoll_pwait /* 315 */ 336 .long sys_epoll_pwait /* 315 */
337 .long sys_utimensat 337 .long sys_utimensat
338 .long sys_signalfd 338 .long sys_signalfd
339 .long sys_timerfd 339 .long sys_ni_syscall
340 .long sys_eventfd 340 .long sys_eventfd
341 .long sys_fallocate /* 320 */ 341 .long sys_fallocate /* 320 */
342 342
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 82480a1717d8..f798139e888e 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -660,7 +660,7 @@ einval: li v0, -EINVAL
660 sys sys_ioprio_get 2 /* 4315 */ 660 sys sys_ioprio_get 2 /* 4315 */
661 sys sys_utimensat 4 661 sys sys_utimensat 4
662 sys sys_signalfd 3 662 sys sys_signalfd 3
663 sys sys_timerfd 4 663 sys sys_ni_syscall 0
664 sys sys_eventfd 1 664 sys sys_eventfd 1
665 sys sys_fallocate 6 /* 4320 */ 665 sys sys_fallocate 6 /* 4320 */
666 .endm 666 .endm
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index c2c10876da2e..a626be6baea3 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -475,7 +475,7 @@ sys_call_table:
475 PTR sys_ioprio_get 475 PTR sys_ioprio_get
476 PTR sys_utimensat /* 5275 */ 476 PTR sys_utimensat /* 5275 */
477 PTR sys_signalfd 477 PTR sys_signalfd
478 PTR sys_timerfd 478 PTR sys_ni_syscall
479 PTR sys_eventfd 479 PTR sys_eventfd
480 PTR sys_fallocate 480 PTR sys_fallocate
481 .size sys_call_table,.-sys_call_table 481 .size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 01993ec3368b..9d5bcaf1b389 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -401,7 +401,7 @@ EXPORT(sysn32_call_table)
401 PTR sys_ioprio_get 401 PTR sys_ioprio_get
402 PTR compat_sys_utimensat 402 PTR compat_sys_utimensat
403 PTR compat_sys_signalfd /* 5280 */ 403 PTR compat_sys_signalfd /* 5280 */
404 PTR compat_sys_timerfd 404 PTR sys_ni_syscall
405 PTR sys_eventfd 405 PTR sys_eventfd
406 PTR sys_fallocate 406 PTR sys_fallocate
407 .size sysn32_call_table,.-sysn32_call_table 407 .size sysn32_call_table,.-sysn32_call_table
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index dd68afce7da5..fd2019c1ec2d 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -523,7 +523,7 @@ sys_call_table:
523 PTR sys_ioprio_get /* 4315 */ 523 PTR sys_ioprio_get /* 4315 */
524 PTR compat_sys_utimensat 524 PTR compat_sys_utimensat
525 PTR compat_sys_signalfd 525 PTR compat_sys_signalfd
526 PTR compat_sys_timerfd 526 PTR sys_ni_syscall
527 PTR sys_eventfd 527 PTR sys_eventfd
528 PTR sys32_fallocate /* 4320 */ 528 PTR sys32_fallocate /* 4320 */
529 .size sys_call_table,.-sys_call_table 529 .size sys_call_table,.-sys_call_table
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b94d4502a477..cf030b004415 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -256,6 +256,9 @@ config IOMMU_VMERGE
256 256
257 Most drivers don't have this problem; it is safe to say Y here. 257 Most drivers don't have this problem; it is safe to say Y here.
258 258
259config IOMMU_HELPER
260 def_bool PPC64
261
259config HOTPLUG_CPU 262config HOTPLUG_CPU
260 bool "Support for enabling/disabling CPUs" 263 bool "Support for enabling/disabling CPUs"
261 depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC) 264 depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC)
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 84239076a5b8..3a317cb0636a 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -31,8 +31,8 @@ static inline unsigned long device_to_mask(struct device *dev)
31static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, 31static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
32 dma_addr_t *dma_handle, gfp_t flag) 32 dma_addr_t *dma_handle, gfp_t flag)
33{ 33{
34 return iommu_alloc_coherent(dev->archdata.dma_data, size, dma_handle, 34 return iommu_alloc_coherent(dev, dev->archdata.dma_data, size,
35 device_to_mask(dev), flag, 35 dma_handle, device_to_mask(dev), flag,
36 dev->archdata.numa_node); 36 dev->archdata.numa_node);
37} 37}
38 38
@@ -52,7 +52,7 @@ static dma_addr_t dma_iommu_map_single(struct device *dev, void *vaddr,
52 size_t size, 52 size_t size,
53 enum dma_data_direction direction) 53 enum dma_data_direction direction)
54{ 54{
55 return iommu_map_single(dev->archdata.dma_data, vaddr, size, 55 return iommu_map_single(dev, dev->archdata.dma_data, vaddr, size,
56 device_to_mask(dev), direction); 56 device_to_mask(dev), direction);
57} 57}
58 58
@@ -68,7 +68,7 @@ static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle,
68static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist, 68static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
69 int nelems, enum dma_data_direction direction) 69 int nelems, enum dma_data_direction direction)
70{ 70{
71 return iommu_map_sg(dev->archdata.dma_data, sglist, nelems, 71 return iommu_map_sg(dev, sglist, nelems,
72 device_to_mask(dev), direction); 72 device_to_mask(dev), direction);
73} 73}
74 74
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index a3c406aca664..8f1f4e539c4b 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -31,6 +31,7 @@
31#include <linux/string.h> 31#include <linux/string.h>
32#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
33#include <linux/bitops.h> 33#include <linux/bitops.h>
34#include <linux/iommu-helper.h>
34#include <asm/io.h> 35#include <asm/io.h>
35#include <asm/prom.h> 36#include <asm/prom.h>
36#include <asm/iommu.h> 37#include <asm/iommu.h>
@@ -81,17 +82,19 @@ static int __init setup_iommu(char *str)
81__setup("protect4gb=", setup_protect4gb); 82__setup("protect4gb=", setup_protect4gb);
82__setup("iommu=", setup_iommu); 83__setup("iommu=", setup_iommu);
83 84
84static unsigned long iommu_range_alloc(struct iommu_table *tbl, 85static unsigned long iommu_range_alloc(struct device *dev,
86 struct iommu_table *tbl,
85 unsigned long npages, 87 unsigned long npages,
86 unsigned long *handle, 88 unsigned long *handle,
87 unsigned long mask, 89 unsigned long mask,
88 unsigned int align_order) 90 unsigned int align_order)
89{ 91{
90 unsigned long n, end, i, start; 92 unsigned long n, end, start;
91 unsigned long limit; 93 unsigned long limit;
92 int largealloc = npages > 15; 94 int largealloc = npages > 15;
93 int pass = 0; 95 int pass = 0;
94 unsigned long align_mask; 96 unsigned long align_mask;
97 unsigned long boundary_size;
95 98
96 align_mask = 0xffffffffffffffffl >> (64 - align_order); 99 align_mask = 0xffffffffffffffffl >> (64 - align_order);
97 100
@@ -136,14 +139,17 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
136 start &= mask; 139 start &= mask;
137 } 140 }
138 141
139 n = find_next_zero_bit(tbl->it_map, limit, start); 142 if (dev)
140 143 boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
141 /* Align allocation */ 144 1 << IOMMU_PAGE_SHIFT);
142 n = (n + align_mask) & ~align_mask; 145 else
143 146 boundary_size = ALIGN(1UL << 32, 1 << IOMMU_PAGE_SHIFT);
144 end = n + npages; 147 /* 4GB boundary for iseries_hv_alloc and iseries_hv_map */
145 148
146 if (unlikely(end >= limit)) { 149 n = iommu_area_alloc(tbl->it_map, limit, start, npages,
150 tbl->it_offset, boundary_size >> IOMMU_PAGE_SHIFT,
151 align_mask);
152 if (n == -1) {
147 if (likely(pass < 2)) { 153 if (likely(pass < 2)) {
148 /* First failure, just rescan the half of the table. 154 /* First failure, just rescan the half of the table.
149 * Second failure, rescan the other half of the table. 155 * Second failure, rescan the other half of the table.
@@ -158,14 +164,7 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
158 } 164 }
159 } 165 }
160 166
161 for (i = n; i < end; i++) 167 end = n + npages;
162 if (test_bit(i, tbl->it_map)) {
163 start = i+1;
164 goto again;
165 }
166
167 for (i = n; i < end; i++)
168 __set_bit(i, tbl->it_map);
169 168
170 /* Bump the hint to a new block for small allocs. */ 169 /* Bump the hint to a new block for small allocs. */
171 if (largealloc) { 170 if (largealloc) {
@@ -184,16 +183,17 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
184 return n; 183 return n;
185} 184}
186 185
187static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page, 186static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
188 unsigned int npages, enum dma_data_direction direction, 187 void *page, unsigned int npages,
189 unsigned long mask, unsigned int align_order) 188 enum dma_data_direction direction,
189 unsigned long mask, unsigned int align_order)
190{ 190{
191 unsigned long entry, flags; 191 unsigned long entry, flags;
192 dma_addr_t ret = DMA_ERROR_CODE; 192 dma_addr_t ret = DMA_ERROR_CODE;
193 193
194 spin_lock_irqsave(&(tbl->it_lock), flags); 194 spin_lock_irqsave(&(tbl->it_lock), flags);
195 195
196 entry = iommu_range_alloc(tbl, npages, NULL, mask, align_order); 196 entry = iommu_range_alloc(dev, tbl, npages, NULL, mask, align_order);
197 197
198 if (unlikely(entry == DMA_ERROR_CODE)) { 198 if (unlikely(entry == DMA_ERROR_CODE)) {
199 spin_unlock_irqrestore(&(tbl->it_lock), flags); 199 spin_unlock_irqrestore(&(tbl->it_lock), flags);
@@ -224,7 +224,6 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
224 unsigned int npages) 224 unsigned int npages)
225{ 225{
226 unsigned long entry, free_entry; 226 unsigned long entry, free_entry;
227 unsigned long i;
228 227
229 entry = dma_addr >> IOMMU_PAGE_SHIFT; 228 entry = dma_addr >> IOMMU_PAGE_SHIFT;
230 free_entry = entry - tbl->it_offset; 229 free_entry = entry - tbl->it_offset;
@@ -246,9 +245,7 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
246 } 245 }
247 246
248 ppc_md.tce_free(tbl, entry, npages); 247 ppc_md.tce_free(tbl, entry, npages);
249 248 iommu_area_free(tbl->it_map, free_entry, npages);
250 for (i = 0; i < npages; i++)
251 __clear_bit(free_entry+i, tbl->it_map);
252} 249}
253 250
254static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, 251static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
@@ -270,16 +267,18 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
270 spin_unlock_irqrestore(&(tbl->it_lock), flags); 267 spin_unlock_irqrestore(&(tbl->it_lock), flags);
271} 268}
272 269
273int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, 270int iommu_map_sg(struct device *dev, struct scatterlist *sglist,
274 int nelems, unsigned long mask, 271 int nelems, unsigned long mask,
275 enum dma_data_direction direction) 272 enum dma_data_direction direction)
276{ 273{
274 struct iommu_table *tbl = dev->archdata.dma_data;
277 dma_addr_t dma_next = 0, dma_addr; 275 dma_addr_t dma_next = 0, dma_addr;
278 unsigned long flags; 276 unsigned long flags;
279 struct scatterlist *s, *outs, *segstart; 277 struct scatterlist *s, *outs, *segstart;
280 int outcount, incount, i; 278 int outcount, incount, i;
281 unsigned int align; 279 unsigned int align;
282 unsigned long handle; 280 unsigned long handle;
281 unsigned int max_seg_size;
283 282
284 BUG_ON(direction == DMA_NONE); 283 BUG_ON(direction == DMA_NONE);
285 284
@@ -298,6 +297,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
298 297
299 spin_lock_irqsave(&(tbl->it_lock), flags); 298 spin_lock_irqsave(&(tbl->it_lock), flags);
300 299
300 max_seg_size = dma_get_max_seg_size(dev);
301 for_each_sg(sglist, s, nelems, i) { 301 for_each_sg(sglist, s, nelems, i) {
302 unsigned long vaddr, npages, entry, slen; 302 unsigned long vaddr, npages, entry, slen;
303 303
@@ -314,7 +314,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
314 if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && slen >= PAGE_SIZE && 314 if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && slen >= PAGE_SIZE &&
315 (vaddr & ~PAGE_MASK) == 0) 315 (vaddr & ~PAGE_MASK) == 0)
316 align = PAGE_SHIFT - IOMMU_PAGE_SHIFT; 316 align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
317 entry = iommu_range_alloc(tbl, npages, &handle, 317 entry = iommu_range_alloc(dev, tbl, npages, &handle,
318 mask >> IOMMU_PAGE_SHIFT, align); 318 mask >> IOMMU_PAGE_SHIFT, align);
319 319
320 DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen); 320 DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen);
@@ -344,7 +344,8 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
344 /* We cannot merge if: 344 /* We cannot merge if:
345 * - allocated dma_addr isn't contiguous to previous allocation 345 * - allocated dma_addr isn't contiguous to previous allocation
346 */ 346 */
347 if (novmerge || (dma_addr != dma_next)) { 347 if (novmerge || (dma_addr != dma_next) ||
348 (outs->dma_length + s->length > max_seg_size)) {
348 /* Can't merge: create a new segment */ 349 /* Can't merge: create a new segment */
349 segstart = s; 350 segstart = s;
350 outcount++; 351 outcount++;
@@ -452,9 +453,6 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
452struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) 453struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
453{ 454{
454 unsigned long sz; 455 unsigned long sz;
455 unsigned long start_index, end_index;
456 unsigned long entries_per_4g;
457 unsigned long index;
458 static int welcomed = 0; 456 static int welcomed = 0;
459 struct page *page; 457 struct page *page;
460 458
@@ -476,6 +474,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
476 474
477#ifdef CONFIG_CRASH_DUMP 475#ifdef CONFIG_CRASH_DUMP
478 if (ppc_md.tce_get) { 476 if (ppc_md.tce_get) {
477 unsigned long index;
479 unsigned long tceval; 478 unsigned long tceval;
480 unsigned long tcecount = 0; 479 unsigned long tcecount = 0;
481 480
@@ -506,23 +505,6 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
506 ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); 505 ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
507#endif 506#endif
508 507
509 /*
510 * DMA cannot cross 4 GB boundary. Mark last entry of each 4
511 * GB chunk as reserved.
512 */
513 if (protect4gb) {
514 entries_per_4g = 0x100000000l >> IOMMU_PAGE_SHIFT;
515
516 /* Mark the last bit before a 4GB boundary as used */
517 start_index = tbl->it_offset | (entries_per_4g - 1);
518 start_index -= tbl->it_offset;
519
520 end_index = tbl->it_size;
521
522 for (index = start_index; index < end_index - 1; index += entries_per_4g)
523 __set_bit(index, tbl->it_map);
524 }
525
526 if (!welcomed) { 508 if (!welcomed) {
527 printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", 509 printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n",
528 novmerge ? "disabled" : "enabled"); 510 novmerge ? "disabled" : "enabled");
@@ -570,9 +552,9 @@ void iommu_free_table(struct iommu_table *tbl, const char *node_name)
570 * need not be page aligned, the dma_addr_t returned will point to the same 552 * need not be page aligned, the dma_addr_t returned will point to the same
571 * byte within the page as vaddr. 553 * byte within the page as vaddr.
572 */ 554 */
573dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, 555dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
574 size_t size, unsigned long mask, 556 void *vaddr, size_t size, unsigned long mask,
575 enum dma_data_direction direction) 557 enum dma_data_direction direction)
576{ 558{
577 dma_addr_t dma_handle = DMA_ERROR_CODE; 559 dma_addr_t dma_handle = DMA_ERROR_CODE;
578 unsigned long uaddr; 560 unsigned long uaddr;
@@ -589,7 +571,7 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
589 ((unsigned long)vaddr & ~PAGE_MASK) == 0) 571 ((unsigned long)vaddr & ~PAGE_MASK) == 0)
590 align = PAGE_SHIFT - IOMMU_PAGE_SHIFT; 572 align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
591 573
592 dma_handle = iommu_alloc(tbl, vaddr, npages, direction, 574 dma_handle = iommu_alloc(dev, tbl, vaddr, npages, direction,
593 mask >> IOMMU_PAGE_SHIFT, align); 575 mask >> IOMMU_PAGE_SHIFT, align);
594 if (dma_handle == DMA_ERROR_CODE) { 576 if (dma_handle == DMA_ERROR_CODE) {
595 if (printk_ratelimit()) { 577 if (printk_ratelimit()) {
@@ -621,8 +603,9 @@ void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
621 * Returns the virtual address of the buffer and sets dma_handle 603 * Returns the virtual address of the buffer and sets dma_handle
622 * to the dma address (mapping) of the first page. 604 * to the dma address (mapping) of the first page.
623 */ 605 */
624void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, 606void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
625 dma_addr_t *dma_handle, unsigned long mask, gfp_t flag, int node) 607 size_t size, dma_addr_t *dma_handle,
608 unsigned long mask, gfp_t flag, int node)
626{ 609{
627 void *ret = NULL; 610 void *ret = NULL;
628 dma_addr_t mapping; 611 dma_addr_t mapping;
@@ -656,7 +639,7 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
656 /* Set up tces to cover the allocated range */ 639 /* Set up tces to cover the allocated range */
657 nio_pages = size >> IOMMU_PAGE_SHIFT; 640 nio_pages = size >> IOMMU_PAGE_SHIFT;
658 io_order = get_iommu_order(size); 641 io_order = get_iommu_order(size);
659 mapping = iommu_alloc(tbl, ret, nio_pages, DMA_BIDIRECTIONAL, 642 mapping = iommu_alloc(dev, tbl, ret, nio_pages, DMA_BIDIRECTIONAL,
660 mask >> IOMMU_PAGE_SHIFT, io_order); 643 mask >> IOMMU_PAGE_SHIFT, io_order);
661 if (mapping == DMA_ERROR_CODE) { 644 if (mapping == DMA_ERROR_CODE) {
662 free_pages((unsigned long)ret, order); 645 free_pages((unsigned long)ret, order);
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 64488723162a..f80f90c4d58b 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -86,7 +86,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
86 return ret; 86 return ret;
87} 87}
88 88
89void pgd_free(pgd_t *pgd) 89void pgd_free(struct mm_struct *mm, pgd_t *pgd)
90{ 90{
91 free_pages((unsigned long)pgd, PGDIR_ORDER); 91 free_pages((unsigned long)pgd, PGDIR_ORDER);
92} 92}
@@ -123,7 +123,7 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
123 return ptepage; 123 return ptepage;
124} 124}
125 125
126void pte_free_kernel(pte_t *pte) 126void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
127{ 127{
128#ifdef CONFIG_SMP 128#ifdef CONFIG_SMP
129 hash_page_sync(); 129 hash_page_sync();
@@ -131,7 +131,7 @@ void pte_free_kernel(pte_t *pte)
131 free_page((unsigned long)pte); 131 free_page((unsigned long)pte);
132} 132}
133 133
134void pte_free(struct page *ptepage) 134void pte_free(struct mm_struct *mm, struct page *ptepage)
135{ 135{
136#ifdef CONFIG_SMP 136#ifdef CONFIG_SMP
137 hash_page_sync(); 137 hash_page_sync();
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 6a0c6f6675cd..11fa3c772ed5 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -199,7 +199,7 @@ static struct iommu_table vio_iommu_table;
199 199
200void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag) 200void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag)
201{ 201{
202 return iommu_alloc_coherent(&vio_iommu_table, size, dma_handle, 202 return iommu_alloc_coherent(NULL, &vio_iommu_table, size, dma_handle,
203 DMA_32BIT_MASK, flag, -1); 203 DMA_32BIT_MASK, flag, -1);
204} 204}
205EXPORT_SYMBOL_GPL(iseries_hv_alloc); 205EXPORT_SYMBOL_GPL(iseries_hv_alloc);
@@ -213,7 +213,7 @@ EXPORT_SYMBOL_GPL(iseries_hv_free);
213dma_addr_t iseries_hv_map(void *vaddr, size_t size, 213dma_addr_t iseries_hv_map(void *vaddr, size_t size,
214 enum dma_data_direction direction) 214 enum dma_data_direction direction)
215{ 215{
216 return iommu_map_single(&vio_iommu_table, vaddr, size, 216 return iommu_map_single(NULL, &vio_iommu_table, vaddr, size,
217 DMA_32BIT_MASK, direction); 217 DMA_32BIT_MASK, direction);
218} 218}
219 219
diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c
index fadacfd18806..409fcaa4994a 100644
--- a/arch/ppc/mm/pgtable.c
+++ b/arch/ppc/mm/pgtable.c
@@ -74,7 +74,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
74 return ret; 74 return ret;
75} 75}
76 76
77void pgd_free(pgd_t *pgd) 77void pgd_free(struct mm_struct *mm, pgd_t *pgd)
78{ 78{
79 free_pages((unsigned long)pgd, PGDIR_ORDER); 79 free_pages((unsigned long)pgd, PGDIR_ORDER);
80} 80}
@@ -111,7 +111,7 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
111 return ptepage; 111 return ptepage;
112} 112}
113 113
114void pte_free_kernel(pte_t *pte) 114void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
115{ 115{
116#ifdef CONFIG_SMP 116#ifdef CONFIG_SMP
117 hash_page_sync(); 117 hash_page_sync();
@@ -119,7 +119,7 @@ void pte_free_kernel(pte_t *pte)
119 free_page((unsigned long)pte); 119 free_page((unsigned long)pte);
120} 120}
121 121
122void pte_free(struct page *ptepage) 122void pte_free(struct mm_struct *mm, struct page *ptepage)
123{ 123{
124#ifdef CONFIG_SMP 124#ifdef CONFIG_SMP
125 hash_page_sync(); 125 hash_page_sync();
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 82cbffd03654..92a4f7b4323a 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -16,6 +16,9 @@ config LOCKDEP_SUPPORT
16config STACKTRACE_SUPPORT 16config STACKTRACE_SUPPORT
17 def_bool y 17 def_bool y
18 18
19config HAVE_LATENCYTOP_SUPPORT
20 def_bool y
21
19config RWSEM_GENERIC_SPINLOCK 22config RWSEM_GENERIC_SPINLOCK
20 bool 23 bool
21 24
@@ -47,6 +50,11 @@ config NO_IOMEM
47config NO_DMA 50config NO_DMA
48 def_bool y 51 def_bool y
49 52
53config GENERIC_LOCKBREAK
54 bool
55 default y
56 depends on SMP && PREEMPT
57
50mainmenu "Linux Kernel Configuration" 58mainmenu "Linux Kernel Configuration"
51 59
52config S390 60config S390
diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug
index 2283933a9a93..4599fa06bd82 100644
--- a/arch/s390/Kconfig.debug
+++ b/arch/s390/Kconfig.debug
@@ -6,4 +6,12 @@ config TRACE_IRQFLAGS_SUPPORT
6 6
7source "lib/Kconfig.debug" 7source "lib/Kconfig.debug"
8 8
9config DEBUG_PAGEALLOC
10 bool "Debug page memory allocations"
11 depends on DEBUG_KERNEL
12 help
13 Unmap pages from the kernel linear mapping after free_pages().
14 This results in a slowdown, but helps to find certain types of
15 memory corruptions.
16
9endmenu 17endmenu
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 6ee1bedbd1bf..062c3d4c0394 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1698,14 +1698,6 @@ compat_sys_signalfd_wrapper:
1698 llgfr %r4,%r4 # compat_size_t 1698 llgfr %r4,%r4 # compat_size_t
1699 jg compat_sys_signalfd 1699 jg compat_sys_signalfd
1700 1700
1701 .globl compat_sys_timerfd_wrapper
1702compat_sys_timerfd_wrapper:
1703 lgfr %r2,%r2 # int
1704 lgfr %r3,%r3 # int
1705 lgfr %r4,%r4 # int
1706 llgtr %r5,%r5 # struct compat_itimerspec *
1707 jg compat_sys_timerfd
1708
1709 .globl sys_eventfd_wrapper 1701 .globl sys_eventfd_wrapper
1710sys_eventfd_wrapper: 1702sys_eventfd_wrapper:
1711 llgfr %r2,%r2 # unsigned int 1703 llgfr %r2,%r2 # unsigned int
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 1a6dac8df6fb..6766e37fe8ea 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -11,6 +11,7 @@
11 11
12#include <linux/sys.h> 12#include <linux/sys.h>
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <linux/init.h>
14#include <asm/cache.h> 15#include <asm/cache.h>
15#include <asm/lowcore.h> 16#include <asm/lowcore.h>
16#include <asm/errno.h> 17#include <asm/errno.h>
@@ -830,9 +831,7 @@ mcck_return:
830 * Restart interruption handler, kick starter for additional CPUs 831 * Restart interruption handler, kick starter for additional CPUs
831 */ 832 */
832#ifdef CONFIG_SMP 833#ifdef CONFIG_SMP
833#ifndef CONFIG_HOTPLUG_CPU 834 __CPUINIT
834 .section .init.text,"ax"
835#endif
836 .globl restart_int_handler 835 .globl restart_int_handler
837restart_int_handler: 836restart_int_handler:
838 l %r15,__LC_SAVE_AREA+60 # load ksp 837 l %r15,__LC_SAVE_AREA+60 # load ksp
@@ -845,9 +844,7 @@ restart_int_handler:
845 br %r14 # branch to start_secondary 844 br %r14 # branch to start_secondary
846restart_addr: 845restart_addr:
847 .long start_secondary 846 .long start_secondary
848#ifndef CONFIG_HOTPLUG_CPU
849 .previous 847 .previous
850#endif
851#else 848#else
852/* 849/*
853 * If we do not run with SMP enabled, let the new CPU crash ... 850 * If we do not run with SMP enabled, let the new CPU crash ...
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index a3e47b893f07..efde6e178f6c 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -11,6 +11,7 @@
11 11
12#include <linux/sys.h> 12#include <linux/sys.h>
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <linux/init.h>
14#include <asm/cache.h> 15#include <asm/cache.h>
15#include <asm/lowcore.h> 16#include <asm/lowcore.h>
16#include <asm/errno.h> 17#include <asm/errno.h>
@@ -801,9 +802,7 @@ mcck_return:
801 * Restart interruption handler, kick starter for additional CPUs 802 * Restart interruption handler, kick starter for additional CPUs
802 */ 803 */
803#ifdef CONFIG_SMP 804#ifdef CONFIG_SMP
804#ifndef CONFIG_HOTPLUG_CPU 805 __CPUINIT
805 .section .init.text,"ax"
806#endif
807 .globl restart_int_handler 806 .globl restart_int_handler
808restart_int_handler: 807restart_int_handler:
809 lg %r15,__LC_SAVE_AREA+120 # load ksp 808 lg %r15,__LC_SAVE_AREA+120 # load ksp
@@ -814,9 +813,7 @@ restart_int_handler:
814 lmg %r6,%r15,__SF_GPRS(%r15) # load registers from clone 813 lmg %r6,%r15,__SF_GPRS(%r15) # load registers from clone
815 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on 814 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on
816 jg start_secondary 815 jg start_secondary
817#ifndef CONFIG_HOTPLUG_CPU
818 .previous 816 .previous
819#endif
820#else 817#else
821/* 818/*
822 * If we do not run with SMP enabled, let the new CPU crash ... 819 * If we do not run with SMP enabled, let the new CPU crash ...
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index db28cca81fef..60acdc266db1 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -439,7 +439,7 @@ static void ipl_run(struct shutdown_trigger *trigger)
439 reipl_ccw_dev(&ipl_info.data.ccw.dev_id); 439 reipl_ccw_dev(&ipl_info.data.ccw.dev_id);
440} 440}
441 441
442static int ipl_init(void) 442static int __init ipl_init(void)
443{ 443{
444 int rc; 444 int rc;
445 445
@@ -471,8 +471,11 @@ out:
471 return 0; 471 return 0;
472} 472}
473 473
474static struct shutdown_action ipl_action = {SHUTDOWN_ACTION_IPL_STR, ipl_run, 474static struct shutdown_action __refdata ipl_action = {
475 ipl_init}; 475 .name = SHUTDOWN_ACTION_IPL_STR,
476 .fn = ipl_run,
477 .init = ipl_init,
478};
476 479
477/* 480/*
478 * reipl shutdown action: Reboot Linux on shutdown. 481 * reipl shutdown action: Reboot Linux on shutdown.
@@ -792,7 +795,7 @@ static int __init reipl_fcp_init(void)
792 return 0; 795 return 0;
793} 796}
794 797
795static int reipl_init(void) 798static int __init reipl_init(void)
796{ 799{
797 int rc; 800 int rc;
798 801
@@ -819,8 +822,11 @@ static int reipl_init(void)
819 return 0; 822 return 0;
820} 823}
821 824
822static struct shutdown_action reipl_action = {SHUTDOWN_ACTION_REIPL_STR, 825static struct shutdown_action __refdata reipl_action = {
823 reipl_run, reipl_init}; 826 .name = SHUTDOWN_ACTION_REIPL_STR,
827 .fn = reipl_run,
828 .init = reipl_init,
829};
824 830
825/* 831/*
826 * dump shutdown action: Dump Linux on shutdown. 832 * dump shutdown action: Dump Linux on shutdown.
@@ -998,7 +1004,7 @@ static int __init dump_fcp_init(void)
998 return 0; 1004 return 0;
999} 1005}
1000 1006
1001static int dump_init(void) 1007static int __init dump_init(void)
1002{ 1008{
1003 int rc; 1009 int rc;
1004 1010
@@ -1020,8 +1026,11 @@ static int dump_init(void)
1020 return 0; 1026 return 0;
1021} 1027}
1022 1028
1023static struct shutdown_action dump_action = {SHUTDOWN_ACTION_DUMP_STR, 1029static struct shutdown_action __refdata dump_action = {
1024 dump_run, dump_init}; 1030 .name = SHUTDOWN_ACTION_DUMP_STR,
1031 .fn = dump_run,
1032 .init = dump_init,
1033};
1025 1034
1026/* 1035/*
1027 * vmcmd shutdown action: Trigger vm command on shutdown. 1036 * vmcmd shutdown action: Trigger vm command on shutdown.
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 766c783bd7a7..29ae165d1749 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -77,7 +77,7 @@ unsigned long machine_flags = 0;
77unsigned long elf_hwcap = 0; 77unsigned long elf_hwcap = 0;
78char elf_platform[ELF_PLATFORM_SIZE]; 78char elf_platform[ELF_PLATFORM_SIZE];
79 79
80struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; 80struct mem_chunk __meminitdata memory_chunk[MEMORY_CHUNKS];
81volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ 81volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
82static unsigned long __initdata memory_end; 82static unsigned long __initdata memory_end;
83 83
@@ -145,7 +145,7 @@ __setup("condev=", condev_setup);
145 145
146static int __init conmode_setup(char *str) 146static int __init conmode_setup(char *str)
147{ 147{
148#if defined(CONFIG_SCLP_CONSOLE) 148#if defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE)
149 if (strncmp(str, "hwc", 4) == 0 || strncmp(str, "sclp", 5) == 0) 149 if (strncmp(str, "hwc", 4) == 0 || strncmp(str, "sclp", 5) == 0)
150 SET_CONSOLE_SCLP; 150 SET_CONSOLE_SCLP;
151#endif 151#endif
@@ -183,7 +183,7 @@ static void __init conmode_default(void)
183 */ 183 */
184 cpcmd("TERM CONMODE 3215", NULL, 0, NULL); 184 cpcmd("TERM CONMODE 3215", NULL, 0, NULL);
185 if (ptr == NULL) { 185 if (ptr == NULL) {
186#if defined(CONFIG_SCLP_CONSOLE) 186#if defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE)
187 SET_CONSOLE_SCLP; 187 SET_CONSOLE_SCLP;
188#endif 188#endif
189 return; 189 return;
@@ -193,7 +193,7 @@ static void __init conmode_default(void)
193 SET_CONSOLE_3270; 193 SET_CONSOLE_3270;
194#elif defined(CONFIG_TN3215_CONSOLE) 194#elif defined(CONFIG_TN3215_CONSOLE)
195 SET_CONSOLE_3215; 195 SET_CONSOLE_3215;
196#elif defined(CONFIG_SCLP_CONSOLE) 196#elif defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE)
197 SET_CONSOLE_SCLP; 197 SET_CONSOLE_SCLP;
198#endif 198#endif
199 } else if (strncmp(ptr + 8, "3215", 4) == 0) { 199 } else if (strncmp(ptr + 8, "3215", 4) == 0) {
@@ -201,7 +201,7 @@ static void __init conmode_default(void)
201 SET_CONSOLE_3215; 201 SET_CONSOLE_3215;
202#elif defined(CONFIG_TN3270_CONSOLE) 202#elif defined(CONFIG_TN3270_CONSOLE)
203 SET_CONSOLE_3270; 203 SET_CONSOLE_3270;
204#elif defined(CONFIG_SCLP_CONSOLE) 204#elif defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE)
205 SET_CONSOLE_SCLP; 205 SET_CONSOLE_SCLP;
206#endif 206#endif
207 } 207 }
@@ -212,7 +212,7 @@ static void __init conmode_default(void)
212 SET_CONSOLE_3270; 212 SET_CONSOLE_3270;
213#endif 213#endif
214 } else { 214 } else {
215#if defined(CONFIG_SCLP_CONSOLE) 215#if defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE)
216 SET_CONSOLE_SCLP; 216 SET_CONSOLE_SCLP;
217#endif 217#endif
218 } 218 }
@@ -528,7 +528,7 @@ static void __init setup_memory_end(void)
528 memory_size = 0; 528 memory_size = 0;
529 memory_end &= PAGE_MASK; 529 memory_end &= PAGE_MASK;
530 530
531 max_mem = memory_end ? min(VMALLOC_START, memory_end) : VMALLOC_START; 531 max_mem = memory_end ? min(VMEM_MAX_PHYS, memory_end) : VMEM_MAX_PHYS;
532 memory_end = min(max_mem, memory_end); 532 memory_end = min(max_mem, memory_end);
533 533
534 /* 534 /*
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index aa37fa154512..85060659fb12 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -225,12 +225,11 @@ EXPORT_SYMBOL(smp_call_function_single);
225 * You must not call this function with disabled interrupts or from a 225 * You must not call this function with disabled interrupts or from a
226 * hardware interrupt handler or from a bottom half handler. 226 * hardware interrupt handler or from a bottom half handler.
227 */ 227 */
228int 228int smp_call_function_mask(cpumask_t mask, void (*func)(void *), void *info,
229smp_call_function_mask(cpumask_t mask, 229 int wait)
230 void (*func)(void *), void *info,
231 int wait)
232{ 230{
233 preempt_disable(); 231 preempt_disable();
232 cpu_clear(smp_processor_id(), mask);
234 __smp_call_function_map(func, info, 0, wait, mask); 233 __smp_call_function_map(func, info, 0, wait, mask);
235 preempt_enable(); 234 preempt_enable();
236 return 0; 235 return 0;
@@ -1008,7 +1007,7 @@ static struct notifier_block __cpuinitdata smp_cpu_nb = {
1008 .notifier_call = smp_cpu_notify, 1007 .notifier_call = smp_cpu_notify,
1009}; 1008};
1010 1009
1011static int smp_add_present_cpu(int cpu) 1010static int __devinit smp_add_present_cpu(int cpu)
1012{ 1011{
1013 struct cpu *c = &per_cpu(cpu_devices, cpu); 1012 struct cpu *c = &per_cpu(cpu_devices, cpu);
1014 struct sys_device *s = &c->sysdev; 1013 struct sys_device *s = &c->sysdev;
@@ -1036,8 +1035,8 @@ out:
1036} 1035}
1037 1036
1038#ifdef CONFIG_HOTPLUG_CPU 1037#ifdef CONFIG_HOTPLUG_CPU
1039static ssize_t rescan_store(struct sys_device *dev, const char *buf, 1038static ssize_t __ref rescan_store(struct sys_device *dev,
1040 size_t count) 1039 const char *buf, size_t count)
1041{ 1040{
1042 cpumask_t newcpus; 1041 cpumask_t newcpus;
1043 int cpu; 1042 int cpu;
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c
index da6924729964..85e46a5d0e08 100644
--- a/arch/s390/kernel/stacktrace.c
+++ b/arch/s390/kernel/stacktrace.c
@@ -14,7 +14,8 @@
14static unsigned long save_context_stack(struct stack_trace *trace, 14static unsigned long save_context_stack(struct stack_trace *trace,
15 unsigned long sp, 15 unsigned long sp,
16 unsigned long low, 16 unsigned long low,
17 unsigned long high) 17 unsigned long high,
18 int savesched)
18{ 19{
19 struct stack_frame *sf; 20 struct stack_frame *sf;
20 struct pt_regs *regs; 21 struct pt_regs *regs;
@@ -47,10 +48,12 @@ static unsigned long save_context_stack(struct stack_trace *trace,
47 return sp; 48 return sp;
48 regs = (struct pt_regs *)sp; 49 regs = (struct pt_regs *)sp;
49 addr = regs->psw.addr & PSW_ADDR_INSN; 50 addr = regs->psw.addr & PSW_ADDR_INSN;
50 if (!trace->skip) 51 if (savesched || !in_sched_functions(addr)) {
51 trace->entries[trace->nr_entries++] = addr; 52 if (!trace->skip)
52 else 53 trace->entries[trace->nr_entries++] = addr;
53 trace->skip--; 54 else
55 trace->skip--;
56 }
54 if (trace->nr_entries >= trace->max_entries) 57 if (trace->nr_entries >= trace->max_entries)
55 return sp; 58 return sp;
56 low = sp; 59 low = sp;
@@ -66,15 +69,27 @@ void save_stack_trace(struct stack_trace *trace)
66 orig_sp = sp & PSW_ADDR_INSN; 69 orig_sp = sp & PSW_ADDR_INSN;
67 new_sp = save_context_stack(trace, orig_sp, 70 new_sp = save_context_stack(trace, orig_sp,
68 S390_lowcore.panic_stack - PAGE_SIZE, 71 S390_lowcore.panic_stack - PAGE_SIZE,
69 S390_lowcore.panic_stack); 72 S390_lowcore.panic_stack, 1);
70 if (new_sp != orig_sp) 73 if (new_sp != orig_sp)
71 return; 74 return;
72 new_sp = save_context_stack(trace, new_sp, 75 new_sp = save_context_stack(trace, new_sp,
73 S390_lowcore.async_stack - ASYNC_SIZE, 76 S390_lowcore.async_stack - ASYNC_SIZE,
74 S390_lowcore.async_stack); 77 S390_lowcore.async_stack, 1);
75 if (new_sp != orig_sp) 78 if (new_sp != orig_sp)
76 return; 79 return;
77 save_context_stack(trace, new_sp, 80 save_context_stack(trace, new_sp,
78 S390_lowcore.thread_info, 81 S390_lowcore.thread_info,
79 S390_lowcore.thread_info + THREAD_SIZE); 82 S390_lowcore.thread_info + THREAD_SIZE, 1);
83}
84
85void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
86{
87 unsigned long sp, low, high;
88
89 sp = tsk->thread.ksp & PSW_ADDR_INSN;
90 low = (unsigned long) task_stack_page(tsk);
91 high = (unsigned long) task_pt_regs(tsk);
92 save_context_stack(trace, sp, low, high, 0);
93 if (trace->nr_entries < trace->max_entries)
94 trace->entries[trace->nr_entries++] = ULONG_MAX;
80} 95}
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 9e26ed9fe4e7..25eac7802fc4 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -325,5 +325,5 @@ SYSCALL(sys_utimes,sys_utimes,compat_sys_utimes_wrapper)
325SYSCALL(s390_fallocate,sys_fallocate,sys_fallocate_wrapper) 325SYSCALL(s390_fallocate,sys_fallocate,sys_fallocate_wrapper)
326SYSCALL(sys_utimensat,sys_utimensat,compat_sys_utimensat_wrapper) /* 315 */ 326SYSCALL(sys_utimensat,sys_utimensat,compat_sys_utimensat_wrapper) /* 315 */
327SYSCALL(sys_signalfd,sys_signalfd,compat_sys_signalfd_wrapper) 327SYSCALL(sys_signalfd,sys_signalfd,compat_sys_signalfd_wrapper)
328SYSCALL(sys_timerfd,sys_timerfd,compat_sys_timerfd_wrapper) 328NI_SYSCALL /* 317 old sys_timer_fd */
329SYSCALL(sys_eventfd,sys_eventfd,sys_eventfd_wrapper) 329SYSCALL(sys_eventfd,sys_eventfd,sys_eventfd_wrapper)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 52b8342c6bf2..1a2fdb6991df 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -271,7 +271,10 @@ void die(const char * str, struct pt_regs * regs, long err)
271 printk("PREEMPT "); 271 printk("PREEMPT ");
272#endif 272#endif
273#ifdef CONFIG_SMP 273#ifdef CONFIG_SMP
274 printk("SMP"); 274 printk("SMP ");
275#endif
276#ifdef CONFIG_DEBUG_PAGEALLOC
277 printk("DEBUG_PAGEALLOC");
275#endif 278#endif
276 printk("\n"); 279 printk("\n");
277 notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV); 280 notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV);
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 7d43c3cd3ef3..b4607155e8d0 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -35,7 +35,7 @@ SECTIONS
35 KPROBES_TEXT 35 KPROBES_TEXT
36 *(.fixup) 36 *(.fixup)
37 *(.gnu.warning) 37 *(.gnu.warning)
38 } = 0x0700 38 } :text = 0x0700
39 39
40 _etext = .; /* End of text section */ 40 _etext = .; /* End of text section */
41 41
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index b234bb4a6da7..983ec6ec0e7c 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -167,6 +167,33 @@ void __init mem_init(void)
167 PFN_ALIGN((unsigned long)&_eshared) - 1); 167 PFN_ALIGN((unsigned long)&_eshared) - 1);
168} 168}
169 169
170#ifdef CONFIG_DEBUG_PAGEALLOC
171void kernel_map_pages(struct page *page, int numpages, int enable)
172{
173 pgd_t *pgd;
174 pud_t *pud;
175 pmd_t *pmd;
176 pte_t *pte;
177 unsigned long address;
178 int i;
179
180 for (i = 0; i < numpages; i++) {
181 address = page_to_phys(page + i);
182 pgd = pgd_offset_k(address);
183 pud = pud_offset(pgd, address);
184 pmd = pmd_offset(pud, address);
185 pte = pte_offset_kernel(pmd, address);
186 if (!enable) {
187 ptep_invalidate(address, pte);
188 continue;
189 }
190 *pte = mk_pte_phys(address, __pgprot(_PAGE_TYPE_RW));
191 /* Flush cpu write queue. */
192 mb();
193 }
194}
195#endif
196
170void free_initmem(void) 197void free_initmem(void)
171{ 198{
172 unsigned long addr; 199 unsigned long addr;
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index 79d13a166a3d..7c1287ccf788 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -62,7 +62,7 @@ void __meminit memmap_init(unsigned long size, int nid, unsigned long zone,
62 } 62 }
63} 63}
64 64
65static void __init_refok *vmem_alloc_pages(unsigned int order) 65static void __ref *vmem_alloc_pages(unsigned int order)
66{ 66{
67 if (slab_is_available()) 67 if (slab_is_available())
68 return (void *)__get_free_pages(GFP_KERNEL, order); 68 return (void *)__get_free_pages(GFP_KERNEL, order);
@@ -250,7 +250,7 @@ static int insert_memory_segment(struct memory_segment *seg)
250{ 250{
251 struct memory_segment *tmp; 251 struct memory_segment *tmp;
252 252
253 if (seg->start + seg->size >= VMALLOC_START || 253 if (seg->start + seg->size >= VMEM_MAX_PHYS ||
254 seg->start + seg->size < seg->start) 254 seg->start + seg->size < seg->start)
255 return -ERANGE; 255 return -ERANGE;
256 256
@@ -360,7 +360,6 @@ void __init vmem_map_init(void)
360{ 360{
361 int i; 361 int i;
362 362
363 BUILD_BUG_ON((unsigned long)VMEM_MAP + VMEM_MAP_SIZE > VMEM_MAP_MAX);
364 NODE_DATA(0)->node_mem_map = VMEM_MAP; 363 NODE_DATA(0)->node_mem_map = VMEM_MAP;
365 for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) 364 for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++)
366 vmem_add_mem(memory_chunk[i].addr, memory_chunk[i].size); 365 vmem_add_mem(memory_chunk[i].addr, memory_chunk[i].size);
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index 55722840859c..ee010f4532a0 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -79,7 +79,7 @@ sys_call_table:
79/*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare 79/*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
80/*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy 80/*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy
81/*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait 81/*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
82/*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd, sys_fallocate 82/*310*/ .long sys_utimensat, sys_signalfd, sys_ni_syscall, sys_eventfd, sys_fallocate
83 83
84#ifdef CONFIG_SUNOS_EMUL 84#ifdef CONFIG_SUNOS_EMUL
85 /* Now the SunOS syscall table. */ 85 /* Now the SunOS syscall table. */
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 070a4846c0cb..4b9115a4d92e 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -580,7 +580,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
580 580
581 /* Step 1: Prepare scatter list. */ 581 /* Step 1: Prepare scatter list. */
582 582
583 npages = prepare_sg(sglist, nelems); 583 npages = prepare_sg(dev, sglist, nelems);
584 584
585 /* Step 2: Allocate a cluster and context, if necessary. */ 585 /* Step 2: Allocate a cluster and context, if necessary. */
586 586
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index efd5dff85f60..72a4acfe8c7b 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -4,6 +4,7 @@
4 * Copyright (C) 1999 David S. Miller (davem@redhat.com) 4 * Copyright (C) 1999 David S. Miller (davem@redhat.com)
5 */ 5 */
6 6
7#include <linux/dma-mapping.h>
7#include "iommu_common.h" 8#include "iommu_common.h"
8 9
9/* You are _strongly_ advised to enable the following debugging code 10/* You are _strongly_ advised to enable the following debugging code
@@ -201,21 +202,24 @@ void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int np
201} 202}
202#endif 203#endif
203 204
204unsigned long prepare_sg(struct scatterlist *sg, int nents) 205unsigned long prepare_sg(struct device *dev, struct scatterlist *sg, int nents)
205{ 206{
206 struct scatterlist *dma_sg = sg; 207 struct scatterlist *dma_sg = sg;
207 unsigned long prev; 208 unsigned long prev;
208 u32 dent_addr, dent_len; 209 u32 dent_addr, dent_len;
210 unsigned int max_seg_size;
209 211
210 prev = (unsigned long) sg_virt(sg); 212 prev = (unsigned long) sg_virt(sg);
211 prev += (unsigned long) (dent_len = sg->length); 213 prev += (unsigned long) (dent_len = sg->length);
212 dent_addr = (u32) ((unsigned long)(sg_virt(sg)) & (IO_PAGE_SIZE - 1UL)); 214 dent_addr = (u32) ((unsigned long)(sg_virt(sg)) & (IO_PAGE_SIZE - 1UL));
215 max_seg_size = dma_get_max_seg_size(dev);
213 while (--nents) { 216 while (--nents) {
214 unsigned long addr; 217 unsigned long addr;
215 218
216 sg = sg_next(sg); 219 sg = sg_next(sg);
217 addr = (unsigned long) sg_virt(sg); 220 addr = (unsigned long) sg_virt(sg);
218 if (! VCONTIG(prev, addr)) { 221 if (! VCONTIG(prev, addr) ||
222 dent_len + sg->length > max_seg_size) {
219 dma_sg->dma_address = dent_addr; 223 dma_sg->dma_address = dent_addr;
220 dma_sg->dma_length = dent_len; 224 dma_sg->dma_length = dent_len;
221 dma_sg = sg_next(dma_sg); 225 dma_sg = sg_next(dma_sg);
diff --git a/arch/sparc64/kernel/iommu_common.h b/arch/sparc64/kernel/iommu_common.h
index 75b5a5814522..a90d046e8024 100644
--- a/arch/sparc64/kernel/iommu_common.h
+++ b/arch/sparc64/kernel/iommu_common.h
@@ -9,6 +9,7 @@
9#include <linux/sched.h> 9#include <linux/sched.h>
10#include <linux/mm.h> 10#include <linux/mm.h>
11#include <linux/scatterlist.h> 11#include <linux/scatterlist.h>
12#include <linux/device.h>
12 13
13#include <asm/iommu.h> 14#include <asm/iommu.h>
14#include <asm/scatterlist.h> 15#include <asm/scatterlist.h>
@@ -46,4 +47,4 @@ extern void verify_sglist(struct scatterlist *sg, int nents, iopte_t *iopte, int
46#define VCONTIG(__X, __Y) (((__X) == (__Y)) || \ 47#define VCONTIG(__X, __Y) (((__X) == (__Y)) || \
47 (((__X) | (__Y)) << (64UL - PAGE_SHIFT)) == 0UL) 48 (((__X) | (__Y)) << (64UL - PAGE_SHIFT)) == 0UL)
48 49
49extern unsigned long prepare_sg(struct scatterlist *sg, int nents); 50extern unsigned long prepare_sg(struct device *dev, struct scatterlist *sg, int nents);
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 1aa8e044b105..5ea2eab1ccda 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -490,7 +490,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
490 goto bad; 490 goto bad;
491 491
492 /* Step 1: Prepare scatter list. */ 492 /* Step 1: Prepare scatter list. */
493 npages = prepare_sg(sglist, nelems); 493 npages = prepare_sg(dev, sglist, nelems);
494 494
495 /* Step 2: Allocate a cluster and context, if necessary. */ 495 /* Step 2: Allocate a cluster and context, if necessary. */
496 spin_lock_irqsave(&iommu->lock, flags); 496 spin_lock_irqsave(&iommu->lock, flags);
@@ -625,8 +625,8 @@ static void __init pci_sun4v_scan_bus(struct pci_pbm_info *pbm)
625 /* XXX register error interrupt handlers XXX */ 625 /* XXX register error interrupt handlers XXX */
626} 626}
627 627
628static unsigned long probe_existing_entries(struct pci_pbm_info *pbm, 628static unsigned long __init probe_existing_entries(struct pci_pbm_info *pbm,
629 struct iommu *iommu) 629 struct iommu *iommu)
630{ 630{
631 struct iommu_arena *arena = &iommu->arena; 631 struct iommu_arena *arena = &iommu->arena;
632 unsigned long i, cnt = 0; 632 unsigned long i, cnt = 0;
@@ -653,7 +653,7 @@ static unsigned long probe_existing_entries(struct pci_pbm_info *pbm,
653 return cnt; 653 return cnt;
654} 654}
655 655
656static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) 656static void __init pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
657{ 657{
658 struct iommu *iommu = pbm->iommu; 658 struct iommu *iommu = pbm->iommu;
659 struct property *prop; 659 struct property *prop;
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 06d10907d8ce..b8058906e727 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -80,7 +80,7 @@ sys_call_table32:
80 .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare 80 .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare
81/*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy 81/*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy
82 .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait 82 .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait
83/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, compat_sys_timerfd, sys_eventfd, compat_sys_fallocate 83/*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_ni_syscall, sys_eventfd, compat_sys_fallocate
84 84
85#endif /* CONFIG_COMPAT */ 85#endif /* CONFIG_COMPAT */
86 86
@@ -152,7 +152,7 @@ sys_call_table:
152 .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare 152 .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
153/*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy 153/*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy
154 .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait 154 .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
155/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd, sys_eventfd, sys_fallocate 155/*310*/ .word sys_utimensat, sys_signalfd, sys_ni_syscall, sys_eventfd, sys_fallocate
156 156
157#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ 157#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
158 defined(CONFIG_SOLARIS_EMUL_MODULE) 158 defined(CONFIG_SOLARIS_EMUL_MODULE)
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 55945db1313c..99e51d059a02 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -68,6 +68,10 @@ config IRQ_RELEASE_METHOD
68 bool 68 bool
69 default y 69 default y
70 70
71config HZ
72 int
73 default 100
74
71menu "UML-specific options" 75menu "UML-specific options"
72 76
73config STATIC_LINK 77config STATIC_LINK
@@ -95,23 +99,6 @@ config LD_SCRIPT_DYN
95 default y 99 default y
96 depends on !LD_SCRIPT_STATIC 100 depends on !LD_SCRIPT_STATIC
97 101
98config NET
99 bool "Networking support"
100 help
101 Unless you really know what you are doing, you should say Y here.
102 The reason is that some programs need kernel networking support even
103 when running on a stand-alone machine that isn't connected to any
104 other computer. If you are upgrading from an older kernel, you
105 should consider updating your networking tools too because changes
106 in the kernel and the tools often go hand in hand. The tools are
107 contained in the package net-tools, the location and version number
108 of which are given in <file:Documentation/Changes>.
109
110 For a general introduction to Linux networking, it is highly
111 recommended to read the NET-HOWTO, available from
112 <http://www.tldp.org/docs.html#howto>.
113
114
115source "fs/Kconfig.binfmt" 102source "fs/Kconfig.binfmt"
116 103
117config HOSTFS 104config HOSTFS
@@ -145,7 +132,7 @@ config HPPFS
145 by removing or changing anything in /proc which gives away the 132 by removing or changing anything in /proc which gives away the
146 identity of a UML. 133 identity of a UML.
147 134
148 See <http://user-mode-linux.sf.net/hppfs.html> for more information. 135 See <http://user-mode-linux.sf.net/old/hppfs.html> for more information.
149 136
150 You only need this if you are setting up a UML honeypot. Otherwise, 137 You only need this if you are setting up a UML honeypot. Otherwise,
151 it is safe to say 'N' here. 138 it is safe to say 'N' here.
@@ -189,8 +176,7 @@ config MAGIC_SYSRQ
189config SMP 176config SMP
190 bool "Symmetric multi-processing support (EXPERIMENTAL)" 177 bool "Symmetric multi-processing support (EXPERIMENTAL)"
191 default n 178 default n
192 #SMP_BROKEN is for x86_64. 179 depends on BROKEN
193 depends on EXPERIMENTAL && (!SMP_BROKEN || (BROKEN && SMP_BROKEN))
194 help 180 help
195 This option enables UML SMP support. 181 This option enables UML SMP support.
196 It is NOT related to having a real SMP box. Not directly, at least. 182 It is NOT related to having a real SMP box. Not directly, at least.
diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char
index 9a78d354f0b4..3a4b396d7979 100644
--- a/arch/um/Kconfig.char
+++ b/arch/um/Kconfig.char
@@ -18,7 +18,7 @@ config SSL
18 lines on the UML that are usually made to show up on the host as 18 lines on the UML that are usually made to show up on the host as
19 ttys or ptys. 19 ttys or ptys.
20 20
21 See <http://user-mode-linux.sourceforge.net/input.html> for more 21 See <http://user-mode-linux.sourceforge.net/old/input.html> for more
22 information and command line examples of how to use this facility. 22 information and command line examples of how to use this facility.
23 23
24 Unless you have a specific reason for disabling this, say Y. 24 Unless you have a specific reason for disabling this, say Y.
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug
index 1f6462ffd3e8..8fce5e536b0f 100644
--- a/arch/um/Kconfig.debug
+++ b/arch/um/Kconfig.debug
@@ -4,12 +4,12 @@ source "lib/Kconfig.debug"
4 4
5config GPROF 5config GPROF
6 bool "Enable gprof support" 6 bool "Enable gprof support"
7 depends on DEBUG_INFO 7 depends on DEBUG_INFO && FRAME_POINTER
8 help 8 help
9 This allows profiling of a User-Mode Linux kernel with the gprof 9 This allows profiling of a User-Mode Linux kernel with the gprof
10 utility. 10 utility.
11 11
12 See <http://user-mode-linux.sourceforge.net/gprof.html> for more 12 See <http://user-mode-linux.sourceforge.net/old/gprof.html> for more
13 details. 13 details.
14 14
15 If you're involved in UML kernel development and want to use gprof, 15 If you're involved in UML kernel development and want to use gprof,
@@ -22,7 +22,7 @@ config GCOV
22 This option allows developers to retrieve coverage data from a UML 22 This option allows developers to retrieve coverage data from a UML
23 session. 23 session.
24 24
25 See <http://user-mode-linux.sourceforge.net/gprof.html> for more 25 See <http://user-mode-linux.sourceforge.net/old/gprof.html> for more
26 details. 26 details.
27 27
28 If you're involved in UML kernel development and want to use gcov, 28 If you're involved in UML kernel development and want to use gcov,
diff --git a/arch/um/Kconfig.net b/arch/um/Kconfig.net
index 66e50026ade9..9e9a4aaa703d 100644
--- a/arch/um/Kconfig.net
+++ b/arch/um/Kconfig.net
@@ -14,7 +14,7 @@ config UML_NET
14 14
15 For more information, including explanations of the networking and 15 For more information, including explanations of the networking and
16 sample configurations, see 16 sample configurations, see
17 <http://user-mode-linux.sourceforge.net/networking.html>. 17 <http://user-mode-linux.sourceforge.net/old/networking.html>.
18 18
19 If you'd like to be able to enable networking in the User-Mode 19 If you'd like to be able to enable networking in the User-Mode
20 linux environment, say Y; otherwise say N. Note that you must 20 linux environment, say Y; otherwise say N. Note that you must
@@ -38,7 +38,7 @@ config UML_NET_ETHERTAP
38 CONFIG_NETLINK_DEV configured as Y or M. 38 CONFIG_NETLINK_DEV configured as Y or M.
39 39
40 For more information, see 40 For more information, see
41 <http://user-mode-linux.sourceforge.net/networking.html> That site 41 <http://user-mode-linux.sourceforge.net/old/networking.html> That site
42 has examples of the UML command line to use to enable Ethertap 42 has examples of the UML command line to use to enable Ethertap
43 networking. 43 networking.
44 44
@@ -72,7 +72,7 @@ config UML_NET_SLIP
72 To use this, your host must support slip devices. 72 To use this, your host must support slip devices.
73 73
74 For more information, see 74 For more information, see
75 <http://user-mode-linux.sourceforge.net/networking.html>. That site 75 <http://user-mode-linux.sourceforge.net/old/networking.html>.
76 has examples of the UML command line to use to enable slip 76 has examples of the UML command line to use to enable slip
77 networking, and details of a few quirks with it. 77 networking, and details of a few quirks with it.
78 78
@@ -96,7 +96,7 @@ config UML_NET_DAEMON
96 networking daemon on the host. 96 networking daemon on the host.
97 97
98 For more information, see 98 For more information, see
99 <http://user-mode-linux.sourceforge.net/networking.html> That site 99 <http://user-mode-linux.sourceforge.net/old/networking.html> That site
100 has examples of the UML command line to use to enable Daemon 100 has examples of the UML command line to use to enable Daemon
101 networking. 101 networking.
102 102
@@ -144,7 +144,7 @@ config UML_NET_MCAST
144 To use this, your host kernel(s) must support IP Multicasting. 144 To use this, your host kernel(s) must support IP Multicasting.
145 145
146 For more information, see 146 For more information, see
147 <http://user-mode-linux.sourceforge.net/networking.html> That site 147 <http://user-mode-linux.sourceforge.net/old/networking.html> That site
148 has examples of the UML command line to use to enable Multicast 148 has examples of the UML command line to use to enable Multicast
149 networking, and notes about the security of this approach. 149 networking, and notes about the security of this approach.
150 150
@@ -165,7 +165,7 @@ config UML_NET_PCAP
165 installed in order to build the pcap transport into UML. 165 installed in order to build the pcap transport into UML.
166 166
167 For more information, see 167 For more information, see
168 <http://user-mode-linux.sourceforge.net/networking.html> That site 168 <http://user-mode-linux.sourceforge.net/old/networking.html> That site
169 has examples of the UML command line to use to enable this option. 169 has examples of the UML command line to use to enable this option.
170 170
171 If you intend to use UML as a network monitor for the host, say 171 If you intend to use UML as a network monitor for the host, say
diff --git a/arch/um/Makefile b/arch/um/Makefile
index ba6813a4aa37..cb4af9bf2074 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -49,7 +49,7 @@ SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
49# 49#
50# These apply to USER_CFLAGS to. 50# These apply to USER_CFLAGS to.
51 51
52KBUILD_CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ 52KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
53 $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ 53 $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \
54 -Din6addr_loopback=kernel_in6addr_loopback \ 54 -Din6addr_loopback=kernel_in6addr_loopback \
55 -Din6addr_any=kernel_in6addr_any 55 -Din6addr_any=kernel_in6addr_any
@@ -58,7 +58,7 @@ KBUILD_AFLAGS += $(ARCH_INCLUDE)
58 58
59USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\ 59USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\
60 $(patsubst -I%,,$(KBUILD_CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \ 60 $(patsubst -I%,,$(KBUILD_CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \
61 -D_FILE_OFFSET_BITS=64 61 $(filter -I%,$(CFLAGS)) -D_FILE_OFFSET_BITS=64
62 62
63include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) 63include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
64 64
@@ -130,7 +130,9 @@ CPPFLAGS_vmlinux.lds = -U$(SUBARCH) -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
130# The wrappers will select whether using "malloc" or the kernel allocator. 130# The wrappers will select whether using "malloc" or the kernel allocator.
131LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc 131LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
132 132
133CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) 133LD_FLAGS_CMDLINE = $(foreach opt,$(LDFLAGS),-Wl,$(opt))
134
135CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE)
134define cmd_vmlinux__ 136define cmd_vmlinux__
135 $(CC) $(CFLAGS_vmlinux) -o $@ \ 137 $(CC) $(CFLAGS_vmlinux) -o $@ \
136 -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ 138 -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
@@ -158,7 +160,7 @@ ifneq ($(KBUILD_SRC),)
158 $(Q)mkdir -p $(objtree)/include/asm-um 160 $(Q)mkdir -p $(objtree)/include/asm-um
159 $(Q)ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@ 161 $(Q)ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@
160else 162else
161 $(Q)cd $(TOPDIR)/$(dir $@) ; \ 163 $(Q)cd $(srctree)/$(dir $@) ; \
162 ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@) 164 ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
163endif 165endif
164 166
@@ -168,7 +170,7 @@ ifneq ($(KBUILD_SRC),)
168 $(Q)mkdir -p $(objtree)/include/asm-um 170 $(Q)mkdir -p $(objtree)/include/asm-um
169 $(Q)ln -fsn $(srctree)/include/asm-$(HEADER_ARCH) include/asm-um/arch 171 $(Q)ln -fsn $(srctree)/include/asm-$(HEADER_ARCH) include/asm-um/arch
170else 172else
171 $(Q)cd $(TOPDIR)/include/asm-um && ln -fsn ../asm-$(HEADER_ARCH) arch 173 $(Q)cd $(srctree)/include/asm-um && ln -fsn ../asm-$(HEADER_ARCH) arch
172endif 174endif
173 175
174$(objtree)/$(ARCH_DIR)/include: 176$(objtree)/$(ARCH_DIR)/include:
diff --git a/arch/um/Makefile-tt b/arch/um/Makefile-tt
deleted file mode 100644
index 03f7b10cfd0b..000000000000
--- a/arch/um/Makefile-tt
+++ /dev/null
@@ -1,5 +0,0 @@
1#
2# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3# Licensed under the GPL
4#
5
diff --git a/arch/um/defconfig b/arch/um/defconfig
index f609edede065..86db2862f222 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -77,7 +77,7 @@ CONFIG_LD_SCRIPT_DYN=y
77CONFIG_NET=y 77CONFIG_NET=y
78CONFIG_BINFMT_ELF=y 78CONFIG_BINFMT_ELF=y
79CONFIG_BINFMT_MISC=m 79CONFIG_BINFMT_MISC=m
80# CONFIG_HOSTFS is not set 80CONFIG_HOSTFS=y
81# CONFIG_HPPFS is not set 81# CONFIG_HPPFS is not set
82CONFIG_MCONSOLE=y 82CONFIG_MCONSOLE=y
83CONFIG_MAGIC_SYSRQ=y 83CONFIG_MAGIC_SYSRQ=y
@@ -188,7 +188,7 @@ CONFIG_CON_CHAN="xterm"
188CONFIG_SSL_CHAN="pts" 188CONFIG_SSL_CHAN="pts"
189CONFIG_UNIX98_PTYS=y 189CONFIG_UNIX98_PTYS=y
190CONFIG_LEGACY_PTYS=y 190CONFIG_LEGACY_PTYS=y
191CONFIG_LEGACY_PTY_COUNT=256 191CONFIG_LEGACY_PTY_COUNT=32
192# CONFIG_WATCHDOG is not set 192# CONFIG_WATCHDOG is not set
193CONFIG_UML_SOUND=m 193CONFIG_UML_SOUND=m
194CONFIG_SOUND=m 194CONFIG_SOUND=m
@@ -508,7 +508,7 @@ CONFIG_DEBUG_KERNEL=y
508CONFIG_LOG_BUF_SHIFT=14 508CONFIG_LOG_BUF_SHIFT=14
509CONFIG_DETECT_SOFTLOCKUP=y 509CONFIG_DETECT_SOFTLOCKUP=y
510# CONFIG_SCHEDSTATS is not set 510# CONFIG_SCHEDSTATS is not set
511CONFIG_DEBUG_SLAB=y 511# CONFIG_DEBUG_SLAB is not set
512# CONFIG_DEBUG_SLAB_LEAK is not set 512# CONFIG_DEBUG_SLAB_LEAK is not set
513# CONFIG_DEBUG_MUTEXES is not set 513# CONFIG_DEBUG_MUTEXES is not set
514# CONFIG_DEBUG_SPINLOCK is not set 514# CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 83bf15a3dda8..2c898c4d6b6a 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -8,6 +8,7 @@
8#include "chan_kern.h" 8#include "chan_kern.h"
9#include "irq_kern.h" 9#include "irq_kern.h"
10#include "irq_user.h" 10#include "irq_user.h"
11#include "kern_util.h"
11#include "os.h" 12#include "os.h"
12 13
13#define LINE_BUFSIZE 4096 14#define LINE_BUFSIZE 4096
@@ -48,7 +49,7 @@ static int write_room(struct line *line)
48 n = line->head - line->tail; 49 n = line->head - line->tail;
49 50
50 if (n <= 0) 51 if (n <= 0)
51 n = LINE_BUFSIZE + n; /* The other case */ 52 n += LINE_BUFSIZE; /* The other case */
52 return n - 1; 53 return n - 1;
53} 54}
54 55
@@ -58,17 +59,10 @@ int line_write_room(struct tty_struct *tty)
58 unsigned long flags; 59 unsigned long flags;
59 int room; 60 int room;
60 61
61 if (tty->stopped)
62 return 0;
63
64 spin_lock_irqsave(&line->lock, flags); 62 spin_lock_irqsave(&line->lock, flags);
65 room = write_room(line); 63 room = write_room(line);
66 spin_unlock_irqrestore(&line->lock, flags); 64 spin_unlock_irqrestore(&line->lock, flags);
67 65
68 /*XXX: Warning to remove */
69 if (0 == room)
70 printk(KERN_DEBUG "%s: %s: no room left in buffer\n",
71 __FUNCTION__,tty->name);
72 return room; 66 return room;
73} 67}
74 68
@@ -79,8 +73,7 @@ int line_chars_in_buffer(struct tty_struct *tty)
79 int ret; 73 int ret;
80 74
81 spin_lock_irqsave(&line->lock, flags); 75 spin_lock_irqsave(&line->lock, flags);
82 76 /* write_room subtracts 1 for the needed NULL, so we readd it.*/
83 /*write_room subtracts 1 for the needed NULL, so we readd it.*/
84 ret = LINE_BUFSIZE - (write_room(line) + 1); 77 ret = LINE_BUFSIZE - (write_room(line) + 1);
85 spin_unlock_irqrestore(&line->lock, flags); 78 spin_unlock_irqrestore(&line->lock, flags);
86 79
@@ -184,10 +177,6 @@ void line_flush_buffer(struct tty_struct *tty)
184 unsigned long flags; 177 unsigned long flags;
185 int err; 178 int err;
186 179
187 /*XXX: copied from line_write, verify if it is correct!*/
188 if (tty->stopped)
189 return;
190
191 spin_lock_irqsave(&line->lock, flags); 180 spin_lock_irqsave(&line->lock, flags);
192 err = flush_buffer(line); 181 err = flush_buffer(line);
193 spin_unlock_irqrestore(&line->lock, flags); 182 spin_unlock_irqrestore(&line->lock, flags);
@@ -213,9 +202,6 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
213 unsigned long flags; 202 unsigned long flags;
214 int n, ret = 0; 203 int n, ret = 0;
215 204
216 if (tty->stopped)
217 return 0;
218
219 spin_lock_irqsave(&line->lock, flags); 205 spin_lock_irqsave(&line->lock, flags);
220 if (line->head != line->tail) 206 if (line->head != line->tail)
221 ret = buffer_data(line, buf, len); 207 ret = buffer_data(line, buf, len);
@@ -788,9 +774,11 @@ static irqreturn_t winch_interrupt(int irq, void *data)
788 tty = winch->tty; 774 tty = winch->tty;
789 if (tty != NULL) { 775 if (tty != NULL) {
790 line = tty->driver_data; 776 line = tty->driver_data;
791 chan_window_size(&line->chan_list, &tty->winsize.ws_row, 777 if (line != NULL) {
792 &tty->winsize.ws_col); 778 chan_window_size(&line->chan_list, &tty->winsize.ws_row,
793 kill_pgrp(tty->pgrp, SIGWINCH, 1); 779 &tty->winsize.ws_col);
780 kill_pgrp(tty->pgrp, SIGWINCH, 1);
781 }
794 } 782 }
795 out: 783 out:
796 if (winch->fd != -1) 784 if (winch->fd != -1)
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 0f3c7d14a6e3..ebb265c07e4d 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -1,23 +1,25 @@
1/* 1/*
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) 2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3 * Copyright (C) 2001 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7#include "linux/console.h" 7#include <linux/console.h>
8#include "linux/ctype.h" 8#include <linux/ctype.h>
9#include "linux/interrupt.h" 9#include <linux/interrupt.h>
10#include "linux/list.h" 10#include <linux/list.h>
11#include "linux/mm.h" 11#include <linux/mm.h>
12#include "linux/module.h" 12#include <linux/module.h>
13#include "linux/notifier.h" 13#include <linux/notifier.h>
14#include "linux/reboot.h" 14#include <linux/reboot.h>
15#include "linux/proc_fs.h" 15#include <linux/proc_fs.h>
16#include "linux/slab.h" 16#include <linux/slab.h>
17#include "linux/syscalls.h" 17#include <linux/syscalls.h>
18#include "linux/utsname.h" 18#include <linux/utsname.h>
19#include "linux/workqueue.h" 19#include <linux/workqueue.h>
20#include "asm/uaccess.h" 20#include <linux/mutex.h>
21#include <asm/uaccess.h>
22
21#include "init.h" 23#include "init.h"
22#include "irq_kern.h" 24#include "irq_kern.h"
23#include "irq_user.h" 25#include "irq_user.h"
@@ -305,7 +307,9 @@ void mconsole_stop(struct mc_request *req)
305 deactivate_fd(req->originating_fd, MCONSOLE_IRQ); 307 deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
306 os_set_fd_block(req->originating_fd, 1); 308 os_set_fd_block(req->originating_fd, 1);
307 mconsole_reply(req, "stopped", 0, 0); 309 mconsole_reply(req, "stopped", 0, 0);
308 while (mconsole_get_request(req->originating_fd, req)) { 310 for (;;) {
311 if (!mconsole_get_request(req->originating_fd, req))
312 continue;
309 if (req->cmd->handler == mconsole_go) 313 if (req->cmd->handler == mconsole_go)
310 break; 314 break;
311 if (req->cmd->handler == mconsole_stop) { 315 if (req->cmd->handler == mconsole_stop) {
@@ -358,7 +362,7 @@ struct unplugged_pages {
358 void *pages[UNPLUGGED_PER_PAGE]; 362 void *pages[UNPLUGGED_PER_PAGE];
359}; 363};
360 364
361static DECLARE_MUTEX(plug_mem_mutex); 365static DEFINE_MUTEX(plug_mem_mutex);
362static unsigned long long unplugged_pages_count = 0; 366static unsigned long long unplugged_pages_count = 0;
363static LIST_HEAD(unplugged_pages); 367static LIST_HEAD(unplugged_pages);
364static int unplug_index = UNPLUGGED_PER_PAGE; 368static int unplug_index = UNPLUGGED_PER_PAGE;
@@ -394,7 +398,7 @@ static int mem_config(char *str, char **error_out)
394 398
395 diff /= PAGE_SIZE; 399 diff /= PAGE_SIZE;
396 400
397 down(&plug_mem_mutex); 401 mutex_lock(&plug_mem_mutex);
398 for (i = 0; i < diff; i++) { 402 for (i = 0; i < diff; i++) {
399 struct unplugged_pages *unplugged; 403 struct unplugged_pages *unplugged;
400 void *addr; 404 void *addr;
@@ -451,7 +455,7 @@ static int mem_config(char *str, char **error_out)
451 455
452 err = 0; 456 err = 0;
453out_unlock: 457out_unlock:
454 up(&plug_mem_mutex); 458 mutex_unlock(&plug_mem_mutex);
455out: 459out:
456 return err; 460 return err;
457} 461}
@@ -741,7 +745,6 @@ void mconsole_stack(struct mc_request *req)
741{ 745{
742 char *ptr = req->request.data; 746 char *ptr = req->request.data;
743 int pid_requested= -1; 747 int pid_requested= -1;
744 struct task_struct *from = NULL;
745 struct task_struct *to = NULL; 748 struct task_struct *to = NULL;
746 749
747 /* 750 /*
@@ -763,9 +766,7 @@ void mconsole_stack(struct mc_request *req)
763 return; 766 return;
764 } 767 }
765 768
766 from = current; 769 to = find_task_by_pid_ns(pid_requested, &init_pid_ns);
767
768 to = find_task_by_pid(pid_requested);
769 if ((to == NULL) || (pid_requested == 0)) { 770 if ((to == NULL) || (pid_requested == 0)) {
770 mconsole_reply(req, "Couldn't find that pid", 1, 0); 771 mconsole_reply(req, "Couldn't find that pid", 1, 0);
771 return; 772 return;
@@ -795,6 +796,8 @@ static int __init mconsole_init(void)
795 printk(KERN_ERR "Failed to initialize management console\n"); 796 printk(KERN_ERR "Failed to initialize management console\n");
796 return 1; 797 return 1;
797 } 798 }
799 if (os_set_fd_block(sock, 0))
800 goto out;
798 801
799 register_reboot_notifier(&reboot_notifier); 802 register_reboot_notifier(&reboot_notifier);
800 803
@@ -803,7 +806,7 @@ static int __init mconsole_init(void)
803 "mconsole", (void *)sock); 806 "mconsole", (void *)sock);
804 if (err) { 807 if (err) {
805 printk(KERN_ERR "Failed to get IRQ for management console\n"); 808 printk(KERN_ERR "Failed to get IRQ for management console\n");
806 return 1; 809 goto out;
807 } 810 }
808 811
809 if (notify_socket != NULL) { 812 if (notify_socket != NULL) {
@@ -819,6 +822,10 @@ static int __init mconsole_init(void)
819 printk(KERN_INFO "mconsole (version %d) initialized on %s\n", 822 printk(KERN_INFO "mconsole (version %d) initialized on %s\n",
820 MCONSOLE_VERSION, mconsole_socket_name); 823 MCONSOLE_VERSION, mconsole_socket_name);
821 return 0; 824 return 0;
825
826 out:
827 os_close_file(sock);
828 return 1;
822} 829}
823 830
824__initcall(mconsole_init); 831__initcall(mconsole_init);
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index 430c024a19b0..13af2f03ed84 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -83,9 +83,8 @@ int mconsole_get_request(int fd, struct mc_request *req)
83 int len; 83 int len;
84 84
85 req->originlen = sizeof(req->origin); 85 req->originlen = sizeof(req->origin);
86 req->len = recvfrom(fd, &req->request, sizeof(req->request), 86 req->len = recvfrom(fd, &req->request, sizeof(req->request), 0,
87 MSG_DONTWAIT, (struct sockaddr *) req->origin, 87 (struct sockaddr *) req->origin, &req->originlen);
88 &req->originlen);
89 if (req->len < 0) 88 if (req->len < 0)
90 return 0; 89 return 0;
91 90
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 3c6c44ca1ffa..1e8f41a99511 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -318,7 +318,7 @@ static void setup_etheraddr(char *str, unsigned char *addr, char *name)
318 if (str == NULL) 318 if (str == NULL)
319 goto random; 319 goto random;
320 320
321 for (i = 0;i < 6; i++) { 321 for (i = 0; i < 6; i++) {
322 addr[i] = simple_strtoul(str, &end, 16); 322 addr[i] = simple_strtoul(str, &end, 16);
323 if ((end == str) || 323 if ((end == str) ||
324 ((*end != ':') && (*end != ',') && (*end != '\0'))) { 324 ((*end != ':') && (*end != ',') && (*end != '\0'))) {
@@ -343,14 +343,13 @@ static void setup_etheraddr(char *str, unsigned char *addr, char *name)
343 } 343 }
344 if (!is_local_ether_addr(addr)) { 344 if (!is_local_ether_addr(addr)) {
345 printk(KERN_WARNING 345 printk(KERN_WARNING
346 "Warning: attempt to assign a globally valid ethernet " 346 "Warning: Assigning a globally valid ethernet "
347 "address to a device\n"); 347 "address to a device\n");
348 printk(KERN_WARNING "You should better enable the 2nd " 348 printk(KERN_WARNING "You should set the 2nd rightmost bit in "
349 "rightmost bit in the first byte of the MAC,\n"); 349 "the first byte of the MAC,\n");
350 printk(KERN_WARNING "i.e. %02x:%02x:%02x:%02x:%02x:%02x\n", 350 printk(KERN_WARNING "i.e. %02x:%02x:%02x:%02x:%02x:%02x\n",
351 addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4], 351 addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4],
352 addr[5]); 352 addr[5]);
353 goto random;
354 } 353 }
355 return; 354 return;
356 355
@@ -368,7 +367,6 @@ static struct platform_driver uml_net_driver = {
368 .name = DRIVER_NAME, 367 .name = DRIVER_NAME,
369 }, 368 },
370}; 369};
371static int driver_registered;
372 370
373static void net_device_release(struct device *dev) 371static void net_device_release(struct device *dev)
374{ 372{
@@ -383,6 +381,12 @@ static void net_device_release(struct device *dev)
383 free_netdev(netdev); 381 free_netdev(netdev);
384} 382}
385 383
384/*
385 * Ensures that platform_driver_register is called only once by
386 * eth_configure. Will be set in an initcall.
387 */
388static int driver_registered;
389
386static void eth_configure(int n, void *init, char *mac, 390static void eth_configure(int n, void *init, char *mac,
387 struct transport *transport) 391 struct transport *transport)
388{ 392{
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 29185cad9fff..abf2653f5517 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -201,7 +201,7 @@ static int change_tramp(char **argv, char *output, int output_len)
201 close(fds[1]); 201 close(fds[1]);
202 202
203 if (pid > 0) 203 if (pid > 0)
204 helper_wait(pid, 0, "change_tramp"); 204 helper_wait(pid);
205 return pid; 205 return pid;
206} 206}
207 207
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index 330543b3129b..19930081d3d8 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -6,6 +6,7 @@
6#include "linux/completion.h" 6#include "linux/completion.h"
7#include "linux/interrupt.h" 7#include "linux/interrupt.h"
8#include "linux/list.h" 8#include "linux/list.h"
9#include "linux/mutex.h"
9#include "asm/atomic.h" 10#include "asm/atomic.h"
10#include "init.h" 11#include "init.h"
11#include "irq_kern.h" 12#include "irq_kern.h"
@@ -120,7 +121,7 @@ static int port_accept(struct port_list *port)
120 return 0; 121 return 0;
121} 122}
122 123
123static DECLARE_MUTEX(ports_sem); 124static DEFINE_MUTEX(ports_mutex);
124static LIST_HEAD(ports); 125static LIST_HEAD(ports);
125 126
126static void port_work_proc(struct work_struct *unused) 127static void port_work_proc(struct work_struct *unused)
@@ -161,7 +162,7 @@ void *port_data(int port_num)
161 struct port_dev *dev = NULL; 162 struct port_dev *dev = NULL;
162 int fd; 163 int fd;
163 164
164 down(&ports_sem); 165 mutex_lock(&ports_mutex);
165 list_for_each(ele, &ports) { 166 list_for_each(ele, &ports) {
166 port = list_entry(ele, struct port_list, list); 167 port = list_entry(ele, struct port_list, list);
167 if (port->port == port_num) 168 if (port->port == port_num)
@@ -216,7 +217,7 @@ void *port_data(int port_num)
216 out_free: 217 out_free:
217 kfree(port); 218 kfree(port);
218 out: 219 out:
219 up(&ports_sem); 220 mutex_unlock(&ports_mutex);
220 return dev; 221 return dev;
221} 222}
222 223
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index e942e836f995..71f0959c1535 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -5,6 +5,7 @@
5 * This software may be used and distributed according to the terms 5 * This software may be used and distributed according to the terms
6 * of the GNU General Public License, incorporated herein by reference. 6 * of the GNU General Public License, incorporated herein by reference.
7 */ 7 */
8#include <linux/sched.h>
8#include <linux/module.h> 9#include <linux/module.h>
9#include <linux/fs.h> 10#include <linux/fs.h>
10#include <linux/miscdevice.h> 11#include <linux/miscdevice.h>
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index b8711e50da80..8b80505a3fb0 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -109,7 +109,7 @@ static int slip_tramp(char **argv, int fd)
109 read_output(fds[0], output, output_len); 109 read_output(fds[0], output, output_len);
110 printk("%s", output); 110 printk("%s", output);
111 111
112 err = helper_wait(pid, 0, argv[0]); 112 err = helper_wait(pid);
113 close(fds[0]); 113 close(fds[0]);
114 114
115out_free: 115out_free:
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index 89c1be225fda..a0ada8fec72a 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -98,7 +98,7 @@ static void slirp_close(int fd, void *data)
98 "(%d)\n", pri->pid, errno); 98 "(%d)\n", pri->pid, errno);
99 } 99 }
100#endif 100#endif
101 err = helper_wait(pri->pid, 1, "slirp_close"); 101 err = helper_wait(pri->pid);
102 if (err < 0) 102 if (err < 0)
103 return; 103 return;
104 104
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 875d60d0c6a2..f1786e64607f 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -15,7 +15,6 @@
15#include "line.h" 15#include "line.h"
16#include "ssl.h" 16#include "ssl.h"
17#include "chan_kern.h" 17#include "chan_kern.h"
18#include "kern_util.h"
19#include "kern.h" 18#include "kern.h"
20#include "init.h" 19#include "init.h"
21#include "irq_user.h" 20#include "irq_user.h"
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 656036e90b19..cec0c33cdd39 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -22,7 +22,6 @@
22#include "stdio_console.h" 22#include "stdio_console.h"
23#include "line.h" 23#include "line.h"
24#include "chan_kern.h" 24#include "chan_kern.h"
25#include "kern_util.h"
26#include "irq_user.h" 25#include "irq_user.h"
27#include "mconsole_kern.h" 26#include "mconsole_kern.h"
28#include "init.h" 27#include "init.h"
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 99f9f9605e9c..be3a2797dac4 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -49,6 +49,7 @@
49#include "irq_user.h" 49#include "irq_user.h"
50#include "irq_kern.h" 50#include "irq_kern.h"
51#include "ubd_user.h" 51#include "ubd_user.h"
52#include "kern_util.h"
52#include "os.h" 53#include "os.h"
53#include "mem.h" 54#include "mem.h"
54#include "mem_kern.h" 55#include "mem_kern.h"
@@ -229,7 +230,7 @@ static int proc_ide_read_media(char *page, char **start, off_t off, int count,
229 return len; 230 return len;
230} 231}
231 232
232static void make_ide_entries(char *dev_name) 233static void make_ide_entries(const char *dev_name)
233{ 234{
234 struct proc_dir_entry *dir, *ent; 235 struct proc_dir_entry *dir, *ent;
235 char name[64]; 236 char name[64];
@@ -244,7 +245,7 @@ static void make_ide_entries(char *dev_name)
244 ent->data = NULL; 245 ent->data = NULL;
245 ent->read_proc = proc_ide_read_media; 246 ent->read_proc = proc_ide_read_media;
246 ent->write_proc = NULL; 247 ent->write_proc = NULL;
247 sprintf(name,"ide0/%s", dev_name); 248 snprintf(name, sizeof(name), "ide0/%s", dev_name);
248 proc_symlink(dev_name, proc_ide_root, name); 249 proc_symlink(dev_name, proc_ide_root, name);
249} 250}
250 251
@@ -437,7 +438,10 @@ __uml_help(ubd_setup,
437" machine by running 'dd' on the device. <n> must be in the range\n" 438" machine by running 'dd' on the device. <n> must be in the range\n"
438" 0 to 7. Appending an 'r' to the number will cause that device\n" 439" 0 to 7. Appending an 'r' to the number will cause that device\n"
439" to be mounted read-only. For example ubd1r=./ext_fs. Appending\n" 440" to be mounted read-only. For example ubd1r=./ext_fs. Appending\n"
440" an 's' will cause data to be written to disk on the host immediately.\n\n" 441" an 's' will cause data to be written to disk on the host immediately.\n"
442" 'c' will cause the device to be treated as being shared between multiple\n"
443" UMLs and file locking will be turned off - this is appropriate for a\n"
444" cluster filesystem and inappropriate at almost all other times.\n\n"
441); 445);
442 446
443static int udb_setup(char *str) 447static int udb_setup(char *str)
@@ -456,20 +460,6 @@ __uml_help(udb_setup,
456" in the boot output.\n\n" 460" in the boot output.\n\n"
457); 461);
458 462
459static int fakehd_set = 0;
460static int fakehd(char *str)
461{
462 printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
463 fakehd_set = 1;
464 return 1;
465}
466
467__setup("fakehd", fakehd);
468__uml_help(fakehd,
469"fakehd\n"
470" Change the ubd device name to \"hd\".\n\n"
471);
472
473static void do_ubd_request(struct request_queue * q); 463static void do_ubd_request(struct request_queue * q);
474 464
475/* Only changed by ubd_init, which is an initcall. */ 465/* Only changed by ubd_init, which is an initcall. */
@@ -718,8 +708,10 @@ static int ubd_add(int n, char **error_out)
718 ubd_disk_register(fake_major, ubd_dev->size, n, 708 ubd_disk_register(fake_major, ubd_dev->size, n,
719 &fake_gendisk[n]); 709 &fake_gendisk[n]);
720 710
721 /* perhaps this should also be under the "if (fake_major)" above */ 711 /*
722 /* using the fake_disk->disk_name and also the fakehd_set name */ 712 * Perhaps this should also be under the "if (fake_major)" above
713 * using the fake_disk->disk_name
714 */
723 if (fake_ide) 715 if (fake_ide)
724 make_ide_entries(ubd_gendisk[n]->disk_name); 716 make_ide_entries(ubd_gendisk[n]->disk_name);
725 717
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
index 48fc7452bc1d..b591bb9c41dd 100644
--- a/arch/um/drivers/ubd_user.c
+++ b/arch/um/drivers/ubd_user.c
@@ -16,7 +16,6 @@
16#include <sys/mman.h> 16#include <sys/mman.h>
17#include <sys/param.h> 17#include <sys/param.h>
18#include "asm/types.h" 18#include "asm/types.h"
19#include "kern_util.h"
20#include "user.h" 19#include "user.h"
21#include "ubd_user.h" 20#include "ubd_user.h"
22#include "os.h" 21#include "os.h"
diff --git a/arch/um/drivers/vde_user.c b/arch/um/drivers/vde_user.c
index d9941fe5f931..56533db25343 100644
--- a/arch/um/drivers/vde_user.c
+++ b/arch/um/drivers/vde_user.c
@@ -80,7 +80,7 @@ void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init)
80 80
81 vpri->args = kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL); 81 vpri->args = kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL);
82 if (vpri->args == NULL) { 82 if (vpri->args == NULL) {
83 printk(UM_KERN_ERR "vde_init_libstuff - vde_open_args" 83 printk(UM_KERN_ERR "vde_init_libstuff - vde_open_args "
84 "allocation failed"); 84 "allocation failed");
85 return; 85 return;
86 } 86 }
diff --git a/arch/um/include/arch.h b/arch/um/include/arch.h
index 49c601ff2bac..2de92a08a76b 100644
--- a/arch/um/include/arch.h
+++ b/arch/um/include/arch.h
@@ -10,6 +10,6 @@
10 10
11extern void arch_check_bugs(void); 11extern void arch_check_bugs(void);
12extern int arch_fixup(unsigned long address, struct uml_pt_regs *regs); 12extern int arch_fixup(unsigned long address, struct uml_pt_regs *regs);
13extern int arch_handle_signal(int sig, struct uml_pt_regs *regs); 13extern void arch_examine_signal(int sig, struct uml_pt_regs *regs);
14 14
15#endif 15#endif
diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h
index a5cdf953e04a..606bb5c7fdf6 100644
--- a/arch/um/include/as-layout.h
+++ b/arch/um/include/as-layout.h
@@ -10,23 +10,31 @@
10#include "kern_constants.h" 10#include "kern_constants.h"
11 11
12/* 12/*
13 * Assembly doesn't want any casting, but C does, so define these 13 * Stolen from linux/const.h, which can't be directly included since
14 * without casts here, and define new symbols with casts inside the C 14 * this is used in userspace code, which has no access to the kernel
15 * section. 15 * headers. Changed to be suitable for adding casts to the start,
16 * rather than "UL" to the end.
16 */ 17 */
17#define ASM_STUB_CODE (UML_CONFIG_TOP_ADDR - 2 * UM_KERN_PAGE_SIZE)
18#define ASM_STUB_DATA (UML_CONFIG_TOP_ADDR - UM_KERN_PAGE_SIZE)
19#define ASM_STUB_START ASM_STUB_CODE
20 18
21/* 19/* Some constant macros are used in both assembler and
22 * This file is included by the assembly stubs, which just want the 20 * C code. Therefore we cannot annotate them always with
23 * definitions above. 21 * 'UL' and other type specifiers unilaterally. We
22 * use the following macros to deal with this.
24 */ 23 */
25#ifndef __ASSEMBLY__
26 24
27#define STUB_CODE ((unsigned long) ASM_STUB_CODE) 25#ifdef __ASSEMBLY__
28#define STUB_DATA ((unsigned long) ASM_STUB_DATA) 26#define _AC(X, Y) (Y)
29#define STUB_START ((unsigned long) ASM_STUB_START) 27#else
28#define __AC(X, Y) (X (Y))
29#define _AC(X, Y) __AC(X, Y)
30#endif
31
32#define STUB_START _AC(, 0x100000)
33#define STUB_CODE _AC((unsigned long), STUB_START)
34#define STUB_DATA _AC((unsigned long), STUB_CODE + UM_KERN_PAGE_SIZE)
35#define STUB_END _AC((unsigned long), STUB_DATA + UM_KERN_PAGE_SIZE)
36
37#ifndef __ASSEMBLY__
30 38
31#include "sysdep/ptrace.h" 39#include "sysdep/ptrace.h"
32 40
diff --git a/arch/um/include/chan_user.h b/arch/um/include/chan_user.h
index 5a2263e05bb2..9b9ced85b703 100644
--- a/arch/um/include/chan_user.h
+++ b/arch/um/include/chan_user.h
@@ -48,7 +48,7 @@ extern void register_winch_irq(int fd, int tty_fd, int pid,
48#define __channel_help(fn, prefix) \ 48#define __channel_help(fn, prefix) \
49__uml_help(fn, prefix "[0-9]*=<channel description>\n" \ 49__uml_help(fn, prefix "[0-9]*=<channel description>\n" \
50" Attach a console or serial line to a host channel. See\n" \ 50" Attach a console or serial line to a host channel. See\n" \
51" http://user-mode-linux.sourceforge.net/input.html for a complete\n" \ 51" http://user-mode-linux.sourceforge.net/old/input.html for a complete\n" \
52" description of this switch.\n\n" \ 52" description of this switch.\n\n" \
53); 53);
54 54
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
index 0edab695ed4e..b54bd35585c2 100644
--- a/arch/um/include/common-offsets.h
+++ b/arch/um/include/common-offsets.h
@@ -18,6 +18,7 @@ DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
18DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE); 18DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
19DEFINE_STR(UM_KERN_INFO, KERN_INFO); 19DEFINE_STR(UM_KERN_INFO, KERN_INFO);
20DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG); 20DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
21DEFINE_STR(UM_KERN_CONT, KERN_CONT);
21 22
22DEFINE(UM_ELF_CLASS, ELF_CLASS); 23DEFINE(UM_ELF_CLASS, ELF_CLASS);
23DEFINE(UM_ELFCLASS32, ELFCLASS32); 24DEFINE(UM_ELFCLASS32, ELFCLASS32);
diff --git a/arch/um/include/init.h b/arch/um/include/init.h
index cebc6cae9190..b00a95741d41 100644
--- a/arch/um/include/init.h
+++ b/arch/um/include/init.h
@@ -40,6 +40,20 @@
40typedef int (*initcall_t)(void); 40typedef int (*initcall_t)(void);
41typedef void (*exitcall_t)(void); 41typedef void (*exitcall_t)(void);
42 42
43#ifndef __KERNEL__
44#ifndef __section
45# define __section(S) __attribute__ ((__section__(#S)))
46#endif
47
48#if __GNUC_MINOR__ >= 3
49# define __used __attribute__((__used__))
50#else
51# define __used __attribute__((__unused__))
52#endif
53
54#else
55#include <linux/compiler.h>
56#endif
43/* These are for everybody (although not all archs will actually 57/* These are for everybody (although not all archs will actually
44 discard it in modules) */ 58 discard it in modules) */
45#define __init __section(.init.text) 59#define __init __section(.init.text)
@@ -127,14 +141,3 @@ extern struct uml_param __uml_setup_start, __uml_setup_end;
127#endif 141#endif
128 142
129#endif /* _LINUX_UML_INIT_H */ 143#endif /* _LINUX_UML_INIT_H */
130
131/*
132 * Overrides for Emacs so that we follow Linus's tabbing style.
133 * Emacs will notice this stuff at the end of the file and automatically
134 * adjust the settings for this buffer only. This must remain at the end
135 * of the file.
136 * ---------------------------------------------------------------------------
137 * Local variables:
138 * c-file-style: "linux"
139 * End:
140 */
diff --git a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h
index 884a9c17eea0..e60b31873de1 100644
--- a/arch/um/include/irq_user.h
+++ b/arch/um/include/irq_user.h
@@ -14,7 +14,6 @@ struct irq_fd {
14 int fd; 14 int fd;
15 int type; 15 int type;
16 int irq; 16 int irq;
17 int pid;
18 int events; 17 int events;
19 int current_events; 18 int current_events;
20}; 19};
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 74ce8e5370a6..3c341222d252 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -9,107 +9,61 @@
9#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
10#include "sysdep/faultinfo.h" 10#include "sysdep/faultinfo.h"
11 11
12typedef void (*kern_hndl)(int, struct uml_pt_regs *); 12extern int uml_exitcode;
13
14struct kern_handlers {
15 kern_hndl relay_signal;
16 kern_hndl winch;
17 kern_hndl bus_handler;
18 kern_hndl page_fault;
19 kern_hndl sigio_handler;
20 kern_hndl timer_handler;
21};
22
23extern const struct kern_handlers handlinfo_kern;
24 13
25extern int ncpus; 14extern int ncpus;
26extern char *gdb_init;
27extern int kmalloc_ok; 15extern int kmalloc_ok;
28extern int jail;
29extern int nsyscalls;
30 16
31#define UML_ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK))
32#define UML_ROUND_UP(addr) \ 17#define UML_ROUND_UP(addr) \
33 UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1) 18 ((((unsigned long) addr) + PAGE_SIZE - 1) & PAGE_MASK)
34 19
35extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg);
36extern int kernel_thread_proc(void *data);
37extern void syscall_segv(int sig);
38extern int current_pid(void);
39extern unsigned long alloc_stack(int order, int atomic); 20extern unsigned long alloc_stack(int order, int atomic);
21extern void free_stack(unsigned long stack, int order);
22
40extern int do_signal(void); 23extern int do_signal(void);
41extern int is_stack_fault(unsigned long sp); 24extern void copy_sc(struct uml_pt_regs *regs, void *from);
25extern void interrupt_end(void);
26extern void relay_signal(int sig, struct uml_pt_regs *regs);
27
42extern unsigned long segv(struct faultinfo fi, unsigned long ip, 28extern unsigned long segv(struct faultinfo fi, unsigned long ip,
43 int is_user, struct uml_pt_regs *regs); 29 int is_user, struct uml_pt_regs *regs);
44extern int handle_page_fault(unsigned long address, unsigned long ip, 30extern int handle_page_fault(unsigned long address, unsigned long ip,
45 int is_write, int is_user, int *code_out); 31 int is_write, int is_user, int *code_out);
46extern void syscall_ready(void); 32
47extern void set_tracing(void *t, int tracing);
48extern int is_tracing(void *task);
49extern int segv_syscall(void);
50extern void kern_finish_exec(void *task, int new_pid, unsigned long stack);
51extern unsigned long page_mask(void);
52extern int need_finish_fork(void);
53extern void free_stack(unsigned long stack, int order);
54extern void add_input_request(int op, void (*proc)(int), void *arg);
55extern char *current_cmd(void);
56extern void timer_handler(int sig, struct uml_pt_regs *regs);
57extern int set_signals(int enable);
58extern int pid_to_processor_id(int pid);
59extern void deliver_signals(void *t);
60extern int next_trap_index(int max);
61extern void default_idle(void);
62extern void finish_fork(void);
63extern void paging_init(void);
64extern void init_flush_vm(void);
65extern void *syscall_sp(void *t);
66extern void syscall_trace(struct uml_pt_regs *regs, int entryexit);
67extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs); 33extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs);
68extern void interrupt_end(void);
69extern void initial_thread_cb(void (*proc)(void *), void *arg);
70extern int debugger_signal(int status, int pid);
71extern void debugger_parent_signal(int status, int pid);
72extern void child_signal(int pid, int status);
73extern int init_ptrace_proxy(int idle_pid, int startup, int stop);
74extern int init_parent_proxy(int pid);
75extern int singlestepping(void *t);
76extern void check_stack_overflow(void *ptr);
77extern void relay_signal(int sig, struct uml_pt_regs *regs);
78extern int user_context(unsigned long sp);
79extern void timer_irq(struct uml_pt_regs *regs);
80extern void do_uml_exitcalls(void);
81extern int attach_debugger(int idle_pid, int pid, int stop);
82extern int config_gdb(char *str);
83extern int remove_gdb(void);
84extern char *uml_strdup(char *string);
85extern void unprotect_kernel_mem(void);
86extern void protect_kernel_mem(void);
87extern void uml_cleanup(void);
88extern void lock_signalled_task(void *t);
89extern void IPI_handler(int cpu);
90extern int jail_setup(char *line, int *add);
91extern void *get_init_task(void);
92extern int clear_user_proc(void *buf, int size);
93extern int copy_to_user_proc(void *to, void *from, int size);
94extern int copy_from_user_proc(void *to, void *from, int size);
95extern int strlen_user_proc(char *str);
96extern long execute_syscall(void *r);
97extern int smp_sigio_handler(void); 34extern int smp_sigio_handler(void);
98extern void *get_current(void); 35extern void initial_thread_cb(void (*proc)(void *), void *arg);
99extern struct task_struct *get_task(int pid, int require);
100extern void machine_halt(void);
101extern int is_syscall(unsigned long addr); 36extern int is_syscall(unsigned long addr);
37extern void timer_handler(int sig, struct uml_pt_regs *regs);
102 38
103extern void free_irq(unsigned int, void *); 39extern void timer_handler(int sig, struct uml_pt_regs *regs);
104extern int cpu(void);
105 40
106extern void time_init_kern(void); 41extern int start_uml(void);
42extern void paging_init(void);
107 43
108/* Are we disallowed to sleep? Used to choose between GFP_KERNEL and GFP_ATOMIC. */ 44extern void uml_cleanup(void);
45extern void do_uml_exitcalls(void);
46
47/*
48 * Are we disallowed to sleep? Used to choose between GFP_KERNEL and
49 * GFP_ATOMIC.
50 */
109extern int __cant_sleep(void); 51extern int __cant_sleep(void);
110extern void sigio_handler(int sig, struct uml_pt_regs *regs); 52extern void *get_current(void);
111extern void copy_sc(struct uml_pt_regs *regs, void *from); 53extern int copy_from_user_proc(void *to, void *from, int size);
54extern int cpu(void);
55extern char *uml_strdup(const char *string);
56
112extern unsigned long to_irq_stack(unsigned long *mask_out); 57extern unsigned long to_irq_stack(unsigned long *mask_out);
113unsigned long from_irq_stack(int nested); 58extern unsigned long from_irq_stack(int nested);
114extern int start_uml(void); 59
60extern void syscall_trace(struct uml_pt_regs *regs, int entryexit);
61extern int singlestepping(void *t);
62
63extern void segv_handler(int sig, struct uml_pt_regs *regs);
64extern void bus_handler(int sig, struct uml_pt_regs *regs);
65extern void winch(int sig, struct uml_pt_regs *regs);
66extern void fatal_sigsegv(void) __attribute__ ((noreturn));
67
68
115#endif 69#endif
diff --git a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h
index a54514d2cc3a..46384acd547b 100644
--- a/arch/um/include/mem_user.h
+++ b/arch/um/include/mem_user.h
@@ -46,9 +46,6 @@ extern int iomem_size;
46 46
47#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1)) 47#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
48 48
49extern unsigned long host_task_size;
50extern unsigned long task_size;
51
52extern int init_mem_user(void); 49extern int init_mem_user(void);
53extern void setup_memory(void *entry); 50extern void setup_memory(void *entry);
54extern unsigned long find_iomem(char *driver, unsigned long *len_out); 51extern unsigned long find_iomem(char *driver, unsigned long *len_out);
@@ -59,9 +56,7 @@ extern void setup_physmem(unsigned long start, unsigned long usable,
59 unsigned long len, unsigned long long highmem); 56 unsigned long len, unsigned long long highmem);
60extern void add_iomem(char *name, int fd, unsigned long size); 57extern void add_iomem(char *name, int fd, unsigned long size);
61extern unsigned long phys_offset(unsigned long phys); 58extern unsigned long phys_offset(unsigned long phys);
62extern void unmap_physmem(void);
63extern void map_memory(unsigned long virt, unsigned long phys, 59extern void map_memory(unsigned long virt, unsigned long phys,
64 unsigned long len, int r, int w, int x); 60 unsigned long len, int r, int w, int x);
65extern unsigned long get_kmem_end(void);
66 61
67#endif 62#endif
diff --git a/arch/um/include/misc_constants.h b/arch/um/include/misc_constants.h
deleted file mode 100644
index 989bc08de36e..000000000000
--- a/arch/um/include/misc_constants.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef __MISC_CONSTANT_H_
2#define __MISC_CONSTANT_H_
3
4#include <user_constants.h>
5
6#endif
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 6f0d1c741bca..0b6b62733303 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -8,7 +8,6 @@
8 8
9#include <stdarg.h> 9#include <stdarg.h>
10#include "irq_user.h" 10#include "irq_user.h"
11#include "kern_util.h"
12#include "longjmp.h" 11#include "longjmp.h"
13#include "mm_id.h" 12#include "mm_id.h"
14#include "sysdep/tls.h" 13#include "sysdep/tls.h"
@@ -128,33 +127,31 @@ static inline struct openflags of_cloexec(struct openflags flags)
128extern int os_stat_file(const char *file_name, struct uml_stat *buf); 127extern int os_stat_file(const char *file_name, struct uml_stat *buf);
129extern int os_stat_fd(const int fd, struct uml_stat *buf); 128extern int os_stat_fd(const int fd, struct uml_stat *buf);
130extern int os_access(const char *file, int mode); 129extern int os_access(const char *file, int mode);
131extern int os_get_exec_close(int fd, int *close_on_exec);
132extern int os_set_exec_close(int fd); 130extern int os_set_exec_close(int fd);
133extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg); 131extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
134extern int os_get_ifname(int fd, char *namebuf); 132extern int os_get_ifname(int fd, char *namebuf);
135extern int os_set_slip(int fd); 133extern int os_set_slip(int fd);
136extern int os_set_owner(int fd, int pid);
137extern int os_mode_fd(int fd, int mode); 134extern int os_mode_fd(int fd, int mode);
138 135
139extern int os_seek_file(int fd, unsigned long long offset); 136extern int os_seek_file(int fd, unsigned long long offset);
140extern int os_open_file(char *file, struct openflags flags, int mode); 137extern int os_open_file(const char *file, struct openflags flags, int mode);
141extern int os_read_file(int fd, void *buf, int len); 138extern int os_read_file(int fd, void *buf, int len);
142extern int os_write_file(int fd, const void *buf, int count); 139extern int os_write_file(int fd, const void *buf, int count);
143extern int os_file_size(char *file, unsigned long long *size_out); 140extern int os_file_size(const char *file, unsigned long long *size_out);
144extern int os_file_modtime(char *file, unsigned long *modtime); 141extern int os_file_modtime(const char *file, unsigned long *modtime);
145extern int os_pipe(int *fd, int stream, int close_on_exec); 142extern int os_pipe(int *fd, int stream, int close_on_exec);
146extern int os_set_fd_async(int fd, int owner); 143extern int os_set_fd_async(int fd);
147extern int os_clear_fd_async(int fd); 144extern int os_clear_fd_async(int fd);
148extern int os_set_fd_block(int fd, int blocking); 145extern int os_set_fd_block(int fd, int blocking);
149extern int os_accept_connection(int fd); 146extern int os_accept_connection(int fd);
150extern int os_create_unix_socket(char *file, int len, int close_on_exec); 147extern int os_create_unix_socket(const char *file, int len, int close_on_exec);
151extern int os_shutdown_socket(int fd, int r, int w); 148extern int os_shutdown_socket(int fd, int r, int w);
152extern void os_close_file(int fd); 149extern void os_close_file(int fd);
153extern int os_rcv_fd(int fd, int *helper_pid_out); 150extern int os_rcv_fd(int fd, int *helper_pid_out);
154extern int create_unix_socket(char *file, int len, int close_on_exec); 151extern int create_unix_socket(char *file, int len, int close_on_exec);
155extern int os_connect_socket(char *name); 152extern int os_connect_socket(const char *name);
156extern int os_file_type(char *file); 153extern int os_file_type(char *file);
157extern int os_file_mode(char *file, struct openflags *mode_out); 154extern int os_file_mode(const char *file, struct openflags *mode_out);
158extern int os_lock_file(int fd, int excl); 155extern int os_lock_file(int fd, int excl);
159extern void os_flush_stdout(void); 156extern void os_flush_stdout(void);
160extern int os_stat_filesystem(char *path, long *bsize_out, 157extern int os_stat_filesystem(char *path, long *bsize_out,
@@ -168,14 +165,10 @@ extern int os_fchange_dir(int fd);
168 165
169/* start_up.c */ 166/* start_up.c */
170extern void os_early_checks(void); 167extern void os_early_checks(void);
171extern int can_do_skas(void); 168extern void can_do_skas(void);
172extern void os_check_bugs(void); 169extern void os_check_bugs(void);
173extern void check_host_supports_tls(int *supports_tls, int *tls_min); 170extern void check_host_supports_tls(int *supports_tls, int *tls_min);
174 171
175/* Make sure they are clear when running in TT mode. Required by
176 * SEGV_MAYBE_FIXABLE */
177#define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0)
178
179/* mem.c */ 172/* mem.c */
180extern int create_mem_file(unsigned long long len); 173extern int create_mem_file(unsigned long long len);
181 174
@@ -214,7 +207,7 @@ extern int execvp_noalloc(char *buf, const char *file, char *const argv[]);
214extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv); 207extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv);
215extern int run_helper_thread(int (*proc)(void *), void *arg, 208extern int run_helper_thread(int (*proc)(void *), void *arg,
216 unsigned int flags, unsigned long *stack_out); 209 unsigned int flags, unsigned long *stack_out);
217extern int helper_wait(int pid, int nohang, char *pname); 210extern int helper_wait(int pid);
218 211
219 212
220/* tls.c */ 213/* tls.c */
@@ -237,16 +230,12 @@ extern void unblock_signals(void);
237extern int get_signals(void); 230extern int get_signals(void);
238extern int set_signals(int enable); 231extern int set_signals(int enable);
239 232
240/* trap.c */
241extern void os_fill_handlinfo(struct kern_handlers h);
242
243/* util.c */ 233/* util.c */
244extern void stack_protections(unsigned long address); 234extern void stack_protections(unsigned long address);
245extern int raw(int fd); 235extern int raw(int fd);
246extern void setup_machinename(char *machine_out); 236extern void setup_machinename(char *machine_out);
247extern void setup_hostinfo(char *buf, int len); 237extern void setup_hostinfo(char *buf, int len);
248extern int setjmp_wrapper(void (*proc)(void *, void *), ...); 238extern void os_dump_core(void) __attribute__ ((noreturn));
249extern void os_dump_core(void);
250 239
251/* time.c */ 240/* time.c */
252extern void idle_sleep(unsigned long long nsecs); 241extern void idle_sleep(unsigned long long nsecs);
@@ -275,11 +264,9 @@ extern int protect(struct mm_id * mm_idp, unsigned long addr,
275extern int is_skas_winch(int pid, int fd, void *data); 264extern int is_skas_winch(int pid, int fd, void *data);
276extern int start_userspace(unsigned long stub_stack); 265extern int start_userspace(unsigned long stub_stack);
277extern int copy_context_skas0(unsigned long stack, int pid); 266extern int copy_context_skas0(unsigned long stack, int pid);
278extern void save_registers(int pid, struct uml_pt_regs *regs);
279extern void restore_registers(int pid, struct uml_pt_regs *regs);
280extern void userspace(struct uml_pt_regs *regs); 267extern void userspace(struct uml_pt_regs *regs);
281extern void map_stub_pages(int fd, unsigned long code, 268extern int map_stub_pages(int fd, unsigned long code, unsigned long data,
282 unsigned long data, unsigned long stack); 269 unsigned long stack);
283extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)); 270extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void));
284extern void switch_threads(jmp_buf *me, jmp_buf *you); 271extern void switch_threads(jmp_buf *me, jmp_buf *you);
285extern int start_idle_thread(void *stack, jmp_buf *switch_buf); 272extern int start_idle_thread(void *stack, jmp_buf *switch_buf);
@@ -298,16 +285,12 @@ extern void os_free_irq_later(struct irq_fd *active_fds,
298extern int os_get_pollfd(int i); 285extern int os_get_pollfd(int i);
299extern void os_set_pollfd(int i, int fd); 286extern void os_set_pollfd(int i, int fd);
300extern void os_set_ioignore(void); 287extern void os_set_ioignore(void);
301extern void init_irq_signals(int on_sigstack);
302 288
303/* sigio.c */ 289/* sigio.c */
304extern int add_sigio_fd(int fd); 290extern int add_sigio_fd(int fd);
305extern int ignore_sigio_fd(int fd); 291extern int ignore_sigio_fd(int fd);
306extern void maybe_sigio_broken(int fd, int read); 292extern void maybe_sigio_broken(int fd, int read);
307 293
308/* skas/trap */
309extern void sig_handler_common_skas(int sig, void *sc_ptr);
310
311/* sys-x86_64/prctl.c */ 294/* sys-x86_64/prctl.c */
312extern int os_arch_prctl(int pid, int code, unsigned long *addr); 295extern int os_arch_prctl(int pid, int code, unsigned long *addr);
313 296
diff --git a/arch/um/include/ptrace_user.h b/arch/um/include/ptrace_user.h
index f3450e6bc18d..4bce6e012889 100644
--- a/arch/um/include/ptrace_user.h
+++ b/arch/um/include/ptrace_user.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -10,12 +10,6 @@
10 10
11extern int ptrace_getregs(long pid, unsigned long *regs_out); 11extern int ptrace_getregs(long pid, unsigned long *regs_out);
12extern int ptrace_setregs(long pid, unsigned long *regs_in); 12extern int ptrace_setregs(long pid, unsigned long *regs_in);
13extern int ptrace_getfpregs(long pid, unsigned long *regs_out);
14extern int ptrace_setfpregs(long pid, unsigned long *regs);
15extern void arch_enter_kernel(void *task, int pid);
16extern void arch_leave_kernel(void *task, int pid);
17extern void ptrace_pokeuser(unsigned long addr, unsigned long data);
18
19 13
20/* syscall emulation path in ptrace */ 14/* syscall emulation path in ptrace */
21 15
@@ -54,7 +48,8 @@ extern int sysemu_supported;
54 (((int[3][3] ) { \ 48 (((int[3][3] ) { \
55 { PTRACE_SYSCALL, PTRACE_SYSCALL, PTRACE_SINGLESTEP }, \ 49 { PTRACE_SYSCALL, PTRACE_SYSCALL, PTRACE_SINGLESTEP }, \
56 { PTRACE_SYSEMU, PTRACE_SYSEMU, PTRACE_SINGLESTEP }, \ 50 { PTRACE_SYSEMU, PTRACE_SYSEMU, PTRACE_SINGLESTEP }, \
57 { PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP, PTRACE_SYSEMU_SINGLESTEP }}) \ 51 { PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP, \
52 PTRACE_SYSEMU_SINGLESTEP } }) \
58 [sysemu_mode][singlestep_mode]) 53 [sysemu_mode][singlestep_mode])
59 54
60#endif 55#endif
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
index 0e27406a43a4..9ea1ae3c8f46 100644
--- a/arch/um/include/registers.h
+++ b/arch/um/include/registers.h
@@ -9,14 +9,13 @@
9#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
10#include "sysdep/archsetjmp.h" 10#include "sysdep/archsetjmp.h"
11 11
12extern void init_thread_registers(struct uml_pt_regs *to);
13extern int save_fp_registers(int pid, unsigned long *fp_regs); 12extern int save_fp_registers(int pid, unsigned long *fp_regs);
14extern int restore_fp_registers(int pid, unsigned long *fp_regs); 13extern int restore_fp_registers(int pid, unsigned long *fp_regs);
15extern int save_fpx_registers(int pid, unsigned long *fp_regs); 14extern int save_fpx_registers(int pid, unsigned long *fp_regs);
16extern int restore_fpx_registers(int pid, unsigned long *fp_regs); 15extern int restore_fpx_registers(int pid, unsigned long *fp_regs);
17extern void save_registers(int pid, struct uml_pt_regs *regs); 16extern int save_registers(int pid, struct uml_pt_regs *regs);
18extern void restore_registers(int pid, struct uml_pt_regs *regs); 17extern int restore_registers(int pid, struct uml_pt_regs *regs);
19extern void init_registers(int pid); 18extern int init_registers(int pid);
20extern void get_safe_registers(unsigned long *regs); 19extern void get_safe_registers(unsigned long *regs);
21extern unsigned long get_thread_reg(int reg, jmp_buf *buf); 20extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
22 21
diff --git a/arch/um/include/signal_kern.h b/arch/um/include/signal_kern.h
deleted file mode 100644
index aeb5d5ab1dfd..000000000000
--- a/arch/um/include/signal_kern.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SIGNAL_KERN_H__
7#define __SIGNAL_KERN_H__
8
9extern int have_signals(void *t);
10
11#endif
12
13/*
14 * Overrides for Emacs so that we follow Linus's tabbing style.
15 * Emacs will notice this stuff at the end of the file and automatically
16 * adjust the settings for this buffer only. This must remain at the end
17 * of the file.
18 * ---------------------------------------------------------------------------
19 * Local variables:
20 * c-file-style: "linux"
21 * End:
22 */
diff --git a/arch/um/include/skas/mode-skas.h b/arch/um/include/skas/mode-skas.h
deleted file mode 100644
index e065feb000df..000000000000
--- a/arch/um/include/skas/mode-skas.h
+++ /dev/null
@@ -1,11 +0,0 @@
1/*
2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __MODE_SKAS_H__
7#define __MODE_SKAS_H__
8
9extern void kill_off_processes_skas(void);
10
11#endif
diff --git a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h
index 57bd79efbee3..905698197e35 100644
--- a/arch/um/include/sysdep-i386/syscalls.h
+++ b/arch/um/include/sysdep-i386/syscalls.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -18,7 +18,8 @@ extern syscall_handler_t old_mmap_i386;
18extern syscall_handler_t *sys_call_table[]; 18extern syscall_handler_t *sys_call_table[];
19 19
20#define EXECUTE_SYSCALL(syscall, regs) \ 20#define EXECUTE_SYSCALL(syscall, regs) \
21 ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs)) 21 ((long (*)(struct syscall_args)) \
22 (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
22 23
23extern long sys_mmap2(unsigned long addr, unsigned long len, 24extern long sys_mmap2(unsigned long addr, unsigned long len,
24 unsigned long prot, unsigned long flags, 25 unsigned long prot, unsigned long flags,
diff --git a/arch/um/include/sysdep-x86_64/kernel-offsets.h b/arch/um/include/sysdep-x86_64/kernel-offsets.h
index c978b589df41..a307237b7964 100644
--- a/arch/um/include/sysdep-x86_64/kernel-offsets.h
+++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h
@@ -17,16 +17,7 @@
17#define OFFSET(sym, str, mem) \ 17#define OFFSET(sym, str, mem) \
18 DEFINE(sym, offsetof(struct str, mem)); 18 DEFINE(sym, offsetof(struct str, mem));
19 19
20#define __NO_STUBS 1
21#undef __SYSCALL
22#undef _ASM_X86_64_UNISTD_H_
23#define __SYSCALL(nr, sym) [nr] = 1,
24static char syscalls[] = {
25#include <asm/arch/unistd.h>
26};
27
28void foo(void) 20void foo(void)
29{ 21{
30#include <common-offsets.h> 22#include <common-offsets.h>
31DEFINE(UM_NR_syscall_max, sizeof(syscalls) - 1);
32} 23}
diff --git a/arch/um/include/sysdep-x86_64/syscalls.h b/arch/um/include/sysdep-x86_64/syscalls.h
index cf72256609e4..7cfb0b085655 100644
--- a/arch/um/include/sysdep-x86_64/syscalls.h
+++ b/arch/um/include/sysdep-x86_64/syscalls.h
@@ -30,6 +30,4 @@ extern long old_mmap(unsigned long addr, unsigned long len,
30extern syscall_handler_t sys_modify_ldt; 30extern syscall_handler_t sys_modify_ldt;
31extern syscall_handler_t sys_arch_prctl; 31extern syscall_handler_t sys_arch_prctl;
32 32
33#define NR_syscalls (UM_NR_syscall_max + 1)
34
35#endif 33#endif
diff --git a/arch/um/include/um_mmu.h b/arch/um/include/um_mmu.h
index 8855d8df512f..82865fcf6872 100644
--- a/arch/um/include/um_mmu.h
+++ b/arch/um/include/um_mmu.h
@@ -12,10 +12,6 @@
12 12
13typedef struct mm_context { 13typedef struct mm_context {
14 struct mm_id id; 14 struct mm_id id;
15 unsigned long last_page_table;
16#ifdef CONFIG_3_LEVEL_PGTABLES
17 unsigned long last_pmd;
18#endif
19 struct uml_ldt ldt; 15 struct uml_ldt ldt;
20} mm_context_t; 16} mm_context_t;
21 17
diff --git a/arch/um/include/um_uaccess.h b/arch/um/include/um_uaccess.h
index fdfc06b85605..2b6fc8e0f071 100644
--- a/arch/um/include/um_uaccess.h
+++ b/arch/um/include/um_uaccess.h
@@ -6,7 +6,9 @@
6#ifndef __ARCH_UM_UACCESS_H 6#ifndef __ARCH_UM_UACCESS_H
7#define __ARCH_UM_UACCESS_H 7#define __ARCH_UM_UACCESS_H
8 8
9#include "asm/fixmap.h" 9#include <asm/elf.h>
10#include <asm/fixmap.h>
11#include "sysdep/archsetjmp.h"
10 12
11#define __under_task_size(addr, size) \ 13#define __under_task_size(addr, size) \
12 (((unsigned long) (addr) < TASK_SIZE) && \ 14 (((unsigned long) (addr) < TASK_SIZE) && \
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index 8196450451cd..76a62c0cb2bc 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -19,12 +19,13 @@
19void flush_thread(void) 19void flush_thread(void)
20{ 20{
21 void *data = NULL; 21 void *data = NULL;
22 unsigned long end = proc_mm ? task_size : STUB_START;
23 int ret; 22 int ret;
24 23
25 arch_flush_thread(&current->thread.arch); 24 arch_flush_thread(&current->thread.arch);
26 25
27 ret = unmap(&current->mm->context.id, 0, end, 1, &data); 26 ret = unmap(&current->mm->context.id, 0, STUB_START, 0, &data);
27 ret = ret || unmap(&current->mm->context.id, STUB_END,
28 TASK_SIZE - STUB_END, 1, &data);
28 if (ret) { 29 if (ret) {
29 printk(KERN_ERR "flush_thread - clearing address space failed, " 30 printk(KERN_ERR "flush_thread - clearing address space failed, "
30 "err = %d\n", ret); 31 "err = %d\n", ret);
diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c
index c716b5a6db13..984f80e668ca 100644
--- a/arch/um/kernel/exitcode.c
+++ b/arch/um/kernel/exitcode.c
@@ -1,15 +1,17 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/kernel.h" 6#include <linux/ctype.h>
7#include "linux/init.h" 7#include <linux/init.h>
8#include "linux/ctype.h" 8#include <linux/kernel.h>
9#include "linux/proc_fs.h" 9#include <linux/proc_fs.h>
10#include "asm/uaccess.h" 10#include <linux/types.h>
11#include <asm/uaccess.h>
11 12
12/* If read and write race, the read will still atomically read a valid 13/*
14 * If read and write race, the read will still atomically read a valid
13 * value. 15 * value.
14 */ 16 */
15int uml_exitcode = 0; 17int uml_exitcode = 0;
@@ -19,18 +21,19 @@ static int read_proc_exitcode(char *page, char **start, off_t off,
19{ 21{
20 int len, val; 22 int len, val;
21 23
22 /* Save uml_exitcode in a local so that we don't need to guarantee 24 /*
25 * Save uml_exitcode in a local so that we don't need to guarantee
23 * that sprintf accesses it atomically. 26 * that sprintf accesses it atomically.
24 */ 27 */
25 val = uml_exitcode; 28 val = uml_exitcode;
26 len = sprintf(page, "%d\n", val); 29 len = sprintf(page, "%d\n", val);
27 len -= off; 30 len -= off;
28 if(len <= off+count) 31 if (len <= off+count)
29 *eof = 1; 32 *eof = 1;
30 *start = page + off; 33 *start = page + off;
31 if(len > count) 34 if (len > count)
32 len = count; 35 len = count;
33 if(len < 0) 36 if (len < 0)
34 len = 0; 37 len = 0;
35 return len; 38 return len;
36} 39}
@@ -41,11 +44,11 @@ static int write_proc_exitcode(struct file *file, const char __user *buffer,
41 char *end, buf[sizeof("nnnnn\0")]; 44 char *end, buf[sizeof("nnnnn\0")];
42 int tmp; 45 int tmp;
43 46
44 if(copy_from_user(buf, buffer, count)) 47 if (copy_from_user(buf, buffer, count))
45 return -EFAULT; 48 return -EFAULT;
46 49
47 tmp = simple_strtol(buf, &end, 0); 50 tmp = simple_strtol(buf, &end, 0);
48 if((*end != '\0') && !isspace(*end)) 51 if ((*end != '\0') && !isspace(*end))
49 return -EINVAL; 52 return -EINVAL;
50 53
51 uml_exitcode = tmp; 54 uml_exitcode = tmp;
@@ -57,7 +60,7 @@ static int make_proc_exitcode(void)
57 struct proc_dir_entry *ent; 60 struct proc_dir_entry *ent;
58 61
59 ent = create_proc_entry("exitcode", 0600, &proc_root); 62 ent = create_proc_entry("exitcode", 0600, &proc_root);
60 if(ent == NULL){ 63 if (ent == NULL) {
61 printk(KERN_WARNING "make_proc_exitcode : Failed to register " 64 printk(KERN_WARNING "make_proc_exitcode : Failed to register "
62 "/proc/exitcode\n"); 65 "/proc/exitcode\n");
63 return 0; 66 return 0;
diff --git a/arch/um/kernel/gmon_syms.c b/arch/um/kernel/gmon_syms.c
index 734f873cab12..72eccd2a4113 100644
--- a/arch/um/kernel/gmon_syms.c
+++ b/arch/um/kernel/gmon_syms.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -8,12 +8,13 @@
8extern void __bb_init_func(void *) __attribute__((weak)); 8extern void __bb_init_func(void *) __attribute__((weak));
9EXPORT_SYMBOL(__bb_init_func); 9EXPORT_SYMBOL(__bb_init_func);
10 10
11/* This is defined (and referred to in profiling stub code) only by some GCC 11/*
12 * This is defined (and referred to in profiling stub code) only by some GCC
12 * versions in libgcov. 13 * versions in libgcov.
13 * 14 *
14 * Since SuSE backported the fix, we cannot handle it depending on GCC version. 15 * Since SuSE backported the fix, we cannot handle it depending on GCC version.
15 * So, unconditionally export it. But also give it a weak declaration, which will 16 * So, unconditionally export it. But also give it a weak declaration, which
16 * be overridden by any other one. 17 * will be overridden by any other one.
17 */ 18 */
18 19
19extern void __gcov_init(void *) __attribute__((weak)); 20extern void __gcov_init(void *) __attribute__((weak));
diff --git a/arch/um/kernel/gprof_syms.c b/arch/um/kernel/gprof_syms.c
index 9244f018d44c..e2f043d0de6c 100644
--- a/arch/um/kernel/gprof_syms.c
+++ b/arch/um/kernel/gprof_syms.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -7,14 +7,3 @@
7 7
8extern void mcount(void); 8extern void mcount(void);
9EXPORT_SYMBOL(mcount); 9EXPORT_SYMBOL(mcount);
10
11/*
12 * Overrides for Emacs so that we follow Linus's tabbing style.
13 * Emacs will notice this stuff at the end of the file and automatically
14 * adjust the settings for this buffer only. This must remain at the end
15 * of the file.
16 * ---------------------------------------------------------------------------
17 * Local variables:
18 * c-file-style: "linux"
19 * End:
20 */
diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c
index 16dc43e9d940..fa015565001b 100644
--- a/arch/um/kernel/initrd.c
+++ b/arch/um/kernel/initrd.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -7,7 +7,6 @@
7#include "linux/bootmem.h" 7#include "linux/bootmem.h"
8#include "linux/initrd.h" 8#include "linux/initrd.h"
9#include "asm/types.h" 9#include "asm/types.h"
10#include "kern_util.h"
11#include "initrd.h" 10#include "initrd.h"
12#include "init.h" 11#include "init.h"
13#include "os.h" 12#include "os.h"
@@ -21,18 +20,27 @@ static int __init read_initrd(void)
21 long long size; 20 long long size;
22 int err; 21 int err;
23 22
24 if(initrd == NULL) 23 if (initrd == NULL)
25 return 0; 24 return 0;
26 25
27 err = os_file_size(initrd, &size); 26 err = os_file_size(initrd, &size);
28 if(err) 27 if (err)
29 return 0; 28 return 0;
30 29
30 /*
31 * This is necessary because alloc_bootmem craps out if you
32 * ask for no memory.
33 */
34 if (size == 0) {
35 printk(KERN_ERR "\"%\" is a zero-size initrd\n");
36 return 0;
37 }
38
31 area = alloc_bootmem(size); 39 area = alloc_bootmem(size);
32 if(area == NULL) 40 if (area == NULL)
33 return 0; 41 return 0;
34 42
35 if(load_initrd(initrd, area, size) == -1) 43 if (load_initrd(initrd, area, size) == -1)
36 return 0; 44 return 0;
37 45
38 initrd_start = (unsigned long) area; 46 initrd_start = (unsigned long) area;
@@ -59,13 +67,15 @@ int load_initrd(char *filename, void *buf, int size)
59 int fd, n; 67 int fd, n;
60 68
61 fd = os_open_file(filename, of_read(OPENFLAGS()), 0); 69 fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
62 if(fd < 0){ 70 if (fd < 0) {
63 printk("Opening '%s' failed - err = %d\n", filename, -fd); 71 printk(KERN_ERR "Opening '%s' failed - err = %d\n", filename,
72 -fd);
64 return -1; 73 return -1;
65 } 74 }
66 n = os_read_file(fd, buf, size); 75 n = os_read_file(fd, buf, size);
67 if(n != size){ 76 if (n != size) {
68 printk("Read of %d bytes from '%s' failed, err = %d\n", size, 77 printk(KERN_ERR "Read of %d bytes from '%s' failed, "
78 "err = %d\n", size,
69 filename, -n); 79 filename, -n);
70 return -1; 80 return -1;
71 } 81 }
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index ba11ccd6a8a3..91587f8db340 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -107,10 +107,9 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
107 struct pollfd *tmp_pfd; 107 struct pollfd *tmp_pfd;
108 struct irq_fd *new_fd, *irq_fd; 108 struct irq_fd *new_fd, *irq_fd;
109 unsigned long flags; 109 unsigned long flags;
110 int pid, events, err, n; 110 int events, err, n;
111 111
112 pid = os_getpid(); 112 err = os_set_fd_async(fd);
113 err = os_set_fd_async(fd, pid);
114 if (err < 0) 113 if (err < 0)
115 goto out; 114 goto out;
116 115
@@ -127,7 +126,6 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
127 .fd = fd, 126 .fd = fd,
128 .type = type, 127 .type = type,
129 .irq = irq, 128 .irq = irq,
130 .pid = pid,
131 .events = events, 129 .events = events,
132 .current_events = 0 } ); 130 .current_events = 0 } );
133 131
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 7c7142ba3bd7..5311ee93ede3 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -18,15 +18,11 @@ EXPORT_SYMBOL(set_signals);
18EXPORT_SYMBOL(get_signals); 18EXPORT_SYMBOL(get_signals);
19EXPORT_SYMBOL(kernel_thread); 19EXPORT_SYMBOL(kernel_thread);
20EXPORT_SYMBOL(sys_waitpid); 20EXPORT_SYMBOL(sys_waitpid);
21EXPORT_SYMBOL(task_size);
22EXPORT_SYMBOL(flush_tlb_range); 21EXPORT_SYMBOL(flush_tlb_range);
23EXPORT_SYMBOL(host_task_size);
24EXPORT_SYMBOL(arch_validate); 22EXPORT_SYMBOL(arch_validate);
25EXPORT_SYMBOL(get_kmem_end);
26 23
27EXPORT_SYMBOL(high_physmem); 24EXPORT_SYMBOL(high_physmem);
28EXPORT_SYMBOL(empty_zero_page); 25EXPORT_SYMBOL(empty_zero_page);
29EXPORT_SYMBOL(um_virt_to_phys);
30EXPORT_SYMBOL(handle_page_fault); 26EXPORT_SYMBOL(handle_page_fault);
31EXPORT_SYMBOL(find_iomem); 27EXPORT_SYMBOL(find_iomem);
32 28
@@ -40,7 +36,6 @@ EXPORT_SYMBOL(uml_strdup);
40EXPORT_SYMBOL(os_stat_fd); 36EXPORT_SYMBOL(os_stat_fd);
41EXPORT_SYMBOL(os_stat_file); 37EXPORT_SYMBOL(os_stat_file);
42EXPORT_SYMBOL(os_access); 38EXPORT_SYMBOL(os_access);
43EXPORT_SYMBOL(os_get_exec_close);
44EXPORT_SYMBOL(os_set_exec_close); 39EXPORT_SYMBOL(os_set_exec_close);
45EXPORT_SYMBOL(os_getpid); 40EXPORT_SYMBOL(os_getpid);
46EXPORT_SYMBOL(os_open_file); 41EXPORT_SYMBOL(os_open_file);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 59822dee438a..d872fdce1d7e 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -1,49 +1,41 @@
1/* 1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/stddef.h" 6#include <linux/stddef.h>
7#include "linux/kernel.h" 7#include <linux/bootmem.h>
8#include "linux/mm.h" 8#include <linux/gfp.h>
9#include "linux/bootmem.h" 9#include <linux/highmem.h>
10#include "linux/swap.h" 10#include <linux/mm.h>
11#include "linux/highmem.h" 11#include <linux/swap.h>
12#include "linux/gfp.h" 12#include <asm/fixmap.h>
13#include "asm/page.h" 13#include <asm/page.h>
14#include "asm/fixmap.h"
15#include "asm/pgalloc.h"
16#include "kern_util.h"
17#include "as-layout.h" 14#include "as-layout.h"
15#include "init.h"
18#include "kern.h" 16#include "kern.h"
17#include "kern_util.h"
19#include "mem_user.h" 18#include "mem_user.h"
20#include "um_uaccess.h"
21#include "os.h" 19#include "os.h"
22#include "linux/types.h"
23#include "linux/string.h"
24#include "init.h"
25#include "kern_constants.h"
26 20
27/* allocated in paging_init, zeroed in mem_init, and unchanged thereafter */ 21/* allocated in paging_init, zeroed in mem_init, and unchanged thereafter */
28unsigned long *empty_zero_page = NULL; 22unsigned long *empty_zero_page = NULL;
29/* allocated in paging_init and unchanged thereafter */ 23/* allocated in paging_init and unchanged thereafter */
30unsigned long *empty_bad_page = NULL; 24unsigned long *empty_bad_page = NULL;
25
26/*
27 * Initialized during boot, and readonly for initializing page tables
28 * afterwards
29 */
31pgd_t swapper_pg_dir[PTRS_PER_PGD]; 30pgd_t swapper_pg_dir[PTRS_PER_PGD];
31
32/* Initialized at boot time, and readonly after that */
32unsigned long long highmem; 33unsigned long long highmem;
33int kmalloc_ok = 0; 34int kmalloc_ok = 0;
34 35
36/* Used during early boot */
35static unsigned long brk_end; 37static unsigned long brk_end;
36 38
37void unmap_physmem(void)
38{
39 os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
40}
41
42static void map_cb(void *unused)
43{
44 map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
45}
46
47#ifdef CONFIG_HIGHMEM 39#ifdef CONFIG_HIGHMEM
48static void setup_highmem(unsigned long highmem_start, 40static void setup_highmem(unsigned long highmem_start,
49 unsigned long highmem_len) 41 unsigned long highmem_len)
@@ -53,7 +45,7 @@ static void setup_highmem(unsigned long highmem_start,
53 int i; 45 int i;
54 46
55 highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT; 47 highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT;
56 for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){ 48 for (i = 0; i < highmem_len >> PAGE_SHIFT; i++) {
57 page = &mem_map[highmem_pfn + i]; 49 page = &mem_map[highmem_pfn + i];
58 ClearPageReserved(page); 50 ClearPageReserved(page);
59 init_page_count(page); 51 init_page_count(page);
@@ -65,14 +57,13 @@ static void setup_highmem(unsigned long highmem_start,
65void __init mem_init(void) 57void __init mem_init(void)
66{ 58{
67 /* clear the zero-page */ 59 /* clear the zero-page */
68 memset((void *) empty_zero_page, 0, PAGE_SIZE); 60 memset(empty_zero_page, 0, PAGE_SIZE);
69 61
70 /* Map in the area just after the brk now that kmalloc is about 62 /* Map in the area just after the brk now that kmalloc is about
71 * to be turned on. 63 * to be turned on.
72 */ 64 */
73 brk_end = (unsigned long) UML_ROUND_UP(sbrk(0)); 65 brk_end = (unsigned long) UML_ROUND_UP(sbrk(0));
74 map_cb(NULL); 66 map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
75 initial_thread_cb(map_cb, NULL);
76 free_bootmem(__pa(brk_end), uml_reserved - brk_end); 67 free_bootmem(__pa(brk_end), uml_reserved - brk_end);
77 uml_reserved = brk_end; 68 uml_reserved = brk_end;
78 69
@@ -85,7 +76,7 @@ void __init mem_init(void)
85#endif 76#endif
86 num_physpages = totalram_pages; 77 num_physpages = totalram_pages;
87 max_pfn = totalram_pages; 78 max_pfn = totalram_pages;
88 printk(KERN_INFO "Memory: %luk available\n", 79 printk(KERN_INFO "Memory: %luk available\n",
89 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10)); 80 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10));
90 kmalloc_ok = 1; 81 kmalloc_ok = 1;
91 82
@@ -119,7 +110,7 @@ static void __init one_md_table_init(pud_t *pud)
119#endif 110#endif
120} 111}
121 112
122static void __init fixrange_init(unsigned long start, unsigned long end, 113static void __init fixrange_init(unsigned long start, unsigned long end,
123 pgd_t *pgd_base) 114 pgd_t *pgd_base)
124{ 115{
125 pgd_t *pgd; 116 pgd_t *pgd;
@@ -138,7 +129,7 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
138 if (pud_none(*pud)) 129 if (pud_none(*pud))
139 one_md_table_init(pud); 130 one_md_table_init(pud);
140 pmd = pmd_offset(pud, vaddr); 131 pmd = pmd_offset(pud, vaddr);
141 for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { 132 for (; (j < PTRS_PER_PMD) && (vaddr < end); pmd++, j++) {
142 one_page_table_init(pmd); 133 one_page_table_init(pmd);
143 vaddr += PMD_SIZE; 134 vaddr += PMD_SIZE;
144 } 135 }
@@ -152,7 +143,7 @@ pgprot_t kmap_prot;
152 143
153#define kmap_get_fixmap_pte(vaddr) \ 144#define kmap_get_fixmap_pte(vaddr) \
154 pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)),\ 145 pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)),\
155 (vaddr)), (vaddr)) 146 (vaddr)), (vaddr))
156 147
157static void __init kmap_init(void) 148static void __init kmap_init(void)
158{ 149{
@@ -197,21 +188,23 @@ static void __init fixaddr_user_init( void)
197 pud_t *pud; 188 pud_t *pud;
198 pmd_t *pmd; 189 pmd_t *pmd;
199 pte_t *pte; 190 pte_t *pte;
200 unsigned long paddr, vaddr = FIXADDR_USER_START; 191 phys_t p;
192 unsigned long v, vaddr = FIXADDR_USER_START;
201 193
202 if ( ! size ) 194 if (!size)
203 return; 195 return;
204 196
205 fixrange_init( FIXADDR_USER_START, FIXADDR_USER_END, swapper_pg_dir); 197 fixrange_init( FIXADDR_USER_START, FIXADDR_USER_END, swapper_pg_dir);
206 paddr = (unsigned long)alloc_bootmem_low_pages( size); 198 v = (unsigned long) alloc_bootmem_low_pages(size);
207 memcpy( (void *)paddr, (void *)FIXADDR_USER_START, size); 199 memcpy((void *) v , (void *) FIXADDR_USER_START, size);
208 paddr = __pa(paddr); 200 p = __pa(v);
209 for ( ; size > 0; size-=PAGE_SIZE, vaddr+=PAGE_SIZE, paddr+=PAGE_SIZE){ 201 for ( ; size > 0; size -= PAGE_SIZE, vaddr += PAGE_SIZE,
202 p += PAGE_SIZE) {
210 pgd = swapper_pg_dir + pgd_index(vaddr); 203 pgd = swapper_pg_dir + pgd_index(vaddr);
211 pud = pud_offset(pgd, vaddr); 204 pud = pud_offset(pgd, vaddr);
212 pmd = pmd_offset(pud, vaddr); 205 pmd = pmd_offset(pud, vaddr);
213 pte = pte_offset_kernel(pmd, vaddr); 206 pte = pte_offset_kernel(pmd, vaddr);
214 pte_set_val( (*pte), paddr, PAGE_READONLY); 207 pte_set_val(*pte, p, PAGE_READONLY);
215 } 208 }
216#endif 209#endif
217} 210}
@@ -223,7 +216,7 @@ void __init paging_init(void)
223 216
224 empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE); 217 empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
225 empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE); 218 empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
226 for(i = 0; i < ARRAY_SIZE(zones_size); i++) 219 for (i = 0; i < ARRAY_SIZE(zones_size); i++)
227 zones_size[i] = 0; 220 zones_size[i] = 0;
228 221
229 zones_size[ZONE_NORMAL] = (end_iomem >> PAGE_SHIFT) - 222 zones_size[ZONE_NORMAL] = (end_iomem >> PAGE_SHIFT) -
@@ -253,32 +246,33 @@ struct page *arch_validate(struct page *page, gfp_t mask, int order)
253 int i; 246 int i;
254 247
255 again: 248 again:
256 if(page == NULL) 249 if (page == NULL)
257 return page; 250 return page;
258 if(PageHighMem(page)) 251 if (PageHighMem(page))
259 return page; 252 return page;
260 253
261 addr = (unsigned long) page_address(page); 254 addr = (unsigned long) page_address(page);
262 for(i = 0; i < (1 << order); i++){ 255 for (i = 0; i < (1 << order); i++) {
263 current->thread.fault_addr = (void *) addr; 256 current->thread.fault_addr = (void *) addr;
264 if(__do_copy_to_user((void __user *) addr, &zero, 257 if (__do_copy_to_user((void __user *) addr, &zero,
265 sizeof(zero), 258 sizeof(zero),
266 &current->thread.fault_addr, 259 &current->thread.fault_addr,
267 &current->thread.fault_catcher)){ 260 &current->thread.fault_catcher)) {
268 if(!(mask & __GFP_WAIT)) 261 if (!(mask & __GFP_WAIT))
269 return NULL; 262 return NULL;
270 else break; 263 else break;
271 } 264 }
272 addr += PAGE_SIZE; 265 addr += PAGE_SIZE;
273 } 266 }
274 267
275 if(i == (1 << order)) 268 if (i == (1 << order))
276 return page; 269 return page;
277 page = alloc_pages(mask, order); 270 page = alloc_pages(mask, order);
278 goto again; 271 goto again;
279} 272}
280 273
281/* This can't do anything because nothing in the kernel image can be freed 274/*
275 * This can't do anything because nothing in the kernel image can be freed
282 * since it's not in kernel physical memory. 276 * since it's not in kernel physical memory.
283 */ 277 */
284 278
@@ -290,8 +284,8 @@ void free_initmem(void)
290void free_initrd_mem(unsigned long start, unsigned long end) 284void free_initrd_mem(unsigned long start, unsigned long end)
291{ 285{
292 if (start < end) 286 if (start < end)
293 printk ("Freeing initrd memory: %ldk freed\n", 287 printk(KERN_INFO "Freeing initrd memory: %ldk freed\n",
294 (end - start) >> 10); 288 (end - start) >> 10);
295 for (; start < end; start += PAGE_SIZE) { 289 for (; start < end; start += PAGE_SIZE) {
296 ClearPageReserved(virt_to_page(start)); 290 ClearPageReserved(virt_to_page(start));
297 init_page_count(virt_to_page(start)); 291 init_page_count(virt_to_page(start));
@@ -308,32 +302,31 @@ void show_mem(void)
308 int highmem = 0; 302 int highmem = 0;
309 struct page *page; 303 struct page *page;
310 304
311 printk("Mem-info:\n"); 305 printk(KERN_INFO "Mem-info:\n");
312 show_free_areas(); 306 show_free_areas();
313 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); 307 printk(KERN_INFO "Free swap: %6ldkB\n",
308 nr_swap_pages<<(PAGE_SHIFT-10));
314 pfn = max_mapnr; 309 pfn = max_mapnr;
315 while(pfn-- > 0) { 310 while (pfn-- > 0) {
316 page = pfn_to_page(pfn); 311 page = pfn_to_page(pfn);
317 total++; 312 total++;
318 if(PageHighMem(page)) 313 if (PageHighMem(page))
319 highmem++; 314 highmem++;
320 if(PageReserved(page)) 315 if (PageReserved(page))
321 reserved++; 316 reserved++;
322 else if(PageSwapCache(page)) 317 else if (PageSwapCache(page))
323 cached++; 318 cached++;
324 else if(page_count(page)) 319 else if (page_count(page))
325 shared += page_count(page) - 1; 320 shared += page_count(page) - 1;
326 } 321 }
327 printk("%d pages of RAM\n", total); 322 printk(KERN_INFO "%d pages of RAM\n", total);
328 printk("%d pages of HIGHMEM\n", highmem); 323 printk(KERN_INFO "%d pages of HIGHMEM\n", highmem);
329 printk("%d reserved pages\n", reserved); 324 printk(KERN_INFO "%d reserved pages\n", reserved);
330 printk("%d pages shared\n", shared); 325 printk(KERN_INFO "%d pages shared\n", shared);
331 printk("%d pages swap cached\n", cached); 326 printk(KERN_INFO "%d pages swap cached\n", cached);
332} 327}
333 328
334/* 329/* Allocate and free page tables. */
335 * Allocate and free page tables.
336 */
337 330
338pgd_t *pgd_alloc(struct mm_struct *mm) 331pgd_t *pgd_alloc(struct mm_struct *mm)
339{ 332{
@@ -341,14 +334,14 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
341 334
342 if (pgd) { 335 if (pgd) {
343 memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); 336 memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
344 memcpy(pgd + USER_PTRS_PER_PGD, 337 memcpy(pgd + USER_PTRS_PER_PGD,
345 swapper_pg_dir + USER_PTRS_PER_PGD, 338 swapper_pg_dir + USER_PTRS_PER_PGD,
346 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 339 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
347 } 340 }
348 return pgd; 341 return pgd;
349} 342}
350 343
351void pgd_free(pgd_t *pgd) 344void pgd_free(struct mm_struct *mm, pgd_t *pgd)
352{ 345{
353 free_page((unsigned long) pgd); 346 free_page((unsigned long) pgd);
354} 347}
@@ -368,3 +361,15 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
368 pte = alloc_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); 361 pte = alloc_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
369 return pte; 362 return pte;
370} 363}
364
365#ifdef CONFIG_3_LEVEL_PGTABLES
366pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
367{
368 pmd_t *pmd = (pmd_t *) __get_free_page(GFP_KERNEL);
369
370 if (pmd)
371 memset(pmd, 0, PAGE_SIZE);
372
373 return pmd;
374}
375#endif
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index e66432f42485..9757085a0220 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -55,16 +55,6 @@ int __init init_maps(unsigned long physmem, unsigned long iomem,
55 return 0; 55 return 0;
56} 56}
57 57
58/* Changed during early boot */
59static unsigned long kmem_top = 0;
60
61unsigned long get_kmem_end(void)
62{
63 if (kmem_top == 0)
64 kmem_top = host_task_size - 1024 * 1024;
65 return kmem_top;
66}
67
68void map_memory(unsigned long virt, unsigned long phys, unsigned long len, 58void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
69 int r, int w, int x) 59 int r, int w, int x)
70{ 60{
@@ -174,10 +164,10 @@ __uml_setup("iomem=", parse_iomem,
174 * setup_iomem, both of which run during early boot. Afterwards, it's 164 * setup_iomem, both of which run during early boot. Afterwards, it's
175 * unchanged. 165 * unchanged.
176 */ 166 */
177struct iomem_region *iomem_regions = NULL; 167struct iomem_region *iomem_regions;
178 168
179/* Initialized in parse_iomem */ 169/* Initialized in parse_iomem and unchanged thereafter */
180int iomem_size = 0; 170int iomem_size;
181 171
182unsigned long find_iomem(char *driver, unsigned long *len_out) 172unsigned long find_iomem(char *driver, unsigned long *len_out)
183{ 173{
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 0eae00b3e588..c07961bedb75 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -4,19 +4,21 @@
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7#include "linux/stddef.h" 7#include <linux/stddef.h>
8#include "linux/err.h" 8#include <linux/err.h>
9#include "linux/hardirq.h" 9#include <linux/hardirq.h>
10#include "linux/mm.h" 10#include <linux/gfp.h>
11#include "linux/personality.h" 11#include <linux/mm.h>
12#include "linux/proc_fs.h" 12#include <linux/personality.h>
13#include "linux/ptrace.h" 13#include <linux/proc_fs.h>
14#include "linux/random.h" 14#include <linux/ptrace.h>
15#include "linux/sched.h" 15#include <linux/random.h>
16#include "linux/tick.h" 16#include <linux/sched.h>
17#include "linux/threads.h" 17#include <linux/tick.h>
18#include "asm/pgtable.h" 18#include <linux/threads.h>
19#include "asm/uaccess.h" 19#include <asm/current.h>
20#include <asm/pgtable.h>
21#include <asm/uaccess.h>
20#include "as-layout.h" 22#include "as-layout.h"
21#include "kern_util.h" 23#include "kern_util.h"
22#include "os.h" 24#include "os.h"
@@ -30,7 +32,7 @@
30 */ 32 */
31struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; 33struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
32 34
33static inline int external_pid(struct task_struct *task) 35static inline int external_pid(void)
34{ 36{
35 /* FIXME: Need to look up userspace_pid by cpu */ 37 /* FIXME: Need to look up userspace_pid by cpu */
36 return userspace_pid[0]; 38 return userspace_pid[0];
@@ -40,7 +42,7 @@ int pid_to_processor_id(int pid)
40{ 42{
41 int i; 43 int i;
42 44
43 for(i = 0; i < ncpus; i++) { 45 for (i = 0; i < ncpus; i++) {
44 if (cpu_tasks[i].pid == pid) 46 if (cpu_tasks[i].pid == pid)
45 return i; 47 return i;
46 } 48 }
@@ -60,8 +62,6 @@ unsigned long alloc_stack(int order, int atomic)
60 if (atomic) 62 if (atomic)
61 flags = GFP_ATOMIC; 63 flags = GFP_ATOMIC;
62 page = __get_free_pages(flags, order); 64 page = __get_free_pages(flags, order);
63 if (page == 0)
64 return 0;
65 65
66 return page; 66 return page;
67} 67}
@@ -80,15 +80,15 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
80static inline void set_current(struct task_struct *task) 80static inline void set_current(struct task_struct *task)
81{ 81{
82 cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task) 82 cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
83 { external_pid(task), task }); 83 { external_pid(), task });
84} 84}
85 85
86extern void arch_switch_to(struct task_struct *from, struct task_struct *to); 86extern void arch_switch_to(struct task_struct *to);
87 87
88void *_switch_to(void *prev, void *next, void *last) 88void *_switch_to(void *prev, void *next, void *last)
89{ 89{
90 struct task_struct *from = prev; 90 struct task_struct *from = prev;
91 struct task_struct *to= next; 91 struct task_struct *to = next;
92 92
93 to->thread.prev_sched = from; 93 to->thread.prev_sched = from;
94 set_current(to); 94 set_current(to);
@@ -99,13 +99,13 @@ void *_switch_to(void *prev, void *next, void *last)
99 switch_threads(&from->thread.switch_buf, 99 switch_threads(&from->thread.switch_buf,
100 &to->thread.switch_buf); 100 &to->thread.switch_buf);
101 101
102 arch_switch_to(current->thread.prev_sched, current); 102 arch_switch_to(current);
103 103
104 if (current->thread.saved_task) 104 if (current->thread.saved_task)
105 show_regs(&(current->thread.regs)); 105 show_regs(&(current->thread.regs));
106 next= current->thread.saved_task; 106 to = current->thread.saved_task;
107 prev= current; 107 from = current;
108 } while(current->thread.saved_task); 108 } while (current->thread.saved_task);
109 109
110 return current->thread.prev_sched; 110 return current->thread.prev_sched;
111 111
@@ -163,8 +163,6 @@ void new_thread_handler(void)
163void fork_handler(void) 163void fork_handler(void)
164{ 164{
165 force_flush_all(); 165 force_flush_all();
166 if (current->thread.prev_sched == NULL)
167 panic("blech");
168 166
169 schedule_tail(current->thread.prev_sched); 167 schedule_tail(current->thread.prev_sched);
170 168
@@ -173,7 +171,7 @@ void fork_handler(void)
173 * arch_switch_to isn't needed. We could want to apply this to 171 * arch_switch_to isn't needed. We could want to apply this to
174 * improve performance. -bb 172 * improve performance. -bb
175 */ 173 */
176 arch_switch_to(current->thread.prev_sched, current); 174 arch_switch_to(current);
177 175
178 current->thread.prev_sched = NULL; 176 current->thread.prev_sched = NULL;
179 177
@@ -204,7 +202,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
204 arch_copy_thread(&current->thread.arch, &p->thread.arch); 202 arch_copy_thread(&current->thread.arch, &p->thread.arch);
205 } 203 }
206 else { 204 else {
207 init_thread_registers(&p->thread.regs.regs); 205 get_safe_registers(p->thread.regs.regs.gp);
208 p->thread.request.u.thread = current->thread.request.u.thread; 206 p->thread.request.u.thread = current->thread.request.u.thread;
209 handler = new_thread_handler; 207 handler = new_thread_handler;
210 } 208 }
@@ -237,7 +235,7 @@ void default_idle(void)
237{ 235{
238 unsigned long long nsecs; 236 unsigned long long nsecs;
239 237
240 while(1) { 238 while (1) {
241 /* endless idle loop with no priority at all */ 239 /* endless idle loop with no priority at all */
242 240
243 /* 241 /*
@@ -256,53 +254,10 @@ void default_idle(void)
256 254
257void cpu_idle(void) 255void cpu_idle(void)
258{ 256{
259 cpu_tasks[current_thread->cpu].pid = os_getpid(); 257 cpu_tasks[current_thread_info()->cpu].pid = os_getpid();
260 default_idle(); 258 default_idle();
261} 259}
262 260
263void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
264 pte_t *pte_out)
265{
266 pgd_t *pgd;
267 pud_t *pud;
268 pmd_t *pmd;
269 pte_t *pte;
270 pte_t ptent;
271
272 if (task->mm == NULL)
273 return ERR_PTR(-EINVAL);
274 pgd = pgd_offset(task->mm, addr);
275 if (!pgd_present(*pgd))
276 return ERR_PTR(-EINVAL);
277
278 pud = pud_offset(pgd, addr);
279 if (!pud_present(*pud))
280 return ERR_PTR(-EINVAL);
281
282 pmd = pmd_offset(pud, addr);
283 if (!pmd_present(*pmd))
284 return ERR_PTR(-EINVAL);
285
286 pte = pte_offset_kernel(pmd, addr);
287 ptent = *pte;
288 if (!pte_present(ptent))
289 return ERR_PTR(-EINVAL);
290
291 if (pte_out != NULL)
292 *pte_out = ptent;
293 return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK);
294}
295
296char *current_cmd(void)
297{
298#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
299 return "(Unknown)";
300#else
301 void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
302 return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
303#endif
304}
305
306void dump_thread(struct pt_regs *regs, struct user *u) 261void dump_thread(struct pt_regs *regs, struct user *u)
307{ 262{
308} 263}
@@ -317,7 +272,7 @@ int user_context(unsigned long sp)
317 unsigned long stack; 272 unsigned long stack;
318 273
319 stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER); 274 stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
320 return stack != (unsigned long) current_thread; 275 return stack != (unsigned long) current_thread_info();
321} 276}
322 277
323extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; 278extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
@@ -331,7 +286,7 @@ void do_uml_exitcalls(void)
331 (*call)(); 286 (*call)();
332} 287}
333 288
334char *uml_strdup(char *string) 289char *uml_strdup(const char *string)
335{ 290{
336 return kstrdup(string, GFP_KERNEL); 291 return kstrdup(string, GFP_KERNEL);
337} 292}
@@ -359,7 +314,7 @@ int strlen_user_proc(char __user *str)
359int smp_sigio_handler(void) 314int smp_sigio_handler(void)
360{ 315{
361#ifdef CONFIG_SMP 316#ifdef CONFIG_SMP
362 int cpu = current_thread->cpu; 317 int cpu = current_thread_info()->cpu;
363 IPI_handler(cpu); 318 IPI_handler(cpu);
364 if (cpu != 0) 319 if (cpu != 0)
365 return 1; 320 return 1;
@@ -369,7 +324,7 @@ int smp_sigio_handler(void)
369 324
370int cpu(void) 325int cpu(void)
371{ 326{
372 return current_thread->cpu; 327 return current_thread_info()->cpu;
373} 328}
374 329
375static atomic_t using_sysemu = ATOMIC_INIT(0); 330static atomic_t using_sysemu = ATOMIC_INIT(0);
@@ -435,7 +390,7 @@ int singlestepping(void * t)
435{ 390{
436 struct task_struct *task = t ? t : current; 391 struct task_struct *task = t ? t : current;
437 392
438 if ( ! (task->ptrace & PT_DTRACE) ) 393 if (!(task->ptrace & PT_DTRACE))
439 return 0; 394 return 0;
440 395
441 if (task->thread.singlestep_syscall) 396 if (task->thread.singlestep_syscall)
@@ -459,3 +414,46 @@ unsigned long arch_align_stack(unsigned long sp)
459 return sp & ~0xf; 414 return sp & ~0xf;
460} 415}
461#endif 416#endif
417
418unsigned long get_wchan(struct task_struct *p)
419{
420 unsigned long stack_page, sp, ip;
421 bool seen_sched = 0;
422
423 if ((p == NULL) || (p == current) || (p->state == TASK_RUNNING))
424 return 0;
425
426 stack_page = (unsigned long) task_stack_page(p);
427 /* Bail if the process has no kernel stack for some reason */
428 if (stack_page == 0)
429 return 0;
430
431 sp = p->thread.switch_buf->JB_SP;
432 /*
433 * Bail if the stack pointer is below the bottom of the kernel
434 * stack for some reason
435 */
436 if (sp < stack_page)
437 return 0;
438
439 while (sp < stack_page + THREAD_SIZE) {
440 ip = *((unsigned long *) sp);
441 if (in_sched_functions(ip))
442 /* Ignore everything until we're above the scheduler */
443 seen_sched = 1;
444 else if (kernel_text_address(ip) && seen_sched)
445 return ip;
446
447 sp += sizeof(unsigned long);
448 }
449
450 return 0;
451}
452
453int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu)
454{
455 int cpu = current_thread_info()->cpu;
456
457 return save_fp_registers(userspace_pid[cpu], (unsigned long *) fpu);
458}
459
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 04cebcf0679f..00197d3d21ec 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -4,6 +4,7 @@
4 */ 4 */
5 5
6#include "linux/sched.h" 6#include "linux/sched.h"
7#include "kern_util.h"
7#include "os.h" 8#include "os.h"
8#include "skas.h" 9#include "skas.h"
9 10
@@ -11,7 +12,7 @@ void (*pm_power_off)(void);
11 12
12static void kill_off_processes(void) 13static void kill_off_processes(void)
13{ 14{
14 if(proc_mm) 15 if (proc_mm)
15 /* 16 /*
16 * FIXME: need to loop over userspace_pids 17 * FIXME: need to loop over userspace_pids
17 */ 18 */
@@ -21,8 +22,8 @@ static void kill_off_processes(void)
21 int pid, me; 22 int pid, me;
22 23
23 me = os_getpid(); 24 me = os_getpid();
24 for_each_process(p){ 25 for_each_process(p) {
25 if(p->mm == NULL) 26 if (p->mm == NULL)
26 continue; 27 continue;
27 28
28 pid = p->mm->context.id.u.pid; 29 pid = p->mm->context.id.u.pid;
diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c
index 89f9866a1354..2b272b63b514 100644
--- a/arch/um/kernel/sigio.c
+++ b/arch/um/kernel/sigio.c
@@ -1,18 +1,12 @@
1/* 1/*
2 * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/kernel.h" 6#include <linux/interrupt.h>
7#include "linux/list.h"
8#include "linux/slab.h"
9#include "linux/signal.h"
10#include "linux/interrupt.h"
11#include "init.h"
12#include "sigio.h"
13#include "irq_user.h"
14#include "irq_kern.h" 7#include "irq_kern.h"
15#include "os.h" 8#include "os.h"
9#include "sigio.h"
16 10
17/* Protected by sigio_lock() called from write_sigio_workaround */ 11/* Protected by sigio_lock() called from write_sigio_workaround */
18static int sigio_irq_fd = -1; 12static int sigio_irq_fd = -1;
@@ -33,9 +27,9 @@ int write_sigio_irq(int fd)
33 err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, 27 err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
34 IRQF_DISABLED|IRQF_SAMPLE_RANDOM, "write sigio", 28 IRQF_DISABLED|IRQF_SAMPLE_RANDOM, "write sigio",
35 NULL); 29 NULL);
36 if(err){ 30 if (err) {
37 printk("write_sigio_irq : um_request_irq failed, err = %d\n", 31 printk(KERN_ERR "write_sigio_irq : um_request_irq failed, "
38 err); 32 "err = %d\n", err);
39 return -1; 33 return -1;
40 } 34 }
41 sigio_irq_fd = fd; 35 sigio_irq_fd = fd;
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
index 19cb97733937..b0fce720c4d0 100644
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -3,12 +3,12 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/module.h" 6#include <linux/module.h>
7#include "linux/ptrace.h" 7#include <linux/ptrace.h>
8#include "linux/sched.h" 8#include <linux/sched.h>
9#include "asm/siginfo.h" 9#include <asm/siginfo.h>
10#include "asm/signal.h" 10#include <asm/signal.h>
11#include "asm/unistd.h" 11#include <asm/unistd.h>
12#include "frame_kern.h" 12#include "frame_kern.h"
13#include "kern_util.h" 13#include "kern_util.h"
14#include "sigcontext.h" 14#include "sigcontext.h"
@@ -36,7 +36,7 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
36 /* Did we come from a system call? */ 36 /* Did we come from a system call? */
37 if (PT_REGS_SYSCALL_NR(regs) >= 0) { 37 if (PT_REGS_SYSCALL_NR(regs) >= 0) {
38 /* If so, check system call restarting.. */ 38 /* If so, check system call restarting.. */
39 switch(PT_REGS_SYSCALL_RET(regs)) { 39 switch (PT_REGS_SYSCALL_RET(regs)) {
40 case -ERESTART_RESTARTBLOCK: 40 case -ERESTART_RESTARTBLOCK:
41 case -ERESTARTNOHAND: 41 case -ERESTARTNOHAND:
42 PT_REGS_SYSCALL_RET(regs) = -EINTR; 42 PT_REGS_SYSCALL_RET(regs) = -EINTR;
@@ -116,7 +116,7 @@ static int kern_do_signal(struct pt_regs *regs)
116 /* Did we come from a system call? */ 116 /* Did we come from a system call? */
117 if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) { 117 if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) {
118 /* Restart the system call - no handlers present */ 118 /* Restart the system call - no handlers present */
119 switch(PT_REGS_SYSCALL_RET(regs)) { 119 switch (PT_REGS_SYSCALL_RET(regs)) {
120 case -ERESTARTNOHAND: 120 case -ERESTARTNOHAND:
121 case -ERESTARTSYS: 121 case -ERESTARTSYS:
122 case -ERESTARTNOINTR: 122 case -ERESTARTNOINTR:
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c
index 8d07a7acb909..2c8583c1a344 100644
--- a/arch/um/kernel/skas/clone.c
+++ b/arch/um/kernel/skas/clone.c
@@ -1,17 +1,20 @@
1#include <sched.h> 1/*
2 * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
4 */
5
2#include <signal.h> 6#include <signal.h>
3#include <sys/mman.h> 7#include <sched.h>
4#include <sys/time.h>
5#include <asm/unistd.h> 8#include <asm/unistd.h>
9#include <sys/time.h>
6#include "as-layout.h" 10#include "as-layout.h"
11#include "kern_constants.h"
7#include "ptrace_user.h" 12#include "ptrace_user.h"
8#include "skas.h"
9#include "stub-data.h" 13#include "stub-data.h"
10#include "uml-config.h"
11#include "sysdep/stub.h" 14#include "sysdep/stub.h"
12#include "kern_constants.h"
13 15
14/* This is in a separate file because it needs to be compiled with any 16/*
17 * This is in a separate file because it needs to be compiled with any
15 * extraneous gcc flags (-pg, -fprofile-arcs, -ftest-coverage) disabled 18 * extraneous gcc flags (-pg, -fprofile-arcs, -ftest-coverage) disabled
16 * 19 *
17 * Use UM_KERN_PAGE_SIZE instead of PAGE_SIZE because that calls getpagesize 20 * Use UM_KERN_PAGE_SIZE instead of PAGE_SIZE because that calls getpagesize
@@ -26,25 +29,26 @@ stub_clone_handler(void)
26 29
27 err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, 30 err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
28 STUB_DATA + UM_KERN_PAGE_SIZE / 2 - sizeof(void *)); 31 STUB_DATA + UM_KERN_PAGE_SIZE / 2 - sizeof(void *));
29 if(err != 0) 32 if (err != 0)
30 goto out; 33 goto out;
31 34
32 err = stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0); 35 err = stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0);
33 if(err) 36 if (err)
34 goto out; 37 goto out;
35 38
36 err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL, 39 err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL,
37 (long) &data->timer, 0); 40 (long) &data->timer, 0);
38 if(err) 41 if (err)
39 goto out; 42 goto out;
40 43
41 remap_stack(data->fd, data->offset); 44 remap_stack(data->fd, data->offset);
42 goto done; 45 goto done;
43 46
44 out: 47 out:
45 /* save current result. 48 /*
46 * Parent: pid; 49 * save current result.
47 * child: retcode of mmap already saved and it jumps around this 50 * Parent: pid;
51 * child: retcode of mmap already saved and it jumps around this
48 * assignment 52 * assignment
49 */ 53 */
50 data->err = err; 54 data->err = err;
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index f859ec306cd5..78b3e9f69d57 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -34,33 +34,14 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
34 if (!pte) 34 if (!pte)
35 goto out_pte; 35 goto out_pte;
36 36
37 /*
38 * There's an interaction between the skas0 stub pages, stack
39 * randomization, and the BUG at the end of exit_mmap. exit_mmap
40 * checks that the number of page tables freed is the same as had
41 * been allocated. If the stack is on the last page table page,
42 * then the stack pte page will be freed, and if not, it won't. To
43 * avoid having to know where the stack is, or if the process mapped
44 * something at the top of its address space for some other reason,
45 * we set TASK_SIZE to end at the start of the last page table.
46 * This keeps exit_mmap off the last page, but introduces a leak
47 * of that page. So, we hang onto it here and free it in
48 * destroy_context_skas.
49 */
50
51 mm->context.last_page_table = pmd_page_vaddr(*pmd);
52#ifdef CONFIG_3_LEVEL_PGTABLES
53 mm->context.last_pmd = (unsigned long) __va(pud_val(*pud));
54#endif
55
56 *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); 37 *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
57 *pte = pte_mkread(*pte); 38 *pte = pte_mkread(*pte);
58 return 0; 39 return 0;
59 40
60 out_pmd: 41 out_pmd:
61 pud_free(pud); 42 pud_free(mm, pud);
62 out_pte: 43 out_pte:
63 pmd_free(pmd); 44 pmd_free(mm, pmd);
64 out: 45 out:
65 return -ENOMEM; 46 return -ENOMEM;
66} 47}
@@ -76,24 +57,6 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
76 stack = get_zeroed_page(GFP_KERNEL); 57 stack = get_zeroed_page(GFP_KERNEL);
77 if (stack == 0) 58 if (stack == 0)
78 goto out; 59 goto out;
79
80 /*
81 * This zeros the entry that pgd_alloc didn't, needed since
82 * we are about to reinitialize it, and want mm.nr_ptes to
83 * be accurate.
84 */
85 mm->pgd[USER_PTRS_PER_PGD] = __pgd(0);
86
87 ret = init_stub_pte(mm, STUB_CODE,
88 (unsigned long) &__syscall_stub_start);
89 if (ret)
90 goto out_free;
91
92 ret = init_stub_pte(mm, STUB_DATA, stack);
93 if (ret)
94 goto out_free;
95
96 mm->nr_ptes--;
97 } 60 }
98 61
99 to_mm->id.stack = stack; 62 to_mm->id.stack = stack;
@@ -114,6 +77,11 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
114 to_mm->id.u.pid = copy_context_skas0(stack, 77 to_mm->id.u.pid = copy_context_skas0(stack,
115 from_mm->id.u.pid); 78 from_mm->id.u.pid);
116 else to_mm->id.u.pid = start_userspace(stack); 79 else to_mm->id.u.pid = start_userspace(stack);
80
81 if (to_mm->id.u.pid < 0) {
82 ret = to_mm->id.u.pid;
83 goto out_free;
84 }
117 } 85 }
118 86
119 ret = init_new_ldt(to_mm, from_mm); 87 ret = init_new_ldt(to_mm, from_mm);
@@ -132,24 +100,87 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
132 return ret; 100 return ret;
133} 101}
134 102
103void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
104{
105 struct page **pages;
106 int err, ret;
107
108 if (!skas_needs_stub)
109 return;
110
111 ret = init_stub_pte(mm, STUB_CODE,
112 (unsigned long) &__syscall_stub_start);
113 if (ret)
114 goto out;
115
116 ret = init_stub_pte(mm, STUB_DATA, mm->context.id.stack);
117 if (ret)
118 goto out;
119
120 pages = kmalloc(2 * sizeof(struct page *), GFP_KERNEL);
121 if (pages == NULL) {
122 printk(KERN_ERR "arch_dup_mmap failed to allocate 2 page "
123 "pointers\n");
124 goto out;
125 }
126
127 pages[0] = virt_to_page(&__syscall_stub_start);
128 pages[1] = virt_to_page(mm->context.id.stack);
129
130 /* dup_mmap already holds mmap_sem */
131 err = install_special_mapping(mm, STUB_START, STUB_END - STUB_START,
132 VM_READ | VM_MAYREAD | VM_EXEC |
133 VM_MAYEXEC | VM_DONTCOPY, pages);
134 if (err) {
135 printk(KERN_ERR "install_special_mapping returned %d\n", err);
136 goto out_free;
137 }
138 return;
139
140out_free:
141 kfree(pages);
142out:
143 force_sigsegv(SIGSEGV, current);
144}
145
146void arch_exit_mmap(struct mm_struct *mm)
147{
148 pte_t *pte;
149
150 pte = virt_to_pte(mm, STUB_CODE);
151 if (pte != NULL)
152 pte_clear(mm, STUB_CODE, pte);
153
154 pte = virt_to_pte(mm, STUB_DATA);
155 if (pte == NULL)
156 return;
157
158 pte_clear(mm, STUB_DATA, pte);
159}
160
135void destroy_context(struct mm_struct *mm) 161void destroy_context(struct mm_struct *mm)
136{ 162{
137 struct mm_context *mmu = &mm->context; 163 struct mm_context *mmu = &mm->context;
138 164
139 if (proc_mm) 165 if (proc_mm)
140 os_close_file(mmu->id.u.mm_fd); 166 os_close_file(mmu->id.u.mm_fd);
141 else 167 else {
168 /*
169 * If init_new_context wasn't called, this will be
170 * zero, resulting in a kill(0), which will result in the
171 * whole UML suddenly dying. Also, cover negative and
172 * 1 cases, since they shouldn't happen either.
173 */
174 if (mmu->id.u.pid < 2) {
175 printk(KERN_ERR "corrupt mm_context - pid = %d\n",
176 mmu->id.u.pid);
177 return;
178 }
142 os_kill_ptraced_process(mmu->id.u.pid, 1); 179 os_kill_ptraced_process(mmu->id.u.pid, 1);
180 }
143 181
144 if (!proc_mm || !ptrace_faultinfo) { 182 if (skas_needs_stub)
145 free_page(mmu->id.stack); 183 free_page(mmu->id.stack);
146 pte_lock_deinit(virt_to_page(mmu->last_page_table));
147 pte_free_kernel((pte_t *) mmu->last_page_table);
148 dec_zone_page_state(virt_to_page(mmu->last_page_table), NR_PAGETABLE);
149#ifdef CONFIG_3_LEVEL_PGTABLES
150 pmd_free((pmd_t *) mmu->last_pmd);
151#endif
152 }
153 184
154 free_ldt(mmu); 185 free_ldt(mmu);
155} 186}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index fce389c2342f..2e9852c0d487 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -6,19 +6,25 @@
6#include "linux/init.h" 6#include "linux/init.h"
7#include "linux/sched.h" 7#include "linux/sched.h"
8#include "as-layout.h" 8#include "as-layout.h"
9#include "kern.h"
9#include "os.h" 10#include "os.h"
10#include "skas.h" 11#include "skas.h"
11 12
12int new_mm(unsigned long stack) 13int new_mm(unsigned long stack)
13{ 14{
14 int fd; 15 int fd, err;
15 16
16 fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0); 17 fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
17 if (fd < 0) 18 if (fd < 0)
18 return fd; 19 return fd;
19 20
20 if (skas_needs_stub) 21 if (skas_needs_stub) {
21 map_stub_pages(fd, STUB_CODE, STUB_DATA, stack); 22 err = map_stub_pages(fd, STUB_CODE, STUB_DATA, stack);
23 if (err) {
24 os_close_file(fd);
25 return err;
26 }
27 }
22 28
23 return fd; 29 return fd;
24} 30}
@@ -49,8 +55,14 @@ int __init start_uml(void)
49{ 55{
50 stack_protections((unsigned long) &cpu0_irqstack); 56 stack_protections((unsigned long) &cpu0_irqstack);
51 set_sigstack(cpu0_irqstack, THREAD_SIZE); 57 set_sigstack(cpu0_irqstack, THREAD_SIZE);
52 if (proc_mm) 58 if (proc_mm) {
53 userspace_pid[0] = start_userspace(0); 59 userspace_pid[0] = start_userspace(0);
60 if (userspace_pid[0] < 0) {
61 printf("start_uml - start_userspace returned %d\n",
62 userspace_pid[0]);
63 exit(1);
64 }
65 }
54 66
55 init_new_thread_signals(); 67 init_new_thread_signals();
56 68
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 50b476f2b38d..4e3b820bd2be 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -9,6 +9,9 @@
9#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
10#include "sysdep/syscalls.h" 10#include "sysdep/syscalls.h"
11 11
12extern int syscall_table_size;
13#define NR_syscalls (syscall_table_size / sizeof(void *))
14
12void handle_syscall(struct uml_pt_regs *r) 15void handle_syscall(struct uml_pt_regs *r)
13{ 16{
14 struct pt_regs *regs = container_of(r, struct pt_regs, regs); 17 struct pt_regs *regs = container_of(r, struct pt_regs, regs);
@@ -17,9 +20,6 @@ void handle_syscall(struct uml_pt_regs *r)
17 20
18 syscall_trace(r, 0); 21 syscall_trace(r, 0);
19 22
20 current->thread.nsyscalls++;
21 nsyscalls++;
22
23 /* 23 /*
24 * This should go in the declaration of syscall, but when I do that, 24 * This should go in the declaration of syscall, but when I do that,
25 * strace -f -c bash -c 'ls ; ls' breaks, sometimes not tracing 25 * strace -f -c bash -c 'ls ; ls' breaks, sometimes not tracing
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 1d8b119f2d0e..e22c96993db3 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -3,128 +3,130 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/err.h" 6#include <linux/err.h>
7#include "linux/highmem.h" 7#include <linux/highmem.h>
8#include "linux/mm.h" 8#include <linux/mm.h>
9#include "asm/current.h" 9#include <linux/sched.h>
10#include "asm/page.h" 10#include <asm/current.h>
11#include "asm/pgtable.h" 11#include <asm/page.h>
12#include <asm/pgtable.h>
12#include "kern_util.h" 13#include "kern_util.h"
13#include "os.h" 14#include "os.h"
14 15
15extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 16pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr)
16 pte_t *pte_out);
17
18static unsigned long maybe_map(unsigned long virt, int is_write)
19{ 17{
20 pte_t pte; 18 pgd_t *pgd;
21 int err; 19 pud_t *pud;
20 pmd_t *pmd;
21
22 if (mm == NULL)
23 return NULL;
24
25 pgd = pgd_offset(mm, addr);
26 if (!pgd_present(*pgd))
27 return NULL;
28
29 pud = pud_offset(pgd, addr);
30 if (!pud_present(*pud))
31 return NULL;
22 32
23 void *phys = um_virt_to_phys(current, virt, &pte); 33 pmd = pmd_offset(pud, addr);
24 int dummy_code; 34 if (!pmd_present(*pmd))
35 return NULL;
36
37 return pte_offset_kernel(pmd, addr);
38}
39
40static pte_t *maybe_map(unsigned long virt, int is_write)
41{
42 pte_t *pte = virt_to_pte(current->mm, virt);
43 int err, dummy_code;
25 44
26 if (IS_ERR(phys) || (is_write && !pte_write(pte))) { 45 if ((pte == NULL) || !pte_present(*pte) ||
46 (is_write && !pte_write(*pte))) {
27 err = handle_page_fault(virt, 0, is_write, 1, &dummy_code); 47 err = handle_page_fault(virt, 0, is_write, 1, &dummy_code);
28 if (err) 48 if (err)
29 return -1UL; 49 return NULL;
30 phys = um_virt_to_phys(current, virt, NULL); 50 pte = virt_to_pte(current->mm, virt);
31 } 51 }
32 if (IS_ERR(phys)) 52 if (!pte_present(*pte))
33 phys = (void *) -1; 53 pte = NULL;
34 54
35 return (unsigned long) phys; 55 return pte;
36} 56}
37 57
38static int do_op_one_page(unsigned long addr, int len, int is_write, 58static int do_op_one_page(unsigned long addr, int len, int is_write,
39 int (*op)(unsigned long addr, int len, void *arg), void *arg) 59 int (*op)(unsigned long addr, int len, void *arg), void *arg)
40{ 60{
61 jmp_buf buf;
41 struct page *page; 62 struct page *page;
42 int n; 63 pte_t *pte;
64 int n, faulted;
43 65
44 addr = maybe_map(addr, is_write); 66 pte = maybe_map(addr, is_write);
45 if (addr == -1UL) 67 if (pte == NULL)
46 return -1; 68 return -1;
47 69
48 page = phys_to_page(addr); 70 page = pte_page(*pte);
49 addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) + 71 addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) +
50 (addr & ~PAGE_MASK); 72 (addr & ~PAGE_MASK);
51 73
52 n = (*op)(addr, len, arg); 74 current->thread.fault_catcher = &buf;
75
76 faulted = UML_SETJMP(&buf);
77 if (faulted == 0)
78 n = (*op)(addr, len, arg);
79 else
80 n = -1;
81
82 current->thread.fault_catcher = NULL;
53 83
54 kunmap_atomic(page, KM_UML_USERCOPY); 84 kunmap_atomic(page, KM_UML_USERCOPY);
55 85
56 return n; 86 return n;
57} 87}
58 88
59static void do_buffer_op(void *jmpbuf, void *arg_ptr) 89static int buffer_op(unsigned long addr, int len, int is_write,
90 int (*op)(unsigned long, int, void *), void *arg)
60{ 91{
61 va_list args; 92 int size, remain, n;
62 unsigned long addr; 93
63 int len, is_write, size, remain, n;
64 int (*op)(unsigned long, int, void *);
65 void *arg;
66 int *res;
67
68 va_copy(args, *(va_list *)arg_ptr);
69 addr = va_arg(args, unsigned long);
70 len = va_arg(args, int);
71 is_write = va_arg(args, int);
72 op = va_arg(args, void *);
73 arg = va_arg(args, void *);
74 res = va_arg(args, int *);
75 va_end(args);
76 size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len); 94 size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
77 remain = len; 95 remain = len;
78 96
79 current->thread.fault_catcher = jmpbuf;
80 n = do_op_one_page(addr, size, is_write, op, arg); 97 n = do_op_one_page(addr, size, is_write, op, arg);
81 if (n != 0) { 98 if (n != 0) {
82 *res = (n < 0 ? remain : 0); 99 remain = (n < 0 ? remain : 0);
83 goto out; 100 goto out;
84 } 101 }
85 102
86 addr += size; 103 addr += size;
87 remain -= size; 104 remain -= size;
88 if (remain == 0) { 105 if (remain == 0)
89 *res = 0;
90 goto out; 106 goto out;
91 }
92 107
93 while(addr < ((addr + remain) & PAGE_MASK)) { 108 while (addr < ((addr + remain) & PAGE_MASK)) {
94 n = do_op_one_page(addr, PAGE_SIZE, is_write, op, arg); 109 n = do_op_one_page(addr, PAGE_SIZE, is_write, op, arg);
95 if (n != 0) { 110 if (n != 0) {
96 *res = (n < 0 ? remain : 0); 111 remain = (n < 0 ? remain : 0);
97 goto out; 112 goto out;
98 } 113 }
99 114
100 addr += PAGE_SIZE; 115 addr += PAGE_SIZE;
101 remain -= PAGE_SIZE; 116 remain -= PAGE_SIZE;
102 } 117 }
103 if (remain == 0) { 118 if (remain == 0)
104 *res = 0;
105 goto out; 119 goto out;
106 }
107 120
108 n = do_op_one_page(addr, remain, is_write, op, arg); 121 n = do_op_one_page(addr, remain, is_write, op, arg);
109 if (n != 0) 122 if (n != 0) {
110 *res = (n < 0 ? remain : 0); 123 remain = (n < 0 ? remain : 0);
111 else *res = 0; 124 goto out;
112 out: 125 }
113 current->thread.fault_catcher = NULL;
114}
115
116static int buffer_op(unsigned long addr, int len, int is_write,
117 int (*op)(unsigned long addr, int len, void *arg),
118 void *arg)
119{
120 int faulted, res;
121
122 faulted = setjmp_wrapper(do_buffer_op, addr, len, is_write, op, arg,
123 &res);
124 if (!faulted)
125 return res;
126 126
127 return addr + len - (unsigned long) current->thread.fault_addr; 127 return 0;
128 out:
129 return remain;
128} 130}
129 131
130static int copy_chunk_from_user(unsigned long from, int len, void *arg) 132static int copy_chunk_from_user(unsigned long from, int len, void *arg)
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index 36d89cf8d20b..e1062ec36d40 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -21,7 +21,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
21#include "asm/smp.h" 21#include "asm/smp.h"
22#include "asm/processor.h" 22#include "asm/processor.h"
23#include "asm/spinlock.h" 23#include "asm/spinlock.h"
24#include "kern_util.h"
25#include "kern.h" 24#include "kern.h"
26#include "irq_user.h" 25#include "irq_user.h"
27#include "os.h" 26#include "os.h"
@@ -61,7 +60,7 @@ void smp_send_stop(void)
61 continue; 60 continue;
62 os_write_file(cpu_data[i].ipi_pipe[1], "S", 1); 61 os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
63 } 62 }
64 printk(KERN_INFO "done\n"); 63 printk(KERN_CONT "done\n");
65} 64}
66 65
67static cpumask_t smp_commenced_mask = CPU_MASK_NONE; 66static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
@@ -75,8 +74,7 @@ static int idle_proc(void *cpup)
75 if (err < 0) 74 if (err < 0)
76 panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err); 75 panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
77 76
78 os_set_fd_async(cpu_data[cpu].ipi_pipe[0], 77 os_set_fd_async(cpu_data[cpu].ipi_pipe[0]);
79 current->thread.mode.tt.extern_pid);
80 78
81 wmb(); 79 wmb();
82 if (cpu_test_and_set(cpu, cpu_callin_map)) { 80 if (cpu_test_and_set(cpu, cpu_callin_map)) {
@@ -129,8 +127,7 @@ void smp_prepare_cpus(unsigned int maxcpus)
129 if (err < 0) 127 if (err < 0)
130 panic("CPU#0 failed to create IPI pipe, errno = %d", -err); 128 panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
131 129
132 os_set_fd_async(cpu_data[me].ipi_pipe[0], 130 os_set_fd_async(cpu_data[me].ipi_pipe[0]);
133 current->thread.mode.tt.extern_pid);
134 131
135 for (cpu = 1; cpu < ncpus; cpu++) { 132 for (cpu = 1; cpu < ncpus; cpu++) {
136 printk(KERN_INFO "Booting processor %d...\n", cpu); 133 printk(KERN_INFO "Booting processor %d...\n", cpu);
@@ -143,9 +140,8 @@ void smp_prepare_cpus(unsigned int maxcpus)
143 while (waittime-- && !cpu_isset(cpu, cpu_callin_map)) 140 while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
144 cpu_relax(); 141 cpu_relax();
145 142
146 if (cpu_isset(cpu, cpu_callin_map)) 143 printk(KERN_INFO "%s\n",
147 printk(KERN_INFO "done\n"); 144 cpu_isset(cpu, cpu_calling_map) ? "done" : "failed");
148 else printk(KERN_INFO "failed\n");
149 } 145 }
150} 146}
151 147
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index b9d92b2089ae..9cffc628a37e 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -13,9 +13,6 @@
13#include "asm/uaccess.h" 13#include "asm/uaccess.h"
14#include "asm/unistd.h" 14#include "asm/unistd.h"
15 15
16/* Unlocked, I don't care if this is a bit off */
17int nsyscalls = 0;
18
19long sys_fork(void) 16long sys_fork(void)
20{ 17{
21 long ret; 18 long ret;
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index 93263571d813..56d43d0a3960 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -1,38 +1,37 @@
1/* 1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/sched.h" 6#include <linux/kallsyms.h>
7#include "linux/kernel.h" 7#include <linux/kernel.h>
8#include "linux/module.h" 8#include <linux/module.h>
9#include "linux/kallsyms.h" 9#include <linux/sched.h>
10#include "asm/page.h"
11#include "asm/processor.h"
12#include "sysrq.h" 10#include "sysrq.h"
13 11
14/* Catch non-i386 SUBARCH's. */ 12/* Catch non-i386 SUBARCH's. */
15#if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT) 13#if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT)
16void show_trace(struct task_struct *task, unsigned long * stack) 14void show_trace(struct task_struct *task, unsigned long * stack)
17{ 15{
18 unsigned long addr; 16 unsigned long addr;
19 17
20 if (!stack) { 18 if (!stack) {
21 stack = (unsigned long*) &stack; 19 stack = (unsigned long*) &stack;
22 WARN_ON(1); 20 WARN_ON(1);
23 } 21 }
24 22
25 printk("Call Trace: \n"); 23 printk(KERN_INFO "Call Trace: \n");
26 while (((long) stack & (THREAD_SIZE-1)) != 0) { 24 while (((long) stack & (THREAD_SIZE-1)) != 0) {
27 addr = *stack; 25 addr = *stack;
28 if (__kernel_text_address(addr)) { 26 if (__kernel_text_address(addr)) {
29 printk("%08lx: [<%08lx>]", (unsigned long) stack, addr); 27 printk(KERN_INFO "%08lx: [<%08lx>]",
30 print_symbol(" %s", addr); 28 (unsigned long) stack, addr);
31 printk("\n"); 29 print_symbol(KERN_CONT " %s", addr);
32 } 30 printk(KERN_CONT "\n");
33 stack++; 31 }
34 } 32 stack++;
35 printk("\n"); 33 }
34 printk(KERN_INFO "\n");
36} 35}
37#endif 36#endif
38 37
@@ -67,14 +66,13 @@ void show_stack(struct task_struct *task, unsigned long *esp)
67 } 66 }
68 67
69 stack = esp; 68 stack = esp;
70 for(i = 0; i < kstack_depth_to_print; i++) { 69 for (i = 0; i < kstack_depth_to_print; i++) {
71 if (kstack_end(stack)) 70 if (kstack_end(stack))
72 break; 71 break;
73 if (i && ((i % 8) == 0)) 72 if (i && ((i % 8) == 0))
74 printk("\n "); 73 printk("\n" KERN_INFO " ");
75 printk("%08lx ", *stack++); 74 printk("%08lx ", *stack++);
76 } 75 }
77 76
78 printk("Call Trace: \n");
79 show_trace(task, esp); 77 show_trace(task, esp);
80} 78}
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 1ac746a9eae1..e066e84493b1 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -3,12 +3,12 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/clockchips.h" 6#include <linux/clockchips.h>
7#include "linux/interrupt.h" 7#include <linux/interrupt.h>
8#include "linux/jiffies.h" 8#include <linux/jiffies.h>
9#include "linux/threads.h" 9#include <linux/threads.h>
10#include "asm/irq.h" 10#include <asm/irq.h>
11#include "asm/param.h" 11#include <asm/param.h>
12#include "kern_util.h" 12#include "kern_util.h"
13#include "os.h" 13#include "os.h"
14 14
@@ -32,7 +32,7 @@ void timer_handler(int sig, struct uml_pt_regs *regs)
32static void itimer_set_mode(enum clock_event_mode mode, 32static void itimer_set_mode(enum clock_event_mode mode,
33 struct clock_event_device *evt) 33 struct clock_event_device *evt)
34{ 34{
35 switch(mode) { 35 switch (mode) {
36 case CLOCK_EVT_MODE_PERIODIC: 36 case CLOCK_EVT_MODE_PERIODIC:
37 set_interval(); 37 set_interval();
38 break; 38 break;
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index f4a0e407eee4..d175d0566af0 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -3,9 +3,10 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/mm.h" 6#include <linux/mm.h>
7#include "asm/pgtable.h" 7#include <linux/sched.h>
8#include "asm/tlbflush.h" 8#include <asm/pgtable.h>
9#include <asm/tlbflush.h>
9#include "as-layout.h" 10#include "as-layout.h"
10#include "mem_user.h" 11#include "mem_user.h"
11#include "os.h" 12#include "os.h"
@@ -56,7 +57,7 @@ static int do_ops(struct host_vm_change *hvc, int end,
56 57
57 for (i = 0; i < end && !ret; i++) { 58 for (i = 0; i < end && !ret; i++) {
58 op = &hvc->ops[i]; 59 op = &hvc->ops[i];
59 switch(op->type) { 60 switch (op->type) {
60 case MMAP: 61 case MMAP:
61 ret = map(hvc->id, op->u.mmap.addr, op->u.mmap.len, 62 ret = map(hvc->id, op->u.mmap.addr, op->u.mmap.len,
62 op->u.mmap.prot, op->u.mmap.fd, 63 op->u.mmap.prot, op->u.mmap.fd,
@@ -183,27 +184,30 @@ static inline int update_pte_range(pmd_t *pmd, unsigned long addr,
183 184
184 pte = pte_offset_kernel(pmd, addr); 185 pte = pte_offset_kernel(pmd, addr);
185 do { 186 do {
187 if ((addr >= STUB_START) && (addr < STUB_END))
188 continue;
189
186 r = pte_read(*pte); 190 r = pte_read(*pte);
187 w = pte_write(*pte); 191 w = pte_write(*pte);
188 x = pte_exec(*pte); 192 x = pte_exec(*pte);
189 if (!pte_young(*pte)) { 193 if (!pte_young(*pte)) {
190 r = 0; 194 r = 0;
191 w = 0; 195 w = 0;
192 } else if (!pte_dirty(*pte)) { 196 } else if (!pte_dirty(*pte))
193 w = 0; 197 w = 0;
194 } 198
195 prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | 199 prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
196 (x ? UM_PROT_EXEC : 0)); 200 (x ? UM_PROT_EXEC : 0));
197 if (hvc->force || pte_newpage(*pte)) { 201 if (hvc->force || pte_newpage(*pte)) {
198 if (pte_present(*pte)) 202 if (pte_present(*pte))
199 ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK, 203 ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK,
200 PAGE_SIZE, prot, hvc); 204 PAGE_SIZE, prot, hvc);
201 else ret = add_munmap(addr, PAGE_SIZE, hvc); 205 else
202 } 206 ret = add_munmap(addr, PAGE_SIZE, hvc);
203 else if (pte_newprot(*pte)) 207 } else if (pte_newprot(*pte))
204 ret = add_mprotect(addr, PAGE_SIZE, prot, hvc); 208 ret = add_mprotect(addr, PAGE_SIZE, prot, hvc);
205 *pte = pte_mkuptodate(*pte); 209 *pte = pte_mkuptodate(*pte);
206 } while (pte++, addr += PAGE_SIZE, ((addr != end) && !ret)); 210 } while (pte++, addr += PAGE_SIZE, ((addr < end) && !ret));
207 return ret; 211 return ret;
208} 212}
209 213
@@ -225,7 +229,7 @@ static inline int update_pmd_range(pud_t *pud, unsigned long addr,
225 } 229 }
226 } 230 }
227 else ret = update_pte_range(pmd, addr, next, hvc); 231 else ret = update_pte_range(pmd, addr, next, hvc);
228 } while (pmd++, addr = next, ((addr != end) && !ret)); 232 } while (pmd++, addr = next, ((addr < end) && !ret));
229 return ret; 233 return ret;
230} 234}
231 235
@@ -247,7 +251,7 @@ static inline int update_pud_range(pgd_t *pgd, unsigned long addr,
247 } 251 }
248 } 252 }
249 else ret = update_pmd_range(pud, addr, next, hvc); 253 else ret = update_pmd_range(pud, addr, next, hvc);
250 } while (pud++, addr = next, ((addr != end) && !ret)); 254 } while (pud++, addr = next, ((addr < end) && !ret));
251 return ret; 255 return ret;
252} 256}
253 257
@@ -270,7 +274,7 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
270 } 274 }
271 } 275 }
272 else ret = update_pud_range(pgd, addr, next, &hvc); 276 else ret = update_pud_range(pgd, addr, next, &hvc);
273 } while (pgd++, addr = next, ((addr != end_addr) && !ret)); 277 } while (pgd++, addr = next, ((addr < end_addr) && !ret));
274 278
275 if (!ret) 279 if (!ret)
276 ret = do_ops(&hvc, hvc.index, 1); 280 ret = do_ops(&hvc, hvc.index, 1);
@@ -485,9 +489,6 @@ void __flush_tlb_one(unsigned long addr)
485static void fix_range(struct mm_struct *mm, unsigned long start_addr, 489static void fix_range(struct mm_struct *mm, unsigned long start_addr,
486 unsigned long end_addr, int force) 490 unsigned long end_addr, int force)
487{ 491{
488 if (!proc_mm && (end_addr > STUB_START))
489 end_addr = STUB_START;
490
491 fix_range_common(mm, start_addr, end_addr, force); 492 fix_range_common(mm, start_addr, end_addr, force);
492} 493}
493 494
@@ -499,10 +500,9 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
499 else fix_range(vma->vm_mm, start, end, 0); 500 else fix_range(vma->vm_mm, start, end, 0);
500} 501}
501 502
502void flush_tlb_mm(struct mm_struct *mm) 503void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
504 unsigned long end)
503{ 505{
504 unsigned long end;
505
506 /* 506 /*
507 * Don't bother flushing if this address space is about to be 507 * Don't bother flushing if this address space is about to be
508 * destroyed. 508 * destroyed.
@@ -510,8 +510,17 @@ void flush_tlb_mm(struct mm_struct *mm)
510 if (atomic_read(&mm->mm_users) == 0) 510 if (atomic_read(&mm->mm_users) == 0)
511 return; 511 return;
512 512
513 end = proc_mm ? task_size : STUB_START; 513 fix_range(mm, start, end, 0);
514 fix_range(mm, 0, end, 0); 514}
515
516void flush_tlb_mm(struct mm_struct *mm)
517{
518 struct vm_area_struct *vma = mm->mmap;
519
520 while (vma != NULL) {
521 fix_range(mm, vma->vm_start, vma->vm_end, 0);
522 vma = vma->vm_next;
523 }
515} 524}
516 525
517void force_flush_all(void) 526void force_flush_all(void)
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index cb3321f8e0a9..44e490419495 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -13,6 +13,7 @@
13#include "as-layout.h" 13#include "as-layout.h"
14#include "kern_util.h" 14#include "kern_util.h"
15#include "os.h" 15#include "os.h"
16#include "skas.h"
16#include "sysdep/sigcontext.h" 17#include "sysdep/sigcontext.h"
17 18
18/* 19/*
@@ -128,7 +129,19 @@ static void bad_segv(struct faultinfo fi, unsigned long ip)
128 force_sig_info(SIGSEGV, &si, current); 129 force_sig_info(SIGSEGV, &si, current);
129} 130}
130 131
131static void segv_handler(int sig, struct uml_pt_regs *regs) 132void fatal_sigsegv(void)
133{
134 force_sigsegv(SIGSEGV, current);
135 do_signal();
136 /*
137 * This is to tell gcc that we're not returning - do_signal
138 * can, in general, return, but in this case, it's not, since
139 * we just got a fatal SIGSEGV queued.
140 */
141 os_dump_core();
142}
143
144void segv_handler(int sig, struct uml_pt_regs *regs)
132{ 145{
133 struct faultinfo * fi = UPT_FAULTINFO(regs); 146 struct faultinfo * fi = UPT_FAULTINFO(regs);
134 147
@@ -216,9 +229,6 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
216 229
217void relay_signal(int sig, struct uml_pt_regs *regs) 230void relay_signal(int sig, struct uml_pt_regs *regs)
218{ 231{
219 if (arch_handle_signal(sig, regs))
220 return;
221
222 if (!UPT_IS_USER(regs)) { 232 if (!UPT_IS_USER(regs)) {
223 if (sig == SIGBUS) 233 if (sig == SIGBUS)
224 printk(KERN_ERR "Bus error - the host /dev/shm or /tmp " 234 printk(KERN_ERR "Bus error - the host /dev/shm or /tmp "
@@ -226,31 +236,24 @@ void relay_signal(int sig, struct uml_pt_regs *regs)
226 panic("Kernel mode signal %d", sig); 236 panic("Kernel mode signal %d", sig);
227 } 237 }
228 238
239 arch_examine_signal(sig, regs);
240
229 current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); 241 current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
230 force_sig(sig, current); 242 force_sig(sig, current);
231} 243}
232 244
233static void bus_handler(int sig, struct uml_pt_regs *regs) 245void bus_handler(int sig, struct uml_pt_regs *regs)
234{ 246{
235 if (current->thread.fault_catcher != NULL) 247 if (current->thread.fault_catcher != NULL)
236 UML_LONGJMP(current->thread.fault_catcher, 1); 248 UML_LONGJMP(current->thread.fault_catcher, 1);
237 else relay_signal(sig, regs); 249 else relay_signal(sig, regs);
238} 250}
239 251
240static void winch(int sig, struct uml_pt_regs *regs) 252void winch(int sig, struct uml_pt_regs *regs)
241{ 253{
242 do_IRQ(WINCH_IRQ, regs); 254 do_IRQ(WINCH_IRQ, regs);
243} 255}
244 256
245const struct kern_handlers handlinfo_kern = {
246 .relay_signal = relay_signal,
247 .winch = winch,
248 .bus_handler = bus_handler,
249 .page_fault = segv_handler,
250 .sigio_handler = sigio_handler,
251 .timer_handler = timer_handler
252};
253
254void trap_init(void) 257void trap_init(void)
255{ 258{
256} 259}
diff --git a/arch/um/kernel/uaccess.c b/arch/um/kernel/uaccess.c
index d7436aacd26f..f0f4b040d7c5 100644
--- a/arch/um/kernel/uaccess.c
+++ b/arch/um/kernel/uaccess.c
@@ -1,10 +1,11 @@
1/* 1/*
2 * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk) 2 * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
3 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7/* These are here rather than tt/uaccess.c because skas mode needs them in 7/*
8 * These are here rather than tt/uaccess.c because skas mode needs them in
8 * order to do SIGBUS recovery when a tmpfs mount runs out of room. 9 * order to do SIGBUS recovery when a tmpfs mount runs out of room.
9 */ 10 */
10 11
@@ -25,6 +26,8 @@ int __do_copy_to_user(void *to, const void *from, int n,
25 26
26 fault = __do_user_copy(to, from, n, fault_addr, fault_catcher, 27 fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
27 __do_copy, &faulted); 28 __do_copy, &faulted);
28 if(!faulted) return(0); 29 if (!faulted)
29 else return(n - (fault - (unsigned long) to)); 30 return 0;
31 else
32 return n - (fault - (unsigned long) to);
30} 33}
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index f1c71393f578..468aba990dbd 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -3,22 +3,23 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/delay.h" 6#include <linux/delay.h>
7#include "linux/mm.h" 7#include <linux/init.h>
8#include "linux/module.h" 8#include <linux/mm.h>
9#include "linux/seq_file.h" 9#include <linux/module.h>
10#include "linux/string.h" 10#include <linux/seq_file.h>
11#include "linux/utsname.h" 11#include <linux/string.h>
12#include "asm/pgtable.h" 12#include <linux/utsname.h>
13#include "asm/processor.h" 13#include <asm/pgtable.h>
14#include "asm/setup.h" 14#include <asm/processor.h>
15#include "arch.h" 15#include <asm/setup.h>
16#include "as-layout.h" 16#include "as-layout.h"
17#include "arch.h"
17#include "init.h" 18#include "init.h"
18#include "kern.h" 19#include "kern.h"
20#include "kern_util.h"
19#include "mem_user.h" 21#include "mem_user.h"
20#include "os.h" 22#include "os.h"
21#include "skas.h"
22 23
23#define DEFAULT_COMMAND_LINE "root=98:0" 24#define DEFAULT_COMMAND_LINE "root=98:0"
24 25
@@ -100,8 +101,6 @@ const struct seq_operations cpuinfo_op = {
100}; 101};
101 102
102/* Set in linux_main */ 103/* Set in linux_main */
103unsigned long host_task_size;
104unsigned long task_size;
105unsigned long uml_physmem; 104unsigned long uml_physmem;
106unsigned long uml_reserved; /* Also modified in mem_init */ 105unsigned long uml_reserved; /* Also modified in mem_init */
107unsigned long start_vm; 106unsigned long start_vm;
@@ -197,20 +196,19 @@ __uml_setup("--help", Usage,
197" Prints this message.\n\n" 196" Prints this message.\n\n"
198); 197);
199 198
200static int __init uml_checksetup(char *line, int *add) 199static void __init uml_checksetup(char *line, int *add)
201{ 200{
202 struct uml_param *p; 201 struct uml_param *p;
203 202
204 p = &__uml_setup_start; 203 p = &__uml_setup_start;
205 while(p < &__uml_setup_end) { 204 while (p < &__uml_setup_end) {
206 int n; 205 int n;
207 206
208 n = strlen(p->str); 207 n = strlen(p->str);
209 if (!strncmp(line, p->str, n) && p->setup_func(line + n, add)) 208 if (!strncmp(line, p->str, n) && p->setup_func(line + n, add))
210 return 1; 209 return;
211 p++; 210 p++;
212 } 211 }
213 return 0;
214} 212}
215 213
216static void __init uml_postsetup(void) 214static void __init uml_postsetup(void)
@@ -218,13 +216,30 @@ static void __init uml_postsetup(void)
218 initcall_t *p; 216 initcall_t *p;
219 217
220 p = &__uml_postsetup_start; 218 p = &__uml_postsetup_start;
221 while(p < &__uml_postsetup_end) { 219 while (p < &__uml_postsetup_end) {
222 (*p)(); 220 (*p)();
223 p++; 221 p++;
224 } 222 }
225 return; 223 return;
226} 224}
227 225
226static int panic_exit(struct notifier_block *self, unsigned long unused1,
227 void *unused2)
228{
229 bust_spinlocks(1);
230 show_regs(&(current->thread.regs));
231 bust_spinlocks(0);
232 uml_exitcode = 1;
233 os_dump_core();
234 return 0;
235}
236
237static struct notifier_block panic_exit_notifier = {
238 .notifier_call = panic_exit,
239 .next = NULL,
240 .priority = 0
241};
242
228/* Set during early boot */ 243/* Set during early boot */
229unsigned long brk_start; 244unsigned long brk_start;
230unsigned long end_iomem; 245unsigned long end_iomem;
@@ -234,20 +249,6 @@ EXPORT_SYMBOL(end_iomem);
234 249
235extern char __binary_start; 250extern char __binary_start;
236 251
237static unsigned long set_task_sizes_skas(unsigned long *task_size_out)
238{
239 /* Round up to the nearest 4M */
240 unsigned long host_task_size = ROUND_4M((unsigned long)
241 &host_task_size);
242
243 if (!skas_needs_stub)
244 *task_size_out = host_task_size;
245 else
246 *task_size_out = STUB_START & PGDIR_MASK;
247
248 return host_task_size;
249}
250
251int __init linux_main(int argc, char **argv) 252int __init linux_main(int argc, char **argv)
252{ 253{
253 unsigned long avail, diff; 254 unsigned long avail, diff;
@@ -278,13 +279,6 @@ int __init linux_main(int argc, char **argv)
278 279
279 printf("UML running in %s mode\n", mode); 280 printf("UML running in %s mode\n", mode);
280 281
281 host_task_size = set_task_sizes_skas(&task_size);
282
283 /*
284 * Setting up handlers to 'sig_info' struct
285 */
286 os_fill_handlinfo(handlinfo_kern);
287
288 brk_start = (unsigned long) sbrk(0); 282 brk_start = (unsigned long) sbrk(0);
289 283
290 /* 284 /*
@@ -309,7 +303,7 @@ int __init linux_main(int argc, char **argv)
309 303
310 highmem = 0; 304 highmem = 0;
311 iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; 305 iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
312 max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; 306 max_physmem = CONFIG_TOP_ADDR - uml_physmem - iomem_size - MIN_VMALLOC;
313 307
314 /* 308 /*
315 * Zones have to begin on a 1 << MAX_ORDER page boundary, 309 * Zones have to begin on a 1 << MAX_ORDER page boundary,
@@ -341,7 +335,7 @@ int __init linux_main(int argc, char **argv)
341 } 335 }
342 336
343 virtmem_size = physmem_size; 337 virtmem_size = physmem_size;
344 avail = get_kmem_end() - start_vm; 338 avail = CONFIG_TOP_ADDR - start_vm;
345 if (physmem_size > avail) 339 if (physmem_size > avail)
346 virtmem_size = avail; 340 virtmem_size = avail;
347 end_vm = start_vm + virtmem_size; 341 end_vm = start_vm + virtmem_size;
@@ -350,6 +344,9 @@ int __init linux_main(int argc, char **argv)
350 printf("Kernel virtual memory size shrunk to %lu bytes\n", 344 printf("Kernel virtual memory size shrunk to %lu bytes\n",
351 virtmem_size); 345 virtmem_size);
352 346
347 atomic_notifier_chain_register(&panic_notifier_list,
348 &panic_exit_notifier);
349
353 uml_postsetup(); 350 uml_postsetup();
354 351
355 stack_protections((unsigned long) &init_thread_info); 352 stack_protections((unsigned long) &init_thread_info);
@@ -358,29 +355,8 @@ int __init linux_main(int argc, char **argv)
358 return start_uml(); 355 return start_uml();
359} 356}
360 357
361extern int uml_exitcode;
362
363static int panic_exit(struct notifier_block *self, unsigned long unused1,
364 void *unused2)
365{
366 bust_spinlocks(1);
367 show_regs(&(current->thread.regs));
368 bust_spinlocks(0);
369 uml_exitcode = 1;
370 os_dump_core();
371 return 0;
372}
373
374static struct notifier_block panic_exit_notifier = {
375 .notifier_call = panic_exit,
376 .next = NULL,
377 .priority = 0
378};
379
380void __init setup_arch(char **cmdline_p) 358void __init setup_arch(char **cmdline_p)
381{ 359{
382 atomic_notifier_chain_register(&panic_notifier_list,
383 &panic_exit_notifier);
384 paging_init(); 360 paging_init();
385 strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); 361 strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
386 *cmdline_p = command_line; 362 *cmdline_p = command_line;
diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
index 039e16efcd55..81e07e2be3ae 100644
--- a/arch/um/kernel/umid.c
+++ b/arch/um/kernel/umid.c
@@ -1,13 +1,12 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "asm/errno.h" 6#include <asm/errno.h>
7#include "init.h" 7#include "init.h"
8#include "os.h"
9#include "kern.h" 8#include "kern.h"
10#include "linux/kernel.h" 9#include "os.h"
11 10
12/* Changed by set_umid_arg */ 11/* Changed by set_umid_arg */
13static int umid_inited = 0; 12static int umid_inited = 0;
@@ -16,16 +15,16 @@ static int __init set_umid_arg(char *name, int *add)
16{ 15{
17 int err; 16 int err;
18 17
19 if(umid_inited){ 18 if (umid_inited) {
20 printf("umid already set\n"); 19 printf("umid already set\n");
21 return 0; 20 return 0;
22 } 21 }
23 22
24 *add = 0; 23 *add = 0;
25 err = set_umid(name); 24 err = set_umid(name);
26 if(err == -EEXIST) 25 if (err == -EEXIST)
27 printf("umid '%s' already in use\n", name); 26 printf("umid '%s' already in use\n", name);
28 else if(!err) 27 else if (!err)
29 umid_inited = 1; 28 umid_inited = 1;
30 29
31 return 0; 30 return 0;
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 8e129af8170d..8a48d6a30064 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -4,7 +4,7 @@
4# 4#
5 5
6obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ 6obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \
7 registers.o sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o \ 7 registers.o sigio.o signal.o start_up.o time.o tty.o uaccess.o \
8 umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/ 8 umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/
9 9
10obj-$(CONFIG_TTY_LOG) += tty_log.o 10obj-$(CONFIG_TTY_LOG) += tty_log.o
@@ -12,7 +12,7 @@ user-objs-$(CONFIG_TTY_LOG) += tty_log.o
12 12
13USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ 13USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \
14 main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \ 14 main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \
15 trap.o tty.o tls.o uaccess.o umid.o util.o 15 tty.o tls.o uaccess.o umid.o util.o
16 16
17CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) 17CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH)
18 18
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index 93dc0c80ebaf..b8d8c9ca8d4a 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -12,6 +12,7 @@
12#include "aio.h" 12#include "aio.h"
13#include "init.h" 13#include "init.h"
14#include "kern_constants.h" 14#include "kern_constants.h"
15#include "kern_util.h"
15#include "os.h" 16#include "os.h"
16#include "user.h" 17#include "user.h"
17 18
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 07ca0cb472ac..6fb0b174f538 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -131,7 +131,7 @@ static int etap_tramp(char *dev, char *gate, int control_me,
131 } 131 }
132 if (c != 1) { 132 if (c != 1) {
133 printk(UM_KERN_ERR "etap_tramp : uml_net failed\n"); 133 printk(UM_KERN_ERR "etap_tramp : uml_net failed\n");
134 err = helper_wait(pid, 0, "uml_net"); 134 err = helper_wait(pid);
135 } 135 }
136 return err; 136 return err;
137} 137}
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index 1037a3b6386e..2448be03fd7a 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -14,6 +14,7 @@
14#include <sys/wait.h> 14#include <sys/wait.h>
15#include <sys/uio.h> 15#include <sys/uio.h>
16#include "kern_constants.h" 16#include "kern_constants.h"
17#include "kern_util.h"
17#include "os.h" 18#include "os.h"
18#include "tuntap.h" 19#include "tuntap.h"
19#include "user.h" 20#include "user.h"
@@ -107,7 +108,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
107 "errno = %d\n", errno); 108 "errno = %d\n", errno);
108 return err; 109 return err;
109 } 110 }
110 helper_wait(pid, 0, "tuntap_open_tramp"); 111 helper_wait(pid);
111 112
112 cmsg = CMSG_FIRSTHDR(&msg); 113 cmsg = CMSG_FIRSTHDR(&msg);
113 if (cmsg == NULL) { 114 if (cmsg == NULL) {
@@ -148,7 +149,7 @@ static int tuntap_open(void *data)
148 memset(&ifr, 0, sizeof(ifr)); 149 memset(&ifr, 0, sizeof(ifr));
149 ifr.ifr_flags = IFF_TAP | IFF_NO_PI; 150 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
150 strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name)); 151 strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
151 if (ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0) { 152 if (ioctl(pri->fd, TUNSETIFF, &ifr) < 0) {
152 err = -errno; 153 err = -errno;
153 printk(UM_KERN_ERR "TUNSETIFF failed, errno = %d\n", 154 printk(UM_KERN_ERR "TUNSETIFF failed, errno = %d\n",
154 errno); 155 errno);
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index f83462758627..b5afcfd0f861 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -8,18 +8,16 @@
8#include <errno.h> 8#include <errno.h>
9#include <fcntl.h> 9#include <fcntl.h>
10#include <signal.h> 10#include <signal.h>
11#include <sys/types.h>
12#include <sys/stat.h>
13#include <sys/socket.h>
14#include <sys/un.h>
15#include <sys/ioctl.h> 11#include <sys/ioctl.h>
16#include <sys/mount.h> 12#include <sys/mount.h>
17#include <sys/uio.h> 13#include <sys/socket.h>
14#include <sys/stat.h>
15#include <sys/un.h>
16#include "kern_constants.h"
18#include "os.h" 17#include "os.h"
19#include "user.h" 18#include "user.h"
20#include "kern_util.h"
21 19
22static void copy_stat(struct uml_stat *dst, struct stat64 *src) 20static void copy_stat(struct uml_stat *dst, const struct stat64 *src)
23{ 21{
24 *dst = ((struct uml_stat) { 22 *dst = ((struct uml_stat) {
25 .ust_dev = src->st_dev, /* device */ 23 .ust_dev = src->st_dev, /* device */
@@ -43,10 +41,10 @@ int os_stat_fd(const int fd, struct uml_stat *ubuf)
43 int err; 41 int err;
44 42
45 CATCH_EINTR(err = fstat64(fd, &sbuf)); 43 CATCH_EINTR(err = fstat64(fd, &sbuf));
46 if(err < 0) 44 if (err < 0)
47 return -errno; 45 return -errno;
48 46
49 if(ubuf != NULL) 47 if (ubuf != NULL)
50 copy_stat(ubuf, &sbuf); 48 copy_stat(ubuf, &sbuf);
51 return err; 49 return err;
52} 50}
@@ -56,27 +54,26 @@ int os_stat_file(const char *file_name, struct uml_stat *ubuf)
56 struct stat64 sbuf; 54 struct stat64 sbuf;
57 int err; 55 int err;
58 56
59 do { 57 CATCH_EINTR(err = stat64(file_name, &sbuf));
60 err = stat64(file_name, &sbuf); 58 if (err < 0)
61 } while((err < 0) && (errno == EINTR)) ;
62
63 if(err < 0)
64 return -errno; 59 return -errno;
65 60
66 if(ubuf != NULL) 61 if (ubuf != NULL)
67 copy_stat(ubuf, &sbuf); 62 copy_stat(ubuf, &sbuf);
68 return err; 63 return err;
69} 64}
70 65
71int os_access(const char* file, int mode) 66int os_access(const char *file, int mode)
72{ 67{
73 int amode, err; 68 int amode, err;
74 69
75 amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) | 70 amode = (mode & OS_ACC_R_OK ? R_OK : 0) |
76 (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ; 71 (mode & OS_ACC_W_OK ? W_OK : 0) |
72 (mode & OS_ACC_X_OK ? X_OK : 0) |
73 (mode & OS_ACC_F_OK ? F_OK : 0);
77 74
78 err = access(file, amode); 75 err = access(file, amode);
79 if(err < 0) 76 if (err < 0)
80 return -errno; 77 return -errno;
81 78
82 return 0; 79 return 0;
@@ -88,7 +85,7 @@ int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
88 int err; 85 int err;
89 86
90 err = ioctl(fd, cmd, arg); 87 err = ioctl(fd, cmd, arg);
91 if(err < 0) 88 if (err < 0)
92 return -errno; 89 return -errno;
93 90
94 return err; 91 return err;
@@ -97,7 +94,7 @@ int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
97/* FIXME: ensure namebuf in os_get_if_name is big enough */ 94/* FIXME: ensure namebuf in os_get_if_name is big enough */
98int os_get_ifname(int fd, char* namebuf) 95int os_get_ifname(int fd, char* namebuf)
99{ 96{
100 if(ioctl(fd, SIOCGIFNAME, namebuf) < 0) 97 if (ioctl(fd, SIOCGIFNAME, namebuf) < 0)
101 return -errno; 98 return -errno;
102 99
103 return 0; 100 return 0;
@@ -108,37 +105,22 @@ int os_set_slip(int fd)
108 int disc, sencap; 105 int disc, sencap;
109 106
110 disc = N_SLIP; 107 disc = N_SLIP;
111 if(ioctl(fd, TIOCSETD, &disc) < 0) 108 if (ioctl(fd, TIOCSETD, &disc) < 0)
112 return -errno; 109 return -errno;
113 110
114 sencap = 0; 111 sencap = 0;
115 if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0) 112 if (ioctl(fd, SIOCSIFENCAP, &sencap) < 0)
116 return -errno; 113 return -errno;
117 114
118 return 0; 115 return 0;
119} 116}
120 117
121int os_set_owner(int fd, int pid)
122{
123 if(fcntl(fd, F_SETOWN, pid) < 0){
124 int save_errno = errno;
125
126 if(fcntl(fd, F_GETOWN, 0) != pid)
127 return -save_errno;
128 }
129
130 return 0;
131}
132
133int os_mode_fd(int fd, int mode) 118int os_mode_fd(int fd, int mode)
134{ 119{
135 int err; 120 int err;
136 121
137 do { 122 CATCH_EINTR(err = fchmod(fd, mode));
138 err = fchmod(fd, mode); 123 if (err < 0)
139 } while((err < 0) && (errno==EINTR)) ;
140
141 if(err < 0)
142 return -errno; 124 return -errno;
143 125
144 return 0; 126 return 0;
@@ -150,64 +132,73 @@ int os_file_type(char *file)
150 int err; 132 int err;
151 133
152 err = os_stat_file(file, &buf); 134 err = os_stat_file(file, &buf);
153 if(err < 0) 135 if (err < 0)
154 return err; 136 return err;
155 137
156 if(S_ISDIR(buf.ust_mode)) 138 if (S_ISDIR(buf.ust_mode))
157 return OS_TYPE_DIR; 139 return OS_TYPE_DIR;
158 else if(S_ISLNK(buf.ust_mode)) 140 else if (S_ISLNK(buf.ust_mode))
159 return OS_TYPE_SYMLINK; 141 return OS_TYPE_SYMLINK;
160 else if(S_ISCHR(buf.ust_mode)) 142 else if (S_ISCHR(buf.ust_mode))
161 return OS_TYPE_CHARDEV; 143 return OS_TYPE_CHARDEV;
162 else if(S_ISBLK(buf.ust_mode)) 144 else if (S_ISBLK(buf.ust_mode))
163 return OS_TYPE_BLOCKDEV; 145 return OS_TYPE_BLOCKDEV;
164 else if(S_ISFIFO(buf.ust_mode)) 146 else if (S_ISFIFO(buf.ust_mode))
165 return OS_TYPE_FIFO; 147 return OS_TYPE_FIFO;
166 else if(S_ISSOCK(buf.ust_mode)) 148 else if (S_ISSOCK(buf.ust_mode))
167 return OS_TYPE_SOCK; 149 return OS_TYPE_SOCK;
168 else return OS_TYPE_FILE; 150 else return OS_TYPE_FILE;
169} 151}
170 152
171int os_file_mode(char *file, struct openflags *mode_out) 153int os_file_mode(const char *file, struct openflags *mode_out)
172{ 154{
173 int err; 155 int err;
174 156
175 *mode_out = OPENFLAGS(); 157 *mode_out = OPENFLAGS();
176 158
177 err = access(file, W_OK); 159 err = access(file, W_OK);
178 if(err && (errno != EACCES)) 160 if (err && (errno != EACCES))
179 return -errno; 161 return -errno;
180 else if(!err) 162 else if (!err)
181 *mode_out = of_write(*mode_out); 163 *mode_out = of_write(*mode_out);
182 164
183 err = access(file, R_OK); 165 err = access(file, R_OK);
184 if(err && (errno != EACCES)) 166 if (err && (errno != EACCES))
185 return -errno; 167 return -errno;
186 else if(!err) 168 else if (!err)
187 *mode_out = of_read(*mode_out); 169 *mode_out = of_read(*mode_out);
188 170
189 return err; 171 return err;
190} 172}
191 173
192int os_open_file(char *file, struct openflags flags, int mode) 174int os_open_file(const char *file, struct openflags flags, int mode)
193{ 175{
194 int fd, err, f = 0; 176 int fd, err, f = 0;
195 177
196 if(flags.r && flags.w) f = O_RDWR; 178 if (flags.r && flags.w)
197 else if(flags.r) f = O_RDONLY; 179 f = O_RDWR;
198 else if(flags.w) f = O_WRONLY; 180 else if (flags.r)
181 f = O_RDONLY;
182 else if (flags.w)
183 f = O_WRONLY;
199 else f = 0; 184 else f = 0;
200 185
201 if(flags.s) f |= O_SYNC; 186 if (flags.s)
202 if(flags.c) f |= O_CREAT; 187 f |= O_SYNC;
203 if(flags.t) f |= O_TRUNC; 188 if (flags.c)
204 if(flags.e) f |= O_EXCL; 189 f |= O_CREAT;
190 if (flags.t)
191 f |= O_TRUNC;
192 if (flags.e)
193 f |= O_EXCL;
194 if (flags.a)
195 f |= O_APPEND;
205 196
206 fd = open64(file, f, mode); 197 fd = open64(file, f, mode);
207 if(fd < 0) 198 if (fd < 0)
208 return -errno; 199 return -errno;
209 200
210 if(flags.cl && fcntl(fd, F_SETFD, 1)){ 201 if (flags.cl && fcntl(fd, F_SETFD, 1)) {
211 err = -errno; 202 err = -errno;
212 close(fd); 203 close(fd);
213 return err; 204 return err;
@@ -216,7 +207,7 @@ int os_open_file(char *file, struct openflags flags, int mode)
216 return fd; 207 return fd;
217} 208}
218 209
219int os_connect_socket(char *name) 210int os_connect_socket(const char *name)
220{ 211{
221 struct sockaddr_un sock; 212 struct sockaddr_un sock;
222 int fd, err; 213 int fd, err;
@@ -225,13 +216,13 @@ int os_connect_socket(char *name)
225 snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name); 216 snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
226 217
227 fd = socket(AF_UNIX, SOCK_STREAM, 0); 218 fd = socket(AF_UNIX, SOCK_STREAM, 0);
228 if(fd < 0) { 219 if (fd < 0) {
229 err = -errno; 220 err = -errno;
230 goto out; 221 goto out;
231 } 222 }
232 223
233 err = connect(fd, (struct sockaddr *) &sock, sizeof(sock)); 224 err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
234 if(err) { 225 if (err) {
235 err = -errno; 226 err = -errno;
236 goto out_close; 227 goto out_close;
237 } 228 }
@@ -254,7 +245,7 @@ int os_seek_file(int fd, unsigned long long offset)
254 unsigned long long actual; 245 unsigned long long actual;
255 246
256 actual = lseek64(fd, offset, SEEK_SET); 247 actual = lseek64(fd, offset, SEEK_SET);
257 if(actual != offset) 248 if (actual != offset)
258 return -errno; 249 return -errno;
259 return 0; 250 return 0;
260} 251}
@@ -263,7 +254,7 @@ int os_read_file(int fd, void *buf, int len)
263{ 254{
264 int n = read(fd, buf, len); 255 int n = read(fd, buf, len);
265 256
266 if(n < 0) 257 if (n < 0)
267 return -errno; 258 return -errno;
268 return n; 259 return n;
269} 260}
@@ -272,37 +263,38 @@ int os_write_file(int fd, const void *buf, int len)
272{ 263{
273 int n = write(fd, (void *) buf, len); 264 int n = write(fd, (void *) buf, len);
274 265
275 if(n < 0) 266 if (n < 0)
276 return -errno; 267 return -errno;
277 return n; 268 return n;
278} 269}
279 270
280int os_file_size(char *file, unsigned long long *size_out) 271int os_file_size(const char *file, unsigned long long *size_out)
281{ 272{
282 struct uml_stat buf; 273 struct uml_stat buf;
283 int err; 274 int err;
284 275
285 err = os_stat_file(file, &buf); 276 err = os_stat_file(file, &buf);
286 if(err < 0){ 277 if (err < 0) {
287 printk("Couldn't stat \"%s\" : err = %d\n", file, -err); 278 printk(UM_KERN_ERR "Couldn't stat \"%s\" : err = %d\n", file,
279 -err);
288 return err; 280 return err;
289 } 281 }
290 282
291 if(S_ISBLK(buf.ust_mode)){ 283 if (S_ISBLK(buf.ust_mode)) {
292 int fd; 284 int fd;
293 long blocks; 285 long blocks;
294 286
295 fd = open(file, O_RDONLY, 0); 287 fd = open(file, O_RDONLY, 0);
296 if(fd < 0) { 288 if (fd < 0) {
297 err = -errno; 289 err = -errno;
298 printk("Couldn't open \"%s\", errno = %d\n", file, 290 printk(UM_KERN_ERR "Couldn't open \"%s\", "
299 errno); 291 "errno = %d\n", file, errno);
300 return err; 292 return err;
301 } 293 }
302 if(ioctl(fd, BLKGETSIZE, &blocks) < 0){ 294 if (ioctl(fd, BLKGETSIZE, &blocks) < 0) {
303 err = -errno; 295 err = -errno;
304 printk("Couldn't get the block size of \"%s\", " 296 printk(UM_KERN_ERR "Couldn't get the block size of "
305 "errno = %d\n", file, errno); 297 "\"%s\", errno = %d\n", file, errno);
306 close(fd); 298 close(fd);
307 return err; 299 return err;
308 } 300 }
@@ -314,14 +306,15 @@ int os_file_size(char *file, unsigned long long *size_out)
314 return 0; 306 return 0;
315} 307}
316 308
317int os_file_modtime(char *file, unsigned long *modtime) 309int os_file_modtime(const char *file, unsigned long *modtime)
318{ 310{
319 struct uml_stat buf; 311 struct uml_stat buf;
320 int err; 312 int err;
321 313
322 err = os_stat_file(file, &buf); 314 err = os_stat_file(file, &buf);
323 if(err < 0){ 315 if (err < 0) {
324 printk("Couldn't stat \"%s\" : err = %d\n", file, -err); 316 printk(UM_KERN_ERR "Couldn't stat \"%s\" : err = %d\n", file,
317 -err);
325 return err; 318 return err;
326 } 319 }
327 320
@@ -329,26 +322,13 @@ int os_file_modtime(char *file, unsigned long *modtime)
329 return 0; 322 return 0;
330} 323}
331 324
332int os_get_exec_close(int fd, int *close_on_exec)
333{
334 int ret;
335
336 CATCH_EINTR(ret = fcntl(fd, F_GETFD));
337
338 if(ret < 0)
339 return -errno;
340
341 *close_on_exec = (ret & FD_CLOEXEC) ? 1 : 0;
342 return ret;
343}
344
345int os_set_exec_close(int fd) 325int os_set_exec_close(int fd)
346{ 326{
347 int err; 327 int err;
348 328
349 CATCH_EINTR(err = fcntl(fd, F_SETFD, FD_CLOEXEC)); 329 CATCH_EINTR(err = fcntl(fd, F_SETFD, FD_CLOEXEC));
350 330
351 if(err < 0) 331 if (err < 0)
352 return -errno; 332 return -errno;
353 return err; 333 return err;
354} 334}
@@ -358,53 +338,51 @@ int os_pipe(int *fds, int stream, int close_on_exec)
358 int err, type = stream ? SOCK_STREAM : SOCK_DGRAM; 338 int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
359 339
360 err = socketpair(AF_UNIX, type, 0, fds); 340 err = socketpair(AF_UNIX, type, 0, fds);
361 if(err < 0) 341 if (err < 0)
362 return -errno; 342 return -errno;
363 343
364 if(!close_on_exec) 344 if (!close_on_exec)
365 return 0; 345 return 0;
366 346
367 err = os_set_exec_close(fds[0]); 347 err = os_set_exec_close(fds[0]);
368 if(err < 0) 348 if (err < 0)
369 goto error; 349 goto error;
370 350
371 err = os_set_exec_close(fds[1]); 351 err = os_set_exec_close(fds[1]);
372 if(err < 0) 352 if (err < 0)
373 goto error; 353 goto error;
374 354
375 return 0; 355 return 0;
376 356
377 error: 357 error:
378 printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err); 358 printk(UM_KERN_ERR "os_pipe : Setting FD_CLOEXEC failed, err = %d\n",
359 -err);
379 close(fds[1]); 360 close(fds[1]);
380 close(fds[0]); 361 close(fds[0]);
381 return err; 362 return err;
382} 363}
383 364
384int os_set_fd_async(int fd, int owner) 365int os_set_fd_async(int fd)
385{ 366{
386 int err; 367 int err, flags;
368
369 flags = fcntl(fd, F_GETFL);
370 if (flags < 0)
371 return -errno;
387 372
388 /* XXX This should do F_GETFL first */ 373 flags |= O_ASYNC | O_NONBLOCK;
389 if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){ 374 if (fcntl(fd, F_SETFL, flags) < 0) {
390 err = -errno; 375 err = -errno;
391 printk("os_set_fd_async : failed to set O_ASYNC and " 376 printk(UM_KERN_ERR "os_set_fd_async : failed to set O_ASYNC "
392 "O_NONBLOCK on fd # %d, errno = %d\n", fd, errno); 377 "and O_NONBLOCK on fd # %d, errno = %d\n", fd, errno);
393 return err; 378 return err;
394 } 379 }
395#ifdef notdef
396 if(fcntl(fd, F_SETFD, 1) < 0){
397 printk("os_set_fd_async : Setting FD_CLOEXEC failed, "
398 "errno = %d\n", errno);
399 }
400#endif
401 380
402 if((fcntl(fd, F_SETSIG, SIGIO) < 0) || 381 if ((fcntl(fd, F_SETSIG, SIGIO) < 0) ||
403 (fcntl(fd, F_SETOWN, owner) < 0)){ 382 (fcntl(fd, F_SETOWN, os_getpid()) < 0)) {
404 err = -errno; 383 err = -errno;
405 printk("os_set_fd_async : Failed to fcntl F_SETOWN " 384 printk(UM_KERN_ERR "os_set_fd_async : Failed to fcntl F_SETOWN "
406 "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, 385 "(or F_SETSIG) fd %d, errno = %d\n", fd, errno);
407 owner, errno);
408 return err; 386 return err;
409 } 387 }
410 388
@@ -413,10 +391,14 @@ int os_set_fd_async(int fd, int owner)
413 391
414int os_clear_fd_async(int fd) 392int os_clear_fd_async(int fd)
415{ 393{
416 int flags = fcntl(fd, F_GETFL); 394 int flags;
395
396 flags = fcntl(fd, F_GETFL);
397 if (flags < 0)
398 return -errno;
417 399
418 flags &= ~(O_ASYNC | O_NONBLOCK); 400 flags &= ~(O_ASYNC | O_NONBLOCK);
419 if(fcntl(fd, F_SETFL, flags) < 0) 401 if (fcntl(fd, F_SETFL, flags) < 0)
420 return -errno; 402 return -errno;
421 return 0; 403 return 0;
422} 404}
@@ -426,11 +408,15 @@ int os_set_fd_block(int fd, int blocking)
426 int flags; 408 int flags;
427 409
428 flags = fcntl(fd, F_GETFL); 410 flags = fcntl(fd, F_GETFL);
411 if (flags < 0)
412 return -errno;
429 413
430 if(blocking) flags &= ~O_NONBLOCK; 414 if (blocking)
431 else flags |= O_NONBLOCK; 415 flags &= ~O_NONBLOCK;
416 else
417 flags |= O_NONBLOCK;
432 418
433 if(fcntl(fd, F_SETFL, flags) < 0) 419 if (fcntl(fd, F_SETFL, flags) < 0)
434 return -errno; 420 return -errno;
435 421
436 return 0; 422 return 0;
@@ -441,7 +427,7 @@ int os_accept_connection(int fd)
441 int new; 427 int new;
442 428
443 new = accept(fd, NULL, 0); 429 new = accept(fd, NULL, 0);
444 if(new < 0) 430 if (new < 0)
445 return -errno; 431 return -errno;
446 return new; 432 return new;
447} 433}
@@ -462,15 +448,17 @@ int os_shutdown_socket(int fd, int r, int w)
462{ 448{
463 int what, err; 449 int what, err;
464 450
465 if(r && w) what = SHUT_RDWR; 451 if (r && w)
466 else if(r) what = SHUT_RD; 452 what = SHUT_RDWR;
467 else if(w) what = SHUT_WR; 453 else if (r)
468 else { 454 what = SHUT_RD;
469 printk("os_shutdown_socket : neither r or w was set\n"); 455 else if (w)
456 what = SHUT_WR;
457 else
470 return -EINVAL; 458 return -EINVAL;
471 } 459
472 err = shutdown(fd, what); 460 err = shutdown(fd, what);
473 if(err < 0) 461 if (err < 0)
474 return -errno; 462 return -errno;
475 return 0; 463 return 0;
476} 464}
@@ -494,19 +482,20 @@ int os_rcv_fd(int fd, int *helper_pid_out)
494 msg.msg_flags = 0; 482 msg.msg_flags = 0;
495 483
496 n = recvmsg(fd, &msg, 0); 484 n = recvmsg(fd, &msg, 0);
497 if(n < 0) 485 if (n < 0)
498 return -errno; 486 return -errno;
499 else if(n != iov.iov_len) 487 else if (n != iov.iov_len)
500 *helper_pid_out = -1; 488 *helper_pid_out = -1;
501 489
502 cmsg = CMSG_FIRSTHDR(&msg); 490 cmsg = CMSG_FIRSTHDR(&msg);
503 if(cmsg == NULL){ 491 if (cmsg == NULL) {
504 printk("rcv_fd didn't receive anything, error = %d\n", errno); 492 printk(UM_KERN_ERR "rcv_fd didn't receive anything, "
493 "error = %d\n", errno);
505 return -1; 494 return -1;
506 } 495 }
507 if((cmsg->cmsg_level != SOL_SOCKET) || 496 if ((cmsg->cmsg_level != SOL_SOCKET) ||
508 (cmsg->cmsg_type != SCM_RIGHTS)){ 497 (cmsg->cmsg_type != SCM_RIGHTS)) {
509 printk("rcv_fd didn't receive a descriptor\n"); 498 printk(UM_KERN_ERR "rcv_fd didn't receive a descriptor\n");
510 return -1; 499 return -1;
511 } 500 }
512 501
@@ -514,29 +503,28 @@ int os_rcv_fd(int fd, int *helper_pid_out)
514 return new; 503 return new;
515} 504}
516 505
517int os_create_unix_socket(char *file, int len, int close_on_exec) 506int os_create_unix_socket(const char *file, int len, int close_on_exec)
518{ 507{
519 struct sockaddr_un addr; 508 struct sockaddr_un addr;
520 int sock, err; 509 int sock, err;
521 510
522 sock = socket(PF_UNIX, SOCK_DGRAM, 0); 511 sock = socket(PF_UNIX, SOCK_DGRAM, 0);
523 if(sock < 0) 512 if (sock < 0)
524 return -errno; 513 return -errno;
525 514
526 if(close_on_exec) { 515 if (close_on_exec) {
527 err = os_set_exec_close(sock); 516 err = os_set_exec_close(sock);
528 if(err < 0) 517 if (err < 0)
529 printk("create_unix_socket : close_on_exec failed, " 518 printk(UM_KERN_ERR "create_unix_socket : "
530 "err = %d", -err); 519 "close_on_exec failed, err = %d", -err);
531 } 520 }
532 521
533 addr.sun_family = AF_UNIX; 522 addr.sun_family = AF_UNIX;
534 523
535 /* XXX Be more careful about overflow */
536 snprintf(addr.sun_path, len, "%s", file); 524 snprintf(addr.sun_path, len, "%s", file);
537 525
538 err = bind(sock, (struct sockaddr *) &addr, sizeof(addr)); 526 err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
539 if(err < 0) 527 if (err < 0)
540 return -errno; 528 return -errno;
541 529
542 return sock; 530 return sock;
@@ -557,17 +545,18 @@ int os_lock_file(int fd, int excl)
557 int err, save; 545 int err, save;
558 546
559 err = fcntl(fd, F_SETLK, &lock); 547 err = fcntl(fd, F_SETLK, &lock);
560 if(!err) 548 if (!err)
561 goto out; 549 goto out;
562 550
563 save = -errno; 551 save = -errno;
564 err = fcntl(fd, F_GETLK, &lock); 552 err = fcntl(fd, F_GETLK, &lock);
565 if(err){ 553 if (err) {
566 err = -errno; 554 err = -errno;
567 goto out; 555 goto out;
568 } 556 }
569 557
570 printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid); 558 printk(UM_KERN_ERR "F_SETLK failed, file already locked by pid %d\n",
559 lock.l_pid);
571 err = save; 560 err = save;
572 out: 561 out:
573 return err; 562 return err;
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index fba3f0fefeef..f4bd349d4412 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -1,22 +1,19 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h>
7#include <stdlib.h> 6#include <stdlib.h>
8#include <unistd.h> 7#include <unistd.h>
9#include <errno.h> 8#include <errno.h>
10#include <sched.h> 9#include <sched.h>
11#include <limits.h>
12#include <sys/signal.h>
13#include <sys/wait.h>
14#include <sys/socket.h> 10#include <sys/socket.h>
15#include "user.h" 11#include <sys/wait.h>
12#include "kern_constants.h"
16#include "kern_util.h" 13#include "kern_util.h"
17#include "os.h" 14#include "os.h"
18#include "um_malloc.h" 15#include "um_malloc.h"
19#include "kern_constants.h" 16#include "user.h"
20 17
21struct helper_data { 18struct helper_data {
22 void (*pre_exec)(void*); 19 void (*pre_exec)(void*);
@@ -30,21 +27,19 @@ static int helper_child(void *arg)
30{ 27{
31 struct helper_data *data = arg; 28 struct helper_data *data = arg;
32 char **argv = data->argv; 29 char **argv = data->argv;
33 int errval; 30 int err;
34 31
35 if (data->pre_exec != NULL) 32 if (data->pre_exec != NULL)
36 (*data->pre_exec)(data->pre_data); 33 (*data->pre_exec)(data->pre_data);
37 errval = execvp_noalloc(data->buf, argv[0], argv); 34 err = execvp_noalloc(data->buf, argv[0], argv);
38 printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], 35
39 -errval); 36 /* If the exec succeeds, we don't get here */
40 write(data->fd, &errval, sizeof(errval)); 37 write(data->fd, &err, sizeof(err));
41 kill(os_getpid(), SIGKILL); 38
42 return 0; 39 return 0;
43} 40}
44 41
45/* Returns either the pid of the child process we run or -E* on failure. 42/* Returns either the pid of the child process we run or -E* on failure. */
46 * XXX The alloc_stack here breaks if this is called in the tracing thread, so
47 * we need to receive a preallocated stack (a local buffer is ok). */
48int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv) 43int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
49{ 44{
50 struct helper_data data; 45 struct helper_data data;
@@ -58,14 +53,15 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
58 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 53 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
59 if (ret < 0) { 54 if (ret < 0) {
60 ret = -errno; 55 ret = -errno;
61 printk("run_helper : pipe failed, errno = %d\n", errno); 56 printk(UM_KERN_ERR "run_helper : pipe failed, errno = %d\n",
57 errno);
62 goto out_free; 58 goto out_free;
63 } 59 }
64 60
65 ret = os_set_exec_close(fds[1]); 61 ret = os_set_exec_close(fds[1]);
66 if (ret < 0) { 62 if (ret < 0) {
67 printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n", 63 printk(UM_KERN_ERR "run_helper : setting FD_CLOEXEC failed, "
68 -ret); 64 "ret = %d\n", -ret);
69 goto out_close; 65 goto out_close;
70 } 66 }
71 67
@@ -79,7 +75,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
79 pid = clone(helper_child, (void *) sp, CLONE_VM, &data); 75 pid = clone(helper_child, (void *) sp, CLONE_VM, &data);
80 if (pid < 0) { 76 if (pid < 0) {
81 ret = -errno; 77 ret = -errno;
82 printk("run_helper : clone failed, errno = %d\n", errno); 78 printk(UM_KERN_ERR "run_helper : clone failed, errno = %d\n",
79 errno);
83 goto out_free2; 80 goto out_free2;
84 } 81 }
85 82
@@ -96,10 +93,9 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
96 } else { 93 } else {
97 if (n < 0) { 94 if (n < 0) {
98 n = -errno; 95 n = -errno;
99 printk("run_helper : read on pipe failed, ret = %d\n", 96 printk(UM_KERN_ERR "run_helper : read on pipe failed, "
100 -n); 97 "ret = %d\n", -n);
101 ret = n; 98 ret = n;
102 kill(pid, SIGKILL);
103 } 99 }
104 CATCH_EINTR(waitpid(pid, NULL, __WCLONE)); 100 CATCH_EINTR(waitpid(pid, NULL, __WCLONE));
105 } 101 }
@@ -129,50 +125,40 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
129 pid = clone(proc, (void *) sp, flags, arg); 125 pid = clone(proc, (void *) sp, flags, arg);
130 if (pid < 0) { 126 if (pid < 0) {
131 err = -errno; 127 err = -errno;
132 printk("run_helper_thread : clone failed, errno = %d\n", 128 printk(UM_KERN_ERR "run_helper_thread : clone failed, "
133 errno); 129 "errno = %d\n", errno);
134 return err; 130 return err;
135 } 131 }
136 if (stack_out == NULL) { 132 if (stack_out == NULL) {
137 CATCH_EINTR(pid = waitpid(pid, &status, __WCLONE)); 133 CATCH_EINTR(pid = waitpid(pid, &status, __WCLONE));
138 if (pid < 0) { 134 if (pid < 0) {
139 err = -errno; 135 err = -errno;
140 printk("run_helper_thread - wait failed, errno = %d\n", 136 printk(UM_KERN_ERR "run_helper_thread - wait failed, "
141 errno); 137 "errno = %d\n", errno);
142 pid = err; 138 pid = err;
143 } 139 }
144 if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) 140 if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
145 printk("run_helper_thread - thread returned status " 141 printk(UM_KERN_ERR "run_helper_thread - thread "
146 "0x%x\n", status); 142 "returned status 0x%x\n", status);
147 free_stack(stack, 0); 143 free_stack(stack, 0);
148 } else 144 } else
149 *stack_out = stack; 145 *stack_out = stack;
150 return pid; 146 return pid;
151} 147}
152 148
153int helper_wait(int pid, int nohang, char *pname) 149int helper_wait(int pid)
154{ 150{
155 int ret, status; 151 int ret, status;
156 int wflags = __WCLONE; 152 int wflags = __WCLONE;
157 153
158 if (nohang)
159 wflags |= WNOHANG;
160
161 if (!pname)
162 pname = "helper_wait";
163
164 CATCH_EINTR(ret = waitpid(pid, &status, wflags)); 154 CATCH_EINTR(ret = waitpid(pid, &status, wflags));
165 if (ret < 0) { 155 if (ret < 0) {
166 printk(UM_KERN_ERR "%s : waitpid process %d failed, " 156 printk(UM_KERN_ERR "helper_wait : waitpid process %d failed, "
167 "errno = %d\n", pname, pid, errno); 157 "errno = %d\n", pid, errno);
168 return -errno; 158 return -errno;
169 } else if (nohang && ret == 0) {
170 printk(UM_KERN_ERR "%s : process %d has not exited\n",
171 pname, pid);
172 return -ECHILD;
173 } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 159 } else if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
174 printk(UM_KERN_ERR "%s : process %d didn't exit with " 160 printk(UM_KERN_ERR "helper_wait : process %d exited with "
175 "status 0\n", pname, pid); 161 "status 0x%x\n", pid, status);
176 return -ECHILD; 162 return -ECHILD;
177 } else 163 } else
178 return 0; 164 return 0;
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index 6aa6f95d6524..0348b975e81c 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -1,23 +1,19 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdlib.h> 6#include <stdlib.h>
7#include <unistd.h>
8#include <errno.h> 7#include <errno.h>
8#include <poll.h>
9#include <signal.h> 9#include <signal.h>
10#include <string.h> 10#include <string.h>
11#include <sys/poll.h>
12#include <sys/types.h>
13#include <sys/time.h>
14#include "kern_util.h"
15#include "user.h"
16#include "process.h"
17#include "sigio.h"
18#include "irq_user.h" 11#include "irq_user.h"
12#include "kern_constants.h"
19#include "os.h" 13#include "os.h"
14#include "process.h"
20#include "um_malloc.h" 15#include "um_malloc.h"
16#include "user.h"
21 17
22/* 18/*
23 * Locked by irq_lock in arch/um/kernel/irq.c. Changed by os_create_pollfd 19 * Locked by irq_lock in arch/um/kernel/irq.c. Changed by os_create_pollfd
@@ -36,7 +32,7 @@ int os_waiting_for_events(struct irq_fd *active_fds)
36 if (n < 0) { 32 if (n < 0) {
37 err = -errno; 33 err = -errno;
38 if (errno != EINTR) 34 if (errno != EINTR)
39 printk("sigio_handler: os_waiting_for_events:" 35 printk(UM_KERN_ERR "os_waiting_for_events:"
40 " poll returned %d, errno = %d\n", n, errno); 36 " poll returned %d, errno = %d\n", n, errno);
41 return err; 37 return err;
42 } 38 }
@@ -95,24 +91,26 @@ void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg,
95 struct irq_fd *old_fd = *prev; 91 struct irq_fd *old_fd = *prev;
96 if ((pollfds[i].fd != -1) && 92 if ((pollfds[i].fd != -1) &&
97 (pollfds[i].fd != (*prev)->fd)) { 93 (pollfds[i].fd != (*prev)->fd)) {
98 printk("os_free_irq_by_cb - mismatch between " 94 printk(UM_KERN_ERR "os_free_irq_by_cb - "
99 "active_fds and pollfds, fd %d vs %d\n", 95 "mismatch between active_fds and "
96 "pollfds, fd %d vs %d\n",
100 (*prev)->fd, pollfds[i].fd); 97 (*prev)->fd, pollfds[i].fd);
101 goto out; 98 goto out;
102 } 99 }
103 100
104 pollfds_num--; 101 pollfds_num--;
105 102
106 /* This moves the *whole* array after pollfds[i] 103 /*
104 * This moves the *whole* array after pollfds[i]
107 * (though it doesn't spot as such)! 105 * (though it doesn't spot as such)!
108 */ 106 */
109 memmove(&pollfds[i], &pollfds[i + 1], 107 memmove(&pollfds[i], &pollfds[i + 1],
110 (pollfds_num - i) * sizeof(pollfds[0])); 108 (pollfds_num - i) * sizeof(pollfds[0]));
111 if(*last_irq_ptr2 == &old_fd->next) 109 if (*last_irq_ptr2 == &old_fd->next)
112 *last_irq_ptr2 = prev; 110 *last_irq_ptr2 = prev;
113 111
114 *prev = (*prev)->next; 112 *prev = (*prev)->next;
115 if(old_fd->type == IRQ_WRITE) 113 if (old_fd->type == IRQ_WRITE)
116 ignore_sigio_fd(old_fd->fd); 114 ignore_sigio_fd(old_fd->fd);
117 kfree(old_fd); 115 kfree(old_fd);
118 continue; 116 continue;
@@ -138,14 +136,3 @@ void os_set_ioignore(void)
138{ 136{
139 signal(SIGIO, SIG_IGN); 137 signal(SIGIO, SIG_IGN);
140} 138}
141
142void init_irq_signals(int on_sigstack)
143{
144 int flags;
145
146 flags = on_sigstack ? SA_ONSTACK : 0;
147
148 set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
149 SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
150 signal(SIGWINCH, SIG_IGN);
151}
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 82c3778627b8..abb9b0ffd960 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -73,7 +73,7 @@ static void install_fatal_handler(int sig)
73 action.sa_handler = last_ditch_exit; 73 action.sa_handler = last_ditch_exit;
74 if (sigaction(sig, &action, NULL) < 0) { 74 if (sigaction(sig, &action, NULL) < 0) {
75 printf("failed to install handler for signal %d - errno = %d\n", 75 printf("failed to install handler for signal %d - errno = %d\n",
76 errno); 76 sig, errno);
77 exit(1); 77 exit(1);
78 } 78 }
79} 79}
@@ -92,7 +92,8 @@ static void setup_env_path(void)
92 * just use the default + /usr/lib/uml 92 * just use the default + /usr/lib/uml
93 */ 93 */
94 if (!old_path || (path_len = strlen(old_path)) == 0) { 94 if (!old_path || (path_len = strlen(old_path)) == 0) {
95 putenv("PATH=:/bin:/usr/bin/" UML_LIB_PATH); 95 if (putenv("PATH=:/bin:/usr/bin/" UML_LIB_PATH))
96 perror("couldn't putenv");
96 return; 97 return;
97 } 98 }
98 99
@@ -100,15 +101,16 @@ static void setup_env_path(void)
100 path_len += strlen("PATH=" UML_LIB_PATH) + 1; 101 path_len += strlen("PATH=" UML_LIB_PATH) + 1;
101 new_path = malloc(path_len); 102 new_path = malloc(path_len);
102 if (!new_path) { 103 if (!new_path) {
103 perror("coudn't malloc to set a new PATH"); 104 perror("couldn't malloc to set a new PATH");
104 return; 105 return;
105 } 106 }
106 snprintf(new_path, path_len, "PATH=%s" UML_LIB_PATH, old_path); 107 snprintf(new_path, path_len, "PATH=%s" UML_LIB_PATH, old_path);
107 putenv(new_path); 108 if (putenv(new_path)) {
109 perror("couldn't putenv to set a new PATH");
110 free(new_path);
111 }
108} 112}
109 113
110extern int uml_exitcode;
111
112extern void scan_elf_aux( char **envp); 114extern void scan_elf_aux( char **envp);
113 115
114int __init main(int argc, char **argv, char **envp) 116int __init main(int argc, char **argv, char **envp)
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 436f8d20b20f..eedc2d88ef8a 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -9,7 +9,6 @@
9#include <sys/types.h> 9#include <sys/types.h>
10#include <sys/mman.h> 10#include <sys/mman.h>
11#include <sys/statfs.h> 11#include <sys/statfs.h>
12#include "kern_util.h"
13#include "user.h" 12#include "user.h"
14#include "mem_user.h" 13#include "mem_user.h"
15#include "init.h" 14#include "init.h"
@@ -30,7 +29,7 @@ static char *tempdir = NULL;
30 29
31static void __init find_tempdir(void) 30static void __init find_tempdir(void)
32{ 31{
33 char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL }; 32 const char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL };
34 int i; 33 int i;
35 char *dir = NULL; 34 char *dir = NULL;
36 35
@@ -59,9 +58,10 @@ static void __init find_tempdir(void)
59 * read the file as needed. If there's an error, -errno is returned; 58 * read the file as needed. If there's an error, -errno is returned;
60 * if the end of the file is reached, 0 is returned. 59 * if the end of the file is reached, 0 is returned.
61 */ 60 */
62static int next(int fd, char *buf, int size, char c) 61static int next(int fd, char *buf, size_t size, char c)
63{ 62{
64 int n, len; 63 ssize_t n;
64 size_t len;
65 char *ptr; 65 char *ptr;
66 66
67 while((ptr = strchr(buf, c)) == NULL){ 67 while((ptr = strchr(buf, c)) == NULL){
@@ -172,13 +172,15 @@ int __init make_tempfile(const char *template, char **out_tempname,
172 172
173 which_tmpdir(); 173 which_tmpdir();
174 tempname = malloc(MAXPATHLEN); 174 tempname = malloc(MAXPATHLEN);
175 if (!tempname)
176 goto out;
175 177
176 find_tempdir(); 178 find_tempdir();
177 if (template[0] != '/') 179 if (template[0] != '/')
178 strcpy(tempname, tempdir); 180 strcpy(tempname, tempdir);
179 else 181 else
180 tempname[0] = '\0'; 182 tempname[0] = '\0';
181 strcat(tempname, template); 183 strncat(tempname, template, MAXPATHLEN-1-strlen(tempname));
182 fd = mkstemp(tempname); 184 fd = mkstemp(tempname);
183 if(fd < 0){ 185 if(fd < 0){
184 fprintf(stderr, "open - cannot create %s: %s\n", tempname, 186 fprintf(stderr, "open - cannot create %s: %s\n", tempname,
@@ -268,6 +270,7 @@ void __init check_tmpexec(void)
268 if(addr == MAP_FAILED){ 270 if(addr == MAP_FAILED){
269 err = errno; 271 err = errno;
270 perror("failed"); 272 perror("failed");
273 close(fd);
271 if(err == EPERM) 274 if(err == EPERM)
272 printf("%s must be not mounted noexec\n",tempdir); 275 printf("%s must be not mounted noexec\n",tempdir);
273 exit(1); 276 exit(1);
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index bda5c3150d6c..abf6beae3df1 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -249,7 +249,10 @@ void init_new_thread_signals(void)
249 SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); 249 SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
250 signal(SIGHUP, SIG_IGN); 250 signal(SIGHUP, SIG_IGN);
251 251
252 init_irq_signals(1); 252 set_handler(SIGIO, (__sighandler_t) sig_handler,
253 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM,
254 SIGVTALRM, -1);
255 signal(SIGWINCH, SIG_IGN);
253} 256}
254 257
255int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr) 258int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr)
diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c
index a32ba6ab1211..830fe6a1518a 100644
--- a/arch/um/os-Linux/registers.c
+++ b/arch/um/os-Linux/registers.c
@@ -8,47 +8,41 @@
8#include <string.h> 8#include <string.h>
9#include <sys/ptrace.h> 9#include <sys/ptrace.h>
10#include "sysdep/ptrace.h" 10#include "sysdep/ptrace.h"
11#include "user.h"
12 11
13/* This is set once at boot time and not changed thereafter */ 12int save_registers(int pid, struct uml_pt_regs *regs)
14
15static unsigned long exec_regs[MAX_REG_NR];
16
17void init_thread_registers(struct uml_pt_regs *to)
18{
19 memcpy(to->gp, exec_regs, sizeof(to->gp));
20}
21
22void save_registers(int pid, struct uml_pt_regs *regs)
23{ 13{
24 int err; 14 int err;
25 15
26 err = ptrace(PTRACE_GETREGS, pid, 0, regs->gp); 16 err = ptrace(PTRACE_GETREGS, pid, 0, regs->gp);
27 if (err < 0) 17 if (err < 0)
28 panic("save_registers - saving registers failed, errno = %d\n", 18 return -errno;
29 errno); 19 return 0;
30} 20}
31 21
32void restore_registers(int pid, struct uml_pt_regs *regs) 22int restore_registers(int pid, struct uml_pt_regs *regs)
33{ 23{
34 int err; 24 int err;
35 25
36 err = ptrace(PTRACE_SETREGS, pid, 0, regs->gp); 26 err = ptrace(PTRACE_SETREGS, pid, 0, regs->gp);
37 if (err < 0) 27 if (err < 0)
38 panic("restore_registers - saving registers failed, " 28 return -errno;
39 "errno = %d\n", errno); 29 return 0;
40} 30}
41 31
42void init_registers(int pid) 32/* This is set once at boot time and not changed thereafter */
33
34static unsigned long exec_regs[MAX_REG_NR];
35
36int init_registers(int pid)
43{ 37{
44 int err; 38 int err;
45 39
46 err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); 40 err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
47 if (err) 41 if (err < 0)
48 panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", 42 return -errno;
49 errno);
50 43
51 arch_init_registers(pid); 44 arch_init_registers(pid);
45 return 0;
52} 46}
53 47
54void get_safe_registers(unsigned long *regs) 48void get_safe_registers(unsigned long *regs)
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index dc03e9cccb63..abf47a7c4abd 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -1,34 +1,33 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <unistd.h> 6#include <unistd.h>
7#include <stdlib.h> 7#include <errno.h>
8#include <termios.h> 8#include <fcntl.h>
9#include <poll.h>
9#include <pty.h> 10#include <pty.h>
11#include <sched.h>
10#include <signal.h> 12#include <signal.h>
11#include <fcntl.h>
12#include <errno.h>
13#include <string.h> 13#include <string.h>
14#include <sched.h> 14#include "kern_constants.h"
15#include <sys/socket.h>
16#include <sys/poll.h>
17#include "init.h"
18#include "user.h"
19#include "kern_util.h" 15#include "kern_util.h"
20#include "sigio.h" 16#include "init.h"
21#include "os.h" 17#include "os.h"
18#include "sigio.h"
22#include "um_malloc.h" 19#include "um_malloc.h"
23#include "init.h" 20#include "user.h"
24 21
25/* Protected by sigio_lock(), also used by sigio_cleanup, which is an 22/*
23 * Protected by sigio_lock(), also used by sigio_cleanup, which is an
26 * exitcall. 24 * exitcall.
27 */ 25 */
28static int write_sigio_pid = -1; 26static int write_sigio_pid = -1;
29static unsigned long write_sigio_stack; 27static unsigned long write_sigio_stack;
30 28
31/* These arrays are initialized before the sigio thread is started, and 29/*
30 * These arrays are initialized before the sigio thread is started, and
32 * the descriptors closed after it is killed. So, it can't see them change. 31 * the descriptors closed after it is killed. So, it can't see them change.
33 * On the UML side, they are changed under the sigio_lock. 32 * On the UML side, they are changed under the sigio_lock.
34 */ 33 */
@@ -43,7 +42,8 @@ struct pollfds {
43 int used; 42 int used;
44}; 43};
45 44
46/* Protected by sigio_lock(). Used by the sigio thread, but the UML thread 45/*
46 * Protected by sigio_lock(). Used by the sigio thread, but the UML thread
47 * synchronizes with it. 47 * synchronizes with it.
48 */ 48 */
49static struct pollfds current_poll; 49static struct pollfds current_poll;
@@ -57,23 +57,26 @@ static int write_sigio_thread(void *unused)
57 int i, n, respond_fd; 57 int i, n, respond_fd;
58 char c; 58 char c;
59 59
60 signal(SIGWINCH, SIG_IGN); 60 signal(SIGWINCH, SIG_IGN);
61 fds = &current_poll; 61 fds = &current_poll;
62 while(1){ 62 while (1) {
63 n = poll(fds->poll, fds->used, -1); 63 n = poll(fds->poll, fds->used, -1);
64 if(n < 0){ 64 if (n < 0) {
65 if(errno == EINTR) continue; 65 if (errno == EINTR)
66 printk("write_sigio_thread : poll returned %d, " 66 continue;
67 "errno = %d\n", n, errno); 67 printk(UM_KERN_ERR "write_sigio_thread : poll returned "
68 "%d, errno = %d\n", n, errno);
68 } 69 }
69 for(i = 0; i < fds->used; i++){ 70 for (i = 0; i < fds->used; i++) {
70 p = &fds->poll[i]; 71 p = &fds->poll[i];
71 if(p->revents == 0) continue; 72 if (p->revents == 0)
72 if(p->fd == sigio_private[1]){ 73 continue;
74 if (p->fd == sigio_private[1]) {
73 CATCH_EINTR(n = read(sigio_private[1], &c, 75 CATCH_EINTR(n = read(sigio_private[1], &c,
74 sizeof(c))); 76 sizeof(c)));
75 if(n != sizeof(c)) 77 if (n != sizeof(c))
76 printk("write_sigio_thread : " 78 printk(UM_KERN_ERR
79 "write_sigio_thread : "
77 "read on socket failed, " 80 "read on socket failed, "
78 "err = %d\n", errno); 81 "err = %d\n", errno);
79 tmp = current_poll; 82 tmp = current_poll;
@@ -89,9 +92,10 @@ static int write_sigio_thread(void *unused)
89 } 92 }
90 93
91 CATCH_EINTR(n = write(respond_fd, &c, sizeof(c))); 94 CATCH_EINTR(n = write(respond_fd, &c, sizeof(c)));
92 if(n != sizeof(c)) 95 if (n != sizeof(c))
93 printk("write_sigio_thread : write on socket " 96 printk(UM_KERN_ERR "write_sigio_thread : "
94 "failed, err = %d\n", errno); 97 "write on socket failed, err = %d\n",
98 errno);
95 } 99 }
96 } 100 }
97 101
@@ -102,12 +106,13 @@ static int need_poll(struct pollfds *polls, int n)
102{ 106{
103 struct pollfd *new; 107 struct pollfd *new;
104 108
105 if(n <= polls->size) 109 if (n <= polls->size)
106 return 0; 110 return 0;
107 111
108 new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC); 112 new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
109 if(new == NULL){ 113 if (new == NULL) {
110 printk("need_poll : failed to allocate new pollfds\n"); 114 printk(UM_KERN_ERR "need_poll : failed to allocate new "
115 "pollfds\n");
111 return -ENOMEM; 116 return -ENOMEM;
112 } 117 }
113 118
@@ -119,7 +124,8 @@ static int need_poll(struct pollfds *polls, int n)
119 return 0; 124 return 0;
120} 125}
121 126
122/* Must be called with sigio_lock held, because it's needed by the marked 127/*
128 * Must be called with sigio_lock held, because it's needed by the marked
123 * critical section. 129 * critical section.
124 */ 130 */
125static void update_thread(void) 131static void update_thread(void)
@@ -129,15 +135,17 @@ static void update_thread(void)
129 char c; 135 char c;
130 136
131 flags = set_signals(0); 137 flags = set_signals(0);
132 n = write(sigio_private[0], &c, sizeof(c)); 138 CATCH_EINTR(n = write(sigio_private[0], &c, sizeof(c)));
133 if(n != sizeof(c)){ 139 if (n != sizeof(c)) {
134 printk("update_thread : write failed, err = %d\n", errno); 140 printk(UM_KERN_ERR "update_thread : write failed, err = %d\n",
141 errno);
135 goto fail; 142 goto fail;
136 } 143 }
137 144
138 CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c))); 145 CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c)));
139 if(n != sizeof(c)){ 146 if (n != sizeof(c)) {
140 printk("update_thread : read failed, err = %d\n", errno); 147 printk(UM_KERN_ERR "update_thread : read failed, err = %d\n",
148 errno);
141 goto fail; 149 goto fail;
142 } 150 }
143 151
@@ -164,23 +172,23 @@ int add_sigio_fd(int fd)
164 int err = 0, i, n; 172 int err = 0, i, n;
165 173
166 sigio_lock(); 174 sigio_lock();
167 for(i = 0; i < all_sigio_fds.used; i++){ 175 for (i = 0; i < all_sigio_fds.used; i++) {
168 if(all_sigio_fds.poll[i].fd == fd) 176 if (all_sigio_fds.poll[i].fd == fd)
169 break; 177 break;
170 } 178 }
171 if(i == all_sigio_fds.used) 179 if (i == all_sigio_fds.used)
172 goto out; 180 goto out;
173 181
174 p = &all_sigio_fds.poll[i]; 182 p = &all_sigio_fds.poll[i];
175 183
176 for(i = 0; i < current_poll.used; i++){ 184 for (i = 0; i < current_poll.used; i++) {
177 if(current_poll.poll[i].fd == fd) 185 if (current_poll.poll[i].fd == fd)
178 goto out; 186 goto out;
179 } 187 }
180 188
181 n = current_poll.used; 189 n = current_poll.used;
182 err = need_poll(&next_poll, n + 1); 190 err = need_poll(&next_poll, n + 1);
183 if(err) 191 if (err)
184 goto out; 192 goto out;
185 193
186 memcpy(next_poll.poll, current_poll.poll, 194 memcpy(next_poll.poll, current_poll.poll,
@@ -198,27 +206,29 @@ int ignore_sigio_fd(int fd)
198 struct pollfd *p; 206 struct pollfd *p;
199 int err = 0, i, n = 0; 207 int err = 0, i, n = 0;
200 208
201 /* This is called from exitcalls elsewhere in UML - if 209 /*
210 * This is called from exitcalls elsewhere in UML - if
202 * sigio_cleanup has already run, then update_thread will hang 211 * sigio_cleanup has already run, then update_thread will hang
203 * or fail because the thread is no longer running. 212 * or fail because the thread is no longer running.
204 */ 213 */
205 if(write_sigio_pid == -1) 214 if (write_sigio_pid == -1)
206 return -EIO; 215 return -EIO;
207 216
208 sigio_lock(); 217 sigio_lock();
209 for(i = 0; i < current_poll.used; i++){ 218 for (i = 0; i < current_poll.used; i++) {
210 if(current_poll.poll[i].fd == fd) break; 219 if (current_poll.poll[i].fd == fd)
220 break;
211 } 221 }
212 if(i == current_poll.used) 222 if (i == current_poll.used)
213 goto out; 223 goto out;
214 224
215 err = need_poll(&next_poll, current_poll.used - 1); 225 err = need_poll(&next_poll, current_poll.used - 1);
216 if(err) 226 if (err)
217 goto out; 227 goto out;
218 228
219 for(i = 0; i < current_poll.used; i++){ 229 for (i = 0; i < current_poll.used; i++) {
220 p = &current_poll.poll[i]; 230 p = &current_poll.poll[i];
221 if(p->fd != fd) 231 if (p->fd != fd)
222 next_poll.poll[n++] = *p; 232 next_poll.poll[n++] = *p;
223 } 233 }
224 next_poll.used = current_poll.used - 1; 234 next_poll.used = current_poll.used - 1;
@@ -235,7 +245,8 @@ static struct pollfd *setup_initial_poll(int fd)
235 245
236 p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL); 246 p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
237 if (p == NULL) { 247 if (p == NULL) {
238 printk("setup_initial_poll : failed to allocate poll\n"); 248 printk(UM_KERN_ERR "setup_initial_poll : failed to allocate "
249 "poll\n");
239 return NULL; 250 return NULL;
240 } 251 }
241 *p = ((struct pollfd) { .fd = fd, 252 *p = ((struct pollfd) { .fd = fd,
@@ -261,27 +272,29 @@ static void write_sigio_workaround(void)
261 return; 272 return;
262 273
263 err = os_pipe(l_write_sigio_fds, 1, 1); 274 err = os_pipe(l_write_sigio_fds, 1, 1);
264 if(err < 0){ 275 if (err < 0) {
265 printk("write_sigio_workaround - os_pipe 1 failed, " 276 printk(UM_KERN_ERR "write_sigio_workaround - os_pipe 1 failed, "
266 "err = %d\n", -err); 277 "err = %d\n", -err);
267 return; 278 return;
268 } 279 }
269 err = os_pipe(l_sigio_private, 1, 1); 280 err = os_pipe(l_sigio_private, 1, 1);
270 if(err < 0){ 281 if (err < 0) {
271 printk("write_sigio_workaround - os_pipe 2 failed, " 282 printk(UM_KERN_ERR "write_sigio_workaround - os_pipe 2 failed, "
272 "err = %d\n", -err); 283 "err = %d\n", -err);
273 goto out_close1; 284 goto out_close1;
274 } 285 }
275 286
276 p = setup_initial_poll(l_sigio_private[1]); 287 p = setup_initial_poll(l_sigio_private[1]);
277 if(!p) 288 if (!p)
278 goto out_close2; 289 goto out_close2;
279 290
280 sigio_lock(); 291 sigio_lock();
281 292
282 /* Did we race? Don't try to optimize this, please, it's not so likely 293 /*
283 * to happen, and no more than once at the boot. */ 294 * Did we race? Don't try to optimize this, please, it's not so likely
284 if(write_sigio_pid != -1) 295 * to happen, and no more than once at the boot.
296 */
297 if (write_sigio_pid != -1)
285 goto out_free; 298 goto out_free;
286 299
287 current_poll = ((struct pollfds) { .poll = p, 300 current_poll = ((struct pollfds) { .poll = p,
@@ -333,19 +346,19 @@ void maybe_sigio_broken(int fd, int read)
333{ 346{
334 int err; 347 int err;
335 348
336 if(!isatty(fd)) 349 if (!isatty(fd))
337 return; 350 return;
338 351
339 if((read || pty_output_sigio) && (!read || pty_close_sigio)) 352 if ((read || pty_output_sigio) && (!read || pty_close_sigio))
340 return; 353 return;
341 354
342 write_sigio_workaround(); 355 write_sigio_workaround();
343 356
344 sigio_lock(); 357 sigio_lock();
345 err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1); 358 err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
346 if(err){ 359 if (err) {
347 printk("maybe_sigio_broken - failed to add pollfd for " 360 printk(UM_KERN_ERR "maybe_sigio_broken - failed to add pollfd "
348 "descriptor %d\n", fd); 361 "for descriptor %d\n", fd);
349 goto out; 362 goto out;
350 } 363 }
351 364
@@ -388,7 +401,7 @@ static void openpty_cb(void *arg)
388 struct openpty_arg *info = arg; 401 struct openpty_arg *info = arg;
389 402
390 info->err = 0; 403 info->err = 0;
391 if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) 404 if (openpty(&info->master, &info->slave, NULL, NULL, NULL))
392 info->err = -errno; 405 info->err = -errno;
393} 406}
394 407
@@ -397,17 +410,17 @@ static int async_pty(int master, int slave)
397 int flags; 410 int flags;
398 411
399 flags = fcntl(master, F_GETFL); 412 flags = fcntl(master, F_GETFL);
400 if(flags < 0) 413 if (flags < 0)
401 return -errno; 414 return -errno;
402 415
403 if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || 416 if ((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
404 (fcntl(master, F_SETOWN, os_getpid()) < 0)) 417 (fcntl(master, F_SETOWN, os_getpid()) < 0))
405 return -errno; 418 return -errno;
406 419
407 if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) 420 if ((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
408 return -errno; 421 return -errno;
409 422
410 return(0); 423 return 0;
411} 424}
412 425
413static void __init check_one_sigio(void (*proc)(int, int)) 426static void __init check_one_sigio(void (*proc)(int, int))
@@ -417,34 +430,49 @@ static void __init check_one_sigio(void (*proc)(int, int))
417 int master, slave, err; 430 int master, slave, err;
418 431
419 initial_thread_cb(openpty_cb, &pty); 432 initial_thread_cb(openpty_cb, &pty);
420 if(pty.err){ 433 if (pty.err) {
421 printk("openpty failed, errno = %d\n", -pty.err); 434 printk(UM_KERN_ERR "check_one_sigio failed, errno = %d\n",
435 -pty.err);
422 return; 436 return;
423 } 437 }
424 438
425 master = pty.master; 439 master = pty.master;
426 slave = pty.slave; 440 slave = pty.slave;
427 441
428 if((master == -1) || (slave == -1)){ 442 if ((master == -1) || (slave == -1)) {
429 printk("openpty failed to allocate a pty\n"); 443 printk(UM_KERN_ERR "check_one_sigio failed to allocate a "
444 "pty\n");
430 return; 445 return;
431 } 446 }
432 447
433 /* Not now, but complain so we now where we failed. */ 448 /* Not now, but complain so we now where we failed. */
434 err = raw(master); 449 err = raw(master);
435 if (err < 0) 450 if (err < 0) {
436 panic("check_sigio : __raw failed, errno = %d\n", -err); 451 printk(UM_KERN_ERR "check_one_sigio : raw failed, errno = %d\n",
452 -err);
453 return;
454 }
437 455
438 err = async_pty(master, slave); 456 err = async_pty(master, slave);
439 if(err < 0) 457 if (err < 0) {
440 panic("tty_fds : sigio_async failed, err = %d\n", -err); 458 printk(UM_KERN_ERR "check_one_sigio : sigio_async failed, "
459 "err = %d\n", -err);
460 return;
461 }
462
463 if (sigaction(SIGIO, NULL, &old) < 0) {
464 printk(UM_KERN_ERR "check_one_sigio : sigaction 1 failed, "
465 "errno = %d\n", errno);
466 return;
467 }
441 468
442 if(sigaction(SIGIO, NULL, &old) < 0)
443 panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
444 new = old; 469 new = old;
445 new.sa_handler = handler; 470 new.sa_handler = handler;
446 if(sigaction(SIGIO, &new, NULL) < 0) 471 if (sigaction(SIGIO, &new, NULL) < 0) {
447 panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); 472 printk(UM_KERN_ERR "check_one_sigio : sigaction 2 failed, "
473 "errno = %d\n", errno);
474 return;
475 }
448 476
449 got_sigio = 0; 477 got_sigio = 0;
450 (*proc)(master, slave); 478 (*proc)(master, slave);
@@ -452,8 +480,9 @@ static void __init check_one_sigio(void (*proc)(int, int))
452 close(master); 480 close(master);
453 close(slave); 481 close(slave);
454 482
455 if(sigaction(SIGIO, &old, NULL) < 0) 483 if (sigaction(SIGIO, &old, NULL) < 0)
456 panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); 484 printk(UM_KERN_ERR "check_one_sigio : sigaction 3 failed, "
485 "errno = %d\n", errno);
457} 486}
458 487
459static void tty_output(int master, int slave) 488static void tty_output(int master, int slave)
@@ -461,42 +490,45 @@ static void tty_output(int master, int slave)
461 int n; 490 int n;
462 char buf[512]; 491 char buf[512];
463 492
464 printk("Checking that host ptys support output SIGIO..."); 493 printk(UM_KERN_INFO "Checking that host ptys support output SIGIO...");
465 494
466 memset(buf, 0, sizeof(buf)); 495 memset(buf, 0, sizeof(buf));
467 496
468 while(write(master, buf, sizeof(buf)) > 0) ; 497 while (write(master, buf, sizeof(buf)) > 0) ;
469 if(errno != EAGAIN) 498 if (errno != EAGAIN)
470 panic("tty_output : write failed, errno = %d\n", errno); 499 printk(UM_KERN_ERR "tty_output : write failed, errno = %d\n",
471 while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; 500 errno);
501 while (((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio)
502 ;
472 503
473 if(got_sigio){ 504 if (got_sigio) {
474 printk("Yes\n"); 505 printk(UM_KERN_CONT "Yes\n");
475 pty_output_sigio = 1; 506 pty_output_sigio = 1;
476 } 507 } else if (n == -EAGAIN)
477 else if(n == -EAGAIN) 508 printk(UM_KERN_CONT "No, enabling workaround\n");
478 printk("No, enabling workaround\n"); 509 else
479 else panic("tty_output : read failed, err = %d\n", n); 510 printk(UM_KERN_CONT "tty_output : read failed, err = %d\n", n);
480} 511}
481 512
482static void tty_close(int master, int slave) 513static void tty_close(int master, int slave)
483{ 514{
484 printk("Checking that host ptys support SIGIO on close..."); 515 printk(UM_KERN_INFO "Checking that host ptys support SIGIO on "
516 "close...");
485 517
486 close(slave); 518 close(slave);
487 if(got_sigio){ 519 if (got_sigio) {
488 printk("Yes\n"); 520 printk(UM_KERN_CONT "Yes\n");
489 pty_close_sigio = 1; 521 pty_close_sigio = 1;
490 } 522 } else
491 else printk("No, enabling workaround\n"); 523 printk(UM_KERN_CONT "No, enabling workaround\n");
492} 524}
493 525
494void __init check_sigio(void) 526void __init check_sigio(void)
495{ 527{
496 if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && 528 if ((access("/dev/ptmx", R_OK) < 0) &&
497 (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ 529 (access("/dev/ptyp0", R_OK) < 0)) {
498 printk("No pseudo-terminals available - skipping pty SIGIO " 530 printk(UM_KERN_WARNING "No pseudo-terminals available - "
499 "check\n"); 531 "skipping pty SIGIO check\n");
500 return; 532 return;
501 } 533 }
502 check_one_sigio(tty_output); 534 check_one_sigio(tty_output);
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index e9800b0b5689..0fb0cc8d4757 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -9,11 +9,47 @@
9#include <errno.h> 9#include <errno.h>
10#include <signal.h> 10#include <signal.h>
11#include <strings.h> 11#include <strings.h>
12#include "as-layout.h"
13#include "kern_util.h"
12#include "os.h" 14#include "os.h"
13#include "sysdep/barrier.h" 15#include "sysdep/barrier.h"
14#include "sysdep/sigcontext.h" 16#include "sysdep/sigcontext.h"
15#include "user.h" 17#include "user.h"
16 18
19/* Copied from linux/compiler-gcc.h since we can't include it directly */
20#define barrier() __asm__ __volatile__("": : :"memory")
21
22void (*sig_info[NSIG])(int, struct uml_pt_regs *) = {
23 [SIGTRAP] = relay_signal,
24 [SIGFPE] = relay_signal,
25 [SIGILL] = relay_signal,
26 [SIGWINCH] = winch,
27 [SIGBUS] = bus_handler,
28 [SIGSEGV] = segv_handler,
29 [SIGIO] = sigio_handler,
30 [SIGVTALRM] = timer_handler };
31
32static void sig_handler_common(int sig, struct sigcontext *sc)
33{
34 struct uml_pt_regs r;
35 int save_errno = errno;
36
37 r.is_user = 0;
38 if (sig == SIGSEGV) {
39 /* For segfaults, we want the data from the sigcontext. */
40 copy_sc(&r, sc);
41 GET_FAULTINFO_FROM_SC(r.faultinfo, sc);
42 }
43
44 /* enable signals if sig isn't IRQ signal */
45 if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM))
46 unblock_signals();
47
48 (*sig_info[sig])(sig, &r);
49
50 errno = save_errno;
51}
52
17/* 53/*
18 * These are the asynchronous signals. SIGPROF is excluded because we want to 54 * These are the asynchronous signals. SIGPROF is excluded because we want to
19 * be able to profile all of UML, not just the non-critical sections. If 55 * be able to profile all of UML, not just the non-critical sections. If
@@ -26,13 +62,8 @@
26#define SIGVTALRM_BIT 1 62#define SIGVTALRM_BIT 1
27#define SIGVTALRM_MASK (1 << SIGVTALRM_BIT) 63#define SIGVTALRM_MASK (1 << SIGVTALRM_BIT)
28 64
29/* 65static int signals_enabled;
30 * These are used by both the signal handlers and 66static unsigned int signals_pending;
31 * block/unblock_signals. I don't want modifications cached in a
32 * register - they must go straight to memory.
33 */
34static volatile int signals_enabled = 1;
35static volatile int pending = 0;
36 67
37void sig_handler(int sig, struct sigcontext *sc) 68void sig_handler(int sig, struct sigcontext *sc)
38{ 69{
@@ -40,13 +71,13 @@ void sig_handler(int sig, struct sigcontext *sc)
40 71
41 enabled = signals_enabled; 72 enabled = signals_enabled;
42 if (!enabled && (sig == SIGIO)) { 73 if (!enabled && (sig == SIGIO)) {
43 pending |= SIGIO_MASK; 74 signals_pending |= SIGIO_MASK;
44 return; 75 return;
45 } 76 }
46 77
47 block_signals(); 78 block_signals();
48 79
49 sig_handler_common_skas(sig, sc); 80 sig_handler_common(sig, sc);
50 81
51 set_signals(enabled); 82 set_signals(enabled);
52} 83}
@@ -68,7 +99,7 @@ void alarm_handler(int sig, struct sigcontext *sc)
68 99
69 enabled = signals_enabled; 100 enabled = signals_enabled;
70 if (!signals_enabled) { 101 if (!signals_enabled) {
71 pending |= SIGVTALRM_MASK; 102 signals_pending |= SIGVTALRM_MASK;
72 return; 103 return;
73 } 104 }
74 105
@@ -94,16 +125,6 @@ void set_sigstack(void *sig_stack, int size)
94 panic("enabling signal stack failed, errno = %d\n", errno); 125 panic("enabling signal stack failed, errno = %d\n", errno);
95} 126}
96 127
97void remove_sigstack(void)
98{
99 stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE,
100 .ss_sp = NULL,
101 .ss_size = 0 });
102
103 if (sigaltstack(&stack, NULL) != 0)
104 panic("disabling signal stack failed, errno = %d\n", errno);
105}
106
107void (*handlers[_NSIG])(int sig, struct sigcontext *sc); 128void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
108 129
109void handle_signal(int sig, struct sigcontext *sc) 130void handle_signal(int sig, struct sigcontext *sc)
@@ -166,6 +187,9 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
166 sigaddset(&action.sa_mask, mask); 187 sigaddset(&action.sa_mask, mask);
167 va_end(ap); 188 va_end(ap);
168 189
190 if (sig == SIGSEGV)
191 flags |= SA_NODEFER;
192
169 action.sa_flags = flags; 193 action.sa_flags = flags;
170 action.sa_restorer = NULL; 194 action.sa_restorer = NULL;
171 if (sigaction(sig, &action, NULL) < 0) 195 if (sigaction(sig, &action, NULL) < 0)
@@ -179,12 +203,14 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
179 203
180int change_sig(int signal, int on) 204int change_sig(int signal, int on)
181{ 205{
182 sigset_t sigset, old; 206 sigset_t sigset;
183 207
184 sigemptyset(&sigset); 208 sigemptyset(&sigset);
185 sigaddset(&sigset, signal); 209 sigaddset(&sigset, signal);
186 sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old); 210 if (sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, NULL) < 0)
187 return !sigismember(&old, signal); 211 return -errno;
212
213 return 0;
188} 214}
189 215
190void block_signals(void) 216void block_signals(void)
@@ -196,7 +222,7 @@ void block_signals(void)
196 * This might matter if gcc figures out how to inline this and 222 * This might matter if gcc figures out how to inline this and
197 * decides to shuffle this code into the caller. 223 * decides to shuffle this code into the caller.
198 */ 224 */
199 mb(); 225 barrier();
200} 226}
201 227
202void unblock_signals(void) 228void unblock_signals(void)
@@ -209,36 +235,26 @@ void unblock_signals(void)
209 /* 235 /*
210 * We loop because the IRQ handler returns with interrupts off. So, 236 * We loop because the IRQ handler returns with interrupts off. So,
211 * interrupts may have arrived and we need to re-enable them and 237 * interrupts may have arrived and we need to re-enable them and
212 * recheck pending. 238 * recheck signals_pending.
213 */ 239 */
214 while(1) { 240 while(1) {
215 /* 241 /*
216 * Save and reset save_pending after enabling signals. This 242 * Save and reset save_pending after enabling signals. This
217 * way, pending won't be changed while we're reading it. 243 * way, signals_pending won't be changed while we're reading it.
218 */ 244 */
219 signals_enabled = 1; 245 signals_enabled = 1;
220 246
221 /* 247 /*
222 * Setting signals_enabled and reading pending must 248 * Setting signals_enabled and reading signals_pending must
223 * happen in this order. 249 * happen in this order.
224 */ 250 */
225 mb(); 251 barrier();
226 252
227 save_pending = pending; 253 save_pending = signals_pending;
228 if (save_pending == 0) { 254 if (save_pending == 0)
229 /*
230 * This must return with signals enabled, so
231 * this barrier ensures that writes are
232 * flushed out before the return. This might
233 * matter if gcc figures out how to inline
234 * this (unlikely, given its size) and decides
235 * to shuffle this code into the caller.
236 */
237 mb();
238 return; 255 return;
239 }
240 256
241 pending = 0; 257 signals_pending = 0;
242 258
243 /* 259 /*
244 * We have pending interrupts, so disable signals, as the 260 * We have pending interrupts, so disable signals, as the
@@ -254,7 +270,7 @@ void unblock_signals(void)
254 * back here. 270 * back here.
255 */ 271 */
256 if (save_pending & SIGIO_MASK) 272 if (save_pending & SIGIO_MASK)
257 sig_handler_common_skas(SIGIO, NULL); 273 sig_handler_common(SIGIO, NULL);
258 274
259 if (save_pending & SIGVTALRM_MASK) 275 if (save_pending & SIGVTALRM_MASK)
260 real_alarm_handler(NULL); 276 real_alarm_handler(NULL);
diff --git a/arch/um/os-Linux/skas/Makefile b/arch/um/os-Linux/skas/Makefile
index 5fd8d4dad66a..d2ea3409e072 100644
--- a/arch/um/os-Linux/skas/Makefile
+++ b/arch/um/os-Linux/skas/Makefile
@@ -1,10 +1,10 @@
1# 1#
2# Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com) 2# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-y := mem.o process.o trap.o 6obj-y := mem.o process.o
7 7
8USER_OBJS := mem.o process.o trap.o 8USER_OBJS := $(obj-y)
9 9
10include arch/um/scripts/Makefile.rules 10include arch/um/scripts/Makefile.rules
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index e8b7a97e83d3..d36c89c24a45 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -15,6 +15,7 @@
15#include "as-layout.h" 15#include "as-layout.h"
16#include "chan_user.h" 16#include "chan_user.h"
17#include "kern_constants.h" 17#include "kern_constants.h"
18#include "kern_util.h"
18#include "mem.h" 19#include "mem.h"
19#include "os.h" 20#include "os.h"
20#include "process.h" 21#include "process.h"
@@ -37,27 +38,27 @@ int is_skas_winch(int pid, int fd, void *data)
37 38
38static int ptrace_dump_regs(int pid) 39static int ptrace_dump_regs(int pid)
39{ 40{
40 unsigned long regs[MAX_REG_NR]; 41 unsigned long regs[MAX_REG_NR];
41 int i; 42 int i;
42 43
43 if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) 44 if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
44 return -errno; 45 return -errno;
45 46
46 printk(UM_KERN_ERR "Stub registers -\n"); 47 printk(UM_KERN_ERR "Stub registers -\n");
47 for (i = 0; i < ARRAY_SIZE(regs); i++) 48 for (i = 0; i < ARRAY_SIZE(regs); i++)
48 printk(UM_KERN_ERR "\t%d - %lx\n", i, regs[i]); 49 printk(UM_KERN_ERR "\t%d - %lx\n", i, regs[i]);
49 50
50 return 0; 51 return 0;
51} 52}
52 53
53/* 54/*
54 * Signals that are OK to receive in the stub - we'll just continue it. 55 * Signals that are OK to receive in the stub - we'll just continue it.
55 * SIGWINCH will happen when UML is inside a detached screen. 56 * SIGWINCH will happen when UML is inside a detached screen.
56 */ 57 */
57#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH)) 58#define STUB_SIG_MASK (1 << SIGVTALRM)
58 59
59/* Signals that the stub will finish with - anything else is an error */ 60/* Signals that the stub will finish with - anything else is an error */
60#define STUB_DONE_MASK ((1 << SIGUSR1) | (1 << SIGTRAP)) 61#define STUB_DONE_MASK (1 << SIGTRAP)
61 62
62void wait_stub_done(int pid) 63void wait_stub_done(int pid)
63{ 64{
@@ -72,9 +73,11 @@ void wait_stub_done(int pid)
72 break; 73 break;
73 74
74 err = ptrace(PTRACE_CONT, pid, 0, 0); 75 err = ptrace(PTRACE_CONT, pid, 0, 0);
75 if (err) 76 if (err) {
76 panic("wait_stub_done : continue failed, errno = %d\n", 77 printk(UM_KERN_ERR "wait_stub_done : continue failed, "
77 errno); 78 "errno = %d\n", errno);
79 fatal_sigsegv();
80 }
78 } 81 }
79 82
80 if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) 83 if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0)
@@ -85,8 +88,10 @@ bad_wait:
85 if (err) 88 if (err)
86 printk(UM_KERN_ERR "Failed to get registers from stub, " 89 printk(UM_KERN_ERR "Failed to get registers from stub, "
87 "errno = %d\n", -err); 90 "errno = %d\n", -err);
88 panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, " 91 printk(UM_KERN_ERR "wait_stub_done : failed to wait for SIGTRAP, "
89 "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status); 92 "pid = %d, n = %d, errno = %d, status = 0x%x\n", pid, n, errno,
93 status);
94 fatal_sigsegv();
90} 95}
91 96
92extern unsigned long current_stub_stack(void); 97extern unsigned long current_stub_stack(void);
@@ -97,9 +102,11 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
97 102
98 if (ptrace_faultinfo) { 103 if (ptrace_faultinfo) {
99 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); 104 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
100 if (err) 105 if (err) {
101 panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " 106 printk(UM_KERN_ERR "get_skas_faultinfo - "
102 "errno = %d\n", errno); 107 "PTRACE_FAULTINFO failed, errno = %d\n", errno);
108 fatal_sigsegv();
109 }
103 110
104 /* Special handling for i386, which has different structs */ 111 /* Special handling for i386, which has different structs */
105 if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo)) 112 if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
@@ -109,9 +116,11 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
109 } 116 }
110 else { 117 else {
111 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); 118 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
112 if (err) 119 if (err) {
113 panic("Failed to continue stub, pid = %d, errno = %d\n", 120 printk(UM_KERN_ERR "Failed to continue stub, pid = %d, "
114 pid, errno); 121 "errno = %d\n", pid, errno);
122 fatal_sigsegv();
123 }
115 wait_stub_done(pid); 124 wait_stub_done(pid);
116 125
117 /* 126 /*
@@ -137,6 +146,9 @@ static void handle_trap(int pid, struct uml_pt_regs *regs,
137{ 146{
138 int err, status; 147 int err, status;
139 148
149 if ((UPT_IP(regs) >= STUB_START) && (UPT_IP(regs) < STUB_END))
150 fatal_sigsegv();
151
140 /* Mark this as a syscall */ 152 /* Mark this as a syscall */
141 UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->gp); 153 UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->gp);
142 154
@@ -144,25 +156,31 @@ static void handle_trap(int pid, struct uml_pt_regs *regs,
144 { 156 {
145 err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, 157 err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
146 __NR_getpid); 158 __NR_getpid);
147 if (err < 0) 159 if (err < 0) {
148 panic("handle_trap - nullifying syscall failed, " 160 printk(UM_KERN_ERR "handle_trap - nullifying syscall "
149 "errno = %d\n", errno); 161 "failed, errno = %d\n", errno);
162 fatal_sigsegv();
163 }
150 164
151 err = ptrace(PTRACE_SYSCALL, pid, 0, 0); 165 err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
152 if (err < 0) 166 if (err < 0) {
153 panic("handle_trap - continuing to end of syscall " 167 printk(UM_KERN_ERR "handle_trap - continuing to end of "
154 "failed, errno = %d\n", errno); 168 "syscall failed, errno = %d\n", errno);
169 fatal_sigsegv();
170 }
155 171
156 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL)); 172 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL));
157 if ((err < 0) || !WIFSTOPPED(status) || 173 if ((err < 0) || !WIFSTOPPED(status) ||
158 (WSTOPSIG(status) != SIGTRAP + 0x80)) { 174 (WSTOPSIG(status) != SIGTRAP + 0x80)) {
159 err = ptrace_dump_regs(pid); 175 err = ptrace_dump_regs(pid);
160 if (err) 176 if (err)
161 printk(UM_KERN_ERR "Failed to get registers " 177 printk(UM_KERN_ERR "Failed to get registers "
162 "from process, errno = %d\n", -err); 178 "from process, errno = %d\n", -err);
163 panic("handle_trap - failed to wait at end of syscall, " 179 printk(UM_KERN_ERR "handle_trap - failed to wait at "
164 "errno = %d, status = %d\n", errno, status); 180 "end of syscall, errno = %d, status = %d\n",
165 } 181 errno, status);
182 fatal_sigsegv();
183 }
166 } 184 }
167 185
168 handle_syscall(regs); 186 handle_syscall(regs);
@@ -178,10 +196,13 @@ static int userspace_tramp(void *stack)
178 ptrace(PTRACE_TRACEME, 0, 0, 0); 196 ptrace(PTRACE_TRACEME, 0, 0, 0);
179 197
180 signal(SIGTERM, SIG_DFL); 198 signal(SIGTERM, SIG_DFL);
199 signal(SIGWINCH, SIG_IGN);
181 err = set_interval(); 200 err = set_interval();
182 if (err) 201 if (err) {
183 panic("userspace_tramp - setting timer failed, errno = %d\n", 202 printk(UM_KERN_ERR "userspace_tramp - setting timer failed, "
184 err); 203 "errno = %d\n", err);
204 exit(1);
205 }
185 206
186 if (!proc_mm) { 207 if (!proc_mm) {
187 /* 208 /*
@@ -221,16 +242,14 @@ static int userspace_tramp(void *stack)
221 242
222 set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE); 243 set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
223 sigemptyset(&sa.sa_mask); 244 sigemptyset(&sa.sa_mask);
224 sigaddset(&sa.sa_mask, SIGIO); 245 sa.sa_flags = SA_ONSTACK | SA_NODEFER;
225 sigaddset(&sa.sa_mask, SIGWINCH);
226 sigaddset(&sa.sa_mask, SIGVTALRM);
227 sigaddset(&sa.sa_mask, SIGUSR1);
228 sa.sa_flags = SA_ONSTACK;
229 sa.sa_handler = (void *) v; 246 sa.sa_handler = (void *) v;
230 sa.sa_restorer = NULL; 247 sa.sa_restorer = NULL;
231 if (sigaction(SIGSEGV, &sa, NULL) < 0) 248 if (sigaction(SIGSEGV, &sa, NULL) < 0) {
232 panic("userspace_tramp - setting SIGSEGV handler " 249 printk(UM_KERN_ERR "userspace_tramp - setting SIGSEGV "
233 "failed - errno = %d\n", errno); 250 "handler failed - errno = %d\n", errno);
251 exit(1);
252 }
234 } 253 }
235 254
236 kill(os_getpid(), SIGSTOP); 255 kill(os_getpid(), SIGSTOP);
@@ -246,13 +265,18 @@ int start_userspace(unsigned long stub_stack)
246{ 265{
247 void *stack; 266 void *stack;
248 unsigned long sp; 267 unsigned long sp;
249 int pid, status, n, flags; 268 int pid, status, n, flags, err;
250 269
251 stack = mmap(NULL, UM_KERN_PAGE_SIZE, 270 stack = mmap(NULL, UM_KERN_PAGE_SIZE,
252 PROT_READ | PROT_WRITE | PROT_EXEC, 271 PROT_READ | PROT_WRITE | PROT_EXEC,
253 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 272 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
254 if (stack == MAP_FAILED) 273 if (stack == MAP_FAILED) {
255 panic("start_userspace : mmap failed, errno = %d", errno); 274 err = -errno;
275 printk(UM_KERN_ERR "start_userspace : mmap failed, "
276 "errno = %d\n", errno);
277 return err;
278 }
279
256 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); 280 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
257 281
258 flags = CLONE_FILES; 282 flags = CLONE_FILES;
@@ -262,29 +286,50 @@ int start_userspace(unsigned long stub_stack)
262 flags |= SIGCHLD; 286 flags |= SIGCHLD;
263 287
264 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); 288 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
265 if (pid < 0) 289 if (pid < 0) {
266 panic("start_userspace : clone failed, errno = %d", errno); 290 err = -errno;
291 printk(UM_KERN_ERR "start_userspace : clone failed, "
292 "errno = %d\n", errno);
293 return err;
294 }
267 295
268 do { 296 do {
269 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL)); 297 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL));
270 if (n < 0) 298 if (n < 0) {
271 panic("start_userspace : wait failed, errno = %d", 299 err = -errno;
272 errno); 300 printk(UM_KERN_ERR "start_userspace : wait failed, "
301 "errno = %d\n", errno);
302 goto out_kill;
303 }
273 } while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM)); 304 } while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
274 305
275 if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) 306 if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) {
276 panic("start_userspace : expected SIGSTOP, got status = %d", 307 err = -EINVAL;
277 status); 308 printk(UM_KERN_ERR "start_userspace : expected SIGSTOP, got "
309 "status = %d\n", status);
310 goto out_kill;
311 }
278 312
279 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, 313 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
280 (void *) PTRACE_O_TRACESYSGOOD) < 0) 314 (void *) PTRACE_O_TRACESYSGOOD) < 0) {
281 panic("start_userspace : PTRACE_OLDSETOPTIONS failed, " 315 err = -errno;
282 "errno = %d\n", errno); 316 printk(UM_KERN_ERR "start_userspace : PTRACE_OLDSETOPTIONS "
317 "failed, errno = %d\n", errno);
318 goto out_kill;
319 }
283 320
284 if (munmap(stack, UM_KERN_PAGE_SIZE) < 0) 321 if (munmap(stack, UM_KERN_PAGE_SIZE) < 0) {
285 panic("start_userspace : munmap failed, errno = %d\n", errno); 322 err = -errno;
323 printk(UM_KERN_ERR "start_userspace : munmap failed, "
324 "errno = %d\n", errno);
325 goto out_kill;
326 }
286 327
287 return pid; 328 return pid;
329
330 out_kill:
331 os_kill_ptraced_process(pid, 1);
332 return err;
288} 333}
289 334
290void userspace(struct uml_pt_regs *regs) 335void userspace(struct uml_pt_regs *regs)
@@ -302,7 +347,16 @@ void userspace(struct uml_pt_regs *regs)
302 nsecs += os_nsecs(); 347 nsecs += os_nsecs();
303 348
304 while (1) { 349 while (1) {
305 restore_registers(pid, regs); 350 /*
351 * This can legitimately fail if the process loads a
352 * bogus value into a segment register. It will
353 * segfault and PTRACE_GETREGS will read that value
354 * out of the process. However, PTRACE_SETREGS will
355 * fail. In this case, there is nothing to do but
356 * just kill the process.
357 */
358 if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp))
359 fatal_sigsegv();
306 360
307 /* Now we set local_using_sysemu to be used for one loop */ 361 /* Now we set local_using_sysemu to be used for one loop */
308 local_using_sysemu = get_using_sysemu(); 362 local_using_sysemu = get_using_sysemu();
@@ -310,19 +364,26 @@ void userspace(struct uml_pt_regs *regs)
310 op = SELECT_PTRACE_OPERATION(local_using_sysemu, 364 op = SELECT_PTRACE_OPERATION(local_using_sysemu,
311 singlestepping(NULL)); 365 singlestepping(NULL));
312 366
313 err = ptrace(op, pid, 0, 0); 367 if (ptrace(op, pid, 0, 0)) {
314 if (err) 368 printk(UM_KERN_ERR "userspace - ptrace continue "
315 panic("userspace - could not resume userspace process, " 369 "failed, op = %d, errno = %d\n", op, errno);
316 "pid=%d, ptrace operation = %d, errno = %d\n", 370 fatal_sigsegv();
317 pid, op, errno); 371 }
318 372
319 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL)); 373 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED | __WALL));
320 if (err < 0) 374 if (err < 0) {
321 panic("userspace - waitpid failed, errno = %d\n", 375 printk(UM_KERN_ERR "userspace - wait failed, "
322 errno); 376 "errno = %d\n", errno);
377 fatal_sigsegv();
378 }
323 379
324 regs->is_user = 1; 380 regs->is_user = 1;
325 save_registers(pid, regs); 381 if (ptrace(PTRACE_GETREGS, pid, 0, regs->gp)) {
382 printk(UM_KERN_ERR "userspace - PTRACE_GETREGS failed, "
383 "errno = %d\n", errno);
384 fatal_sigsegv();
385 }
386
326 UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ 387 UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
327 388
328 if (WIFSTOPPED(status)) { 389 if (WIFSTOPPED(status)) {
@@ -345,7 +406,7 @@ void userspace(struct uml_pt_regs *regs)
345 break; 406 break;
346 case SIGVTALRM: 407 case SIGVTALRM:
347 now = os_nsecs(); 408 now = os_nsecs();
348 if(now < nsecs) 409 if (now < nsecs)
349 break; 410 break;
350 block_signals(); 411 block_signals();
351 (*sig_info[sig])(sig, regs); 412 (*sig_info[sig])(sig, regs);
@@ -368,6 +429,7 @@ void userspace(struct uml_pt_regs *regs)
368 default: 429 default:
369 printk(UM_KERN_ERR "userspace - child stopped " 430 printk(UM_KERN_ERR "userspace - child stopped "
370 "with signal %d\n", sig); 431 "with signal %d\n", sig);
432 fatal_sigsegv();
371 } 433 }
372 pid = userspace_pid[0]; 434 pid = userspace_pid[0];
373 interrupt_end(); 435 interrupt_end();
@@ -419,9 +481,12 @@ int copy_context_skas0(unsigned long new_stack, int pid)
419 .it_interval = tv }) }); 481 .it_interval = tv }) });
420 482
421 err = ptrace_setregs(pid, thread_regs); 483 err = ptrace_setregs(pid, thread_regs);
422 if (err < 0) 484 if (err < 0) {
423 panic("copy_context_skas0 : PTRACE_SETREGS failed, " 485 err = -errno;
424 "pid = %d, errno = %d\n", pid, -err); 486 printk(UM_KERN_ERR "copy_context_skas0 : PTRACE_SETREGS "
487 "failed, pid = %d, errno = %d\n", pid, -err);
488 return err;
489 }
425 490
426 /* set a well known return code for detection of child write failure */ 491 /* set a well known return code for detection of child write failure */
427 child_data->err = 12345678; 492 child_data->err = 12345678;
@@ -431,31 +496,47 @@ int copy_context_skas0(unsigned long new_stack, int pid)
431 * parent's stack, and check, if bad result. 496 * parent's stack, and check, if bad result.
432 */ 497 */
433 err = ptrace(PTRACE_CONT, pid, 0, 0); 498 err = ptrace(PTRACE_CONT, pid, 0, 0);
434 if (err) 499 if (err) {
435 panic("Failed to continue new process, pid = %d, " 500 err = -errno;
436 "errno = %d\n", pid, errno); 501 printk(UM_KERN_ERR "Failed to continue new process, pid = %d, "
502 "errno = %d\n", pid, errno);
503 return err;
504 }
505
437 wait_stub_done(pid); 506 wait_stub_done(pid);
438 507
439 pid = data->err; 508 pid = data->err;
440 if (pid < 0) 509 if (pid < 0) {
441 panic("copy_context_skas0 - stub-parent reports error %d\n", 510 printk(UM_KERN_ERR "copy_context_skas0 - stub-parent reports "
442 -pid); 511 "error %d\n", -pid);
512 return pid;
513 }
443 514
444 /* 515 /*
445 * Wait, until child has finished too: read child's result from 516 * Wait, until child has finished too: read child's result from
446 * child's stack and check it. 517 * child's stack and check it.
447 */ 518 */
448 wait_stub_done(pid); 519 wait_stub_done(pid);
449 if (child_data->err != STUB_DATA) 520 if (child_data->err != STUB_DATA) {
450 panic("copy_context_skas0 - stub-child reports error %ld\n", 521 printk(UM_KERN_ERR "copy_context_skas0 - stub-child reports "
451 child_data->err); 522 "error %ld\n", child_data->err);
523 err = child_data->err;
524 goto out_kill;
525 }
452 526
453 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, 527 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
454 (void *)PTRACE_O_TRACESYSGOOD) < 0) 528 (void *)PTRACE_O_TRACESYSGOOD) < 0) {
455 panic("copy_context_skas0 : PTRACE_OLDSETOPTIONS failed, " 529 err = -errno;
456 "errno = %d\n", errno); 530 printk(UM_KERN_ERR "copy_context_skas0 : PTRACE_OLDSETOPTIONS "
531 "failed, errno = %d\n", errno);
532 goto out_kill;
533 }
457 534
458 return pid; 535 return pid;
536
537 out_kill:
538 os_kill_ptraced_process(pid, 1);
539 return err;
459} 540}
460 541
461/* 542/*
@@ -463,8 +544,8 @@ int copy_context_skas0(unsigned long new_stack, int pid)
463 * available. Opening /proc/mm creates a new mm_context, which lacks 544 * available. Opening /proc/mm creates a new mm_context, which lacks
464 * the stub-pages. Thus, we map them using /proc/mm-fd 545 * the stub-pages. Thus, we map them using /proc/mm-fd
465 */ 546 */
466void map_stub_pages(int fd, unsigned long code, 547int map_stub_pages(int fd, unsigned long code, unsigned long data,
467 unsigned long data, unsigned long stack) 548 unsigned long stack)
468{ 549{
469 struct proc_mm_op mmop; 550 struct proc_mm_op mmop;
470 int n; 551 int n;
@@ -488,8 +569,9 @@ void map_stub_pages(int fd, unsigned long code,
488 printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, " 569 printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, "
489 "offset = %llx\n", code, code_fd, 570 "offset = %llx\n", code, code_fd,
490 (unsigned long long) code_offset); 571 (unsigned long long) code_offset);
491 panic("map_stub_pages : /proc/mm map for code failed, " 572 printk(UM_KERN_ERR "map_stub_pages : /proc/mm map for code "
492 "err = %d\n", n); 573 "failed, err = %d\n", n);
574 return -n;
493 } 575 }
494 576
495 if (stack) { 577 if (stack) {
@@ -507,10 +589,15 @@ void map_stub_pages(int fd, unsigned long code,
507 .offset = map_offset 589 .offset = map_offset
508 } } }); 590 } } });
509 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); 591 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
510 if (n != sizeof(mmop)) 592 if (n != sizeof(mmop)) {
511 panic("map_stub_pages : /proc/mm map for data failed, " 593 n = errno;
512 "err = %d\n", errno); 594 printk(UM_KERN_ERR "map_stub_pages : /proc/mm map for "
595 "data failed, err = %d\n", n);
596 return -n;
597 }
513 } 598 }
599
600 return 0;
514} 601}
515 602
516void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)) 603void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
@@ -571,7 +658,9 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
571 kmalloc_ok = 0; 658 kmalloc_ok = 0;
572 return 1; 659 return 1;
573 default: 660 default:
574 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); 661 printk(UM_KERN_ERR "Bad sigsetjmp return in "
662 "start_idle_thread - %d\n", n);
663 fatal_sigsegv();
575 } 664 }
576 longjmp(*switch_buf, 1); 665 longjmp(*switch_buf, 1);
577} 666}
@@ -614,9 +703,11 @@ void __switch_mm(struct mm_id *mm_idp)
614 if (proc_mm) { 703 if (proc_mm) {
615 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, 704 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
616 mm_idp->u.mm_fd); 705 mm_idp->u.mm_fd);
617 if (err) 706 if (err) {
618 panic("__switch_mm - PTRACE_SWITCH_MM failed, " 707 printk(UM_KERN_ERR "__switch_mm - PTRACE_SWITCH_MM "
619 "errno = %d\n", errno); 708 "failed, errno = %d\n", errno);
709 fatal_sigsegv();
710 }
620 } 711 }
621 else userspace_pid[0] = mm_idp->u.pid; 712 else userspace_pid[0] = mm_idp->u.pid;
622} 713}
diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c
deleted file mode 100644
index 3b1b9244f468..000000000000
--- a/arch/um/os-Linux/skas/trap.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
4 */
5
6#if 0
7#include "kern_util.h"
8#include "skas.h"
9#include "ptrace_user.h"
10#include "sysdep/ptrace_user.h"
11#endif
12
13#include <errno.h>
14#include <signal.h>
15#include "sysdep/ptrace.h"
16#include "kern_constants.h"
17#include "as-layout.h"
18#include "os.h"
19#include "sigcontext.h"
20#include "task.h"
21
22static struct uml_pt_regs ksig_regs[UM_NR_CPUS];
23
24void sig_handler_common_skas(int sig, void *sc_ptr)
25{
26 struct sigcontext *sc = sc_ptr;
27 struct uml_pt_regs *r;
28 void (*handler)(int, struct uml_pt_regs *);
29 int save_user, save_errno = errno;
30
31 /*
32 * This is done because to allow SIGSEGV to be delivered inside a SEGV
33 * handler. This can happen in copy_user, and if SEGV is disabled,
34 * the process will die.
35 * XXX Figure out why this is better than SA_NODEFER
36 */
37 if (sig == SIGSEGV) {
38 change_sig(SIGSEGV, 1);
39 /*
40 * For segfaults, we want the data from the
41 * sigcontext. In this case, we don't want to mangle
42 * the process registers, so use a static set of
43 * registers. For other signals, the process
44 * registers are OK.
45 */
46 r = &ksig_regs[cpu()];
47 copy_sc(r, sc_ptr);
48 }
49 else r = TASK_REGS(get_current());
50
51 save_user = r->is_user;
52 r->is_user = 0;
53 if ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
54 (sig == SIGILL) || (sig == SIGTRAP))
55 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
56
57 change_sig(SIGUSR1, 1);
58
59 handler = sig_info[sig];
60
61 /* unblock SIGVTALRM, SIGIO if sig isn't IRQ signal */
62 if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM))
63 unblock_signals();
64
65 handler(sig, r);
66
67 errno = save_errno;
68 r->is_user = save_user;
69}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 7b81f6c08a5e..b616e15638fb 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -60,10 +60,11 @@ static int ptrace_child(void)
60 * the UML code itself. 60 * the UML code itself.
61 */ 61 */
62 ret = 2; 62 ret = 2;
63 _exit(ret); 63
64 exit(ret);
64} 65}
65 66
66static void fatal_perror(char *str) 67static void fatal_perror(const char *str)
67{ 68{
68 perror(str); 69 perror(str);
69 exit(1); 70 exit(1);
@@ -341,6 +342,8 @@ static void __init check_coredump_limit(void)
341 342
342void __init os_early_checks(void) 343void __init os_early_checks(void)
343{ 344{
345 int pid;
346
344 /* Print out the core dump limits early */ 347 /* Print out the core dump limits early */
345 check_coredump_limit(); 348 check_coredump_limit();
346 349
@@ -350,6 +353,11 @@ void __init os_early_checks(void)
350 * kernel is running. 353 * kernel is running.
351 */ 354 */
352 check_tmpexec(); 355 check_tmpexec();
356
357 pid = start_ptraced_child();
358 if (init_registers(pid))
359 fatal("Failed to initialize default registers");
360 stop_ptraced_child(pid, 1, 1);
353} 361}
354 362
355static int __init noprocmm_cmd_param(char *str, int* add) 363static int __init noprocmm_cmd_param(char *str, int* add)
@@ -411,7 +419,6 @@ static inline void check_skas3_ptrace_faultinfo(void)
411 non_fatal("found\n"); 419 non_fatal("found\n");
412 } 420 }
413 421
414 init_registers(pid);
415 stop_ptraced_child(pid, 1, 1); 422 stop_ptraced_child(pid, 1, 1);
416} 423}
417 424
@@ -466,7 +473,7 @@ static inline void check_skas3_proc_mm(void)
466 else non_fatal("found\n"); 473 else non_fatal("found\n");
467} 474}
468 475
469int can_do_skas(void) 476void can_do_skas(void)
470{ 477{
471 non_fatal("Checking for the skas3 patch in the host:\n"); 478 non_fatal("Checking for the skas3 patch in the host:\n");
472 479
@@ -476,8 +483,6 @@ int can_do_skas(void)
476 483
477 if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt) 484 if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
478 skas_needs_stub = 1; 485 skas_needs_stub = 1;
479
480 return 1;
481} 486}
482 487
483int __init parse_iomem(char *str, int *add) 488int __init parse_iomem(char *str, int *add)
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
deleted file mode 100644
index 2a1c9843e32e..000000000000
--- a/arch/um/os-Linux/trap.c
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
4 */
5
6#include <signal.h>
7#include "os.h"
8#include "sysdep/ptrace.h"
9
10/* Initialized from linux_main() */
11void (*sig_info[NSIG])(int, struct uml_pt_regs *);
12
13void os_fill_handlinfo(struct kern_handlers h)
14{
15 sig_info[SIGTRAP] = h.relay_signal;
16 sig_info[SIGFPE] = h.relay_signal;
17 sig_info[SIGILL] = h.relay_signal;
18 sig_info[SIGWINCH] = h.winch;
19 sig_info[SIGBUS] = h.bus_handler;
20 sig_info[SIGSEGV] = h.page_fault;
21 sig_info[SIGIO] = h.sigio_handler;
22 sig_info[SIGVTALRM] = h.timer_handler;
23}
diff --git a/arch/um/os-Linux/tty.c b/arch/um/os-Linux/tty.c
index 4cfdd18ea1ef..b09ff66a77ee 100644
--- a/arch/um/os-Linux/tty.c
+++ b/arch/um/os-Linux/tty.c
@@ -1,13 +1,16 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdlib.h> 6#include <stdlib.h>
7#include <unistd.h>
7#include <errno.h> 8#include <errno.h>
9#include <fcntl.h>
10#include "kern_constants.h"
11#include "kern_util.h"
8#include "os.h" 12#include "os.h"
9#include "user.h" 13#include "user.h"
10#include "kern_util.h"
11 14
12struct grantpt_info { 15struct grantpt_info {
13 int fd; 16 int fd;
@@ -26,36 +29,34 @@ static void grantpt_cb(void *arg)
26int get_pty(void) 29int get_pty(void)
27{ 30{
28 struct grantpt_info info; 31 struct grantpt_info info;
29 int fd; 32 int fd, err;
30 33
31 fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0); 34 fd = open("/dev/ptmx", O_RDWR);
32 if(fd < 0){ 35 if (fd < 0) {
33 printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd); 36 err = -errno;
34 return(fd); 37 printk(UM_KERN_ERR "get_pty : Couldn't open /dev/ptmx - "
38 "err = %d\n", errno);
39 return err;
35 } 40 }
36 41
37 info.fd = fd; 42 info.fd = fd;
38 initial_thread_cb(grantpt_cb, &info); 43 initial_thread_cb(grantpt_cb, &info);
39 44
40 if(info.res < 0){ 45 if (info.res < 0) {
41 printk("get_pty : Couldn't grant pty - errno = %d\n", 46 err = -info.err;
42 -info.err); 47 printk(UM_KERN_ERR "get_pty : Couldn't grant pty - "
43 return(-1); 48 "errno = %d\n", -info.err);
49 goto out;
44 } 50 }
45 if(unlockpt(fd) < 0){ 51
46 printk("get_pty : Couldn't unlock pty - errno = %d\n", errno); 52 if (unlockpt(fd) < 0) {
47 return(-1); 53 err = -errno;
54 printk(UM_KERN_ERR "get_pty : Couldn't unlock pty - "
55 "errno = %d\n", errno);
56 goto out;
48 } 57 }
49 return(fd); 58 return fd;
59out:
60 close(fd);
61 return err;
50} 62}
51
52/*
53 * Overrides for Emacs so that we follow Linus's tabbing style.
54 * Emacs will notice this stuff at the end of the file and automatically
55 * adjust the settings for this buffer only. This must remain at the end
56 * of the file.
57 * ---------------------------------------------------------------------------
58 * Local variables:
59 * c-file-style: "linux"
60 * End:
61 */
diff --git a/arch/um/os-Linux/tty_log.c b/arch/um/os-Linux/tty_log.c
index d11a55baa6bd..cc648e6fd3a2 100644
--- a/arch/um/os-Linux/tty_log.c
+++ b/arch/um/os-Linux/tty_log.c
@@ -12,7 +12,6 @@
12#include <sys/time.h> 12#include <sys/time.h>
13#include "init.h" 13#include "init.h"
14#include "user.h" 14#include "user.h"
15#include "kern_util.h"
16#include "os.h" 15#include "os.h"
17 16
18#define TTY_LOG_DIR "./" 17#define TTY_LOG_DIR "./"
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index 3e058ce9ffb6..a6f31d476993 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -88,21 +88,6 @@ void setup_hostinfo(char *buf, int len)
88 host.release, host.version, host.machine); 88 host.release, host.version, host.machine);
89} 89}
90 90
91int setjmp_wrapper(void (*proc)(void *, void *), ...)
92{
93 va_list args;
94 jmp_buf buf;
95 int n;
96
97 n = UML_SETJMP(&buf);
98 if(n == 0){
99 va_start(args, proc);
100 (*proc)(&buf, &args);
101 }
102 va_end(args);
103 return n;
104}
105
106void os_dump_core(void) 91void os_dump_core(void)
107{ 92{
108 int pid; 93 int pid;
diff --git a/arch/um/sys-i386/bug.c b/arch/um/sys-i386/bug.c
index a4360b5207db..8d4f273f1219 100644
--- a/arch/um/sys-i386/bug.c
+++ b/arch/um/sys-i386/bug.c
@@ -4,6 +4,7 @@
4 */ 4 */
5 5
6#include <linux/uaccess.h> 6#include <linux/uaccess.h>
7#include <asm/errno.h>
7 8
8/* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because 9/* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because
9 * that's not relevant in skas mode. 10 * that's not relevant in skas mode.
diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
index 806895d73bcc..a74442d13762 100644
--- a/arch/um/sys-i386/bugs.c
+++ b/arch/um/sys-i386/bugs.c
@@ -3,171 +3,47 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <errno.h>
7#include <signal.h> 6#include <signal.h>
8#include <string.h>
9#include "kern_constants.h" 7#include "kern_constants.h"
10#include "os.h" 8#include "kern_util.h"
9#include "longjmp.h"
11#include "task.h" 10#include "task.h"
12#include "user.h" 11#include "user.h"
13 12#include "sysdep/ptrace.h"
14#define MAXTOKEN 64
15 13
16/* Set during early boot */ 14/* Set during early boot */
17int host_has_cmov = 1; 15int host_has_cmov = 1;
18int host_has_xmm = 0; 16static jmp_buf cmov_test_return;
19 17
20static char token(int fd, char *buf, int len, char stop) 18static void cmov_sigill_test_handler(int sig)
21{ 19{
22 int n; 20 host_has_cmov = 0;
23 char *ptr, *end, c; 21 longjmp(cmov_test_return, 1);
24
25 ptr = buf;
26 end = &buf[len];
27 do {
28 n = os_read_file(fd, ptr, sizeof(*ptr));
29 c = *ptr++;
30 if (n != sizeof(*ptr)) {
31 if (n == 0)
32 return 0;
33 printk(UM_KERN_ERR "Reading /proc/cpuinfo failed, "
34 "err = %d\n", -n);
35 if (n < 0)
36 return n;
37 else return -EIO;
38 }
39 } while ((c != '\n') && (c != stop) && (ptr < end));
40
41 if (ptr == end) {
42 printk(UM_KERN_ERR "Failed to find '%c' in /proc/cpuinfo\n",
43 stop);
44 return -1;
45 }
46 *(ptr - 1) = '\0';
47 return c;
48}
49
50static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
51{
52 int n;
53 char c;
54
55 scratch[len - 1] = '\0';
56 while (1) {
57 c = token(fd, scratch, len - 1, ':');
58 if (c <= 0)
59 return 0;
60 else if (c != ':') {
61 printk(UM_KERN_ERR "Failed to find ':' in "
62 "/proc/cpuinfo\n");
63 return 0;
64 }
65
66 if (!strncmp(scratch, key, strlen(key)))
67 return 1;
68
69 do {
70 n = os_read_file(fd, &c, sizeof(c));
71 if (n != sizeof(c)) {
72 printk(UM_KERN_ERR "Failed to find newline in "
73 "/proc/cpuinfo, err = %d\n", -n);
74 return 0;
75 }
76 } while (c != '\n');
77 }
78 return 0;
79} 22}
80 23
81static int check_cpu_flag(char *feature, int *have_it) 24void arch_check_bugs(void)
82{
83 char buf[MAXTOKEN], c;
84 int fd, len = ARRAY_SIZE(buf);
85
86 printk(UM_KERN_INFO "Checking for host processor %s support...",
87 feature);
88 fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
89 if (fd < 0) {
90 printk(UM_KERN_ERR "Couldn't open /proc/cpuinfo, err = %d\n",
91 -fd);
92 return 0;
93 }
94
95 *have_it = 0;
96 if (!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf)))
97 goto out;
98
99 c = token(fd, buf, len - 1, ' ');
100 if (c < 0)
101 goto out;
102 else if (c != ' ') {
103 printk(UM_KERN_ERR "Failed to find ' ' in /proc/cpuinfo\n");
104 goto out;
105 }
106
107 while (1) {
108 c = token(fd, buf, len - 1, ' ');
109 if (c < 0)
110 goto out;
111 else if (c == '\n')
112 break;
113
114 if (!strcmp(buf, feature)) {
115 *have_it = 1;
116 goto out;
117 }
118 }
119 out:
120 if (*have_it == 0)
121 printk("No\n");
122 else if (*have_it == 1)
123 printk("Yes\n");
124 os_close_file(fd);
125 return 1;
126}
127
128#if 0 /*
129 * This doesn't work in tt mode, plus it's causing compilation problems
130 * for some people.
131 */
132static void disable_lcall(void)
133{ 25{
134 struct modify_ldt_ldt_s ldt; 26 struct sigaction old, new;
135 int err;
136 27
137 bzero(&ldt, sizeof(ldt)); 28 printk(UM_KERN_INFO "Checking for host processor cmov support...");
138 ldt.entry_number = 7; 29 new.sa_handler = cmov_sigill_test_handler;
139 ldt.base_addr = 0;
140 ldt.limit = 0;
141 err = modify_ldt(1, &ldt, sizeof(ldt));
142 if (err)
143 printk(UM_KERN_ERR "Failed to disable lcall7 - errno = %d\n",
144 errno);
145}
146#endif
147 30
148void arch_init_thread(void) 31 /* Make sure that SIGILL is enabled after the handler longjmps back */
149{ 32 new.sa_flags = SA_NODEFER;
150#if 0 33 sigemptyset(&new.sa_mask);
151 disable_lcall(); 34 sigaction(SIGILL, &new, &old);
152#endif
153}
154 35
155void arch_check_bugs(void) 36 if (setjmp(cmov_test_return) == 0) {
156{ 37 unsigned long foo = 0;
157 int have_it; 38 __asm__ __volatile__("cmovz %0, %1" : "=r" (foo) : "0" (foo));
39 printk(UM_KERN_CONT "Yes\n");
40 } else
41 printk(UM_KERN_CONT "No\n");
158 42
159 if (os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0) { 43 sigaction(SIGILL, &old, &new);
160 printk(UM_KERN_ERR "/proc/cpuinfo not available - skipping CPU "
161 "capability checks\n");
162 return;
163 }
164 if (check_cpu_flag("cmov", &have_it))
165 host_has_cmov = have_it;
166 if (check_cpu_flag("xmm", &have_it))
167 host_has_xmm = have_it;
168} 44}
169 45
170int arch_handle_signal(int sig, struct uml_pt_regs *regs) 46void arch_examine_signal(int sig, struct uml_pt_regs *regs)
171{ 47{
172 unsigned char tmp[2]; 48 unsigned char tmp[2];
173 49
@@ -176,24 +52,25 @@ int arch_handle_signal(int sig, struct uml_pt_regs *regs)
176 * SIGILL in init. 52 * SIGILL in init.
177 */ 53 */
178 if ((sig != SIGILL) || (TASK_PID(get_current()) != 1)) 54 if ((sig != SIGILL) || (TASK_PID(get_current()) != 1))
179 return 0; 55 return;
56
57 if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) {
58 printk(UM_KERN_ERR "SIGILL in init, could not read "
59 "instructions!\n");
60 return;
61 }
180 62
181 if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2))
182 panic("SIGILL in init, could not read instructions!\n");
183 if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) 63 if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
184 return 0; 64 return;
185 65
186 if (host_has_cmov == 0) 66 if (host_has_cmov == 0)
187 panic("SIGILL caused by cmov, which this processor doesn't " 67 printk(UM_KERN_ERR "SIGILL caused by cmov, which this "
188 "implement, boot a filesystem compiled for older " 68 "processor doesn't implement. Boot a filesystem "
189 "processors"); 69 "compiled for older processors");
190 else if (host_has_cmov == 1) 70 else if (host_has_cmov == 1)
191 panic("SIGILL caused by cmov, which this processor claims to " 71 printk(UM_KERN_ERR "SIGILL caused by cmov, which this "
192 "implement"); 72 "processor claims to implement");
193 else if (host_has_cmov == -1) 73 else
194 panic("SIGILL caused by cmov, couldn't tell if this processor " 74 printk(UM_KERN_ERR "Bad value for host_has_cmov (%d)",
195 "implements it, boot a filesystem compiled for older " 75 host_has_cmov);
196 "processors");
197 else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
198 return 0;
199} 76}
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 67c0958eb984..a34263e6b08d 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -3,8 +3,9 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/mm.h" 6#include <linux/mm.h>
7#include "asm/unistd.h" 7#include <linux/sched.h>
8#include <asm/unistd.h>
8#include "os.h" 9#include "os.h"
9#include "proc_mm.h" 10#include "proc_mm.h"
10#include "skas.h" 11#include "skas.h"
@@ -146,7 +147,7 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
146 if (ptrace_ldt) 147 if (ptrace_ldt)
147 return read_ldt_from_host(ptr, bytecount); 148 return read_ldt_from_host(ptr, bytecount);
148 149
149 down(&ldt->semaphore); 150 mutex_lock(&ldt->lock);
150 if (ldt->entry_count <= LDT_DIRECT_ENTRIES) { 151 if (ldt->entry_count <= LDT_DIRECT_ENTRIES) {
151 size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES; 152 size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES;
152 if (size > bytecount) 153 if (size > bytecount)
@@ -170,7 +171,7 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
170 ptr += size; 171 ptr += size;
171 } 172 }
172 } 173 }
173 up(&ldt->semaphore); 174 mutex_unlock(&ldt->lock);
174 175
175 if (bytecount == 0 || err == -EFAULT) 176 if (bytecount == 0 || err == -EFAULT)
176 goto out; 177 goto out;
@@ -228,7 +229,7 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
228 } 229 }
229 230
230 if (!ptrace_ldt) 231 if (!ptrace_ldt)
231 down(&ldt->semaphore); 232 mutex_lock(&ldt->lock);
232 233
233 err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1); 234 err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1);
234 if (err) 235 if (err)
@@ -288,7 +289,7 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
288 err = 0; 289 err = 0;
289 290
290out_unlock: 291out_unlock:
291 up(&ldt->semaphore); 292 mutex_unlock(&ldt->lock);
292out: 293out:
293 return err; 294 return err;
294} 295}
@@ -395,7 +396,7 @@ long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm)
395 396
396 397
397 if (!ptrace_ldt) 398 if (!ptrace_ldt)
398 init_MUTEX(&new_mm->ldt.semaphore); 399 mutex_init(&new_mm->ldt.lock);
399 400
400 if (!from_mm) { 401 if (!from_mm) {
401 memset(&desc, 0, sizeof(desc)); 402 memset(&desc, 0, sizeof(desc));
@@ -455,7 +456,7 @@ long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm)
455 * i.e., we have to use the stub for modify_ldt, which 456 * i.e., we have to use the stub for modify_ldt, which
456 * can't handle the big read buffer of up to 64kB. 457 * can't handle the big read buffer of up to 64kB.
457 */ 458 */
458 down(&from_mm->ldt.semaphore); 459 mutex_lock(&from_mm->ldt.lock);
459 if (from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES) 460 if (from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES)
460 memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries, 461 memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries,
461 sizeof(new_mm->ldt.u.entries)); 462 sizeof(new_mm->ldt.u.entries));
@@ -474,7 +475,7 @@ long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm)
474 } 475 }
475 } 476 }
476 new_mm->ldt.entry_count = from_mm->ldt.entry_count; 477 new_mm->ldt.entry_count = from_mm->ldt.entry_count;
477 up(&from_mm->ldt.semaphore); 478 mutex_unlock(&from_mm->ldt.lock);
478 } 479 }
479 480
480 out: 481 out:
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index bd3da8a61f64..6b4499906a6c 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -8,11 +8,11 @@
8#include "asm/uaccess.h" 8#include "asm/uaccess.h"
9#include "skas.h" 9#include "skas.h"
10 10
11extern int arch_switch_tls(struct task_struct *from, struct task_struct *to); 11extern int arch_switch_tls(struct task_struct *to);
12 12
13void arch_switch_to(struct task_struct *from, struct task_struct *to) 13void arch_switch_to(struct task_struct *to)
14{ 14{
15 int err = arch_switch_tls(from, to); 15 int err = arch_switch_tls(to);
16 if (!err) 16 if (!err)
17 return; 17 return;
18 18
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
index 5cf97bc229b9..0b10c3e74028 100644
--- a/arch/um/sys-i386/ptrace_user.c
+++ b/arch/um/sys-i386/ptrace_user.c
@@ -19,17 +19,3 @@ int ptrace_setregs(long pid, unsigned long *regs)
19 return -errno; 19 return -errno;
20 return 0; 20 return 0;
21} 21}
22
23int ptrace_getfpregs(long pid, unsigned long *regs)
24{
25 if (ptrace(PTRACE_GETFPREGS, pid, 0, regs) < 0)
26 return -errno;
27 return 0;
28}
29
30int ptrace_setfpregs(long pid, unsigned long *regs)
31{
32 if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0)
33 return -errno;
34 return 0;
35}
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 19053d46cb60..fd0c25ad6af3 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -168,12 +168,13 @@ static int copy_sc_from_user(struct pt_regs *regs,
168 struct sigcontext __user *from) 168 struct sigcontext __user *from)
169{ 169{
170 struct sigcontext sc; 170 struct sigcontext sc;
171 int err; 171 int err, pid;
172 172
173 err = copy_from_user(&sc, from, sizeof(sc)); 173 err = copy_from_user(&sc, from, sizeof(sc));
174 if (err) 174 if (err)
175 return err; 175 return err;
176 176
177 pid = userspace_pid[current_thread_info()->cpu];
177 copy_sc(&regs->regs, &sc); 178 copy_sc(&regs->regs, &sc);
178 if (have_fpx_regs) { 179 if (have_fpx_regs) {
179 struct user_fxsr_struct fpx; 180 struct user_fxsr_struct fpx;
@@ -187,8 +188,7 @@ static int copy_sc_from_user(struct pt_regs *regs,
187 if (err) 188 if (err)
188 return 1; 189 return 1;
189 190
190 err = restore_fpx_registers(userspace_pid[current_thread->cpu], 191 err = restore_fpx_registers(pid, (unsigned long *) &fpx);
191 (unsigned long *) &fpx);
192 if (err < 0) { 192 if (err < 0) {
193 printk(KERN_ERR "copy_sc_from_user - " 193 printk(KERN_ERR "copy_sc_from_user - "
194 "restore_fpx_registers failed, errno = %d\n", 194 "restore_fpx_registers failed, errno = %d\n",
@@ -204,8 +204,7 @@ static int copy_sc_from_user(struct pt_regs *regs,
204 if (err) 204 if (err)
205 return 1; 205 return 1;
206 206
207 err = restore_fp_registers(userspace_pid[current_thread->cpu], 207 err = restore_fp_registers(pid, (unsigned long *) &fp);
208 (unsigned long *) &fp);
209 if (err < 0) { 208 if (err < 0) {
210 printk(KERN_ERR "copy_sc_from_user - " 209 printk(KERN_ERR "copy_sc_from_user - "
211 "restore_fp_registers failed, errno = %d\n", 210 "restore_fp_registers failed, errno = %d\n",
@@ -223,7 +222,7 @@ static int copy_sc_to_user(struct sigcontext __user *to,
223{ 222{
224 struct sigcontext sc; 223 struct sigcontext sc;
225 struct faultinfo * fi = &current->thread.arch.faultinfo; 224 struct faultinfo * fi = &current->thread.arch.faultinfo;
226 int err; 225 int err, pid;
227 226
228 sc.gs = REGS_GS(regs->regs.gp); 227 sc.gs = REGS_GS(regs->regs.gp);
229 sc.fs = REGS_FS(regs->regs.gp); 228 sc.fs = REGS_FS(regs->regs.gp);
@@ -249,11 +248,11 @@ static int copy_sc_to_user(struct sigcontext __user *to,
249 to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); 248 to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1));
250 sc.fpstate = to_fp; 249 sc.fpstate = to_fp;
251 250
251 pid = userspace_pid[current_thread_info()->cpu];
252 if (have_fpx_regs) { 252 if (have_fpx_regs) {
253 struct user_fxsr_struct fpx; 253 struct user_fxsr_struct fpx;
254 254
255 err = save_fpx_registers(userspace_pid[current_thread->cpu], 255 err = save_fpx_registers(pid, (unsigned long *) &fpx);
256 (unsigned long *) &fpx);
257 if (err < 0){ 256 if (err < 0){
258 printk(KERN_ERR "copy_sc_to_user - save_fpx_registers " 257 printk(KERN_ERR "copy_sc_to_user - save_fpx_registers "
259 "failed, errno = %d\n", err); 258 "failed, errno = %d\n", err);
@@ -276,8 +275,7 @@ static int copy_sc_to_user(struct sigcontext __user *to,
276 else { 275 else {
277 struct user_i387_struct fp; 276 struct user_i387_struct fp;
278 277
279 err = save_fp_registers(userspace_pid[current_thread->cpu], 278 err = save_fp_registers(pid, (unsigned long *) &fp);
280 (unsigned long *) &fp);
281 if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct))) 279 if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct)))
282 return 1; 280 return 1;
283 } 281 }
diff --git a/arch/um/sys-i386/stub.S b/arch/um/sys-i386/stub.S
index e730772c401b..7699e89f660f 100644
--- a/arch/um/sys-i386/stub.S
+++ b/arch/um/sys-i386/stub.S
@@ -7,7 +7,7 @@
7 .globl batch_syscall_stub 7 .globl batch_syscall_stub
8batch_syscall_stub: 8batch_syscall_stub:
9 /* load pointer to first operation */ 9 /* load pointer to first operation */
10 mov $(ASM_STUB_DATA+8), %esp 10 mov $(STUB_DATA+8), %esp
11 11
12again: 12again:
13 /* load length of additional data */ 13 /* load length of additional data */
@@ -15,12 +15,12 @@ again:
15 15
16 /* if(length == 0) : end of list */ 16 /* if(length == 0) : end of list */
17 /* write possible 0 to header */ 17 /* write possible 0 to header */
18 mov %eax, ASM_STUB_DATA+4 18 mov %eax, STUB_DATA+4
19 cmpl $0, %eax 19 cmpl $0, %eax
20 jz done 20 jz done
21 21
22 /* save current pointer */ 22 /* save current pointer */
23 mov %esp, ASM_STUB_DATA+4 23 mov %esp, STUB_DATA+4
24 24
25 /* skip additional data */ 25 /* skip additional data */
26 add %eax, %esp 26 add %eax, %esp
@@ -46,7 +46,7 @@ again:
46 46
47done: 47done:
48 /* save return value */ 48 /* save return value */
49 mov %eax, ASM_STUB_DATA 49 mov %eax, STUB_DATA
50 50
51 /* stop */ 51 /* stop */
52 int3 52 int3
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c
index b3999cb76bfd..28ccf737a79f 100644
--- a/arch/um/sys-i386/stub_segv.c
+++ b/arch/um/sys-i386/stub_segv.c
@@ -1,32 +1,17 @@
1/* 1/*
2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <signal.h>
7#include <sys/select.h> /* The only way I can see to get sigset_t */
8#include <asm/unistd.h>
9#include "as-layout.h"
10#include "uml-config.h"
11#include "sysdep/stub.h" 6#include "sysdep/stub.h"
12#include "sysdep/sigcontext.h" 7#include "sysdep/sigcontext.h"
13#include "sysdep/faultinfo.h"
14 8
15void __attribute__ ((__section__ (".__syscall_stub"))) 9void __attribute__ ((__section__ (".__syscall_stub")))
16stub_segv_handler(int sig) 10stub_segv_handler(int sig)
17{ 11{
18 struct sigcontext *sc = (struct sigcontext *) (&sig + 1); 12 struct sigcontext *sc = (struct sigcontext *) (&sig + 1);
19 int pid;
20 13
21 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc); 14 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc);
22 15
23 pid = stub_syscall0(__NR_getpid); 16 trap_myself();
24 stub_syscall2(__NR_kill, pid, SIGUSR1);
25
26 /* Load pointer to sigcontext into esp, since we need to leave
27 * the stack in its original form when we do the sigreturn here, by
28 * hand.
29 */
30 __asm__ __volatile__("mov %0,%%esp ; movl %1, %%eax ; "
31 "int $0x80" : : "a" (sc), "g" (__NR_sigreturn));
32} 17}
diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S
index 12d4148dba39..00e5f5203eea 100644
--- a/arch/um/sys-i386/sys_call_table.S
+++ b/arch/um/sys-i386/sys_call_table.S
@@ -9,4 +9,9 @@
9 9
10#define old_mmap old_mmap_i386 10#define old_mmap old_mmap_i386
11 11
12.section .rodata,"a"
13
12#include "../../x86/kernel/syscall_table_32.S" 14#include "../../x86/kernel/syscall_table_32.S"
15
16ENTRY(syscall_table_size)
17.long .-sys_call_table
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c
index fcaff86b000c..c6c7131e563b 100644
--- a/arch/um/sys-i386/tls.c
+++ b/arch/um/sys-i386/tls.c
@@ -26,6 +26,11 @@ int do_set_thread_area(struct user_desc *info)
26 cpu = get_cpu(); 26 cpu = get_cpu();
27 ret = os_set_thread_area(info, userspace_pid[cpu]); 27 ret = os_set_thread_area(info, userspace_pid[cpu]);
28 put_cpu(); 28 put_cpu();
29
30 if (ret)
31 printk(KERN_ERR "PTRACE_SET_THREAD_AREA failed, err = %d, "
32 "index = %d\n", ret, info->entry_number);
33
29 return ret; 34 return ret;
30} 35}
31 36
@@ -37,6 +42,11 @@ int do_get_thread_area(struct user_desc *info)
37 cpu = get_cpu(); 42 cpu = get_cpu();
38 ret = os_get_thread_area(info, userspace_pid[cpu]); 43 ret = os_get_thread_area(info, userspace_pid[cpu]);
39 put_cpu(); 44 put_cpu();
45
46 if (ret)
47 printk(KERN_ERR "PTRACE_GET_THREAD_AREA failed, err = %d, "
48 "index = %d\n", ret, info->entry_number);
49
40 return ret; 50 return ret;
41} 51}
42 52
@@ -172,7 +182,7 @@ void clear_flushed_tls(struct task_struct *task)
172 * SKAS patch. 182 * SKAS patch.
173 */ 183 */
174 184
175int arch_switch_tls(struct task_struct *from, struct task_struct *to) 185int arch_switch_tls(struct task_struct *to)
176{ 186{
177 if (!host_supports_tls) 187 if (!host_supports_tls)
178 return 0; 188 return 0;
@@ -225,7 +235,8 @@ out:
225} 235}
226 236
227/* XXX: use do_get_thread_area to read the host value? I'm not at all sure! */ 237/* XXX: use do_get_thread_area to read the host value? I'm not at all sure! */
228static int get_tls_entry(struct task_struct* task, struct user_desc *info, int idx) 238static int get_tls_entry(struct task_struct *task, struct user_desc *info,
239 int idx)
229{ 240{
230 struct thread_struct *t = &task->thread; 241 struct thread_struct *t = &task->thread;
231 242
@@ -263,7 +274,7 @@ clear:
263 goto out; 274 goto out;
264} 275}
265 276
266asmlinkage int sys_set_thread_area(struct user_desc __user *user_desc) 277int sys_set_thread_area(struct user_desc __user *user_desc)
267{ 278{
268 struct user_desc info; 279 struct user_desc info;
269 int idx, ret; 280 int idx, ret;
@@ -298,7 +309,7 @@ asmlinkage int sys_set_thread_area(struct user_desc __user *user_desc)
298 * i386. However the only possible error are caused by bugs. 309 * i386. However the only possible error are caused by bugs.
299 */ 310 */
300int ptrace_set_thread_area(struct task_struct *child, int idx, 311int ptrace_set_thread_area(struct task_struct *child, int idx,
301 struct user_desc __user *user_desc) 312 struct user_desc __user *user_desc)
302{ 313{
303 struct user_desc info; 314 struct user_desc info;
304 315
@@ -311,7 +322,7 @@ int ptrace_set_thread_area(struct task_struct *child, int idx,
311 return set_tls_entry(child, &info, idx, 0); 322 return set_tls_entry(child, &info, idx, 0);
312} 323}
313 324
314asmlinkage int sys_get_thread_area(struct user_desc __user *user_desc) 325int sys_get_thread_area(struct user_desc __user *user_desc)
315{ 326{
316 struct user_desc info; 327 struct user_desc info;
317 int idx, ret; 328 int idx, ret;
@@ -355,10 +366,9 @@ out:
355 return ret; 366 return ret;
356} 367}
357 368
358
359/* 369/*
360 * XXX: This part is probably common to i386 and x86-64. Don't create a common 370 * This code is really i386-only, but it detects and logs x86_64 GDT indexes
361 * file for now, do that when implementing x86-64 support. 371 * if a 32-bit UML is running on a 64-bit host.
362 */ 372 */
363static int __init __setup_host_supports_tls(void) 373static int __init __setup_host_supports_tls(void)
364{ 374{
@@ -367,13 +377,16 @@ static int __init __setup_host_supports_tls(void)
367 printk(KERN_INFO "Host TLS support detected\n"); 377 printk(KERN_INFO "Host TLS support detected\n");
368 printk(KERN_INFO "Detected host type: "); 378 printk(KERN_INFO "Detected host type: ");
369 switch (host_gdt_entry_tls_min) { 379 switch (host_gdt_entry_tls_min) {
370 case GDT_ENTRY_TLS_MIN_I386: 380 case GDT_ENTRY_TLS_MIN_I386:
371 printk("i386\n"); 381 printk(KERN_CONT "i386");
372 break; 382 break;
373 case GDT_ENTRY_TLS_MIN_X86_64: 383 case GDT_ENTRY_TLS_MIN_X86_64:
374 printk("x86_64\n"); 384 printk(KERN_CONT "x86_64");
375 break; 385 break;
376 } 386 }
387 printk(KERN_CONT " (GDT indexes %d to %d)\n",
388 host_gdt_entry_tls_min,
389 host_gdt_entry_tls_min + GDT_ENTRY_TLS_ENTRIES);
377 } else 390 } else
378 printk(KERN_ERR " Host TLS support NOT detected! " 391 printk(KERN_ERR " Host TLS support NOT detected! "
379 "TLS support inside UML will not work\n"); 392 "TLS support inside UML will not work\n");
diff --git a/arch/um/sys-ppc/Makefile b/arch/um/sys-ppc/Makefile
index a9814a7ae60e..08901526e893 100644
--- a/arch/um/sys-ppc/Makefile
+++ b/arch/um/sys-ppc/Makefile
@@ -6,7 +6,7 @@ OBJ = built-in.o
6OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \ 6OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \
7 ptrace_user.o sysrq.o 7 ptrace_user.o sysrq.o
8 8
9EXTRA_AFLAGS := -DCONFIG_PPC32 -I. -I$(TOPDIR)/arch/ppc/kernel 9EXTRA_AFLAGS := -DCONFIG_PPC32 -I. -I$(srctree)/arch/ppc/kernel
10 10
11all: $(OBJ) 11all: $(OBJ)
12 12
@@ -22,25 +22,25 @@ sigcontext.o: sigcontext.c
22 22
23semaphore.c: 23semaphore.c:
24 rm -f $@ 24 rm -f $@
25 ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@ 25 ln -s $(srctree)/arch/ppc/kernel/$@ $@
26 26
27checksum.S: 27checksum.S:
28 rm -f $@ 28 rm -f $@
29 ln -s $(TOPDIR)/arch/ppc/lib/$@ $@ 29 ln -s $(srctree)/arch/ppc/lib/$@ $@
30 30
31mk_defs.c: 31mk_defs.c:
32 rm -f $@ 32 rm -f $@
33 ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@ 33 ln -s $(srctree)/arch/ppc/kernel/$@ $@
34 34
35ppc_defs.head: 35ppc_defs.head:
36 rm -f $@ 36 rm -f $@
37 ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@ 37 ln -s $(srctree)/arch/ppc/kernel/$@ $@
38 38
39ppc_defs.h: mk_defs.c ppc_defs.head \ 39ppc_defs.h: mk_defs.c ppc_defs.head \
40 $(TOPDIR)/include/asm-ppc/mmu.h \ 40 $(srctree)/include/asm-ppc/mmu.h \
41 $(TOPDIR)/include/asm-ppc/processor.h \ 41 $(srctree)/include/asm-ppc/processor.h \
42 $(TOPDIR)/include/asm-ppc/pgtable.h \ 42 $(srctree)/include/asm-ppc/pgtable.h \
43 $(TOPDIR)/include/asm-ppc/ptrace.h 43 $(srctree)/include/asm-ppc/ptrace.h
44# $(CC) $(CFLAGS) -S mk_defs.c 44# $(CC) $(CFLAGS) -S mk_defs.c
45 cp ppc_defs.head ppc_defs.h 45 cp ppc_defs.head ppc_defs.h
46# for bk, this way we can write to the file even if it's not checked out 46# for bk, this way we can write to the file even if it's not checked out
@@ -56,13 +56,13 @@ ppc_defs.h: mk_defs.c ppc_defs.head \
56 56
57checksum.o: checksum.S 57checksum.o: checksum.S
58 rm -f asm 58 rm -f asm
59 ln -s $(TOPDIR)/include/asm-ppc asm 59 ln -s $(srctree)/include/asm-ppc asm
60 $(CC) $(EXTRA_AFLAGS) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o 60 $(CC) $(EXTRA_AFLAGS) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
61 rm -f asm 61 rm -f asm
62 62
63misc.o: misc.S ppc_defs.h 63misc.o: misc.S ppc_defs.h
64 rm -f asm 64 rm -f asm
65 ln -s $(TOPDIR)/include/asm-ppc asm 65 ln -s $(srctree)/include/asm-ppc asm
66 $(CC) $(EXTRA_AFLAGS) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o 66 $(CC) $(EXTRA_AFLAGS) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
67 rm -f asm 67 rm -f asm
68 68
diff --git a/arch/um/sys-x86_64/bug.c b/arch/um/sys-x86_64/bug.c
index a4360b5207db..e8034e363d83 100644
--- a/arch/um/sys-x86_64/bug.c
+++ b/arch/um/sys-x86_64/bug.c
@@ -5,7 +5,8 @@
5 5
6#include <linux/uaccess.h> 6#include <linux/uaccess.h>
7 7
8/* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because 8/*
9 * Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because
9 * that's not relevant in skas mode. 10 * that's not relevant in skas mode.
10 */ 11 */
11 12
diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c
index 506b6765bbcb..44e02ba2a265 100644
--- a/arch/um/sys-x86_64/bugs.c
+++ b/arch/um/sys-x86_64/bugs.c
@@ -6,15 +6,10 @@
6 6
7#include "sysdep/ptrace.h" 7#include "sysdep/ptrace.h"
8 8
9void arch_init_thread(void)
10{
11}
12
13void arch_check_bugs(void) 9void arch_check_bugs(void)
14{ 10{
15} 11}
16 12
17int arch_handle_signal(int sig, struct uml_pt_regs *regs) 13void arch_examine_signal(int sig, struct uml_pt_regs *regs)
18{ 14{
19 return 0;
20} 15}
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index b7631b0e9ddc..f3458d7d1c5a 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -5,13 +5,12 @@
5 * Licensed under the GPL 5 * Licensed under the GPL
6 */ 6 */
7 7
8#define __FRAME_OFFSETS 8#include <linux/mm.h>
9#include <asm/ptrace.h>
10#include <linux/sched.h> 9#include <linux/sched.h>
11#include <linux/errno.h> 10#include <linux/errno.h>
12#include <linux/mm.h> 11#define __FRAME_OFFSETS
12#include <asm/ptrace.h>
13#include <asm/uaccess.h> 13#include <asm/uaccess.h>
14#include <asm/elf.h>
15 14
16/* 15/*
17 * determines which flags the user has access to. 16 * determines which flags the user has access to.
@@ -24,12 +23,14 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
24 unsigned long tmp; 23 unsigned long tmp;
25 24
26#ifdef TIF_IA32 25#ifdef TIF_IA32
27 /* Some code in the 64bit emulation may not be 64bit clean. 26 /*
28 Don't take any chances. */ 27 * Some code in the 64bit emulation may not be 64bit clean.
28 * Don't take any chances.
29 */
29 if (test_tsk_thread_flag(child, TIF_IA32)) 30 if (test_tsk_thread_flag(child, TIF_IA32))
30 value &= 0xffffffff; 31 value &= 0xffffffff;
31#endif 32#endif
32 switch (regno){ 33 switch (regno) {
33 case FS: 34 case FS:
34 case GS: 35 case GS:
35 case DS: 36 case DS:
@@ -66,7 +67,7 @@ int poke_user(struct task_struct *child, long addr, long data)
66 if (addr < MAX_REG_OFFSET) 67 if (addr < MAX_REG_OFFSET)
67 return putreg(child, addr, data); 68 return putreg(child, addr, data);
68 else if ((addr >= offsetof(struct user, u_debugreg[0])) && 69 else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
69 (addr <= offsetof(struct user, u_debugreg[7]))){ 70 (addr <= offsetof(struct user, u_debugreg[7]))) {
70 addr -= offsetof(struct user, u_debugreg[0]); 71 addr -= offsetof(struct user, u_debugreg[0]);
71 addr = addr >> 2; 72 addr = addr >> 2;
72 if ((addr == 4) || (addr == 5)) 73 if ((addr == 4) || (addr == 5))
@@ -108,11 +109,10 @@ int peek_user(struct task_struct *child, long addr, long data)
108 return -EIO; 109 return -EIO;
109 110
110 tmp = 0; /* Default return condition */ 111 tmp = 0; /* Default return condition */
111 if (addr < MAX_REG_OFFSET){ 112 if (addr < MAX_REG_OFFSET)
112 tmp = getreg(child, addr); 113 tmp = getreg(child, addr);
113 }
114 else if ((addr >= offsetof(struct user, u_debugreg[0])) && 114 else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
115 (addr <= offsetof(struct user, u_debugreg[7]))){ 115 (addr <= offsetof(struct user, u_debugreg[7]))) {
116 addr -= offsetof(struct user, u_debugreg[0]); 116 addr -= offsetof(struct user, u_debugreg[0]);
117 addr = addr >> 2; 117 addr = addr >> 2;
118 tmp = child->thread.arch.debugregs[addr]; 118 tmp = child->thread.arch.debugregs[addr];
@@ -127,8 +127,9 @@ int is_syscall(unsigned long addr)
127 int n; 127 int n;
128 128
129 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); 129 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
130 if (n){ 130 if (n) {
131 /* access_process_vm() grants access to vsyscall and stub, 131 /*
132 * access_process_vm() grants access to vsyscall and stub,
132 * while copy_from_user doesn't. Maybe access_process_vm is 133 * while copy_from_user doesn't. Maybe access_process_vm is
133 * slow, but that doesn't matter, since it will be called only 134 * slow, but that doesn't matter, since it will be called only
134 * in case of singlestepping, if copy_from_user failed. 135 * in case of singlestepping, if copy_from_user failed.
@@ -155,7 +156,7 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
155 return err; 156 return err;
156 157
157 n = copy_to_user(buf, fpregs, sizeof(fpregs)); 158 n = copy_to_user(buf, fpregs, sizeof(fpregs));
158 if(n > 0) 159 if (n > 0)
159 return -EFAULT; 160 return -EFAULT;
160 161
161 return n; 162 return n;
diff --git a/arch/um/sys-x86_64/ptrace_user.c b/arch/um/sys-x86_64/ptrace_user.c
index b5f9c33e311e..c57a496d3f5b 100644
--- a/arch/um/sys-x86_64/ptrace_user.c
+++ b/arch/um/sys-x86_64/ptrace_user.c
@@ -4,55 +4,19 @@
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7#include <stddef.h>
8#include <errno.h> 7#include <errno.h>
9#include "ptrace_user.h" 8#include "ptrace_user.h"
10#include "user.h"
11#include "kern_constants.h"
12 9
13int ptrace_getregs(long pid, unsigned long *regs_out) 10int ptrace_getregs(long pid, unsigned long *regs_out)
14{ 11{
15 if(ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0) 12 if (ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0)
16 return(-errno); 13 return -errno;
17 return(0);
18}
19
20int ptrace_setregs(long pid, unsigned long *regs)
21{
22 if(ptrace(PTRACE_SETREGS, pid, 0, regs) < 0)
23 return(-errno);
24 return(0); 14 return(0);
25} 15}
26 16
27int ptrace_setfpregs(long pid, unsigned long *regs) 17int ptrace_setregs(long pid, unsigned long *regs_out)
28{ 18{
29 if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0) 19 if (ptrace(PTRACE_SETREGS, pid, 0, regs_out) < 0)
30 return -errno; 20 return -errno;
31 return 0; 21 return(0);
32}
33
34void ptrace_pokeuser(unsigned long addr, unsigned long data)
35{
36 panic("ptrace_pokeuser");
37}
38
39#define DS 184
40#define ES 192
41#define __USER_DS 0x2b
42
43void arch_enter_kernel(void *task, int pid)
44{
45}
46
47void arch_leave_kernel(void *task, int pid)
48{
49#ifdef UM_USER_CS
50 if(ptrace(PTRACE_POKEUSR, pid, CS, UM_USER_CS) < 0)
51 printk("POKEUSR CS failed");
52#endif
53
54 if(ptrace(PTRACE_POKEUSR, pid, DS, __USER_DS) < 0)
55 printk("POKEUSR DS failed");
56 if(ptrace(PTRACE_POKEUSR, pid, ES, __USER_DS) < 0)
57 printk("POKEUSR ES failed");
58} 22}
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index 14070181407b..1a899a7ed7a6 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -81,7 +81,7 @@ static int copy_sc_from_user(struct pt_regs *regs,
81 if (err) 81 if (err)
82 return 1; 82 return 1;
83 83
84 err = restore_fp_registers(userspace_pid[current_thread->cpu], 84 err = restore_fp_registers(userspace_pid[current_thread_info()->cpu],
85 (unsigned long *) &fp); 85 (unsigned long *) &fp);
86 if (err < 0) { 86 if (err < 0) {
87 printk(KERN_ERR "copy_sc_from_user - " 87 printk(KERN_ERR "copy_sc_from_user - "
@@ -143,7 +143,7 @@ static int copy_sc_to_user(struct sigcontext __user *to,
143 if (err) 143 if (err)
144 return 1; 144 return 1;
145 145
146 err = save_fp_registers(userspace_pid[current_thread->cpu], 146 err = save_fp_registers(userspace_pid[current_thread_info()->cpu],
147 (unsigned long *) &fp); 147 (unsigned long *) &fp);
148 if (err < 0) { 148 if (err < 0) {
149 printk(KERN_ERR "copy_sc_from_user - restore_fp_registers " 149 printk(KERN_ERR "copy_sc_from_user - restore_fp_registers "
diff --git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S
index 4afe204a6af7..568768763155 100644
--- a/arch/um/sys-x86_64/stub.S
+++ b/arch/um/sys-x86_64/stub.S
@@ -8,18 +8,18 @@ syscall_stub:
8 /* We don't have 64-bit constants, so this constructs the address 8 /* We don't have 64-bit constants, so this constructs the address
9 * we need. 9 * we need.
10 */ 10 */
11 movq $(ASM_STUB_DATA >> 32), %rbx 11 movq $(STUB_DATA >> 32), %rbx
12 salq $32, %rbx 12 salq $32, %rbx
13 movq $(ASM_STUB_DATA & 0xffffffff), %rcx 13 movq $(STUB_DATA & 0xffffffff), %rcx
14 or %rcx, %rbx 14 or %rcx, %rbx
15 movq %rax, (%rbx) 15 movq %rax, (%rbx)
16 int3 16 int3
17 17
18 .globl batch_syscall_stub 18 .globl batch_syscall_stub
19batch_syscall_stub: 19batch_syscall_stub:
20 mov $(ASM_STUB_DATA >> 32), %rbx 20 mov $(STUB_DATA >> 32), %rbx
21 sal $32, %rbx 21 sal $32, %rbx
22 mov $(ASM_STUB_DATA & 0xffffffff), %rax 22 mov $(STUB_DATA & 0xffffffff), %rax
23 or %rax, %rbx 23 or %rax, %rbx
24 /* load pointer to first operation */ 24 /* load pointer to first operation */
25 mov %rbx, %rsp 25 mov %rbx, %rsp
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c
index 3afb590f0072..ced051afc705 100644
--- a/arch/um/sys-x86_64/stub_segv.c
+++ b/arch/um/sys-x86_64/stub_segv.c
@@ -1,51 +1,22 @@
1/* 1/*
2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stddef.h>
7#include <signal.h> 6#include <signal.h>
8#include <asm/unistd.h>
9#include "as-layout.h" 7#include "as-layout.h"
10#include "uml-config.h"
11#include "sysdep/sigcontext.h"
12#include "sysdep/faultinfo.h"
13#include "sysdep/stub.h" 8#include "sysdep/stub.h"
14 9#include "sysdep/faultinfo.h"
15/* Copied from sys-x86_64/signal.c - Can't find an equivalent definition 10#include "sysdep/sigcontext.h"
16 * in the libc headers anywhere.
17 */
18struct rt_sigframe
19{
20 char *pretcode;
21 struct ucontext uc;
22 struct siginfo info;
23};
24
25/* Copied here from <linux/kernel.h> - we're userspace. */
26#define container_of(ptr, type, member) ({ \
27 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
28 (type *)( (char *)__mptr - offsetof(type,member) );})
29 11
30void __attribute__ ((__section__ (".__syscall_stub"))) 12void __attribute__ ((__section__ (".__syscall_stub")))
31stub_segv_handler(int sig) 13stub_segv_handler(int sig)
32{ 14{
33 struct ucontext *uc; 15 struct ucontext *uc;
34 int pid;
35 16
36 __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :); 17 __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :);
37 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), 18 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA),
38 &uc->uc_mcontext); 19 &uc->uc_mcontext);
39 20 trap_myself();
40 pid = stub_syscall0(__NR_getpid);
41 stub_syscall2(__NR_kill, pid, SIGUSR1);
42
43 /* sys_sigreturn expects that the stack pointer will be 8 bytes into
44 * the signal frame. So, we use the ucontext pointer, which we know
45 * already, to get the signal frame pointer, and add 8 to that.
46 */
47 __asm__ __volatile__("movq %0, %%rsp; movq %1, %%rax ; syscall": :
48 "g" ((unsigned long)
49 container_of(uc, struct rt_sigframe, uc) + 8),
50 "g" (__NR_rt_sigreturn));
51} 21}
22
diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c
index 71b2ae4ad5de..c128eb897008 100644
--- a/arch/um/sys-x86_64/syscall_table.c
+++ b/arch/um/sys-x86_64/syscall_table.c
@@ -1,5 +1,7 @@
1/* System call table for UML/x86-64, copied from arch/x86_64/kernel/syscall.c 1/*
2 * with some changes for UML. */ 2 * System call table for UML/x86-64, copied from arch/x86_64/kernel/syscall.c
3 * with some changes for UML.
4 */
3 5
4#include <linux/linkage.h> 6#include <linux/linkage.h>
5#include <linux/sys.h> 7#include <linux/sys.h>
@@ -8,22 +10,26 @@
8 10
9#define __NO_STUBS 11#define __NO_STUBS
10 12
11/* Below you can see, in terms of #define's, the differences between the x86-64 13/*
12 * and the UML syscall table. */ 14 * Below you can see, in terms of #define's, the differences between the x86-64
15 * and the UML syscall table.
16 */
13 17
14/* Not going to be implemented by UML, since we have no hardware. */ 18/* Not going to be implemented by UML, since we have no hardware. */
15#define stub_iopl sys_ni_syscall 19#define stub_iopl sys_ni_syscall
16#define sys_ioperm sys_ni_syscall 20#define sys_ioperm sys_ni_syscall
17 21
18/* The UML TLS problem. Note that x86_64 does not implement this, so the below 22/*
19 * is needed only for the ia32 compatibility. */ 23 * The UML TLS problem. Note that x86_64 does not implement this, so the below
20/*#define sys_set_thread_area sys_ni_syscall 24 * is needed only for the ia32 compatibility.
21#define sys_get_thread_area sys_ni_syscall*/ 25 */
22 26
23/* On UML we call it this way ("old" means it's not mmap2) */ 27/* On UML we call it this way ("old" means it's not mmap2) */
24#define sys_mmap old_mmap 28#define sys_mmap old_mmap
25/* On x86-64 sys_uname is actually sys_newuname plus a compatibility trick. 29/*
26 * See arch/x86_64/kernel/sys_x86_64.c */ 30 * On x86-64 sys_uname is actually sys_newuname plus a compatibility trick.
31 * See arch/x86_64/kernel/sys_x86_64.c
32 */
27#define sys_uname sys_uname64 33#define sys_uname sys_uname64
28 34
29#define stub_clone sys_clone 35#define stub_clone sys_clone
@@ -46,8 +52,19 @@ typedef void (*sys_call_ptr_t)(void);
46 52
47extern void sys_ni_syscall(void); 53extern void sys_ni_syscall(void);
48 54
49sys_call_ptr_t sys_call_table[UM_NR_syscall_max+1] __cacheline_aligned = { 55/*
50 /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */ 56 * We used to have a trick here which made sure that holes in the
51 [0 ... UM_NR_syscall_max] = &sys_ni_syscall, 57 * x86_64 table were filled in with sys_ni_syscall, but a comment in
58 * unistd_64.h says that holes aren't allowed, so the trick was
59 * removed.
60 * The trick looked like this
61 * [0 ... UM_NR_syscall_max] = &sys_ni_syscall
62 * before including unistd_64.h - the later initializations overwrote
63 * the sys_ni_syscall filler.
64 */
65
66sys_call_ptr_t sys_call_table[] __cacheline_aligned = {
52#include <asm-x86/unistd_64.h> 67#include <asm-x86/unistd_64.h>
53}; 68};
69
70int syscall_table_size = sizeof(sys_call_table);
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index 86f6b18410ee..f1199fd34d38 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -48,7 +48,9 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
48 switch (code) { 48 switch (code) {
49 case ARCH_SET_FS: 49 case ARCH_SET_FS:
50 case ARCH_SET_GS: 50 case ARCH_SET_GS:
51 restore_registers(pid, &current->thread.regs.regs); 51 ret = restore_registers(pid, &current->thread.regs.regs);
52 if (ret)
53 return ret;
52 break; 54 break;
53 case ARCH_GET_FS: 55 case ARCH_GET_FS:
54 case ARCH_GET_GS: 56 case ARCH_GET_GS:
@@ -70,10 +72,10 @@ long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
70 switch (code) { 72 switch (code) {
71 case ARCH_SET_FS: 73 case ARCH_SET_FS:
72 current->thread.arch.fs = (unsigned long) ptr; 74 current->thread.arch.fs = (unsigned long) ptr;
73 save_registers(pid, &current->thread.regs.regs); 75 ret = save_registers(pid, &current->thread.regs.regs);
74 break; 76 break;
75 case ARCH_SET_GS: 77 case ARCH_SET_GS:
76 save_registers(pid, &current->thread.regs.regs); 78 ret = save_registers(pid, &current->thread.regs.regs);
77 break; 79 break;
78 case ARCH_GET_FS: 80 case ARCH_GET_FS:
79 ret = put_user(tmp, addr); 81 ret = put_user(tmp, addr);
@@ -105,7 +107,7 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp,
105 return ret; 107 return ret;
106} 108}
107 109
108void arch_switch_to(struct task_struct *from, struct task_struct *to) 110void arch_switch_to(struct task_struct *to)
109{ 111{
110 if ((to->thread.arch.fs == 0) || (to->mm == NULL)) 112 if ((to->thread.arch.fs == 0) || (to->mm == NULL))
111 return; 113 return;
diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c
index 765444031819..f4f82beb3508 100644
--- a/arch/um/sys-x86_64/sysrq.c
+++ b/arch/um/sys-x86_64/sysrq.c
@@ -4,32 +4,33 @@
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7#include "linux/kernel.h" 7#include <linux/kernel.h>
8#include "linux/utsname.h" 8#include <linux/module.h>
9#include "linux/module.h" 9#include <linux/sched.h>
10#include "asm/current.h" 10#include <linux/utsname.h>
11#include "asm/ptrace.h" 11#include <asm/current.h>
12#include <asm/ptrace.h>
12#include "sysrq.h" 13#include "sysrq.h"
13 14
14void __show_regs(struct pt_regs * regs) 15void __show_regs(struct pt_regs *regs)
15{ 16{
16 printk("\n"); 17 printk("\n");
17 print_modules(); 18 print_modules();
18 printk("Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current), 19 printk(KERN_INFO "Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current),
19 current->comm, print_tainted(), init_utsname()->release); 20 current->comm, print_tainted(), init_utsname()->release);
20 printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff, 21 printk(KERN_INFO "RIP: %04lx:[<%016lx>]\n", PT_REGS_CS(regs) & 0xffff,
21 PT_REGS_RIP(regs)); 22 PT_REGS_RIP(regs));
22 printk("\nRSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs), 23 printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs),
23 PT_REGS_EFLAGS(regs)); 24 PT_REGS_EFLAGS(regs));
24 printk("RAX: %016lx RBX: %016lx RCX: %016lx\n", 25 printk(KERN_INFO "RAX: %016lx RBX: %016lx RCX: %016lx\n",
25 PT_REGS_RAX(regs), PT_REGS_RBX(regs), PT_REGS_RCX(regs)); 26 PT_REGS_RAX(regs), PT_REGS_RBX(regs), PT_REGS_RCX(regs));
26 printk("RDX: %016lx RSI: %016lx RDI: %016lx\n", 27 printk(KERN_INFO "RDX: %016lx RSI: %016lx RDI: %016lx\n",
27 PT_REGS_RDX(regs), PT_REGS_RSI(regs), PT_REGS_RDI(regs)); 28 PT_REGS_RDX(regs), PT_REGS_RSI(regs), PT_REGS_RDI(regs));
28 printk("RBP: %016lx R08: %016lx R09: %016lx\n", 29 printk(KERN_INFO "RBP: %016lx R08: %016lx R09: %016lx\n",
29 PT_REGS_RBP(regs), PT_REGS_R8(regs), PT_REGS_R9(regs)); 30 PT_REGS_RBP(regs), PT_REGS_R8(regs), PT_REGS_R9(regs));
30 printk("R10: %016lx R11: %016lx R12: %016lx\n", 31 printk(KERN_INFO "R10: %016lx R11: %016lx R12: %016lx\n",
31 PT_REGS_R10(regs), PT_REGS_R11(regs), PT_REGS_R12(regs)); 32 PT_REGS_R10(regs), PT_REGS_R11(regs), PT_REGS_R12(regs));
32 printk("R13: %016lx R14: %016lx R15: %016lx\n", 33 printk(KERN_INFO "R13: %016lx R14: %016lx R15: %016lx\n",
33 PT_REGS_R13(regs), PT_REGS_R14(regs), PT_REGS_R15(regs)); 34 PT_REGS_R13(regs), PT_REGS_R14(regs), PT_REGS_R15(regs));
34} 35}
35 36
diff --git a/arch/um/sys-x86_64/um_module.c b/arch/um/sys-x86_64/um_module.c
index 8b8eff1bd977..3dead392a415 100644
--- a/arch/um/sys-x86_64/um_module.c
+++ b/arch/um/sys-x86_64/um_module.c
@@ -1,7 +1,7 @@
1#include <linux/vmalloc.h> 1#include <linux/vmalloc.h>
2#include <linux/moduleloader.h> 2#include <linux/moduleloader.h>
3 3
4/*Copied from i386 arch/i386/kernel/module.c */ 4/* Copied from i386 arch/i386/kernel/module.c */
5void *module_alloc(unsigned long size) 5void *module_alloc(unsigned long size)
6{ 6{
7 if (size == 0) 7 if (size == 0)
@@ -13,7 +13,9 @@ void *module_alloc(unsigned long size)
13void module_free(struct module *mod, void *module_region) 13void module_free(struct module *mod, void *module_region)
14{ 14{
15 vfree(module_region); 15 vfree(module_region);
16 /* FIXME: If module_region == mod->init_region, trim exception 16 /*
17 table entries. */ 17 * FIXME: If module_region == mod->init_region, trim exception
18 * table entries.
19 */
18} 20}
19 21
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 59eef1c7fdaa..434821187cfc 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -465,6 +465,9 @@ config CALGARY_IOMMU_ENABLED_BY_DEFAULT
465 Calgary anyway, pass 'iommu=calgary' on the kernel command line. 465 Calgary anyway, pass 'iommu=calgary' on the kernel command line.
466 If unsure, say Y. 466 If unsure, say Y.
467 467
468config IOMMU_HELPER
469 def_bool (CALGARY_IOMMU || GART_IOMMU)
470
468# need this always selected by IOMMU for the VIA workaround 471# need this always selected by IOMMU for the VIA workaround
469config SWIOTLB 472config SWIOTLB
470 bool 473 bool
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 0db0a6291bbd..8022d3c695c0 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -722,7 +722,9 @@ ia32_sys_call_table:
722 .quad sys_epoll_pwait 722 .quad sys_epoll_pwait
723 .quad compat_sys_utimensat /* 320 */ 723 .quad compat_sys_utimensat /* 320 */
724 .quad compat_sys_signalfd 724 .quad compat_sys_signalfd
725 .quad compat_sys_timerfd 725 .quad sys_timerfd_create
726 .quad sys_eventfd 726 .quad sys_eventfd
727 .quad sys32_fallocate 727 .quad sys32_fallocate
728 .quad compat_sys_timerfd_settime /* 325 */
729 .quad compat_sys_timerfd_gettime
728ia32_syscall_end: 730ia32_syscall_end:
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 1fe7f043ebde..1b5464c2434f 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -35,6 +35,7 @@
35#include <linux/pci.h> 35#include <linux/pci.h>
36#include <linux/delay.h> 36#include <linux/delay.h>
37#include <linux/scatterlist.h> 37#include <linux/scatterlist.h>
38#include <linux/iommu-helper.h>
38#include <asm/gart.h> 39#include <asm/gart.h>
39#include <asm/calgary.h> 40#include <asm/calgary.h>
40#include <asm/tce.h> 41#include <asm/tce.h>
@@ -260,22 +261,28 @@ static void iommu_range_reserve(struct iommu_table *tbl,
260 spin_unlock_irqrestore(&tbl->it_lock, flags); 261 spin_unlock_irqrestore(&tbl->it_lock, flags);
261} 262}
262 263
263static unsigned long iommu_range_alloc(struct iommu_table *tbl, 264static unsigned long iommu_range_alloc(struct device *dev,
264 unsigned int npages) 265 struct iommu_table *tbl,
266 unsigned int npages)
265{ 267{
266 unsigned long flags; 268 unsigned long flags;
267 unsigned long offset; 269 unsigned long offset;
270 unsigned long boundary_size;
271
272 boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
273 PAGE_SIZE) >> PAGE_SHIFT;
268 274
269 BUG_ON(npages == 0); 275 BUG_ON(npages == 0);
270 276
271 spin_lock_irqsave(&tbl->it_lock, flags); 277 spin_lock_irqsave(&tbl->it_lock, flags);
272 278
273 offset = find_next_zero_string(tbl->it_map, tbl->it_hint, 279 offset = iommu_area_alloc(tbl->it_map, tbl->it_size, tbl->it_hint,
274 tbl->it_size, npages); 280 npages, 0, boundary_size, 0);
275 if (offset == ~0UL) { 281 if (offset == ~0UL) {
276 tbl->chip_ops->tce_cache_blast(tbl); 282 tbl->chip_ops->tce_cache_blast(tbl);
277 offset = find_next_zero_string(tbl->it_map, 0, 283
278 tbl->it_size, npages); 284 offset = iommu_area_alloc(tbl->it_map, tbl->it_size, 0,
285 npages, 0, boundary_size, 0);
279 if (offset == ~0UL) { 286 if (offset == ~0UL) {
280 printk(KERN_WARNING "Calgary: IOMMU full.\n"); 287 printk(KERN_WARNING "Calgary: IOMMU full.\n");
281 spin_unlock_irqrestore(&tbl->it_lock, flags); 288 spin_unlock_irqrestore(&tbl->it_lock, flags);
@@ -286,7 +293,6 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
286 } 293 }
287 } 294 }
288 295
289 set_bit_string(tbl->it_map, offset, npages);
290 tbl->it_hint = offset + npages; 296 tbl->it_hint = offset + npages;
291 BUG_ON(tbl->it_hint > tbl->it_size); 297 BUG_ON(tbl->it_hint > tbl->it_size);
292 298
@@ -295,13 +301,13 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
295 return offset; 301 return offset;
296} 302}
297 303
298static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *vaddr, 304static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
299 unsigned int npages, int direction) 305 void *vaddr, unsigned int npages, int direction)
300{ 306{
301 unsigned long entry; 307 unsigned long entry;
302 dma_addr_t ret = bad_dma_address; 308 dma_addr_t ret = bad_dma_address;
303 309
304 entry = iommu_range_alloc(tbl, npages); 310 entry = iommu_range_alloc(dev, tbl, npages);
305 311
306 if (unlikely(entry == bad_dma_address)) 312 if (unlikely(entry == bad_dma_address))
307 goto error; 313 goto error;
@@ -354,7 +360,7 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
354 badbit, tbl, dma_addr, entry, npages); 360 badbit, tbl, dma_addr, entry, npages);
355 } 361 }
356 362
357 __clear_bit_string(tbl->it_map, entry, npages); 363 iommu_area_free(tbl->it_map, entry, npages);
358 364
359 spin_unlock_irqrestore(&tbl->it_lock, flags); 365 spin_unlock_irqrestore(&tbl->it_lock, flags);
360} 366}
@@ -438,7 +444,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
438 vaddr = (unsigned long) sg_virt(s); 444 vaddr = (unsigned long) sg_virt(s);
439 npages = num_dma_pages(vaddr, s->length); 445 npages = num_dma_pages(vaddr, s->length);
440 446
441 entry = iommu_range_alloc(tbl, npages); 447 entry = iommu_range_alloc(dev, tbl, npages);
442 if (entry == bad_dma_address) { 448 if (entry == bad_dma_address) {
443 /* makes sure unmap knows to stop */ 449 /* makes sure unmap knows to stop */
444 s->dma_length = 0; 450 s->dma_length = 0;
@@ -476,7 +482,7 @@ static dma_addr_t calgary_map_single(struct device *dev, void *vaddr,
476 npages = num_dma_pages(uaddr, size); 482 npages = num_dma_pages(uaddr, size);
477 483
478 if (translation_enabled(tbl)) 484 if (translation_enabled(tbl))
479 dma_handle = iommu_alloc(tbl, vaddr, npages, direction); 485 dma_handle = iommu_alloc(dev, tbl, vaddr, npages, direction);
480 else 486 else
481 dma_handle = virt_to_bus(vaddr); 487 dma_handle = virt_to_bus(vaddr);
482 488
@@ -516,7 +522,7 @@ static void* calgary_alloc_coherent(struct device *dev, size_t size,
516 522
517 if (translation_enabled(tbl)) { 523 if (translation_enabled(tbl)) {
518 /* set up tces to cover the allocated range */ 524 /* set up tces to cover the allocated range */
519 mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL); 525 mapping = iommu_alloc(dev, tbl, ret, npages, DMA_BIDIRECTIONAL);
520 if (mapping == bad_dma_address) 526 if (mapping == bad_dma_address)
521 goto free; 527 goto free;
522 528
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 845cbecd68e9..65f6acb025c8 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -25,6 +25,7 @@
25#include <linux/bitops.h> 25#include <linux/bitops.h>
26#include <linux/kdebug.h> 26#include <linux/kdebug.h>
27#include <linux/scatterlist.h> 27#include <linux/scatterlist.h>
28#include <linux/iommu-helper.h>
28#include <asm/atomic.h> 29#include <asm/atomic.h>
29#include <asm/io.h> 30#include <asm/io.h>
30#include <asm/mtrr.h> 31#include <asm/mtrr.h>
@@ -82,17 +83,24 @@ AGPEXTERN __u32 *agp_gatt_table;
82static unsigned long next_bit; /* protected by iommu_bitmap_lock */ 83static unsigned long next_bit; /* protected by iommu_bitmap_lock */
83static int need_flush; /* global flush state. set for each gart wrap */ 84static int need_flush; /* global flush state. set for each gart wrap */
84 85
85static unsigned long alloc_iommu(int size) 86static unsigned long alloc_iommu(struct device *dev, int size)
86{ 87{
87 unsigned long offset, flags; 88 unsigned long offset, flags;
89 unsigned long boundary_size;
90 unsigned long base_index;
91
92 base_index = ALIGN(iommu_bus_base & dma_get_seg_boundary(dev),
93 PAGE_SIZE) >> PAGE_SHIFT;
94 boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1,
95 PAGE_SIZE) >> PAGE_SHIFT;
88 96
89 spin_lock_irqsave(&iommu_bitmap_lock, flags); 97 spin_lock_irqsave(&iommu_bitmap_lock, flags);
90 offset = find_next_zero_string(iommu_gart_bitmap, next_bit, 98 offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, next_bit,
91 iommu_pages, size); 99 size, base_index, boundary_size, 0);
92 if (offset == -1) { 100 if (offset == -1) {
93 need_flush = 1; 101 need_flush = 1;
94 offset = find_next_zero_string(iommu_gart_bitmap, 0, 102 offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, 0,
95 iommu_pages, size); 103 size, base_index, boundary_size, 0);
96 } 104 }
97 if (offset != -1) { 105 if (offset != -1) {
98 set_bit_string(iommu_gart_bitmap, offset, size); 106 set_bit_string(iommu_gart_bitmap, offset, size);
@@ -114,7 +122,7 @@ static void free_iommu(unsigned long offset, int size)
114 unsigned long flags; 122 unsigned long flags;
115 123
116 spin_lock_irqsave(&iommu_bitmap_lock, flags); 124 spin_lock_irqsave(&iommu_bitmap_lock, flags);
117 __clear_bit_string(iommu_gart_bitmap, offset, size); 125 iommu_area_free(iommu_gart_bitmap, offset, size);
118 spin_unlock_irqrestore(&iommu_bitmap_lock, flags); 126 spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
119} 127}
120 128
@@ -235,7 +243,7 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
235 size_t size, int dir) 243 size_t size, int dir)
236{ 244{
237 unsigned long npages = to_pages(phys_mem, size); 245 unsigned long npages = to_pages(phys_mem, size);
238 unsigned long iommu_page = alloc_iommu(npages); 246 unsigned long iommu_page = alloc_iommu(dev, npages);
239 int i; 247 int i;
240 248
241 if (iommu_page == -1) { 249 if (iommu_page == -1) {
@@ -355,10 +363,11 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
355} 363}
356 364
357/* Map multiple scatterlist entries continuous into the first. */ 365/* Map multiple scatterlist entries continuous into the first. */
358static int __dma_map_cont(struct scatterlist *start, int nelems, 366static int __dma_map_cont(struct device *dev, struct scatterlist *start,
359 struct scatterlist *sout, unsigned long pages) 367 int nelems, struct scatterlist *sout,
368 unsigned long pages)
360{ 369{
361 unsigned long iommu_start = alloc_iommu(pages); 370 unsigned long iommu_start = alloc_iommu(dev, pages);
362 unsigned long iommu_page = iommu_start; 371 unsigned long iommu_page = iommu_start;
363 struct scatterlist *s; 372 struct scatterlist *s;
364 int i; 373 int i;
@@ -394,8 +403,8 @@ static int __dma_map_cont(struct scatterlist *start, int nelems,
394} 403}
395 404
396static inline int 405static inline int
397dma_map_cont(struct scatterlist *start, int nelems, struct scatterlist *sout, 406dma_map_cont(struct device *dev, struct scatterlist *start, int nelems,
398 unsigned long pages, int need) 407 struct scatterlist *sout, unsigned long pages, int need)
399{ 408{
400 if (!need) { 409 if (!need) {
401 BUG_ON(nelems != 1); 410 BUG_ON(nelems != 1);
@@ -403,7 +412,7 @@ dma_map_cont(struct scatterlist *start, int nelems, struct scatterlist *sout,
403 sout->dma_length = start->length; 412 sout->dma_length = start->length;
404 return 0; 413 return 0;
405 } 414 }
406 return __dma_map_cont(start, nelems, sout, pages); 415 return __dma_map_cont(dev, start, nelems, sout, pages);
407} 416}
408 417
409/* 418/*
@@ -416,6 +425,8 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
416 struct scatterlist *s, *ps, *start_sg, *sgmap; 425 struct scatterlist *s, *ps, *start_sg, *sgmap;
417 int need = 0, nextneed, i, out, start; 426 int need = 0, nextneed, i, out, start;
418 unsigned long pages = 0; 427 unsigned long pages = 0;
428 unsigned int seg_size;
429 unsigned int max_seg_size;
419 430
420 if (nents == 0) 431 if (nents == 0)
421 return 0; 432 return 0;
@@ -426,6 +437,8 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
426 out = 0; 437 out = 0;
427 start = 0; 438 start = 0;
428 start_sg = sgmap = sg; 439 start_sg = sgmap = sg;
440 seg_size = 0;
441 max_seg_size = dma_get_max_seg_size(dev);
429 ps = NULL; /* shut up gcc */ 442 ps = NULL; /* shut up gcc */
430 for_each_sg(sg, s, nents, i) { 443 for_each_sg(sg, s, nents, i) {
431 dma_addr_t addr = sg_phys(s); 444 dma_addr_t addr = sg_phys(s);
@@ -443,11 +456,13 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
443 * offset. 456 * offset.
444 */ 457 */
445 if (!iommu_merge || !nextneed || !need || s->offset || 458 if (!iommu_merge || !nextneed || !need || s->offset ||
459 (s->length + seg_size > max_seg_size) ||
446 (ps->offset + ps->length) % PAGE_SIZE) { 460 (ps->offset + ps->length) % PAGE_SIZE) {
447 if (dma_map_cont(start_sg, i - start, sgmap, 461 if (dma_map_cont(dev, start_sg, i - start,
448 pages, need) < 0) 462 sgmap, pages, need) < 0)
449 goto error; 463 goto error;
450 out++; 464 out++;
465 seg_size = 0;
451 sgmap = sg_next(sgmap); 466 sgmap = sg_next(sgmap);
452 pages = 0; 467 pages = 0;
453 start = i; 468 start = i;
@@ -455,11 +470,12 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
455 } 470 }
456 } 471 }
457 472
473 seg_size += s->length;
458 need = nextneed; 474 need = nextneed;
459 pages += to_pages(s->offset, s->length); 475 pages += to_pages(s->offset, s->length);
460 ps = s; 476 ps = s;
461 } 477 }
462 if (dma_map_cont(start_sg, i - start, sgmap, pages, need) < 0) 478 if (dma_map_cont(dev, start_sg, i - start, sgmap, pages, need) < 0)
463 goto error; 479 goto error;
464 out++; 480 out++;
465 flush_gart(); 481 flush_gart();
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
index 8344c70adf61..adff5562f5fd 100644
--- a/arch/x86/kernel/syscall_table_32.S
+++ b/arch/x86/kernel/syscall_table_32.S
@@ -321,6 +321,8 @@ ENTRY(sys_call_table)
321 .long sys_epoll_pwait 321 .long sys_epoll_pwait
322 .long sys_utimensat /* 320 */ 322 .long sys_utimensat /* 320 */
323 .long sys_signalfd 323 .long sys_signalfd
324 .long sys_timerfd 324 .long sys_timerfd_create
325 .long sys_eventfd 325 .long sys_eventfd
326 .long sys_fallocate 326 .long sys_fallocate
327 .long sys_timerfd_settime /* 325 */
328 .long sys_timerfd_gettime
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 8f94a0b89dff..cf5308148689 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1739,7 +1739,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
1739 if (bytes == 8) { 1739 if (bytes == 8) {
1740 gpa_t gpa; 1740 gpa_t gpa;
1741 struct page *page; 1741 struct page *page;
1742 char *addr; 1742 char *kaddr;
1743 u64 val; 1743 u64 val;
1744 1744
1745 down_read(&current->mm->mmap_sem); 1745 down_read(&current->mm->mmap_sem);
@@ -1754,9 +1754,9 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
1754 1754
1755 val = *(u64 *)new; 1755 val = *(u64 *)new;
1756 page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); 1756 page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
1757 addr = kmap_atomic(page, KM_USER0); 1757 kaddr = kmap_atomic(page, KM_USER0);
1758 set_64bit((u64 *)(addr + offset_in_page(gpa)), val); 1758 set_64bit((u64 *)(kaddr + offset_in_page(gpa)), val);
1759 kunmap_atomic(addr, KM_USER0); 1759 kunmap_atomic(kaddr, KM_USER0);
1760 kvm_release_page_dirty(page); 1760 kvm_release_page_dirty(page);
1761 emul_write: 1761 emul_write:
1762 up_read(&current->mm->mmap_sem); 1762 up_read(&current->mm->mmap_sem);
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 4876182daf8a..25df1c1989fe 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -21,7 +21,7 @@ else
21 21
22 lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o 22 lib-y += csum-partial_64.o csum-copy_64.o csum-wrappers_64.o
23 lib-y += thunk_64.o clear_page_64.o copy_page_64.o 23 lib-y += thunk_64.o clear_page_64.o copy_page_64.o
24 lib-y += bitstr_64.o bitops_64.o 24 lib-y += bitops_64.o
25 lib-y += memmove_64.o memset_64.o 25 lib-y += memmove_64.o memset_64.o
26 lib-y += copy_user_64.o rwlock_64.o copy_user_nocache_64.o 26 lib-y += copy_user_64.o rwlock_64.o copy_user_nocache_64.o
27endif 27endif
diff --git a/arch/x86/lib/bitstr_64.c b/arch/x86/lib/bitstr_64.c
deleted file mode 100644
index 7445caf1b5de..000000000000
--- a/arch/x86/lib/bitstr_64.c
+++ /dev/null
@@ -1,28 +0,0 @@
1#include <linux/module.h>
2#include <linux/bitops.h>
3
4/* Find string of zero bits in a bitmap */
5unsigned long
6find_next_zero_string(unsigned long *bitmap, long start, long nbits, int len)
7{
8 unsigned long n, end, i;
9
10 again:
11 n = find_next_zero_bit(bitmap, nbits, start);
12 if (n == -1)
13 return -1;
14
15 /* could test bitsliced, but it's hardly worth it */
16 end = n+len;
17 if (end > nbits)
18 return -1;
19 for (i = n+1; i < end; i++) {
20 if (test_bit(i, bitmap)) {
21 start = i+1;
22 goto again;
23 }
24 }
25 return n;
26}
27
28EXPORT_SYMBOL(find_next_zero_string);
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
index c7db504be1ea..6c1914622a88 100644
--- a/arch/x86/mm/pgtable_32.c
+++ b/arch/x86/mm/pgtable_32.c
@@ -272,7 +272,7 @@ static void pgd_dtor(void *pgd)
272 * preallocate which never got a corresponding vma will need to be 272 * preallocate which never got a corresponding vma will need to be
273 * freed manually. 273 * freed manually.
274 */ 274 */
275static void pgd_mop_up_pmds(pgd_t *pgdp) 275static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp)
276{ 276{
277 int i; 277 int i;
278 278
@@ -285,7 +285,7 @@ static void pgd_mop_up_pmds(pgd_t *pgdp)
285 pgdp[i] = native_make_pgd(0); 285 pgdp[i] = native_make_pgd(0);
286 286
287 paravirt_release_pd(pgd_val(pgd) >> PAGE_SHIFT); 287 paravirt_release_pd(pgd_val(pgd) >> PAGE_SHIFT);
288 pmd_free(pmd); 288 pmd_free(mm, pmd);
289 } 289 }
290 } 290 }
291} 291}
@@ -313,7 +313,7 @@ static int pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd)
313 pmd_t *pmd = pmd_alloc_one(mm, addr); 313 pmd_t *pmd = pmd_alloc_one(mm, addr);
314 314
315 if (!pmd) { 315 if (!pmd) {
316 pgd_mop_up_pmds(pgd); 316 pgd_mop_up_pmds(mm, pgd);
317 return 0; 317 return 0;
318 } 318 }
319 319
@@ -333,7 +333,7 @@ static int pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd)
333 return 1; 333 return 1;
334} 334}
335 335
336static void pgd_mop_up_pmds(pgd_t *pgd) 336static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp)
337{ 337{
338} 338}
339#endif /* CONFIG_X86_PAE */ 339#endif /* CONFIG_X86_PAE */
@@ -352,9 +352,9 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
352 return pgd; 352 return pgd;
353} 353}
354 354
355void pgd_free(pgd_t *pgd) 355void pgd_free(struct mm_struct *mm, pgd_t *pgd)
356{ 356{
357 pgd_mop_up_pmds(pgd); 357 pgd_mop_up_pmds(mm, pgd);
358 quicklist_free(0, pgd_dtor, pgd); 358 quicklist_free(0, pgd_dtor, pgd);
359} 359}
360 360
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 42ba0e2da1a0..103b9dff1213 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -72,7 +72,7 @@ pcibios_align_resource(void *data, struct resource *res,
72 } 72 }
73 } 73 }
74} 74}
75 75EXPORT_SYMBOL(pcibios_align_resource);
76 76
77/* 77/*
78 * Handle resources of PCI devices. If the world were perfect, we could 78 * Handle resources of PCI devices. If the world were perfect, we could