]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branches 'ftrace', 'gic', 'io', 'kexec', 'mod', 'sa11x0', 'sh' and 'versatile...
authorRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 5 Jan 2011 18:08:10 +0000 (18:08 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 5 Jan 2011 18:08:10 +0000 (18:08 +0000)
84 files changed:
arch/arm/Kconfig
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/head-shmobile.S [new file with mode: 0644]
arch/arm/common/Makefile
arch/arm/common/gic.c
arch/arm/common/timer-sp.c [moved from arch/arm/plat-versatile/timer-sp.c with 98% similarity]
arch/arm/include/asm/elf.h
arch/arm/include/asm/hardware/entry-macro-gic.S [new file with mode: 0644]
arch/arm/include/asm/hardware/gic.h
arch/arm/include/asm/hardware/timer-sp.h [moved from arch/arm/plat-versatile/include/plat/timer-sp.h with 100% similarity]
arch/arm/include/asm/io.h
arch/arm/include/asm/kexec.h
arch/arm/include/asm/module.h
arch/arm/kernel/machine_kexec.c
arch/arm/kernel/module.c
arch/arm/kernel/smp_twd.c
arch/arm/mach-cns3xxx/core.c
arch/arm/mach-cns3xxx/core.h
arch/arm/mach-cns3xxx/include/mach/entry-macro.S
arch/arm/mach-davinci/include/mach/io.h
arch/arm/mach-integrator/integrator_cp.c
arch/arm/mach-iop13xx/include/mach/io.h
arch/arm/mach-iop32x/include/mach/io.h
arch/arm/mach-iop33x/include/mach/io.h
arch/arm/mach-ixp23xx/include/mach/io.h
arch/arm/mach-ixp4xx/include/mach/io.h
arch/arm/mach-kirkwood/include/mach/io.h
arch/arm/mach-msm/board-msm8x60.c
arch/arm/mach-omap2/include/mach/entry-macro.S
arch/arm/mach-omap2/include/mach/omap4-common.h
arch/arm/mach-omap2/omap-smp.c
arch/arm/mach-omap2/omap4-common.c
arch/arm/mach-orion5x/include/mach/io.h
arch/arm/mach-realview/core.c
arch/arm/mach-realview/core.h
arch/arm/mach-realview/include/mach/entry-macro.S
arch/arm/mach-realview/platsmp.c
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-realview/realview_pb1176.c
arch/arm/mach-realview/realview_pb11mp.c
arch/arm/mach-realview/realview_pba8.c
arch/arm/mach-realview/realview_pbx.c
arch/arm/mach-s5pv310/cpu.c
arch/arm/mach-s5pv310/include/mach/smp.h
arch/arm/mach-s5pv310/platsmp.c
arch/arm/mach-sa1100/Kconfig
arch/arm/mach-sa1100/Makefile
arch/arm/mach-sa1100/cpu-sa1100.c
arch/arm/mach-sa1100/cpu-sa1110.c
arch/arm/mach-sa1100/generic.c
arch/arm/mach-sa1100/include/mach/hardware.h
arch/arm/mach-sa1100/include/mach/nanoengine.h [new file with mode: 0644]
arch/arm/mach-sa1100/nanoengine.c [new file with mode: 0644]
arch/arm/mach-sa1100/pci-nanoengine.c [new file with mode: 0644]
arch/arm/mach-sa1100/simpad.c
arch/arm/mach-shmobile/board-ap4evb.c
arch/arm/mach-shmobile/include/mach/head-ap4evb.txt [new file with mode: 0644]
arch/arm/mach-shmobile/include/mach/zboot.h [new file with mode: 0644]
arch/arm/mach-shmobile/include/mach/zboot_macros.h [new file with mode: 0644]
arch/arm/mach-tegra/include/mach/entry-macro.S
arch/arm/mach-tegra/include/mach/io.h
arch/arm/mach-tegra/irq.c
arch/arm/mach-tegra/platsmp.c
arch/arm/mach-ux500/cpu.c
arch/arm/mach-ux500/include/mach/entry-macro.S
arch/arm/mach-ux500/platsmp.c
arch/arm/mach-versatile/core.c
arch/arm/mach-vexpress/core.h
arch/arm/mach-vexpress/ct-ca9x4.c
arch/arm/mach-vexpress/include/mach/entry-macro.S
arch/arm/mach-vexpress/platsmp.c
arch/arm/mach-vexpress/v2m.c
arch/arm/plat-omap/include/plat/io.h
arch/arm/plat-versatile/Makefile
drivers/pcmcia/Makefile
drivers/pcmcia/sa1100_generic.c
drivers/pcmcia/sa1100_generic.h
drivers/pcmcia/sa1100_nanoengine.c [new file with mode: 0644]
drivers/pcmcia/soc_common.c
drivers/rtc/rtc-sa1100.c
fs/proc/vmcore.c
include/linux/crash_dump.h
scripts/recordmcount.c
scripts/recordmcount.h

index d56d21c0573ba519b36d7f1e4012eb609dfbb664..9d26083633902078535c96f6445e3249ddd9d2d0 100644 (file)
@@ -23,6 +23,7 @@ config ARM
        select PERF_USE_VMALLOC
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V7))
+       select HAVE_C_RECORDMCOUNT
        help
          The ARM series is a line of low-power-consumption RISC chip designs
          licensed by ARM Ltd and targeted at embedded applications and
@@ -1164,7 +1165,7 @@ config ISA_DMA_API
        bool
 
 config PCI
-       bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX
+       bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX || SA1100_NANOENGINE
        help
          Find out whether you have a PCI motherboard. PCI is the name of a
          bus system, i.e. the way the CPU talks to the other stuff inside
@@ -1175,6 +1176,12 @@ config PCI_DOMAINS
        bool
        depends on PCI
 
+config PCI_NANOENGINE
+       bool "BSE nanoEngine PCI support"
+       depends on SA1100_NANOENGINE
+       help
+         Enable PCI on the BSE nanoEngine board.
+
 config PCI_SYSCALL
        def_bool PCI
 
@@ -1650,6 +1657,19 @@ config ATAGS_PROC
          Should the atags used to boot the kernel be exported in an "atags"
          file in procfs. Useful with kexec.
 
+config CRASH_DUMP
+       bool "Build kdump crash kernel (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       help
+         Generate crash dump after being started by kexec. This should
+         be normally only set in special crash dump kernels which are
+         loaded in the main kernel with kexec-tools into a specially
+         reserved region and then later executed after a crash by
+         kdump/kexec. The crash dump kernel must be compiled to a
+         memory address not used by the main kernel
+
+         For more details see Documentation/kdump/kdump.txt
+
 config AUTO_ZRELADDR
        bool "Auto calculation of the decompressed kernel image address"
        depends on !ZBOOT_ROM && !ARCH_U300
index 65a7c1c588a94ab4623be0ddfe02a691fb2954c6..0a8f748e506adfc415b857bc94dec36e25498999 100644 (file)
@@ -45,6 +45,10 @@ else
 endif
 endif
 
+ifeq ($(CONFIG_ARCH_SHMOBILE),y)
+OBJS           += head-shmobile.o
+endif
+
 #
 # We now have a PIC decompressor implementation.  Decompressors running
 # from RAM should not define ZTEXTADDR.  Decompressors running directly
diff --git a/arch/arm/boot/compressed/head-shmobile.S b/arch/arm/boot/compressed/head-shmobile.S
new file mode 100644 (file)
index 0000000..30973b7
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * The head-file for SH-Mobile ARM platforms
+ *
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Simon Horman <horms@verge.net.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef CONFIG_ZBOOT_ROM
+
+       .section        ".start", "ax"
+
+       /* load board-specific initialization code */
+#include <mach/zboot.h>
+
+       b       1f
+__atags:@ tag #1
+       .long   12                      @ tag->hdr.size = tag_size(tag_core);
+       .long   0x54410001              @ tag->hdr.tag = ATAG_CORE;
+       .long   0                       @ tag->u.core.flags = 0;
+       .long   0                       @ tag->u.core.pagesize = 0;
+       .long   0                       @ tag->u.core.rootdev = 0;
+       @ tag #2
+       .long   8                       @ tag->hdr.size = tag_size(tag_mem32);
+       .long   0x54410002              @ tag->hdr.tag = ATAG_MEM;
+       .long   CONFIG_MEMORY_SIZE      @ tag->u.mem.size = CONFIG_MEMORY_SIZE;
+       .long   CONFIG_MEMORY_START     @ @ tag->u.mem.start = CONFIG_MEMORY_START;
+       @ tag #3
+       .long   0                       @ tag->hdr.size = 0
+       .long   0                       @ tag->hdr.tag = ATAG_NONE;
+1:
+
+       /* Set board ID necessary for boot */
+       ldr     r7, 1f                          @ Set machine type register
+       adr     r8, __atags                     @ Set atag register
+       b       2f
+
+1 :    .long MACH_TYPE
+2 :
+
+#endif /* CONFIG_ZBOOT_ROM */
index e6e8664a94139cd7e4086020d537ded4ca087f9e..e7521bca2c3564eaf3d21663fbf4ae3721e43461 100644 (file)
@@ -17,3 +17,4 @@ obj-$(CONFIG_ARCH_IXP2000)    += uengine.o
 obj-$(CONFIG_ARCH_IXP23XX)     += uengine.o
 obj-$(CONFIG_PCI_HOST_ITE8152)  += it8152.o
 obj-$(CONFIG_COMMON_CLKDEV)    += clkdev.o
+obj-$(CONFIG_ARM_TIMER_SP804)  += timer-sp.o
index e6388dcd8cfa2cf5f7a31ee59a6728bda377f89c..0b89ef001330d5f7ef0f256a4081cac0fc47a396 100644 (file)
@@ -35,6 +35,9 @@
 
 static DEFINE_SPINLOCK(irq_controller_lock);
 
+/* Address of GIC 0 CPU interface */
+void __iomem *gic_cpu_base_addr __read_mostly;
+
 struct gic_chip_data {
        unsigned int irq_offset;
        void __iomem *dist_base;
@@ -45,7 +48,7 @@ struct gic_chip_data {
 #define MAX_GIC_NR     1
 #endif
 
-static struct gic_chip_data gic_data[MAX_GIC_NR];
+static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly;
 
 static inline void __iomem *gic_dist_base(unsigned int irq)
 {
@@ -213,21 +216,16 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
        set_irq_chained_handler(irq, gic_handle_cascade_irq);
 }
 
-void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
-                         unsigned int irq_start)
+static void __init gic_dist_init(struct gic_chip_data *gic,
+       unsigned int irq_start)
 {
        unsigned int gic_irqs, irq_limit, i;
+       void __iomem *base = gic->dist_base;
        u32 cpumask = 1 << smp_processor_id();
 
-       if (gic_nr >= MAX_GIC_NR)
-               BUG();
-
        cpumask |= cpumask << 8;
        cpumask |= cpumask << 16;
 
-       gic_data[gic_nr].dist_base = base;
-       gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31;
-
        writel(0, base + GIC_DIST_CTRL);
 
        /*
@@ -267,7 +265,7 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
        /*
         * Limit number of interrupts registered to the platform maximum
         */
-       irq_limit = gic_data[gic_nr].irq_offset + gic_irqs;
+       irq_limit = gic->irq_offset + gic_irqs;
        if (WARN_ON(irq_limit > NR_IRQS))
                irq_limit = NR_IRQS;
 
@@ -276,7 +274,7 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
         */
        for (i = irq_start; i < irq_limit; i++) {
                set_irq_chip(i, &gic_chip);
-               set_irq_chip_data(i, &gic_data[gic_nr]);
+               set_irq_chip_data(i, gic);
                set_irq_handler(i, handle_level_irq);
                set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
        }
@@ -284,19 +282,12 @@ void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
        writel(1, base + GIC_DIST_CTRL);
 }
 
-void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)
+static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
 {
-       void __iomem *dist_base;
+       void __iomem *dist_base = gic->dist_base;
+       void __iomem *base = gic->cpu_base;
        int i;
 
-       if (gic_nr >= MAX_GIC_NR)
-               BUG();
-
-       dist_base = gic_data[gic_nr].dist_base;
-       BUG_ON(!dist_base);
-
-       gic_data[gic_nr].cpu_base = base;
-
        /*
         * Deal with the banked PPI and SGI interrupts - disable all
         * PPI interrupts, ensure all SGI interrupts are enabled.
@@ -314,6 +305,42 @@ void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)
        writel(1, base + GIC_CPU_CTRL);
 }
 
+void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
+       void __iomem *dist_base, void __iomem *cpu_base)
+{
+       struct gic_chip_data *gic;
+
+       BUG_ON(gic_nr >= MAX_GIC_NR);
+
+       gic = &gic_data[gic_nr];
+       gic->dist_base = dist_base;
+       gic->cpu_base = cpu_base;
+       gic->irq_offset = (irq_start - 1) & ~31;
+
+       if (gic_nr == 0)
+               gic_cpu_base_addr = cpu_base;
+
+       gic_dist_init(gic, irq_start);
+       gic_cpu_init(gic);
+}
+
+void __cpuinit gic_secondary_init(unsigned int gic_nr)
+{
+       BUG_ON(gic_nr >= MAX_GIC_NR);
+
+       gic_cpu_init(&gic_data[gic_nr]);
+}
+
+void __cpuinit gic_enable_ppi(unsigned int irq)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       irq_to_desc(irq)->status |= IRQ_NOPROBE;
+       gic_unmask_irq(irq);
+       local_irq_restore(flags);
+}
+
 #ifdef CONFIG_SMP
 void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
 {
similarity index 98%
rename from arch/arm/plat-versatile/timer-sp.c
rename to arch/arm/common/timer-sp.c
index fb0d1c299718c1537ca27a88da17b5439bf8b21d..4740313daa5b0eed4cd2d432903b5f25efda2a83 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/plat-versatile/timer-sp.c
+ *  linux/arch/arm/common/timer-sp.c
  *
  *  Copyright (C) 1999 - 2003 ARM Limited
  *  Copyright (C) 2000 Deep Blue Solutions Ltd
@@ -26,8 +26,6 @@
 
 #include <asm/hardware/arm_timer.h>
 
-#include <plat/timer-sp.h>
-
 /*
  * These timers are currently always setup to be clocked at 1MHz.
  */
index 8bb66bca2e3eb8a8561f2c63d9334e8991ebb728..c3cd8755e64897d49938c8b454dafec18c0ebffc 100644 (file)
@@ -99,6 +99,8 @@ struct elf32_hdr;
 extern int elf_check_arch(const struct elf32_hdr *);
 #define elf_check_arch elf_check_arch
 
+#define vmcore_elf64_check_arch(x) (0)
+
 extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int);
 #define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(&(ex), stk)
 
diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S
new file mode 100644 (file)
index 0000000..c115b82
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * arch/arm/include/asm/hardware/entry-macro-gic.S
+ *
+ * Low-level IRQ helper macros for GIC
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/hardware/gic.h>
+
+#ifndef HAVE_GET_IRQNR_PREAMBLE
+       .macro  get_irqnr_preamble, base, tmp
+       ldr     \base, =gic_cpu_base_addr
+       ldr     \base, [\base]
+       .endm
+#endif
+
+/*
+ * The interrupt numbering scheme is defined in the
+ * interrupt controller spec.  To wit:
+ *
+ * Interrupts 0-15 are IPI
+ * 16-28 are reserved
+ * 29-31 are local.  We allow 30 to be used for the watchdog.
+ * 32-1020 are global
+ * 1021-1022 are reserved
+ * 1023 is "spurious" (no interrupt)
+ *
+ * For now, we ignore all local interrupts so only return an interrupt if it's
+ * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs.
+ *
+ * A simple read from the controller will tell us the number of the highest
+ * priority enabled interrupt.  We then just need to check whether it is in the
+ * valid range for an IRQ (30-1020 inclusive).
+ */
+
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+       ldr     \irqstat, [\base, #GIC_CPU_INTACK]
+       /* bits 12-10 = src CPU, 9-0 = int # */
+
+       ldr     \tmp, =1021
+       bic     \irqnr, \irqstat, #0x1c00
+       cmp     \irqnr, #29
+       cmpcc   \irqnr, \irqnr
+       cmpne   \irqnr, \tmp
+       cmpcs   \irqnr, \irqnr
+       .endm
+
+/* We assume that irqstat (the raw value of the IRQ acknowledge
+ * register) is preserved from the macro above.
+ * If there is an IPI, we immediately signal end of interrupt on the
+ * controller, since this requires the original irqstat value which
+ * we won't easily be able to recreate later.
+ */
+
+       .macro test_for_ipi, irqnr, irqstat, base, tmp
+       bic     \irqnr, \irqstat, #0x1c00
+       cmp     \irqnr, #16
+       strcc   \irqstat, [\base, #GIC_CPU_EOI]
+       cmpcs   \irqnr, \irqnr
+       .endm
+
+/* As above, this assumes that irqstat and base are preserved.. */
+
+       .macro test_for_ltirq, irqnr, irqstat, base, tmp
+       bic     \irqnr, \irqstat, #0x1c00
+       mov     \tmp, #0
+       cmp     \irqnr, #29
+       moveq   \tmp, #1
+       streq   \irqstat, [\base, #GIC_CPU_EOI]
+       cmp     \tmp, #0
+       .endm
index 7f34333bb5455db6093e85f99ea3a8dd7d6d5fef..84557d321001396e62ca8949f126be0db2a1fcb1 100644 (file)
 #define GIC_DIST_SOFTINT               0xf00
 
 #ifndef __ASSEMBLY__
-void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start);
-void gic_cpu_init(unsigned int gic_nr, void __iomem *base);
+extern void __iomem *gic_cpu_base_addr;
+
+void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
+void gic_secondary_init(unsigned int);
 void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
 void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
+void gic_enable_ppi(unsigned int);
 #endif
 
 #endif
index 815efa2d4e07b5087e31965a06fc05c1fdfd9fa0..20e0f7c9e03ed91678324170d8039ceadeea37a3 100644 (file)
@@ -241,18 +241,15 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
  *
  */
 #ifndef __arch_ioremap
-#define ioremap(cookie,size)           __arm_ioremap(cookie, size, MT_DEVICE)
-#define ioremap_nocache(cookie,size)   __arm_ioremap(cookie, size, MT_DEVICE)
-#define ioremap_cached(cookie,size)    __arm_ioremap(cookie, size, MT_DEVICE_CACHED)
-#define ioremap_wc(cookie,size)                __arm_ioremap(cookie, size, MT_DEVICE_WC)
-#define iounmap(cookie)                        __iounmap(cookie)
-#else
+#define __arch_ioremap                 __arm_ioremap
+#define __arch_iounmap                 __iounmap
+#endif
+
 #define ioremap(cookie,size)           __arch_ioremap((cookie), (size), MT_DEVICE)
 #define ioremap_nocache(cookie,size)   __arch_ioremap((cookie), (size), MT_DEVICE)
 #define ioremap_cached(cookie,size)    __arch_ioremap((cookie), (size), MT_DEVICE_CACHED)
 #define ioremap_wc(cookie,size)                __arch_ioremap((cookie), (size), MT_DEVICE_WC)
-#define iounmap(cookie)                        __arch_iounmap(cookie)
-#endif
+#define iounmap                                __arch_iounmap
 
 /*
  * io{read,write}{8,16,32} macros
index 8ec9ef5c3c7be25a2705451e8aab0a8205a47e67..c0094d8edae45c1d331b0ec6a63a0105ee8a109a 100644 (file)
@@ -33,10 +33,20 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
        if (oldregs) {
                memcpy(newregs, oldregs, sizeof(*newregs));
        } else {
-               __asm__ __volatile__ ("stmia %0, {r0 - r15}"
-                                     : : "r" (&newregs->ARM_r0));
-               __asm__ __volatile__ ("mrs %0, cpsr"
-                                     : "=r" (newregs->ARM_cpsr));
+               __asm__ __volatile__ (
+                       "stmia  %[regs_base], {r0-r12}\n\t"
+                       "mov    %[_ARM_sp], sp\n\t"
+                       "str    lr, %[_ARM_lr]\n\t"
+                       "adr    %[_ARM_pc], 1f\n\t"
+                       "mrs    %[_ARM_cpsr], cpsr\n\t"
+               "1:"
+                       : [_ARM_pc] "=r" (newregs->ARM_pc),
+                         [_ARM_cpsr] "=r" (newregs->ARM_cpsr),
+                         [_ARM_sp] "=r" (newregs->ARM_sp),
+                         [_ARM_lr] "=o" (newregs->ARM_lr)
+                       : [regs_base] "r" (&newregs->ARM_r0)
+                       : "memory"
+               );
        }
 }
 
index cbb0bc295d2b184d380e63920dcb55930c7b76b7..12c8e680cbff777dbac6fe992eb4ddac60017913 100644 (file)
@@ -8,11 +8,6 @@
 struct unwind_table;
 
 #ifdef CONFIG_ARM_UNWIND
-struct arm_unwind_mapping {
-       Elf_Shdr *unw_sec;
-       Elf_Shdr *sec_text;
-       struct unwind_table *unwind;
-};
 enum {
        ARM_SEC_INIT,
        ARM_SEC_DEVINIT,
@@ -21,13 +16,13 @@ enum {
        ARM_SEC_DEVEXIT,
        ARM_SEC_MAX,
 };
+#endif
+
 struct mod_arch_specific {
-       struct arm_unwind_mapping map[ARM_SEC_MAX];
-};
-#else
-struct mod_arch_specific {
-};
+#ifdef CONFIG_ARM_UNWIND
+       struct unwind_table *unwind[ARM_SEC_MAX];
 #endif
+};
 
 /*
  * Include the ARM architecture version.
index 3a8fd5140d7a52ef33c8bfc444384ab8bc25c84a..30ead135ff5f48350192291a32662b0d3d0429d5 100644 (file)
@@ -23,6 +23,8 @@ extern unsigned long kexec_indirection_page;
 extern unsigned long kexec_mach_type;
 extern unsigned long kexec_boot_atags;
 
+static atomic_t waiting_for_crash_ipi;
+
 /*
  * Provide a dummy crash_notes definition while crash dump arrives to arm.
  * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
@@ -37,9 +39,37 @@ void machine_kexec_cleanup(struct kimage *image)
 {
 }
 
+void machine_crash_nonpanic_core(void *unused)
+{
+       struct pt_regs regs;
+
+       crash_setup_regs(&regs, NULL);
+       printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n",
+              smp_processor_id());
+       crash_save_cpu(&regs, smp_processor_id());
+       flush_cache_all();
+
+       atomic_dec(&waiting_for_crash_ipi);
+       while (1)
+               cpu_relax();
+}
+
 void machine_crash_shutdown(struct pt_regs *regs)
 {
+       unsigned long msecs;
+
        local_irq_disable();
+
+       atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
+       smp_call_function(machine_crash_nonpanic_core, NULL, false);
+       msecs = 1000; /* Wait at most a second for the other cpus to stop */
+       while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
+               mdelay(1);
+               msecs--;
+       }
+       if (atomic_read(&waiting_for_crash_ipi) > 0)
+               printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n");
+
        crash_save_cpu(regs, smp_processor_id());
 
        printk(KERN_INFO "Loading crashdump kernel...\n");
index d9bd786ce23dc1228ac7937ad442292f08c74cca..0c1bb68ff4a8449b5884949dc3498404532bb293 100644 (file)
@@ -67,35 +67,6 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
                              char *secstrings,
                              struct module *mod)
 {
-#ifdef CONFIG_ARM_UNWIND
-       Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
-       struct arm_unwind_mapping *maps = mod->arch.map;
-
-       for (s = sechdrs; s < sechdrs_end; s++) {
-               char const *secname = secstrings + s->sh_name;
-
-               if (strcmp(".ARM.exidx.init.text", secname) == 0)
-                       maps[ARM_SEC_INIT].unw_sec = s;
-               else if (strcmp(".ARM.exidx.devinit.text", secname) == 0)
-                       maps[ARM_SEC_DEVINIT].unw_sec = s;
-               else if (strcmp(".ARM.exidx", secname) == 0)
-                       maps[ARM_SEC_CORE].unw_sec = s;
-               else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
-                       maps[ARM_SEC_EXIT].unw_sec = s;
-               else if (strcmp(".ARM.exidx.devexit.text", secname) == 0)
-                       maps[ARM_SEC_DEVEXIT].unw_sec = s;
-               else if (strcmp(".init.text", secname) == 0)
-                       maps[ARM_SEC_INIT].sec_text = s;
-               else if (strcmp(".devinit.text", secname) == 0)
-                       maps[ARM_SEC_DEVINIT].sec_text = s;
-               else if (strcmp(".text", secname) == 0)
-                       maps[ARM_SEC_CORE].sec_text = s;
-               else if (strcmp(".exit.text", secname) == 0)
-                       maps[ARM_SEC_EXIT].sec_text = s;
-               else if (strcmp(".devexit.text", secname) == 0)
-                       maps[ARM_SEC_DEVEXIT].sec_text = s;
-       }
-#endif
        return 0;
 }
 
@@ -300,41 +271,69 @@ apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
        return -ENOEXEC;
 }
 
-#ifdef CONFIG_ARM_UNWIND
-static void register_unwind_tables(struct module *mod)
+struct mod_unwind_map {
+       const Elf_Shdr *unw_sec;
+       const Elf_Shdr *txt_sec;
+};
+
+int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
+                   struct module *mod)
 {
+#ifdef CONFIG_ARM_UNWIND
+       const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+       const Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
+       struct mod_unwind_map maps[ARM_SEC_MAX];
        int i;
-       for (i = 0; i < ARM_SEC_MAX; ++i) {
-               struct arm_unwind_mapping *map = &mod->arch.map[i];
-               if (map->unw_sec && map->sec_text)
-                       map->unwind = unwind_table_add(map->unw_sec->sh_addr,
-                                                      map->unw_sec->sh_size,
-                                                      map->sec_text->sh_addr,
-                                                      map->sec_text->sh_size);
+
+       memset(maps, 0, sizeof(maps));
+
+       for (s = sechdrs; s < sechdrs_end; s++) {
+               const char *secname = secstrs + s->sh_name;
+
+               if (!(s->sh_flags & SHF_ALLOC))
+                       continue;
+
+               if (strcmp(".ARM.exidx.init.text", secname) == 0)
+                       maps[ARM_SEC_INIT].unw_sec = s;
+               else if (strcmp(".ARM.exidx.devinit.text", secname) == 0)
+                       maps[ARM_SEC_DEVINIT].unw_sec = s;
+               else if (strcmp(".ARM.exidx", secname) == 0)
+                       maps[ARM_SEC_CORE].unw_sec = s;
+               else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
+                       maps[ARM_SEC_EXIT].unw_sec = s;
+               else if (strcmp(".ARM.exidx.devexit.text", secname) == 0)
+                       maps[ARM_SEC_DEVEXIT].unw_sec = s;
+               else if (strcmp(".init.text", secname) == 0)
+                       maps[ARM_SEC_INIT].txt_sec = s;
+               else if (strcmp(".devinit.text", secname) == 0)
+                       maps[ARM_SEC_DEVINIT].txt_sec = s;
+               else if (strcmp(".text", secname) == 0)
+                       maps[ARM_SEC_CORE].txt_sec = s;
+               else if (strcmp(".exit.text", secname) == 0)
+                       maps[ARM_SEC_EXIT].txt_sec = s;
+               else if (strcmp(".devexit.text", secname) == 0)
+                       maps[ARM_SEC_DEVEXIT].txt_sec = s;
        }
-}
 
-static void unregister_unwind_tables(struct module *mod)
-{
-       int i = ARM_SEC_MAX;
-       while (--i >= 0)
-               unwind_table_del(mod->arch.map[i].unwind);
-}
-#else
-static inline void register_unwind_tables(struct module *mod) { }
-static inline void unregister_unwind_tables(struct module *mod) { }
+       for (i = 0; i < ARM_SEC_MAX; i++)
+               if (maps[i].unw_sec && maps[i].txt_sec)
+                       mod->arch.unwind[i] =
+                               unwind_table_add(maps[i].unw_sec->sh_addr,
+                                                maps[i].unw_sec->sh_size,
+                                                maps[i].txt_sec->sh_addr,
+                                                maps[i].txt_sec->sh_size);
 #endif
-
-int
-module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
-               struct module *module)
-{
-       register_unwind_tables(module);
        return 0;
 }
 
 void
 module_arch_cleanup(struct module *mod)
 {
-       unregister_unwind_tables(mod);
+#ifdef CONFIG_ARM_UNWIND
+       int i;
+
+       for (i = 0; i < ARM_SEC_MAX; i++)
+               if (mod->arch.unwind[i])
+                       unwind_table_del(mod->arch.unwind[i]);
+#endif
 }
index 35882fbf37f90063723d3247352a3c05af480f99..67f933ec4177e2c2bcda7a3e4ce8ae5b6251b909 100644 (file)
@@ -127,8 +127,6 @@ static void __cpuinit twd_calibrate_rate(void)
  */
 void __cpuinit twd_timer_setup(struct clock_event_device *clk)
 {
-       unsigned long flags;
-
        twd_calibrate_rate();
 
        clk->name = "local_timer";
@@ -143,10 +141,7 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
        clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
 
        /* Make sure our local interrupt controller has this enabled */
-       local_irq_save(flags);
-       irq_to_desc(clk->irq)->status |= IRQ_NOPROBE;
-       get_irq_chip(clk->irq)->unmask(clk->irq);
-       local_irq_restore(flags);
+       gic_enable_ppi(clk->irq);
 
        clockevents_register_device(clk);
 }
index 9ca4d581016f8e21c307147713a91818fb449c2c..da30078a80c16078192373b67ac0ed59de30a7a7 100644 (file)
@@ -69,13 +69,10 @@ void __init cns3xxx_map_io(void)
 }
 
 /* used by entry-macro.S */
-void __iomem *gic_cpu_base_addr;
-
 void __init cns3xxx_init_irq(void)
 {
-       gic_cpu_base_addr = __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT);
-       gic_dist_init(0, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT), 29);
-       gic_cpu_init(0, gic_cpu_base_addr);
+       gic_init(0, 29, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT),
+                __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT));
 }
 
 void cns3xxx_power_off(void)
index 6b33ec11346e54b701fa61867804ecd1120d76e2..ef9e5116b1a99d89f26affcffd66deff5d997b19 100644 (file)
@@ -11,7 +11,6 @@
 #ifndef __CNS3XXX_CORE_H
 #define __CNS3XXX_CORE_H
 
-extern void __iomem *gic_cpu_base_addr;
 extern struct sys_timer cns3xxx_timer;
 
 void __init cns3xxx_map_io(void);
index 5e1c5545680f8a46c34723e78f3ba146a1477177..6bd83ed90afe33523c047b7bb22f8cf63c4b94a0 100644 (file)
@@ -9,74 +9,10 @@
  */
 
 #include <mach/hardware.h>
-#include <asm/hardware/gic.h>
+#include <asm/hardware/entry-macro-gic.S>
 
                .macro  disable_fiq
                .endm
 
-               .macro  get_irqnr_preamble, base, tmp
-               ldr     \base, =gic_cpu_base_addr
-               ldr     \base, [\base]
-               .endm
-
                .macro  arch_ret_to_user, tmp1, tmp2
                .endm
-
-               /*
-                * The interrupt numbering scheme is defined in the
-                * interrupt controller spec.  To wit:
-                *
-                * Interrupts 0-15 are IPI
-                * 16-28 are reserved
-                * 29-31 are local.  We allow 30 to be used for the watchdog.
-                * 32-1020 are global
-                * 1021-1022 are reserved
-                * 1023 is "spurious" (no interrupt)
-                *
-                * For now, we ignore all local interrupts so only return an interrupt if it's
-                * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs.
-                *
-                * A simple read from the controller will tell us the number of the highest
-                 * priority enabled interrupt.  We then just need to check whether it is in the
-                * valid range for an IRQ (30-1020 inclusive).
-                */
-
-               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-               ldr     \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
-
-               ldr     \tmp, =1021
-
-               bic     \irqnr, \irqstat, #0x1c00
-
-               cmp     \irqnr, #29
-               cmpcc   \irqnr, \irqnr
-               cmpne   \irqnr, \tmp
-               cmpcs   \irqnr, \irqnr
-
-               .endm
-
-               /* We assume that irqstat (the raw value of the IRQ acknowledge
-                * register) is preserved from the macro above.
-                * If there is an IPI, we immediately signal end of interrupt on the
-                * controller, since this requires the original irqstat value which
-                * we won't easily be able to recreate later.
-                */
-
-               .macro test_for_ipi, irqnr, irqstat, base, tmp
-               bic     \irqnr, \irqstat, #0x1c00
-               cmp     \irqnr, #16
-               strcc   \irqstat, [\base, #GIC_CPU_EOI]
-               cmpcs   \irqnr, \irqnr
-               .endm
-
-               /* As above, this assumes that irqstat and base are preserved.. */
-
-               .macro test_for_ltirq, irqnr, irqstat, base, tmp
-               bic     \irqnr, \irqstat, #0x1c00
-               mov     \tmp, #0
-               cmp     \irqnr, #29
-               moveq   \tmp, #1
-               streq   \irqstat, [\base, #GIC_CPU_EOI]
-               cmp     \tmp, #0
-               .endm
index 62b0a90309adff1a817b2953c4b689b39f7b58ba..d1b954955c1242321dc296056d70d4d849db5555 100644 (file)
@@ -22,8 +22,8 @@
 #define __mem_isa(a)           (a)
 
 #ifndef __ASSEMBLER__
-#define __arch_ioremap(p, s, t)        davinci_ioremap(p, s, t)
-#define __arch_iounmap(v)      davinci_iounmap(v)
+#define __arch_ioremap         davinci_ioremap
+#define __arch_iounmap         davinci_iounmap
 
 void __iomem *davinci_ioremap(unsigned long phys, size_t size,
                              unsigned int type);
index 6258c90d020c30edf75faa7f06976d6cedef2e7e..1713ecf0c95ffda65d98fdad81ee4fcc16660f72 100644 (file)
@@ -41,7 +41,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
-#include <plat/timer-sp.h>
+#include <asm/hardware/timer-sp.h>
 
 #include "common.h"
 
index a6e0f9e6ddcf4136147eb7dbd78bdab7dfa9b489..dffb234bb967ec9b3e76384a8c9af699747dea12 100644 (file)
@@ -35,7 +35,7 @@ extern u32 iop13xx_atux_mem_base;
 extern size_t iop13xx_atue_mem_size;
 extern size_t iop13xx_atux_mem_size;
 
-#define __arch_ioremap(a, s, f) __iop13xx_ioremap(a, s, f)
-#define __arch_iounmap(a)       __iop13xx_iounmap(a)
+#define __arch_ioremap __iop13xx_ioremap
+#define __arch_iounmap __iop13xx_iounmap
 
 #endif
index 339e5854728b5f1f3d1434d8570567b3bc6b2fc8..059c783ce0b2c8651ed5864b8fe4a047894e67d9 100644 (file)
@@ -21,7 +21,7 @@ extern void __iop3xx_iounmap(void __iomem *addr);
 #define __io(p)                ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
 #define __mem_pci(a)           (a)
 
-#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f)
-#define __arch_iounmap(a)       __iop3xx_iounmap(a)
+#define __arch_ioremap __iop3xx_ioremap
+#define __arch_iounmap __iop3xx_iounmap
 
 #endif
index e99a7ed6d0502e0390ccb9f0e4de0c2f7890ba2c..39e893e97c212ba8b67875ee56fcb708189e4460 100644 (file)
@@ -21,7 +21,7 @@ extern void __iop3xx_iounmap(void __iomem *addr);
 #define __io(p)                ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
 #define __mem_pci(a)           (a)
 
-#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f)
-#define __arch_iounmap(a)       __iop3xx_iounmap(a)
+#define __arch_ioremap __iop3xx_ioremap
+#define __arch_iounmap __iop3xx_iounmap
 
 #endif
index fd9ef8e519f7dee6c3ea9cbfd7b4e2bca9d96f37..a1749d0fd8961df2d2f57068950660146b325302 100644 (file)
@@ -45,8 +45,8 @@ ixp23xx_iounmap(void __iomem *addr)
        __iounmap(addr);
 }
 
-#define __arch_ioremap(a,s,f)  ixp23xx_ioremap(a,s,f)
-#define __arch_iounmap(a)      ixp23xx_iounmap(a)
+#define __arch_ioremap ixp23xx_ioremap
+#define __arch_iounmap ixp23xx_iounmap
 
 
 #endif
index de274a1f19d76a95d715b0d3b05d44469171d3a2..57b5410c31f40dc9db120b0b8f04b0e55c0912d6 100644 (file)
@@ -74,8 +74,8 @@ static inline void __indirect_iounmap(void __iomem *addr)
                __iounmap(addr);
 }
 
-#define __arch_ioremap(a, s, f)                __indirect_ioremap(a, s, f)
-#define __arch_iounmap(a)              __indirect_iounmap(a)
+#define __arch_ioremap                 __indirect_ioremap
+#define __arch_iounmap                 __indirect_iounmap
 
 #define writeb(v, p)                   __indirect_writeb(v, p)
 #define writew(v, p)                   __indirect_writew(v, p)
index 44e8be04f25929b6ef792ac75af0b540a09841d5..1aaddc364f2e6259eca95e6bd4e815322fb67673 100644 (file)
@@ -42,8 +42,8 @@ __arch_iounmap(void __iomem *addr)
                __iounmap(addr);
 }
 
-#define __arch_ioremap(p, s, m)        __arch_ioremap(p, s, m)
-#define __arch_iounmap(a)      __arch_iounmap(a)
+#define __arch_ioremap         __arch_ioremap
+#define __arch_iounmap         __arch_iounmap
 #define __io(a)                        __io(a)
 #define __mem_pci(a)           (a)
 
index 7486a681cc7192bfd5c7b04fca59757ca256f7ac..9b5eb2b4ae1b8507a78927e43ce8c9c27b4220f6 100644 (file)
@@ -28,8 +28,6 @@
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
 
-void __iomem *gic_cpu_base_addr;
-
 unsigned long clk_get_max_axi_khz(void)
 {
        return 0;
@@ -44,9 +42,8 @@ static void __init msm8x60_init_irq(void)
 {
        unsigned int i;
 
-       gic_dist_init(0, MSM_QGIC_DIST_BASE, GIC_PPI_START);
-       gic_cpu_base_addr = (void *)MSM_QGIC_CPU_BASE;
-       gic_cpu_init(0, MSM_QGIC_CPU_BASE);
+       gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
+                (void *)MSM_QGIC_CPU_BASE);
 
        /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
        writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
index 06e64e1fc28a7e18957ff0bb9fe620e7487f7284..d54c4f89a8bd0b912dc9f5da70e31e5305d1e2ce 100644 (file)
@@ -105,6 +105,35 @@ omap_irq_base:     .word   0
 9999:
                .endm
 
+#ifdef CONFIG_SMP
+               /* We assume that irqstat (the raw value of the IRQ acknowledge
+                * register) is preserved from the macro above.
+                * If there is an IPI, we immediately signal end of interrupt
+                * on the controller, since this requires the original irqstat
+                * value which we won't easily be able to recreate later.
+                */
+
+               .macro test_for_ipi, irqnr, irqstat, base, tmp
+               bic     \irqnr, \irqstat, #0x1c00
+               cmp     \irqnr, #16
+               it      cc
+               strcc   \irqstat, [\base, #GIC_CPU_EOI]
+               it      cs
+               cmpcs   \irqnr, \irqnr
+               .endm
+
+               /* As above, this assumes that irqstat and base are preserved */
+
+               .macro test_for_ltirq, irqnr, irqstat, base, tmp
+               bic     \irqnr, \irqstat, #0x1c00
+               mov     \tmp, #0
+               cmp     \irqnr, #29
+               itt     eq
+               moveq   \tmp, #1
+               streq   \irqstat, [\base, #GIC_CPU_EOI]
+               cmp     \tmp, #0
+               .endm
+#endif /* CONFIG_SMP */
 
 #else  /* MULTI_OMAP2 */
 
@@ -141,74 +170,16 @@ omap_irq_base:    .word   0
 
 
 #ifdef CONFIG_ARCH_OMAP4
+#define HAVE_GET_IRQNR_PREAMBLE
+#include <asm/hardware/entry-macro-gic.S>
 
                .macro  get_irqnr_preamble, base, tmp
                ldr     \base, =OMAP4_IRQ_BASE
                .endm
 
-               /*
-                * The interrupt numbering scheme is defined in the
-                * interrupt controller spec.  To wit:
-                *
-                * Interrupts 0-15 are IPI
-                * 16-28 are reserved
-                * 29-31 are local.  We allow 30 to be used for the watchdog.
-                * 32-1020 are global
-                * 1021-1022 are reserved
-                * 1023 is "spurious" (no interrupt)
-                *
-                * For now, we ignore all local interrupts so only return an
-                * interrupt if it's between 30 and 1020.  The test_for_ipi
-                * routine below will pick up on IPIs.
-                * A simple read from the controller will tell us the number
-                * of the highest priority enabled interrupt.
-                * We then just need to check whether it is in the
-                * valid range for an IRQ (30-1020 inclusive).
-                */
-               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-               ldr     \irqstat, [\base, #GIC_CPU_INTACK]
-
-               ldr     \tmp, =1021
-
-               bic     \irqnr, \irqstat, #0x1c00
-
-               cmp     \irqnr, #29
-               cmpcc   \irqnr, \irqnr
-               cmpne   \irqnr, \tmp
-               cmpcs   \irqnr, \irqnr
-               .endm
 #endif
-#endif /* MULTI_OMAP2 */
-
-#ifdef CONFIG_SMP
-               /* We assume that irqstat (the raw value of the IRQ acknowledge
-                * register) is preserved from the macro above.
-                * If there is an IPI, we immediately signal end of interrupt
-                * on the controller, since this requires the original irqstat
-                * value which we won't easily be able to recreate later.
-                */
 
-               .macro test_for_ipi, irqnr, irqstat, base, tmp
-               bic     \irqnr, \irqstat, #0x1c00
-               cmp     \irqnr, #16
-               it      cc
-               strcc   \irqstat, [\base, #GIC_CPU_EOI]
-               it      cs
-               cmpcs   \irqnr, \irqnr
-               .endm
-
-               /* As above, this assumes that irqstat and base are preserved */
-
-               .macro test_for_ltirq, irqnr, irqstat, base, tmp
-               bic     \irqnr, \irqstat, #0x1c00
-               mov     \tmp, #0
-               cmp     \irqnr, #29
-               itt     eq
-               moveq   \tmp, #1
-               streq   \irqstat, [\base, #GIC_CPU_EOI]
-               cmp     \tmp, #0
-               .endm
-#endif /* CONFIG_SMP */
+#endif /* MULTI_OMAP2 */
 
                .macro  irq_prio_table
                .endm
index 2744dfee1ff4875cad6e6b2faac9a292020e2065..5b0270b289348116fe92a7741f2cab6f6aa0350b 100644 (file)
@@ -24,7 +24,6 @@
 extern void __iomem *l2cache_base;
 #endif
 
-extern void __iomem *gic_cpu_base_addr;
 extern void __iomem *gic_dist_base_addr;
 
 extern void __init gic_init_irq(void);
index 9e9f70e18e3c95436cf6b957e2791175a3cdc90a..9fbac2c39104a7968eb362935ad33b7831911e64 100644 (file)
@@ -50,7 +50,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
         * core (e.g. timer irq), then they will not have been enabled
         * for us: do so
         */
-       gic_cpu_init(0, gic_cpu_base_addr);
+       gic_secondary_init(0);
 
        /*
         * Synchronise with the boot thread.
index 2f895553e6a815e5df735b47fbf89b2c191ba8d8..666e852988d5d21dfcda20e8ea7779a17fe94d97 100644 (file)
 void __iomem *l2cache_base;
 #endif
 
-void __iomem *gic_cpu_base_addr;
 void __iomem *gic_dist_base_addr;
 
 
 void __init gic_init_irq(void)
 {
+       void __iomem *gic_cpu_base;
+
        /* Static mapping, never released */
        gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K);
        BUG_ON(!gic_dist_base_addr);
-       gic_dist_init(0, gic_dist_base_addr, 29);
 
        /* Static mapping, never released */
-       gic_cpu_base_addr = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);
-       BUG_ON(!gic_cpu_base_addr);
-       gic_cpu_init(0, gic_cpu_base_addr);
+       gic_cpu_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);
+       BUG_ON(!gic_cpu_base);
+
+       gic_init(0, 29, gic_dist_base_addr, gic_cpu_base);
 }
 
 #ifdef CONFIG_CACHE_L2X0
index c47b033bd999e67588e037522aa897aefae6bc12..c5196101a237ac960ccd1eefce8792e6483a8a93 100644 (file)
@@ -38,8 +38,8 @@ __arch_iounmap(void __iomem *addr)
                __iounmap(addr);
 }
 
-#define __arch_ioremap(p, s, m)        __arch_ioremap(p, s, m)
-#define __arch_iounmap(a)      __arch_iounmap(a)
+#define __arch_ioremap         __arch_ioremap
+#define __arch_iounmap         __arch_iounmap
 #define __io(a)                        __typesafe_io(a)
 #define __mem_pci(a)           (a)
 
index 07c08151dfe6434be39b510e215acd79e86ea297..14fbe50376b6888798f3821360d2175d1227944f 100644 (file)
 #include <mach/clkdev.h>
 #include <mach/platform.h>
 #include <mach/irqs.h>
-#include <plat/timer-sp.h>
+#include <asm/hardware/timer-sp.h>
 
 #include "core.h"
 
-/* used by entry-macro.S and platsmp.c */
-void __iomem *gic_cpu_base_addr;
-
 #ifdef CONFIG_ZONE_DMA
 /*
  * Adjust the zones if there are restrictions for DMA access.
index 781bca68a9fadcbe4dec1883e837dcf33a167866..693239ddc39e4cc15653575c9c50081cf10c9213 100644 (file)
@@ -53,7 +53,6 @@ extern struct platform_device realview_i2c_device;
 extern struct mmci_platform_data realview_mmc0_plat_data;
 extern struct mmci_platform_data realview_mmc1_plat_data;
 extern struct clcd_board clcd_plat_data;
-extern void __iomem *gic_cpu_base_addr;
 extern void __iomem *timer0_va_base;
 extern void __iomem *timer1_va_base;
 extern void __iomem *timer2_va_base;
index 340a5c276946b596aef73a9a5b52ad02d7384d6e..4071164aebaaafe9872b0557c599d5788a3b9859 100644 (file)
@@ -8,74 +8,11 @@
  * warranty of any kind, whether express or implied.
  */
 #include <mach/hardware.h>
-#include <asm/hardware/gic.h>
+#include <asm/hardware/entry-macro-gic.S>
 
                .macro  disable_fiq
                .endm
 
-               .macro  get_irqnr_preamble, base, tmp
-               ldr     \base, =gic_cpu_base_addr
-               ldr     \base, [\base]
-               .endm
-
                .macro  arch_ret_to_user, tmp1, tmp2
                .endm
 
-               /*
-                * The interrupt numbering scheme is defined in the
-                * interrupt controller spec.  To wit:
-                *
-                * Interrupts 0-15 are IPI
-                * 16-28 are reserved
-                * 29-31 are local.  We allow 30 to be used for the watchdog.
-                * 32-1020 are global
-                * 1021-1022 are reserved
-                * 1023 is "spurious" (no interrupt)
-                *
-                * For now, we ignore all local interrupts so only return an interrupt if it's
-                * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs.
-                *
-                * A simple read from the controller will tell us the number of the highest
-                 * priority enabled interrupt.  We then just need to check whether it is in the
-                * valid range for an IRQ (30-1020 inclusive).
-                */
-
-               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-               ldr     \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
-
-               ldr     \tmp, =1021
-
-               bic     \irqnr, \irqstat, #0x1c00
-
-               cmp     \irqnr, #29
-               cmpcc   \irqnr, \irqnr
-               cmpne   \irqnr, \tmp
-               cmpcs   \irqnr, \irqnr
-
-               .endm
-
-               /* We assume that irqstat (the raw value of the IRQ acknowledge
-                * register) is preserved from the macro above.
-                * If there is an IPI, we immediately signal end of interrupt on the
-                * controller, since this requires the original irqstat value which
-                * we won't easily be able to recreate later.
-                */
-
-               .macro test_for_ipi, irqnr, irqstat, base, tmp
-               bic     \irqnr, \irqstat, #0x1c00
-               cmp     \irqnr, #16
-               strcc   \irqstat, [\base, #GIC_CPU_EOI]
-               cmpcs   \irqnr, \irqnr
-               .endm
-
-               /* As above, this assumes that irqstat and base are preserved.. */
-
-               .macro test_for_ltirq, irqnr, irqstat, base, tmp
-               bic     \irqnr, \irqstat, #0x1c00
-               mov     \tmp, #0
-               cmp     \irqnr, #29
-               moveq   \tmp, #1
-               streq   \irqstat, [\base, #GIC_CPU_EOI]
-               cmp     \tmp, #0
-               .endm
index 009265818d55752aa401ad8bde837d59a6b89ea5..6da8a2e53c44b2bb911a9a4396947f4b42d5b093 100644 (file)
@@ -69,7 +69,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
         * core (e.g. timer irq), then they will not have been enabled
         * for us: do so
         */
-       gic_cpu_init(0, gic_cpu_base_addr);
+       gic_secondary_init(0);
 
        /*
         * let the primary processor know we're out of the
index f2697106f809fd44a5ad35903496412602dfa1ba..6ef5c5e528b251b86ec91f6f7102788265a62ec3 100644 (file)
@@ -364,21 +364,19 @@ static void __init gic_init_irq(void)
                writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
 
                /* core tile GIC, primary */
-               gic_cpu_base_addr = __io_address(REALVIEW_EB11MP_GIC_CPU_BASE);
-               gic_dist_init(0, __io_address(REALVIEW_EB11MP_GIC_DIST_BASE), 29);
-               gic_cpu_init(0, gic_cpu_base_addr);
+               gic_init(0, 29, __io_address(REALVIEW_EB11MP_GIC_DIST_BASE),
+                        __io_address(REALVIEW_EB11MP_GIC_CPU_BASE));
 
 #ifndef CONFIG_REALVIEW_EB_ARM11MP_REVB
                /* board GIC, secondary */
-               gic_dist_init(1, __io_address(REALVIEW_EB_GIC_DIST_BASE), 64);
-               gic_cpu_init(1, __io_address(REALVIEW_EB_GIC_CPU_BASE));
+               gic_init(1, 64, __io_address(REALVIEW_EB_GIC_DIST_BASE),
+                        __io_address(REALVIEW_EB_GIC_CPU_BASE));
                gic_cascade_irq(1, IRQ_EB11MP_EB_IRQ1);
 #endif
        } else {
                /* board GIC, primary */
-               gic_cpu_base_addr = __io_address(REALVIEW_EB_GIC_CPU_BASE);
-               gic_dist_init(0, __io_address(REALVIEW_EB_GIC_DIST_BASE), 29);
-               gic_cpu_init(0, gic_cpu_base_addr);
+               gic_init(0, 29, __io_address(REALVIEW_EB_GIC_DIST_BASE),
+                        __io_address(REALVIEW_EB_GIC_CPU_BASE));
        }
 }
 
index a4125619d71b2ed54bcaad9431524803c7fe79f1..cbdc97a5685fc11ad764587414f56a8420cb02ab 100644 (file)
@@ -304,13 +304,14 @@ static struct platform_device char_lcd_device = {
 static void __init gic_init_irq(void)
 {
        /* ARM1176 DevChip GIC, primary */
-       gic_cpu_base_addr = __io_address(REALVIEW_DC1176_GIC_CPU_BASE);
-       gic_dist_init(0, __io_address(REALVIEW_DC1176_GIC_DIST_BASE), IRQ_DC1176_GIC_START);
-       gic_cpu_init(0, gic_cpu_base_addr);
+       gic_init(0, IRQ_DC1176_GIC_START,
+                __io_address(REALVIEW_DC1176_GIC_DIST_BASE),
+                __io_address(REALVIEW_DC1176_GIC_CPU_BASE));
 
        /* board GIC, secondary */
-       gic_dist_init(1, __io_address(REALVIEW_PB1176_GIC_DIST_BASE), IRQ_PB1176_GIC_START);
-       gic_cpu_init(1, __io_address(REALVIEW_PB1176_GIC_CPU_BASE));
+       gic_init(1, IRQ_PB1176_GIC_START,
+                __io_address(REALVIEW_PB1176_GIC_DIST_BASE),
+                __io_address(REALVIEW_PB1176_GIC_CPU_BASE));
        gic_cascade_irq(1, IRQ_DC1176_PB_IRQ1);
 }
 
index 117b95b2ca15c7b4bba1f398934f799fbdec570b..8e8ab7d29a6a0d8b6b020b7ea513e6ec8c96c021 100644 (file)
@@ -309,13 +309,13 @@ static void __init gic_init_irq(void)
        writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
 
        /* ARM11MPCore test chip GIC, primary */
-       gic_cpu_base_addr = __io_address(REALVIEW_TC11MP_GIC_CPU_BASE);
-       gic_dist_init(0, __io_address(REALVIEW_TC11MP_GIC_DIST_BASE), 29);
-       gic_cpu_init(0, gic_cpu_base_addr);
+       gic_init(0, 29, __io_address(REALVIEW_TC11MP_GIC_DIST_BASE),
+                __io_address(REALVIEW_TC11MP_GIC_CPU_BASE));
 
        /* board GIC, secondary */
-       gic_dist_init(1, __io_address(REALVIEW_PB11MP_GIC_DIST_BASE), IRQ_PB11MP_GIC_START);
-       gic_cpu_init(1, __io_address(REALVIEW_PB11MP_GIC_CPU_BASE));
+       gic_init(1, IRQ_PB11MP_GIC_START,
+                __io_address(REALVIEW_PB11MP_GIC_DIST_BASE),
+                __io_address(REALVIEW_PB11MP_GIC_CPU_BASE));
        gic_cascade_irq(1, IRQ_TC11MP_PB_IRQ1);
 }
 
index 929b8dc12e81754bfb0fdf88f25fa6e4d2664aa6..841118e3e118c7383be126131f8dc5ef125b6461 100644 (file)
@@ -273,9 +273,9 @@ static struct platform_device pmu_device = {
 static void __init gic_init_irq(void)
 {
        /* ARM PB-A8 on-board GIC */
-       gic_cpu_base_addr = __io_address(REALVIEW_PBA8_GIC_CPU_BASE);
-       gic_dist_init(0, __io_address(REALVIEW_PBA8_GIC_DIST_BASE), IRQ_PBA8_GIC_START);
-       gic_cpu_init(0, __io_address(REALVIEW_PBA8_GIC_CPU_BASE));
+       gic_init(0, IRQ_PBA8_GIC_START,
+                __io_address(REALVIEW_PBA8_GIC_DIST_BASE),
+                __io_address(REALVIEW_PBA8_GIC_CPU_BASE));
 }
 
 static void __init realview_pba8_timer_init(void)
index b9f9e20031a75e1ef9442c252849689fa50d486e..02b755b009dbc0c859f0ebf9d98bbf7f6ea96ad9 100644 (file)
@@ -313,15 +313,12 @@ static void __init gic_init_irq(void)
 {
        /* ARM PBX on-board GIC */
        if (core_tile_pbx11mp() || core_tile_pbxa9mp()) {
-               gic_cpu_base_addr = __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE);
-               gic_dist_init(0, __io_address(REALVIEW_PBX_TILE_GIC_DIST_BASE),
-                             29);
-               gic_cpu_init(0, __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE));
+               gic_init(0, 29, __io_address(REALVIEW_PBX_TILE_GIC_DIST_BASE),
+                        __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE));
        } else {
-               gic_cpu_base_addr = __io_address(REALVIEW_PBX_GIC_CPU_BASE);
-               gic_dist_init(0, __io_address(REALVIEW_PBX_GIC_DIST_BASE),
-                             IRQ_PBX_GIC_START);
-               gic_cpu_init(0, __io_address(REALVIEW_PBX_GIC_CPU_BASE));
+               gic_init(0, IRQ_PBX_GIC_START,
+                        __io_address(REALVIEW_PBX_GIC_DIST_BASE),
+                        __io_address(REALVIEW_PBX_GIC_CPU_BASE));
        }
 }
 
index 82ce4aa6d61a5c07f004f26cc08e11d80f583b0d..72ab289e78166bfb102f6e4e46dc44cfb7f548ac 100644 (file)
@@ -24,8 +24,6 @@
 
 #include <mach/regs-irq.h>
 
-void __iomem *gic_cpu_base_addr;
-
 extern int combiner_init(unsigned int combiner_nr, void __iomem *base,
                         unsigned int irq_start);
 extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
@@ -122,9 +120,7 @@ void __init s5pv310_init_irq(void)
 {
        int irq;
 
-       gic_cpu_base_addr = S5P_VA_GIC_CPU;
-       gic_dist_init(0, S5P_VA_GIC_DIST, IRQ_LOCALTIMER);
-       gic_cpu_init(0, S5P_VA_GIC_CPU);
+       gic_init(0, IRQ_LOCALTIMER, S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
 
        for (irq = 0; irq < MAX_COMBINER_NR; irq++) {
                combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq),
index b7ec252384f47059f681ddad95c1d183ad8b39dc..e1cc6a251c6ac9461996c37112dda226097a2117 100644 (file)
@@ -9,8 +9,6 @@
 #include <asm/hardware/gic.h>
 #include <asm/smp_mpidr.h>
 
-extern void __iomem *gic_cpu_base_addr;
-
 /*
  * We use IRQ1 as the IPI
  */
index d357c198edee308112bc3633256376ca69720abb..15929c169f81c74524555aa246eed84e84cfafec 100644 (file)
@@ -54,7 +54,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
         * core (e.g. timer irq), then they will not have been enabled
         * for us: do so
         */
-       gic_cpu_init(0, gic_cpu_base_addr);
+       gic_secondary_init(0);
 
        /*
         * let the primary processor know we're out of the
index 5da8c35aa0de14f89159a24e2f05a0edc451c01b..42625e4d949a143f828ba96c155754f422aa0d65 100644 (file)
@@ -118,6 +118,16 @@ config SA1100_LART
          (also known as the LART).  See <http://www.lartmaker.nl/> for
          information on the LART.
 
+config SA1100_NANOENGINE
+       bool "nanoEngine"
+       select CPU_FREQ_SA1110
+       select PCI
+       select PCI_NANOENGINE
+       help
+         Say Y here if you are using the Bright Star Engineering nanoEngine.
+         See <http://www.brightstareng.com/arm/nanoeng.htm> for information
+         on the BSE nanoEngine.
+
 config SA1100_PLEB
        bool "PLEB"
        select CPU_FREQ_SA1100
index 89349c1dd7a69b2639fe2277a6622f6aa8324b44..e697691eed283bfd1a81681c8a784328d4aa6ba5 100644 (file)
@@ -37,6 +37,9 @@ obj-$(CONFIG_SA1100_JORNADA720_SSP)   += jornada720_ssp.o
 obj-$(CONFIG_SA1100_LART)              += lart.o
 led-$(CONFIG_SA1100_LART)              += leds-lart.o
 
+obj-$(CONFIG_SA1100_NANOENGINE)                += nanoengine.o
+obj-$(CONFIG_PCI_NANOENGINE)           += pci-nanoengine.o
+
 obj-$(CONFIG_SA1100_PLEB)              += pleb.o
 
 obj-$(CONFIG_SA1100_SHANNON)           += shannon.o
index 96f7dc103b5987c586a663a9e19729027f832e70..07d4e8ba37191606f980ed2bc6dbf03def722c9a 100644 (file)
 
 #include "generic.h"
 
-typedef struct {
+struct sa1100_dram_regs {
        int speed;
        u32 mdcnfg;
        u32 mdcas0;
        u32 mdcas1;
        u32 mdcas2;
-} sa1100_dram_regs_t;
+};
 
 
 static struct cpufreq_driver sa1100_driver;
 
-static sa1100_dram_regs_t sa1100_dram_settings[] =
-{
-       /* speed,     mdcnfg,     mdcas0,     mdcas1,     mdcas2  clock frequency */
-       {  59000, 0x00dc88a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /*  59.0 MHz */
-       {  73700, 0x011490a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /*  73.7 MHz */
-       {  88500, 0x014e90a3, 0xcccccccf, 0xfffffffc, 0xffffffff }, /*  88.5 MHz */
-       { 103200, 0x01889923, 0xcccccccf, 0xfffffffc, 0xffffffff }, /* 103.2 MHz */
-       { 118000, 0x01c29923, 0x9999998f, 0xfffffff9, 0xffffffff }, /* 118.0 MHz */
-       { 132700, 0x01fb2123, 0x9999998f, 0xfffffff9, 0xffffffff }, /* 132.7 MHz */
-       { 147500, 0x02352123, 0x3333330f, 0xfffffff3, 0xffffffff }, /* 147.5 MHz */
-       { 162200, 0x026b29a3, 0x38e38e1f, 0xfff8e38e, 0xffffffff }, /* 162.2 MHz */
-       { 176900, 0x02a329a3, 0x71c71c1f, 0xfff1c71c, 0xffffffff }, /* 176.9 MHz */
-       { 191700, 0x02dd31a3, 0xe38e383f, 0xffe38e38, 0xffffffff }, /* 191.7 MHz */
-       { 206400, 0x03153223, 0xc71c703f, 0xffc71c71, 0xffffffff }, /* 206.4 MHz */
-       { 221200, 0x034fba23, 0xc71c703f, 0xffc71c71, 0xffffffff }, /* 221.2 MHz */
-       { 235900, 0x03853a23, 0xe1e1e07f, 0xe1e1e1e1, 0xffffffe1 }, /* 235.9 MHz */
-       { 250700, 0x03bf3aa3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3 }, /* 250.7 MHz */
-       { 265400, 0x03f7c2a3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3 }, /* 265.4 MHz */
-       { 280200, 0x0431c2a3, 0x878780ff, 0x87878787, 0xffffff87 }, /* 280.2 MHz */
+static struct sa1100_dram_regs sa1100_dram_settings[] = {
+       /*speed,     mdcnfg,     mdcas0,     mdcas1,     mdcas2,   clock freq */
+       { 59000, 0x00dc88a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/*  59.0 MHz */
+       { 73700, 0x011490a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/*  73.7 MHz */
+       { 88500, 0x014e90a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/*  88.5 MHz */
+       {103200, 0x01889923, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 103.2 MHz */
+       {118000, 0x01c29923, 0x9999998f, 0xfffffff9, 0xffffffff},/* 118.0 MHz */
+       {132700, 0x01fb2123, 0x9999998f, 0xfffffff9, 0xffffffff},/* 132.7 MHz */
+       {147500, 0x02352123, 0x3333330f, 0xfffffff3, 0xffffffff},/* 147.5 MHz */
+       {162200, 0x026b29a3, 0x38e38e1f, 0xfff8e38e, 0xffffffff},/* 162.2 MHz */
+       {176900, 0x02a329a3, 0x71c71c1f, 0xfff1c71c, 0xffffffff},/* 176.9 MHz */
+       {191700, 0x02dd31a3, 0xe38e383f, 0xffe38e38, 0xffffffff},/* 191.7 MHz */
+       {206400, 0x03153223, 0xc71c703f, 0xffc71c71, 0xffffffff},/* 206.4 MHz */
+       {221200, 0x034fba23, 0xc71c703f, 0xffc71c71, 0xffffffff},/* 221.2 MHz */
+       {235900, 0x03853a23, 0xe1e1e07f, 0xe1e1e1e1, 0xffffffe1},/* 235.9 MHz */
+       {250700, 0x03bf3aa3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3},/* 250.7 MHz */
+       {265400, 0x03f7c2a3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3},/* 265.4 MHz */
+       {280200, 0x0431c2a3, 0x878780ff, 0x87878787, 0xffffff87},/* 280.2 MHz */
        { 0, 0, 0, 0, 0 } /* last entry */
 };
 
 static void sa1100_update_dram_timings(int current_speed, int new_speed)
 {
-       sa1100_dram_regs_t *settings = sa1100_dram_settings;
+       struct sa1100_dram_regs *settings = sa1100_dram_settings;
 
        /* find speed */
        while (settings->speed != 0) {
-               if(new_speed == settings->speed)
+               if (new_speed == settings->speed)
                        break;
-               
+
                settings++;
        }
 
@@ -149,7 +148,7 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed)
                /* We're going FASTER, so first relax the memory
                 * timings before changing the core frequency
                 */
-               
+
                /* Half the memory access clock */
                MDCNFG |= MDCNFG_CDB2;
 
@@ -187,7 +186,7 @@ static int sa1100_target(struct cpufreq_policy *policy,
        struct cpufreq_freqs freqs;
 
        new_ppcr = sa11x0_freq_to_ppcr(target_freq);
-       switch(relation){
+       switch (relation) {
        case CPUFREQ_RELATION_L:
                if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max)
                        new_ppcr--;
index 7252874d328b59eb808110351aabeff2e4a9c11d..675bf8ef97e8061fbc0041ce2a5ac620d048cc95 100644 (file)
  *
  * The SDRAM type can be passed on the command line as cpu_sa1110.sdram=type
  */
-#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/cpufreq.h>
 #include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
 
-#include <mach/hardware.h>
 #include <asm/cputype.h>
 #include <asm/mach-types.h>
-#include <asm/system.h>
+
+#include <mach/hardware.h>
 
 #include "generic.h"
 
 #undef DEBUG
 
-static struct cpufreq_driver sa1110_driver;
-
 struct sdram_params {
-       const char name[16];
+       const char name[20];
        u_char  rows;           /* bits                          */
        u_char  cas_latency;    /* cycles                        */
        u_char  tck;            /* clock cycle time (ns)         */
@@ -107,6 +103,15 @@ static struct sdram_params sdram_tbl[] __initdata = {
                .twr            = 8,
                .refresh        = 64000,
                .cas_latency    = 3,
+       }, {    /* Micron MT48LC8M16A2TG-75 */
+               .name           = "MT48LC8M16A2TG-75",
+               .rows           = 12,
+               .tck            = 8,
+               .trcd           = 20,
+               .trp            = 20,
+               .twr            = 8,
+               .refresh        = 64000,
+               .cas_latency    = 3,
        },
 };
 
@@ -180,11 +185,13 @@ sdram_calculate_timing(struct sdram_info *sd, u_int cpu_khz,
                sd->mdrefr |= MDREFR_K1DB2;
 
        /* initial number of '1's in MDCAS + 1 */
-       set_mdcas(sd->mdcas, sd_khz >= 62000, ns_to_cycles(sdram->trcd, mem_khz));
+       set_mdcas(sd->mdcas, sd_khz >= 62000,
+               ns_to_cycles(sdram->trcd, mem_khz));
 
 #ifdef DEBUG
-       printk("MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n",
-               sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1], sd->mdcas[2]);
+       printk(KERN_DEBUG "MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n",
+               sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1],
+               sd->mdcas[2]);
 #endif
 }
 
@@ -213,7 +220,7 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
 
 #ifdef DEBUG
        mdelay(250);
-       printk("new dri value = %d\n", dri);
+       printk(KERN_DEBUG "new dri value = %d\n", dri);
 #endif
 
        sdram_set_refresh(dri);
@@ -232,7 +239,7 @@ static int sa1110_target(struct cpufreq_policy *policy,
        unsigned long flags;
        unsigned int ppcr, unused;
 
-       switch(relation){
+       switch (relation) {
        case CPUFREQ_RELATION_L:
                ppcr = sa11x0_freq_to_ppcr(target_freq);
                if (sa11x0_ppcr_to_freq(ppcr) > policy->max)
@@ -280,11 +287,10 @@ static int sa1110_target(struct cpufreq_policy *policy,
         * We wait 20ms to be safe.
         */
        sdram_set_refresh(2);
-       if (!irqs_disabled()) {
+       if (!irqs_disabled())
                msleep(20);
-       } else {
+       else
                mdelay(20);
-       }
 
        /*
         * Reprogram the DRAM timings with interrupts disabled, and
@@ -295,7 +301,7 @@ static int sa1110_target(struct cpufreq_policy *policy,
        local_irq_save(flags);
        asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
        udelay(10);
-       __asm__ __volatile__("                                  \n\
+       __asm__ __volatile__("\n\
                b       2f                                      \n\
                .align  5                                       \n\
 1:             str     %3, [%1, #0]            @ MDCNFG        \n\
@@ -336,7 +342,9 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy)
        return 0;
 }
 
-static struct cpufreq_driver sa1110_driver = {
+/* sa1110_driver needs __refdata because it must remain after init registers
+ * it with cpufreq_register_driver() */
+static struct cpufreq_driver sa1110_driver __refdata = {
        .flags          = CPUFREQ_STICKY,
        .verify         = sa11x0_verify_speed,
        .target         = sa1110_target,
@@ -349,7 +357,8 @@ static struct sdram_params *sa1110_find_sdram(const char *name)
 {
        struct sdram_params *sdram;
 
-       for (sdram = sdram_tbl; sdram < sdram_tbl + ARRAY_SIZE(sdram_tbl); sdram++)
+       for (sdram = sdram_tbl; sdram < sdram_tbl + ARRAY_SIZE(sdram_tbl);
+            sdram++)
                if (strcmp(name, sdram->name) == 0)
                        return sdram;
 
@@ -369,14 +378,14 @@ static int __init sa1110_clk_init(void)
        if (!name[0]) {
                if (machine_is_assabet())
                        name = "TC59SM716-CL3";
-
                if (machine_is_pt_system3())
                        name = "K4S641632D";
-
                if (machine_is_h3100())
                        name = "KM416S4030CT";
                if (machine_is_jornada720())
-                       name = "K4S281632B-1H";
+                       name = "K4S281632B-1H";
+               if (machine_is_nanoengine())
+                       name = "MT48LC8M16A2TG-75";
        }
 
        sdram = sa1110_find_sdram(name);
index 3c1fcd6967145cc91a04752db09c856d031f4e49..3555d616774c0b8f84f6c9827b0f19a2a7c50496 100644 (file)
@@ -163,10 +163,15 @@ static void sa11x0_register_device(struct platform_device *dev, void *data)
 
 static struct resource sa11x0udc_resources[] = {
        [0] = {
-               .start  = 0x80000000,
-               .end    = 0x8000ffff,
+               .start  = __PREG(Ser0UDCCR),
+               .end    = __PREG(Ser0UDCCR) + 0xffff,
                .flags  = IORESOURCE_MEM,
        },
+       [1] = {
+               .start  = IRQ_Ser0UDC,
+               .end    = IRQ_Ser0UDC,
+               .flags  = IORESOURCE_IRQ,
+       },
 };
 
 static u64 sa11x0udc_dma_mask = 0xffffffffUL;
@@ -184,10 +189,15 @@ static struct platform_device sa11x0udc_device = {
 
 static struct resource sa11x0uart1_resources[] = {
        [0] = {
-               .start  = 0x80010000,
-               .end    = 0x8001ffff,
+               .start  = __PREG(Ser1UTCR0),
+               .end    = __PREG(Ser1UTCR0) + 0xffff,
                .flags  = IORESOURCE_MEM,
        },
+       [1] = {
+               .start  = IRQ_Ser1UART,
+               .end    = IRQ_Ser1UART,
+               .flags  = IORESOURCE_IRQ,
+       },
 };
 
 static struct platform_device sa11x0uart1_device = {
@@ -199,10 +209,15 @@ static struct platform_device sa11x0uart1_device = {
 
 static struct resource sa11x0uart3_resources[] = {
        [0] = {
-               .start  = 0x80050000,
-               .end    = 0x8005ffff,
+               .start  = __PREG(Ser3UTCR0),
+               .end    = __PREG(Ser3UTCR0) + 0xffff,
                .flags  = IORESOURCE_MEM,
        },
+       [1] = {
+               .start  = IRQ_Ser3UART,
+               .end    = IRQ_Ser3UART,
+               .flags  = IORESOURCE_IRQ,
+       },
 };
 
 static struct platform_device sa11x0uart3_device = {
@@ -214,10 +229,15 @@ static struct platform_device sa11x0uart3_device = {
 
 static struct resource sa11x0mcp_resources[] = {
        [0] = {
-               .start  = 0x80060000,
-               .end    = 0x8006ffff,
+               .start  = __PREG(Ser4MCCR0),
+               .end    = __PREG(Ser4MCCR0) + 0xffff,
                .flags  = IORESOURCE_MEM,
        },
+       [1] = {
+               .start  = IRQ_Ser4MCP,
+               .end    = IRQ_Ser4MCP,
+               .flags  = IORESOURCE_IRQ,
+       },
 };
 
 static u64 sa11x0mcp_dma_mask = 0xffffffffUL;
@@ -244,6 +264,11 @@ static struct resource sa11x0ssp_resources[] = {
                .end    = 0x8007ffff,
                .flags  = IORESOURCE_MEM,
        },
+       [1] = {
+               .start  = IRQ_Ser4SSP,
+               .end    = IRQ_Ser4SSP,
+               .flags  = IORESOURCE_IRQ,
+       },
 };
 
 static u64 sa11x0ssp_dma_mask = 0xffffffffUL;
index 99f5856d8de424ce006d09c090cf0810f649e811..967ae7684390b5b12488af416a4b6eac2ac78776 100644 (file)
@@ -76,4 +76,12 @@ static inline unsigned long get_clock_tick_rate(void)
 #include "SA-1101.h"
 #endif
 
+#if defined(CONFIG_ARCH_SA1100) && defined(CONFIG_PCI)
+#define PCIBIOS_MIN_IO         0
+#define PCIBIOS_MIN_MEM                0
+#define pcibios_assign_all_busses()    1
+#define HAVE_ARCH_PCI_SET_DMA_MASK     1
+#endif
+
+
 #endif  /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-sa1100/include/mach/nanoengine.h b/arch/arm/mach-sa1100/include/mach/nanoengine.h
new file mode 100644 (file)
index 0000000..14f8382
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/nanoengine.h
+ *
+ * This file contains the hardware specific definitions for nanoEngine.
+ * Only include this file from SA1100-specific files.
+ *
+ * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_ARCH_NANOENGINE_H
+#define __ASM_ARCH_NANOENGINE_H
+
+#include <mach/irqs.h>
+
+#define GPIO_PC_READY0 GPIO_GPIO(11) /* ready for socket 0 (active high)*/
+#define GPIO_PC_READY1 GPIO_GPIO(12) /* ready for socket 1 (active high) */
+#define GPIO_PC_CD0    GPIO_GPIO(13) /* detect for socket 0 (active low) */
+#define GPIO_PC_CD1    GPIO_GPIO(14) /* detect for socket 1 (active low) */
+#define GPIO_PC_RESET0 GPIO_GPIO(15) /* reset socket 0 */
+#define GPIO_PC_RESET1 GPIO_GPIO(16) /* reset socket 1 */
+
+#define NANOENGINE_IRQ_GPIO_PCI                IRQ_GPIO0
+#define NANOENGINE_IRQ_GPIO_PC_READY0  IRQ_GPIO11
+#define NANOENGINE_IRQ_GPIO_PC_READY1  IRQ_GPIO12
+#define NANOENGINE_IRQ_GPIO_PC_CD0     IRQ_GPIO13
+#define NANOENGINE_IRQ_GPIO_PC_CD1     IRQ_GPIO14
+
+/*
+ * nanoEngine Memory Map:
+ *
+ * 0000.0000 - 003F.0000 -   4 MB Flash
+ * C000.0000 - C1FF.FFFF -  32 MB SDRAM
+ * 1860.0000 - 186F.FFFF -   1 MB Internal PCI Memory Read/Write
+ * 18A1.0000 - 18A1.FFFF -  64 KB Internal PCI Config Space
+ * 4000.0000 - 47FF.FFFF - 128 MB External Bus I/O - Multiplexed Mode
+ * 4800.0000 - 4FFF.FFFF - 128 MB External Bus I/O - Non-Multiplexed Mode
+ *
+ */
+
+#define NANO_PCI_MEM_RW_PHYS           0x18600000
+#define NANO_PCI_MEM_RW_VIRT           0xf1000000
+#define NANO_PCI_MEM_RW_SIZE           SZ_1M
+#define NANO_PCI_CONFIG_SPACE_PHYS     0x18A10000
+#define NANO_PCI_CONFIG_SPACE_VIRT     0xf2000000
+#define NANO_PCI_CONFIG_SPACE_SIZE     SZ_64K
+
+#endif
+
diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
new file mode 100644 (file)
index 0000000..72087f0
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * linux/arch/arm/mach-sa1100/nanoengine.c
+ *
+ * Bright Star Engineering's nanoEngine board init code.
+ *
+ * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/root_dev.h>
+
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <mach/hardware.h>
+#include <mach/nanoengine.h>
+
+#include "generic.h"
+
+/* Flash bank 0 */
+static struct mtd_partition nanoengine_partitions[] = {
+       {
+               .name   = "nanoEngine boot firmware and parameter table",
+               .size           = 0x00010000,  /* 32K */
+               .offset         = 0,
+               .mask_flags     = MTD_WRITEABLE,
+       }, {
+               .name           = "kernel/initrd reserved",
+               .size           = 0x002f0000,
+               .offset         = 0x00010000,
+               .mask_flags     = MTD_WRITEABLE,
+       }, {
+               .name           = "experimental filesystem allocation",
+               .size           = 0x00100000,
+               .offset         = 0x00300000,
+               .mask_flags     = MTD_WRITEABLE,
+       }
+};
+
+static struct flash_platform_data nanoengine_flash_data = {
+       .map_name       = "jedec_probe",
+       .parts          = nanoengine_partitions,
+       .nr_parts       = ARRAY_SIZE(nanoengine_partitions),
+};
+
+static struct resource nanoengine_flash_resources[] = {
+       {
+               .start  = SA1100_CS0_PHYS,
+               .end    = SA1100_CS0_PHYS + SZ_32M - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = SA1100_CS1_PHYS,
+               .end    = SA1100_CS1_PHYS + SZ_32M - 1,
+               .flags  = IORESOURCE_MEM,
+       }
+};
+
+static struct map_desc nanoengine_io_desc[] __initdata = {
+       {
+               /* System Registers */
+               .virtual        = 0xf0000000,
+               .pfn            = __phys_to_pfn(0x10000000),
+               .length         = 0x00100000,
+               .type           = MT_DEVICE
+       }, {
+               /* Internal PCI Memory Read/Write */
+               .virtual        = NANO_PCI_MEM_RW_VIRT,
+               .pfn            = __phys_to_pfn(NANO_PCI_MEM_RW_PHYS),
+               .length         = NANO_PCI_MEM_RW_SIZE,
+               .type           = MT_DEVICE
+       }, {
+               /* Internal PCI Config Space */
+               .virtual        = NANO_PCI_CONFIG_SPACE_VIRT,
+               .pfn            = __phys_to_pfn(NANO_PCI_CONFIG_SPACE_PHYS),
+               .length         = NANO_PCI_CONFIG_SPACE_SIZE,
+               .type           = MT_DEVICE
+       }
+};
+
+static void __init nanoengine_map_io(void)
+{
+       sa1100_map_io();
+       iotable_init(nanoengine_io_desc, ARRAY_SIZE(nanoengine_io_desc));
+
+       sa1100_register_uart(0, 1);
+       sa1100_register_uart(1, 2);
+       sa1100_register_uart(2, 3);
+       Ser1SDCR0 |= SDCR0_UART;
+       /* disable IRDA -- UART2 is used as a normal serial port */
+       Ser2UTCR4 = 0;
+       Ser2HSCR0 = 0;
+}
+
+static void __init nanoengine_init(void)
+{
+       sa11x0_register_mtd(&nanoengine_flash_data, nanoengine_flash_resources,
+               ARRAY_SIZE(nanoengine_flash_resources));
+}
+
+MACHINE_START(NANOENGINE, "BSE nanoEngine")
+       .boot_params    = 0xc0000000,
+       .map_io         = nanoengine_map_io,
+       .init_irq       = sa1100_init_irq,
+       .timer          = &sa1100_timer,
+       .init_machine   = nanoengine_init,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c
new file mode 100644 (file)
index 0000000..fba7a91
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * linux/arch/arm/mach-sa1100/pci-nanoengine.c
+ *
+ * PCI functions for BSE nanoEngine PCI
+ *
+ * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+#include <mach/nanoengine.h>
+
+static DEFINE_SPINLOCK(nano_lock);
+
+static int nanoengine_get_pci_address(struct pci_bus *bus,
+       unsigned int devfn, int where, unsigned long *address)
+{
+       int ret = PCIBIOS_DEVICE_NOT_FOUND;
+       unsigned int busnr = bus->number;
+
+       *address = NANO_PCI_CONFIG_SPACE_VIRT +
+               ((bus->number << 16) | (devfn << 8) | (where & ~3));
+
+       ret = (busnr > 255 || devfn > 255 || where > 255) ?
+               PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+
+       return ret;
+}
+
+static int nanoengine_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+       int size, u32 *val)
+{
+       int ret;
+       unsigned long address;
+       unsigned long flags;
+       u32 v;
+
+       /* nanoEngine PCI bridge does not return -1 for a non-existing
+        * device. We must fake the answer. We know that the only valid
+        * device is device zero at bus 0, which is the network chip. */
+       if (bus->number != 0 || (devfn >> 3) != 0) {
+               v = -1;
+               nanoengine_get_pci_address(bus, devfn, where, &address);
+               goto exit_function;
+       }
+
+       spin_lock_irqsave(&nano_lock, flags);
+
+       ret = nanoengine_get_pci_address(bus, devfn, where, &address);
+       if (ret != PCIBIOS_SUCCESSFUL)
+               return ret;
+       v = __raw_readl(address);
+
+       spin_unlock_irqrestore(&nano_lock, flags);
+
+       v >>= ((where & 3) * 8);
+       v &= (unsigned long)(-1) >> ((4 - size) * 8);
+
+exit_function:
+       *val = v;
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int nanoengine_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+       int size, u32 val)
+{
+       int ret;
+       unsigned long address;
+       unsigned long flags;
+       unsigned shift;
+       u32 v;
+
+       shift = (where & 3) * 8;
+
+       spin_lock_irqsave(&nano_lock, flags);
+
+       ret = nanoengine_get_pci_address(bus, devfn, where, &address);
+       if (ret != PCIBIOS_SUCCESSFUL)
+               return ret;
+       v = __raw_readl(address);
+       switch (size) {
+       case 1:
+               v &= ~(0xFF << shift);
+               v |= val << shift;
+               break;
+       case 2:
+               v &= ~(0xFFFF << shift);
+               v |= val << shift;
+               break;
+       case 4:
+               v = val;
+               break;
+       }
+       __raw_writel(v, address);
+
+       spin_unlock_irqrestore(&nano_lock, flags);
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_nano_ops = {
+       .read   = nanoengine_read_config,
+       .write  = nanoengine_write_config,
+};
+
+static int __init pci_nanoengine_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       return NANOENGINE_IRQ_GPIO_PCI;
+}
+
+struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys)
+{
+       return pci_scan_bus(sys->busnr, &pci_nano_ops, sys);
+}
+
+static struct resource pci_io_ports = {
+       .name   = "PCI IO",
+       .start  = 0x400,
+       .end    = 0x7FF,
+       .flags  = IORESOURCE_IO,
+};
+
+static struct resource pci_non_prefetchable_memory = {
+       .name   = "PCI non-prefetchable",
+       .start  = NANO_PCI_MEM_RW_PHYS,
+       /* nanoEngine documentation says there is a 1 Megabyte window here,
+        * but PCI reports just 128 + 8 kbytes. */
+       .end    = NANO_PCI_MEM_RW_PHYS + NANO_PCI_MEM_RW_SIZE - 1,
+/*     .end    = NANO_PCI_MEM_RW_PHYS + SZ_128K + SZ_8K - 1,*/
+       .flags  = IORESOURCE_MEM,
+};
+
+/*
+ * nanoEngine PCI reports 1 Megabyte of prefetchable memory, but it
+ * overlaps with previously defined memory.
+ *
+ * Here is what happens:
+ *
+# dmesg
+...
+pci 0000:00:00.0: [8086:1209] type 0 class 0x000200
+pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff]
+pci 0000:00:00.0: reg 14: [io  0x0000-0x003f]
+pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff]
+pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref]
+pci 0000:00:00.0: supports D1 D2
+pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot
+pci 0000:00:00.0: PME# disabled
+PCI: bus0: Fast back to back transfers enabled
+pci 0000:00:00.0: BAR 6: can't assign mem pref (size 0x100000)
+pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff]
+pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff])
+pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff]
+pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff])
+pci 0000:00:00.0: BAR 1: assigned [io  0x0400-0x043f]
+pci 0000:00:00.0: BAR 1: set to [io  0x0400-0x043f] (PCI address [0x0-0x3f])
+ *
+ * On the other hand, if we do not request the prefetchable memory resource,
+ * linux will alloc it first and the two non-prefetchable memory areas that
+ * are our real interest will not be mapped. So we choose to map it to an
+ * unused area. It gets recognized as expansion ROM, but becomes disabled.
+ *
+ * Here is what happens then:
+ *
+# dmesg
+...
+pci 0000:00:00.0: [8086:1209] type 0 class 0x000200
+pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff]
+pci 0000:00:00.0: reg 14: [io  0x0000-0x003f]
+pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff]
+pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref]
+pci 0000:00:00.0: supports D1 D2
+pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot
+pci 0000:00:00.0: PME# disabled
+PCI: bus0: Fast back to back transfers enabled
+pci 0000:00:00.0: BAR 6: assigned [mem 0x78000000-0x780fffff pref]
+pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff]
+pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff])
+pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff]
+pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff])
+pci 0000:00:00.0: BAR 1: assigned [io  0x0400-0x043f]
+pci 0000:00:00.0: BAR 1: set to [io  0x0400-0x043f] (PCI address [0x0-0x3f])
+
+# lspci -vv -s 0000:00:00.0
+00:00.0 Class 0200: Device 8086:1209 (rev 09)
+        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
+        Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR+ <PERR+ INTx-
+        Latency: 0 (2000ns min, 14000ns max), Cache Line Size: 32 bytes
+        Interrupt: pin A routed to IRQ 0
+        Region 0: Memory at 18620000 (32-bit, non-prefetchable) [size=4K]
+        Region 1: I/O ports at 0400 [size=64]
+        Region 2: [virtual] Memory at 18600000 (32-bit, non-prefetchable) [size=128K]
+        [virtual] Expansion ROM at 78000000 [disabled] [size=1M]
+        Capabilities: [dc] Power Management version 2
+                Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
+                Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=2 PME-
+        Kernel driver in use: e100
+        Kernel modules: e100
+ *
+ */
+static struct resource pci_prefetchable_memory = {
+       .name   = "PCI prefetchable",
+       .start  = 0x78000000,
+       .end    = 0x78000000 + NANO_PCI_MEM_RW_SIZE - 1,
+       .flags  = IORESOURCE_MEM  | IORESOURCE_PREFETCH,
+};
+
+static int __init pci_nanoengine_setup_resources(struct resource **resource)
+{
+       if (request_resource(&ioport_resource, &pci_io_ports)) {
+               printk(KERN_ERR "PCI: unable to allocate io port region\n");
+               return -EBUSY;
+       }
+       if (request_resource(&iomem_resource, &pci_non_prefetchable_memory)) {
+               release_resource(&pci_io_ports);
+               printk(KERN_ERR "PCI: unable to allocate non prefetchable\n");
+               return -EBUSY;
+       }
+       if (request_resource(&iomem_resource, &pci_prefetchable_memory)) {
+               release_resource(&pci_io_ports);
+               release_resource(&pci_non_prefetchable_memory);
+               printk(KERN_ERR "PCI: unable to allocate prefetchable\n");
+               return -EBUSY;
+       }
+       resource[0] = &pci_io_ports;
+       resource[1] = &pci_non_prefetchable_memory;
+       resource[2] = &pci_prefetchable_memory;
+
+       return 1;
+}
+
+int __init pci_nanoengine_setup(int nr, struct pci_sys_data *sys)
+{
+       int ret = 0;
+
+       if (nr == 0) {
+               sys->mem_offset = NANO_PCI_MEM_RW_PHYS;
+               sys->io_offset = 0x400;
+               ret = pci_nanoengine_setup_resources(sys->resource);
+               /* Enable alternate memory bus master mode, see
+                * "Intel StrongARM SA1110 Developer's Manual",
+                * section 10.8, "Alternate Memory Bus Master Mode". */
+               GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
+               GAFR |= GPIO_MBGNT | GPIO_MBREQ;
+               TUCR |= TUCR_MBGPIO;
+       }
+
+       return ret;
+}
+
+static struct hw_pci nanoengine_pci __initdata = {
+       .map_irq                = pci_nanoengine_map_irq,
+       .nr_controllers         = 1,
+       .scan                   = pci_nanoengine_scan_bus,
+       .setup                  = pci_nanoengine_setup,
+};
+
+static int __init nanoengine_pci_init(void)
+{
+       if (machine_is_nanoengine())
+               pci_common_init(&nanoengine_pci);
+       return 0;
+}
+
+subsys_initcall(nanoengine_pci_init);
index 27692d0ffbe81c9d2a5e6931bc323f107973c7c6..cfb76077bd25a19e35e2b1a98134c8896b4b4c74 100644 (file)
@@ -166,9 +166,6 @@ static void __init simpad_map_io(void)
        PCFR = 0;
        PSDR = 0;
 
-       sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
-                             ARRAY_SIZE(simpad_flash_resources));
-       sa11x0_register_mcp(&simpad_mcp_data);
 }
 
 static void simpad_power_off(void)
@@ -216,6 +213,10 @@ static int __init simpad_init(void)
 
        pm_power_off = simpad_power_off;
 
+       sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
+                             ARRAY_SIZE(simpad_flash_resources));
+       sa11x0_register_mcp(&simpad_mcp_data);
+
        ret = platform_add_devices(devices, ARRAY_SIZE(devices));
        if(ret)
                printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device");
index d440e5f456ad943979f7e5ec432cee56d91d8c77..ac429ff2c20d85d35172769b18e55b5609e9203f 100644 (file)
@@ -61,6 +61,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
+#include <asm/setup.h>
 
 /*
  * Address     Interface               BusWidth        note
diff --git a/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt b/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
new file mode 100644 (file)
index 0000000..e3ebfa7
--- /dev/null
@@ -0,0 +1,87 @@
+LIST "partner-jet-setup.txt"
+LIST "(C) Copyright 2010 Renesas Solutions Corp"
+LIST "Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"
+
+LIST "RWT Setting"
+EW 0xE6020004, 0xA500
+EW 0xE6030004, 0xA500
+
+DD 0x01001000, 0x01001000
+
+LIST "GPIO Setting"
+EB 0xE6051013, 0xA2
+
+LIST "CPG"
+ED 0xE6150080, 0x00000180
+ED 0xE61500C0, 0x00000002
+
+WAIT 1, 0xFE40009C
+
+LIST "FRQCR"
+ED 0xE6150000, 0x2D1305C3
+ED 0xE61500E0, 0x9E40358E
+ED 0xE6150004, 0x80331050
+
+WAIT 1, 0xFE40009C
+
+ED 0xE61500E4, 0x00002000
+
+WAIT 1, 0xFE40009C
+
+LIST "PLL"
+ED 0xE6150028, 0x00004000
+
+WAIT 1, 0xFE40009C
+
+ED 0xE615002C, 0x93000040
+
+WAIT 1, 0xFE40009C
+
+LIST "BSC"
+ED 0xFEC10000, 0x00E0001B
+
+LIST "SBSC1"
+ED 0xFE400354, 0x01AD8000
+ED 0xFE400354, 0x01AD8001
+
+WAIT 5, 0xFE40009C
+
+ED 0xFE400008, 0xBCC90151
+ED 0xFE400040, 0x41774113
+ED 0xFE400044, 0x2712E229
+ED 0xFE400048, 0x20C18505
+ED 0xFE40004C, 0x00110209
+ED 0xFE400010, 0x00000087
+
+WAIT 10, 0xFE40009C
+
+ED 0xFE400084, 0x0000003F
+EB 0xFE500000, 0x00
+
+WAIT 5, 0xFE40009C
+
+ED 0xFE400084, 0x0000FF0A
+EB 0xFE500000, 0x00
+
+WAIT 1, 0xFE40009C
+
+ED 0xFE400084, 0x00002201
+EB 0xFE500000, 0x00
+ED 0xFE400084, 0x00000302
+EB 0xFE500000, 0x00
+EB 0xFE5C0000, 0x00
+ED 0xFE400008, 0xBCC90159
+ED 0xFE40008C, 0x88800004
+ED 0xFE400094, 0x00000004
+ED 0xFE400028, 0xA55A0032
+ED 0xFE40002C, 0xA55A000C
+ED 0xFE400020, 0xA55A2048
+ED 0xFE400008, 0xBCC90959
+
+LIST "Change CPGA setting"
+ED 0xE61500E0, 0x9E40352E
+ED 0xE6150004, 0x80331050
+
+WAIT 1, 0xFE40009C
+
+ED 0xE6150354, 0x00000002
diff --git a/arch/arm/mach-shmobile/include/mach/zboot.h b/arch/arm/mach-shmobile/include/mach/zboot.h
new file mode 100644 (file)
index 0000000..3ad86b7
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef ZBOOT_H
+#define ZBOOT_H
+
+#include <asm/mach-types.h>
+#include <mach/zboot_macros.h>
+
+/**************************************************
+ *
+ *             board specific settings
+ *
+ **************************************************/
+
+#ifdef CONFIG_MACH_AP4EVB
+#define MACH_TYPE      MACH_TYPE_AP4EVB
+#include "mach/head-ap4evb.txt"
+#else
+#error "unsupported board."
+#endif
+
+#endif /* ZBOOT_H */
diff --git a/arch/arm/mach-shmobile/include/mach/zboot_macros.h b/arch/arm/mach-shmobile/include/mach/zboot_macros.h
new file mode 100644 (file)
index 0000000..aa6111f
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef __ZBOOT_MACRO_H
+#define __ZBOOT_MACRO_H
+
+/* The LIST command is used to include comments in the script */
+.macro LIST comment
+.endm
+
+/* The ED command is used to write a 32-bit word */
+.macro ED, addr, data
+       LDR     r0, 1f
+       LDR     r1, 2f
+       STR     r1, [r0]
+       B       3f
+1 :    .long   \addr
+2 :    .long   \data
+3 :
+.endm
+
+/* The EW command is used to write a 16-bit word */
+.macro EW, addr, data
+       LDR     r0, 1f
+       LDR     r1, 2f
+       STRH    r1, [r0]
+       B       3f
+1 :    .long   \addr
+2 :    .long   \data
+3 :
+.endm
+
+/* The EB command is used to write an 8-bit word */
+.macro EB, addr, data
+       LDR     r0, 1f
+       LDR     r1, 2f
+       STRB    r1, [r0]
+       B       3f
+1 :    .long   \addr
+2 :    .long   \data
+3 :
+.endm
+
+/* The WAIT command is used to delay the execution */
+.macro  WAIT, time, reg
+       LDR     r1, 1f
+       LDR     r0, 2f
+       STR     r0, [r1]
+10 :
+       LDR     r0, [r1]
+       CMP     r0, #0x00000000
+       BNE     10b
+       NOP
+       B       3f
+1 :    .long   \reg
+2 :    .long   \time * 100
+3 :
+.endm
+
+/* The DD command is used to read a 32-bit word */
+.macro  DD, start, end
+       LDR     r1, 1f
+       B       2f
+1 :    .long   \start
+2 :
+.endm
+
+#endif /* __ZBOOT_MACRO_H */
index 2ba9e5c9d2f6f711aecae8bda9506c7008d406a0..dd165c53889de61d499731f8e5b6da8fc88d5d55 100644 (file)
@@ -16,8 +16,8 @@
 #include <mach/io.h>
 
 #if defined(CONFIG_ARM_GIC)
-
-#include <asm/hardware/gic.h>
+#define HAVE_GET_IRQNR_PREAMBLE
+#include <asm/hardware/entry-macro-gic.S>
 
        /* Uses the GIC interrupt controller built into the cpu */
 #define ICTRL_BASE (IO_CPU_VIRT + 0x100)
 
        .macro  arch_ret_to_user, tmp1, tmp2
        .endm
-
-       /*
-        * The interrupt numbering scheme is defined in the
-        * interrupt controller spec.  To wit:
-        *
-        * Interrupts 0-15 are IPI
-        * 16-28 are reserved
-        * 29-31 are local.  We allow 30 to be used for the watchdog.
-        * 32-1020 are global
-        * 1021-1022 are reserved
-        * 1023 is "spurious" (no interrupt)
-        *
-        * For now, we ignore all local interrupts so only return an interrupt
-        * if it's between 30 and 1020.  The test_for_ipi routine below will
-        * pick up on IPIs.
-        *
-        * A simple read from the controller will tell us the number of the
-        * highest priority enabled interrupt.  We then just need to check
-        * whether it is in the valid range for an IRQ (30-1020 inclusive).
-        */
-
-       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-       /* bits 12-10 = src CPU, 9-0 = int # */
-       ldr     \irqstat, [\base, #GIC_CPU_INTACK]
-
-       ldr             \tmp, =1021
-
-       bic     \irqnr, \irqstat, #0x1c00
-
-       cmp     \irqnr, #29
-       cmpcc   \irqnr, \irqnr
-       cmpne   \irqnr, \tmp
-       cmpcs   \irqnr, \irqnr
-
-       .endm
-
-       /* We assume that irqstat (the raw value of the IRQ acknowledge
-        * register) is preserved from the macro above.
-        * If there is an IPI, we immediately signal end of interrupt on the
-        * controller, since this requires the original irqstat value which
-        * we won't easily be able to recreate later.
-        */
-
-       .macro test_for_ipi, irqnr, irqstat, base, tmp
-       bic     \irqnr, \irqstat, #0x1c00
-       cmp     \irqnr, #16
-       strcc   \irqstat, [\base, #GIC_CPU_EOI]
-       cmpcs   \irqnr, \irqnr
-       .endm
-
-       /* As above, this assumes that irqstat and base are preserved.. */
-
-       .macro test_for_ltirq, irqnr, irqstat, base, tmp
-       bic     \irqnr, \irqstat, #0x1c00
-       mov     \tmp, #0
-       cmp     \irqnr, #29
-       moveq   \tmp, #1
-       streq   \irqstat, [\base, #GIC_CPU_EOI]
-       cmp     \tmp, #0
-       .endm
-
 #else
        /* legacy interrupt controller for AP16 */
        .macro  disable_fiq
index f0981b1ac59eea58d65a1bbd251ad660deb80a0f..4cea2230c8dc92a41fb351b41d613e76fa0811ff 100644 (file)
@@ -65,8 +65,8 @@
 
 #ifndef __ASSEMBLER__
 
-#define __arch_ioremap(p, s, t)        tegra_ioremap(p, s, t)
-#define __arch_iounmap(v)      tegra_iounmap(v)
+#define __arch_ioremap         tegra_ioremap
+#define __arch_iounmap         tegra_iounmap
 
 void __iomem *tegra_ioremap(unsigned long phys, size_t size, unsigned int type);
 void tegra_iounmap(volatile void __iomem *addr);
index 50a8dfb9a0cfe8cbb1dbdaeb8a913d5858000902..5407de01abf0a6eccf51764d4c8d40d319132992 100644 (file)
@@ -94,8 +94,8 @@ void __init tegra_init_irq(void)
                writel(0, ictlr_to_virt(i) + ICTLR_CPU_IEP_CLASS);
        }
 
-       gic_dist_init(0, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 29);
-       gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
+       gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
+                IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
 
        gic = get_irq_chip(29);
        gic_unmask_irq = gic->unmask;
index 1c0fd92cab39e44779a3823e89d5248997163a72..3b7376c4f356cc89d2c8eb4c4c2ec1bf4fc47c62 100644 (file)
@@ -48,7 +48,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
         * core (e.g. timer irq), then they will not have been enabled
         * for us: do so
         */
-       gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x100);
+       gic_secondary_init(0);
 
        /*
         * Synchronise with the boot thread.
index 608a1372b172267170aaab6ecb2e0276fd5d49be..7328c01797699477bc5f9ad079d34b4c5134afa9 100644 (file)
@@ -61,8 +61,8 @@ void __init ux500_init_devices(void)
 
 void __init ux500_init_irq(void)
 {
-       gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29);
-       gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE));
+       gic_init(0, 29, __io_address(UX500_GIC_DIST_BASE),
+                __io_address(UX500_GIC_CPU_BASE));
 
        /*
         * Init clocks here so that they are available for system timer
index 60ea88db8283a521db2fe1e7396d171bff76db6c..a37f585a3ecbbca21270c78a13681c1955f06c4c 100644 (file)
@@ -11,7 +11,8 @@
  * warranty of any kind, whether express or implied.
  */
 #include <mach/hardware.h>
-#include <asm/hardware/gic.h>
+#define HAVE_GET_IRQNR_PREAMBLE
+#include <asm/hardware/entry-macro-gic.S>
 
                .macro  disable_fiq
                .endm
 
                .macro  arch_ret_to_user, tmp1, tmp2
                .endm
-
-               /*
-                * The interrupt numbering scheme is defined in the
-                * interrupt controller spec.  To wit:
-                *
-                * Interrupts 0-15 are IPI
-                * 16-28 are reserved
-                * 29-31 are local.  We allow 30 to be used for the watchdog.
-                * 32-1020 are global
-                * 1021-1022 are reserved
-                * 1023 is "spurious" (no interrupt)
-                *
-                * For now, we ignore all local interrupts so only return an
-                * interrupt if it's between 30 and 1020. The test_for_ipi
-                * routine below will pick up on IPIs.
-                *
-                * A simple read from the controller will tell us the number
-                * of the highest priority enabled interrupt. We then just
-                * need to check whether it is in the valid range for an
-                * IRQ (30-1020 inclusive).
-                */
-
-               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-               /* bits 12-10 = src CPU, 9-0 = int # */
-               ldr     \irqstat, [\base, #GIC_CPU_INTACK]
-
-               ldr     \tmp, =1021
-
-               bic     \irqnr, \irqstat, #0x1c00
-
-               cmp     \irqnr, #29
-               cmpcc   \irqnr, \irqnr
-               cmpne   \irqnr, \tmp
-               cmpcs   \irqnr, \irqnr
-
-               .endm
-
-               /* We assume that irqstat (the raw value of the IRQ
-                * acknowledge register) is preserved from the macro above.
-                * If there is an IPI, we immediately signal end of
-                * interrupt on the controller, since this requires the
-                * original irqstat value which we won't easily be able
-                * to recreate later.
-                */
-
-               .macro test_for_ipi, irqnr, irqstat, base, tmp
-               bic     \irqnr, \irqstat, #0x1c00
-               cmp     \irqnr, #16
-               strcc   \irqstat, [\base, #GIC_CPU_EOI]
-               cmpcs   \irqnr, \irqnr
-               .endm
-
-               /* As above, this assumes that irqstat and base
-                * are preserved..
-                */
-
-               .macro test_for_ltirq, irqnr, irqstat, base, tmp
-               bic     \irqnr, \irqstat, #0x1c00
-               mov     \tmp, #0
-               cmp     \irqnr, #29
-               moveq   \tmp, #1
-               streq   \irqstat, [\base, #GIC_CPU_EOI]
-               cmp     \tmp, #0
-               .endm
index 9e4c678de78593a248c9010a4eb8e0edcb4cb4dc..b5077b4c419fab54f0907f9aa347b5aacf33a810 100644 (file)
@@ -44,7 +44,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
         * core (e.g. timer irq), then they will not have been enabled
         * for us: do so
         */
-       gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE));
+       gic_secondary_init(0);
 
        /*
         * let the primary processor know we're out of the
index e38acb0f89c884b961bdb1dc11fa59b1a0112bc0..6b93bd60027129f8bc107cec157a58e4a308218b 100644 (file)
@@ -49,7 +49,7 @@
 #include <mach/clkdev.h>
 #include <mach/hardware.h>
 #include <mach/platform.h>
-#include <plat/timer-sp.h>
+#include <asm/hardware/timer-sp.h>
 
 #include "core.h"
 
index 57dd95ce41f90f677f0f5a7de2db2f8ea8be5b7a..362780d868de02f5c5ea0e42c3d80e5b02f09607 100644 (file)
@@ -22,5 +22,3 @@ struct map_desc;
 
 void v2m_map_io(struct map_desc *tile, size_t num);
 extern struct sys_timer v2m_timer;
-
-extern void __iomem *gic_cpu_base_addr;
index fd25ccd7272f7045b24a193f4c025a84c3bca97b..cb5793ef3ee0081a235e38dffecf59de6a179b4c 100644 (file)
@@ -21,7 +21,7 @@
 #include <mach/clkdev.h>
 #include <mach/ct-ca9x4.h>
 
-#include <plat/timer-sp.h>
+#include <asm/hardware/timer-sp.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -60,13 +60,10 @@ static void __init ct_ca9x4_map_io(void)
        v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
 }
 
-void __iomem *gic_cpu_base_addr;
-
 static void __init ct_ca9x4_init_irq(void)
 {
-       gic_cpu_base_addr = MMIO_P2V(A9_MPCORE_GIC_CPU);
-       gic_dist_init(0, MMIO_P2V(A9_MPCORE_GIC_DIST), 29);
-       gic_cpu_init(0, gic_cpu_base_addr);
+       gic_init(0, 29, MMIO_P2V(A9_MPCORE_GIC_DIST),
+                MMIO_P2V(A9_MPCORE_GIC_CPU));
 }
 
 #if 0
index 20e9fb514f0ac6aa94d4185ae75b6401e7459f96..73c11297509ed4bf9cfdefad92b831aab9495218 100644 (file)
@@ -1,67 +1,7 @@
-#include <asm/hardware/gic.h>
+#include <asm/hardware/entry-macro-gic.S>
 
        .macro  disable_fiq
        .endm
 
-       .macro  get_irqnr_preamble, base, tmp
-       ldr     \base, =gic_cpu_base_addr
-       ldr     \base, [\base]
-       .endm
-
        .macro  arch_ret_to_user, tmp1, tmp2
        .endm
-
-       /*
-        * The interrupt numbering scheme is defined in the
-        * interrupt controller spec.  To wit:
-        *
-        * Interrupts 0-15 are IPI
-        * 16-28 are reserved
-        * 29-31 are local.  We allow 30 to be used for the watchdog.
-        * 32-1020 are global
-        * 1021-1022 are reserved
-        * 1023 is "spurious" (no interrupt)
-        *
-        * For now, we ignore all local interrupts so only return an interrupt if it's
-        * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs.
-        *
-        * A simple read from the controller will tell us the number of the highest
-        * priority enabled interrupt.  We then just need to check whether it is in the
-        * valid range for an IRQ (30-1020 inclusive).
-        */
-
-       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-       ldr     \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
-       ldr     \tmp, =1021
-       bic     \irqnr, \irqstat, #0x1c00
-       cmp     \irqnr, #29
-       cmpcc   \irqnr, \irqnr
-       cmpne   \irqnr, \tmp
-       cmpcs   \irqnr, \irqnr
-       .endm
-
-       /* We assume that irqstat (the raw value of the IRQ acknowledge
-        * register) is preserved from the macro above.
-        * If there is an IPI, we immediately signal end of interrupt on the
-        * controller, since this requires the original irqstat value which
-        * we won't easily be able to recreate later.
-        */
-
-       .macro test_for_ipi, irqnr, irqstat, base, tmp
-       bic     \irqnr, \irqstat, #0x1c00
-       cmp     \irqnr, #16
-       strcc   \irqstat, [\base, #GIC_CPU_EOI]
-       cmpcs   \irqnr, \irqnr
-       .endm
-
-       /* As above, this assumes that irqstat and base are preserved.. */
-
-       .macro test_for_ltirq, irqnr, irqstat, base, tmp
-       bic     \irqnr, \irqstat, #0x1c00
-       mov     \tmp, #0
-       cmp     \irqnr, #29
-       moveq   \tmp, #1
-       streq   \irqstat, [\base, #GIC_CPU_EOI]
-       cmp     \tmp, #0
-       .endm
-
index 670970699ba93e09d2b270cdc0a061b17b64177b..dfb591031d17c6b3d724b1ef02d27059acd184b9 100644 (file)
@@ -51,7 +51,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
         * core (e.g. timer irq), then they will not have been enabled
         * for us: do so
         */
-       gic_cpu_init(0, gic_cpu_base_addr);
+       gic_secondary_init(0);
 
        /*
         * let the primary processor know we're out of the
index 7eaa232180a5ae627c3639ba642755444a5d3e27..91ff2e0df8569c235d22eeb720edfc144b49816b 100644 (file)
@@ -22,7 +22,7 @@
 #include <mach/clkdev.h>
 #include <mach/motherboard.h>
 
-#include <plat/timer-sp.h>
+#include <asm/hardware/timer-sp.h>
 
 #include "core.h"
 
index 128b549c2796012bf0079ac94a1795423cd233eb..204865f91d93c469c609dcd15aafb6f1a7816334 100644 (file)
@@ -294,8 +294,8 @@ static inline void omap44xx_map_common_io(void)
 extern void omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
                                 struct omap_sdrc_params *sdrc_cs1);
 
-#define __arch_ioremap(p,s,t)  omap_ioremap(p,s,t)
-#define __arch_iounmap(v)      omap_iounmap(v)
+#define __arch_ioremap omap_ioremap
+#define __arch_iounmap omap_iounmap
 
 void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type);
 void omap_iounmap(volatile void __iomem *addr);
index 5cf88e8427b15e66aafa287f1960e937a26fb89a..aaa571d17924fc4085fb43e29f587f5026c4d472 100644 (file)
@@ -1,5 +1,4 @@
 obj-y  := clock.o
-obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
 obj-$(CONFIG_ARCH_REALVIEW) += sched-clock.o
 obj-$(CONFIG_ARCH_VERSATILE) += sched-clock.o
 ifeq ($(CONFIG_LEDS_CLASS),y)
index 8d9386a22eb3392ad0537e3d9491ab8f7e833763..a565300a19c81cca450c466b14a02beddf10ded0 100644 (file)
@@ -50,8 +50,9 @@ sa1111_cs-$(CONFIG_SA1100_JORNADA720)         += sa1100_jornada720.o
 sa1100_cs-y                                    += sa1100_generic.o
 sa1100_cs-$(CONFIG_SA1100_ASSABET)             += sa1100_assabet.o
 sa1100_cs-$(CONFIG_SA1100_CERF)                        += sa1100_cerf.o
-sa1100_cs-$(CONFIG_SA1100_COLLIE)              += pxa2xx_sharpsl.o
+sa1100_cs-$(CONFIG_SA1100_COLLIE)              += pxa2xx_sharpsl.o
 sa1100_cs-$(CONFIG_SA1100_H3600)               += sa1100_h3600.o
+sa1100_cs-$(CONFIG_SA1100_NANOENGINE)          += sa1100_nanoengine.o
 sa1100_cs-$(CONFIG_SA1100_SHANNON)             += sa1100_shannon.o
 sa1100_cs-$(CONFIG_SA1100_SIMPAD)              += sa1100_simpad.o
 
index 6b228590b3fddb5bbd044acd561a029f99bb328d..fb9740d3e9a76e5b30317860ebafee954eef0a6c 100644 (file)
@@ -53,6 +53,9 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
 #if defined(CONFIG_SA1100_H3100) || defined(CONFIG_SA1100_H3600)
        pcmcia_h3600_init,
 #endif
+#ifdef CONFIG_SA1100_NANOENGINE
+       pcmcia_nanoengine_init,
+#endif
 #ifdef CONFIG_SA1100_SHANNON
        pcmcia_shannon_init,
 #endif
index 794f96a35bbafb1a78b5c292a2bc94852db0ee7c..adb08dbc723f63384e2924cdf5213e3f2855c054 100644 (file)
@@ -13,6 +13,7 @@ extern int pcmcia_freebird_init(struct device *);
 extern int pcmcia_gcplus_init(struct device *);
 extern int pcmcia_graphicsmaster_init(struct device *);
 extern int pcmcia_h3600_init(struct device *);
+extern int pcmcia_nanoengine_init(struct device *);
 extern int pcmcia_pangolin_init(struct device *);
 extern int pcmcia_pfs168_init(struct device *);
 extern int pcmcia_shannon_init(struct device *);
diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c
new file mode 100644 (file)
index 0000000..3d2652e
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * drivers/pcmcia/sa1100_nanoengine.c
+ *
+ * PCMCIA implementation routines for BSI nanoEngine.
+ *
+ * In order to have a fully functional pcmcia subsystem in a BSE nanoEngine
+ * board you should carefully read this:
+ * http://cambuca.ldhs.cetuc.puc-rio.br/nanoengine/
+ *
+ * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
+ *
+ * Based on original work for kernel 2.4 by
+ * Miguel Freitas <miguel@cpti.cetuc.puc-rio.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/nanoengine.h>
+
+#include "sa1100_generic.h"
+
+static struct pcmcia_irqs irqs_skt0[] = {
+       /* socket, IRQ, name */
+       { 0, NANOENGINE_IRQ_GPIO_PC_CD0, "PC CD0" },
+};
+
+static struct pcmcia_irqs irqs_skt1[] = {
+       /* socket, IRQ, name */
+       { 1, NANOENGINE_IRQ_GPIO_PC_CD1, "PC CD1" },
+};
+
+struct nanoengine_pins {
+       unsigned input_pins;
+       unsigned output_pins;
+       unsigned clear_outputs;
+       unsigned transition_pins;
+       unsigned pci_irq;
+       struct pcmcia_irqs *pcmcia_irqs;
+       unsigned pcmcia_irqs_size;
+};
+
+static struct nanoengine_pins nano_skts[] = {
+       {
+               .input_pins             = GPIO_PC_READY0 | GPIO_PC_CD0,
+               .output_pins            = GPIO_PC_RESET0,
+               .clear_outputs          = GPIO_PC_RESET0,
+               .transition_pins        = NANOENGINE_IRQ_GPIO_PC_CD0,
+               .pci_irq                = NANOENGINE_IRQ_GPIO_PC_READY0,
+               .pcmcia_irqs            = irqs_skt0,
+               .pcmcia_irqs_size       = ARRAY_SIZE(irqs_skt0)
+       }, {
+               .input_pins             = GPIO_PC_READY1 | GPIO_PC_CD1,
+               .output_pins            = GPIO_PC_RESET1,
+               .clear_outputs          = GPIO_PC_RESET1,
+               .transition_pins        = NANOENGINE_IRQ_GPIO_PC_CD1,
+               .pci_irq                = NANOENGINE_IRQ_GPIO_PC_READY1,
+               .pcmcia_irqs            = irqs_skt1,
+               .pcmcia_irqs_size       = ARRAY_SIZE(irqs_skt1)
+       }
+};
+
+unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts);
+
+static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+       unsigned i = skt->nr;
+
+       if (i >= num_nano_pcmcia_sockets)
+               return -ENXIO;
+
+       GPDR &= ~nano_skts[i].input_pins;
+       GPDR |= nano_skts[i].output_pins;
+       GPCR = nano_skts[i].clear_outputs;
+       set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH);
+       skt->socket.pci_irq = nano_skts[i].pci_irq;
+
+       return soc_pcmcia_request_irqs(skt,
+               nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
+}
+
+/*
+ * Release all resources.
+ */
+static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+       unsigned i = skt->nr;
+
+       if (i >= num_nano_pcmcia_sockets)
+               return;
+
+       soc_pcmcia_free_irqs(skt,
+               nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
+}
+
+static int nanoengine_pcmcia_configure_socket(
+       struct soc_pcmcia_socket *skt, const socket_state_t *state)
+{
+       unsigned reset;
+       unsigned i = skt->nr;
+
+       if (i >= num_nano_pcmcia_sockets)
+               return -ENXIO;
+
+       switch (i) {
+       case 0:
+               reset = GPIO_PC_RESET0;
+               break;
+       case 1:
+               reset = GPIO_PC_RESET1;
+               break;
+       default:
+               return -ENXIO;
+       }
+
+       if (state->flags & SS_RESET)
+               GPSR = reset;
+       else
+               GPCR = reset;
+
+       return 0;
+}
+
+static void nanoengine_pcmcia_socket_state(
+       struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
+{
+       unsigned long levels = GPLR;
+       unsigned i = skt->nr;
+
+       if (i >= num_nano_pcmcia_sockets)
+               return;
+
+       memset(state, 0, sizeof(struct pcmcia_state));
+       switch (i) {
+       case 0:
+               state->ready = (levels & GPIO_PC_READY0) ? 1 : 0;
+               state->detect = !(levels & GPIO_PC_CD0) ? 1 : 0;
+               break;
+       case 1:
+               state->ready = (levels & GPIO_PC_READY1) ? 1 : 0;
+               state->detect = !(levels & GPIO_PC_CD1) ? 1 : 0;
+               break;
+       default:
+               return;
+       }
+       state->bvd1 = 1;
+       state->bvd2 = 1;
+       state->wrprot = 0; /* Not available */
+       state->vs_3v = 1; /* Can only apply 3.3V */
+       state->vs_Xv = 0;
+}
+
+/*
+ * Enable card status IRQs on (re-)initialisation.  This can
+ * be called at initialisation, power management event, or
+ * pcmcia event.
+ */
+static void nanoengine_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+       unsigned i = skt->nr;
+
+       if (i >= num_nano_pcmcia_sockets)
+               return;
+
+       soc_pcmcia_enable_irqs(skt,
+               nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
+}
+
+/*
+ * Disable card status IRQs on suspend.
+ */
+static void nanoengine_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+       unsigned i = skt->nr;
+
+       if (i >= num_nano_pcmcia_sockets)
+               return;
+
+       soc_pcmcia_disable_irqs(skt,
+               nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
+}
+
+static struct pcmcia_low_level nanoengine_pcmcia_ops = {
+       .owner                  = THIS_MODULE,
+
+       .hw_init                = nanoengine_pcmcia_hw_init,
+       .hw_shutdown            = nanoengine_pcmcia_hw_shutdown,
+
+       .configure_socket       = nanoengine_pcmcia_configure_socket,
+       .socket_state           = nanoengine_pcmcia_socket_state,
+       .socket_init            = nanoengine_pcmcia_socket_init,
+       .socket_suspend         = nanoengine_pcmcia_socket_suspend,
+};
+
+int pcmcia_nanoengine_init(struct device *dev)
+{
+       int ret = -ENODEV;
+
+       if (machine_is_nanoengine())
+               ret = sa11xx_drv_pcmcia_probe(
+                       dev, &nanoengine_pcmcia_ops, 0, 2);
+
+       return ret;
+}
+
index 2fe8cb8e95cd3409d74d04e312388736234c5d0c..5a9a392eacdf18d1ba9de1237f11f0a3efefbf7d 100644 (file)
 ======================================================================*/
 
 
-#include <linux/module.h>
-#include <linux/moduleparam.h>
+#include <linux/cpufreq.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
-#include <linux/timer.h>
 #include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/mutex.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
 #include <linux/spinlock.h>
-#include <linux/cpufreq.h>
+#include <linux/timer.h>
 
 #include <mach/hardware.h>
-#include <asm/io.h>
 #include <asm/system.h>
 
 #include "soc_common.h"
@@ -74,7 +74,8 @@ EXPORT_SYMBOL(soc_pcmcia_debug);
 
 #endif
 
-#define to_soc_pcmcia_socket(x)        container_of(x, struct soc_pcmcia_socket, socket)
+#define to_soc_pcmcia_socket(x)        \
+       container_of(x, struct soc_pcmcia_socket, socket)
 
 static unsigned short
 calc_speed(unsigned short *spds, int num, unsigned short dflt)
@@ -91,11 +92,15 @@ calc_speed(unsigned short *spds, int num, unsigned short dflt)
        return speed;
 }
 
-void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt, struct soc_pcmcia_timing *timing)
+void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt,
+       struct soc_pcmcia_timing *timing)
 {
-       timing->io = calc_speed(skt->spd_io, MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS);
-       timing->mem = calc_speed(skt->spd_mem, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
-       timing->attr = calc_speed(skt->spd_attr, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
+       timing->io =
+               calc_speed(skt->spd_io, MAX_IO_WIN, SOC_PCMCIA_IO_ACCESS);
+       timing->mem =
+               calc_speed(skt->spd_mem, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
+       timing->attr =
+               calc_speed(skt->spd_attr, MAX_WIN, SOC_PCMCIA_3V_MEM_ACCESS);
 }
 EXPORT_SYMBOL(soc_common_pcmcia_get_timing);
 
@@ -137,8 +142,8 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
  *
  * Convert PCMCIA socket state to our socket configure structure.
  */
-static int
-soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *state)
+static int soc_common_pcmcia_config_skt(
+       struct soc_pcmcia_socket *skt, socket_state_t *state)
 {
        int ret;
 
@@ -150,7 +155,8 @@ soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *stat
                 */
                if (skt->irq_state != 1 && state->io_irq) {
                        skt->irq_state = 1;
-                       set_irq_type(skt->socket.pci_irq, IRQ_TYPE_EDGE_FALLING);
+                       set_irq_type(skt->socket.pci_irq,
+                               IRQ_TYPE_EDGE_FALLING);
                } else if (skt->irq_state == 1 && state->io_irq == 0) {
                        skt->irq_state = 0;
                        set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE);
@@ -304,24 +310,24 @@ soc_common_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
  * of power configuration, reset, &c. We also record the value of
  * `state' in order to regurgitate it to the PCMCIA core later.
  */
-static int
-soc_common_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
+static int soc_common_pcmcia_set_socket(
+       struct pcmcia_socket *sock, socket_state_t *state)
 {
        struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
 
-       debug(skt, 2, "mask: %s%s%s%s%s%sflags: %s%s%s%s%s%sVcc %d Vpp %d irq %d\n",
-                       (state->csc_mask==0)?"<NONE> ":"",
-                       (state->csc_mask&SS_DETECT)?"DETECT ":"",
-                       (state->csc_mask&SS_READY)?"READY ":"",
-                       (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",
-                       (state->csc_mask&SS_BATWARN)?"BATWARN ":"",
-                       (state->csc_mask&SS_STSCHG)?"STSCHG ":"",
-                       (state->flags==0)?"<NONE> ":"",
-                       (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",
-                       (state->flags&SS_IOCARD)?"IOCARD ":"",
-                       (state->flags&SS_RESET)?"RESET ":"",
-                       (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
-                       (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
+       debug(skt, 2, "mask: %s%s%s%s%s%s flags: %s%s%s%s%s%s Vcc %d Vpp %d irq %d\n",
+                       (state->csc_mask == 0)          ? "<NONE> " :   "",
+                       (state->csc_mask & SS_DETECT)   ? "DETECT " :   "",
+                       (state->csc_mask & SS_READY)    ? "READY " :    "",
+                       (state->csc_mask & SS_BATDEAD)  ? "BATDEAD " :  "",
+                       (state->csc_mask & SS_BATWARN)  ? "BATWARN " :  "",
+                       (state->csc_mask & SS_STSCHG)   ? "STSCHG " :   "",
+                       (state->flags == 0)             ? "<NONE> " :   "",
+                       (state->flags & SS_PWR_AUTO)    ? "PWR_AUTO " : "",
+                       (state->flags & SS_IOCARD)      ? "IOCARD " :   "",
+                       (state->flags & SS_RESET)       ? "RESET " :    "",
+                       (state->flags & SS_SPKR_ENA)    ? "SPKR_ENA " : "",
+                       (state->flags & SS_OUTPUT_ENA)  ? "OUTPUT_ENA " : "",
                        state->Vcc, state->Vpp, state->io_irq);
 
        return soc_common_pcmcia_config_skt(skt, state);
@@ -336,8 +342,8 @@ soc_common_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
  *
  * Returns: 0 on success, -1 on error
  */
-static int
-soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map)
+static int soc_common_pcmcia_set_io_map(
+       struct pcmcia_socket *sock, struct pccard_io_map *map)
 {
        struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
        unsigned short speed = map->speed;
@@ -346,14 +352,14 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
                map->map, map->speed, (unsigned long long)map->start,
                (unsigned long long)map->stop);
        debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n",
-               (map->flags==0)?"<NONE>":"",
-               (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
-               (map->flags&MAP_16BIT)?"16BIT ":"",
-               (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
-               (map->flags&MAP_0WS)?"0WS ":"",
-               (map->flags&MAP_WRPROT)?"WRPROT ":"",
-               (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"",
-               (map->flags&MAP_PREFETCH)?"PREFETCH ":"");
+               (map->flags == 0)               ? "<NONE>"      : "",
+               (map->flags & MAP_ACTIVE)       ? "ACTIVE "     : "",
+               (map->flags & MAP_16BIT)        ? "16BIT "      : "",
+               (map->flags & MAP_AUTOSZ)       ? "AUTOSZ "     : "",
+               (map->flags & MAP_0WS)          ? "0WS "        : "",
+               (map->flags & MAP_WRPROT)       ? "WRPROT "     : "",
+               (map->flags & MAP_USE_WAIT)     ? "USE_WAIT "   : "",
+               (map->flags & MAP_PREFETCH)     ? "PREFETCH "   : "");
 
        if (map->map >= MAX_IO_WIN) {
                printk(KERN_ERR "%s(): map (%d) out of range\n", __func__,
@@ -390,8 +396,8 @@ soc_common_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *m
  *
  * Returns: 0 on success, -ERRNO on error
  */
-static int
-soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map)
+static int soc_common_pcmcia_set_mem_map(
+       struct pcmcia_socket *sock, struct pccard_mem_map *map)
 {
        struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
        struct resource *res;
@@ -400,14 +406,14 @@ soc_common_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map
        debug(skt, 2, "map %u speed %u card_start %08x\n",
                map->map, map->speed, map->card_start);
        debug(skt, 2, "flags: %s%s%s%s%s%s%s%s\n",
-               (map->flags==0)?"<NONE>":"",
-               (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
-               (map->flags&MAP_16BIT)?"16BIT ":"",
-               (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
-               (map->flags&MAP_0WS)?"0WS ":"",
-               (map->flags&MAP_WRPROT)?"WRPROT ":"",
-               (map->flags&MAP_ATTRIB)?"ATTRIB ":"",
-               (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"");
+               (map->flags == 0)               ? "<NONE>"      : "",
+               (map->flags & MAP_ACTIVE)       ? "ACTIVE "     : "",
+               (map->flags & MAP_16BIT)        ? "16BIT "      : "",
+               (map->flags & MAP_AUTOSZ)       ? "AUTOSZ "     : "",
+               (map->flags & MAP_0WS)          ? "0WS "        : "",
+               (map->flags & MAP_WRPROT)       ? "WRPROT "     : "",
+               (map->flags & MAP_ATTRIB)       ? "ATTRIB "     : "",
+               (map->flags & MAP_USE_WAIT)     ? "USE_WAIT "   : "");
 
        if (map->map >= MAX_WIN)
                return -EINVAL;
@@ -462,8 +468,8 @@ static struct bittbl conf_bits[] = {
        { SS_OUTPUT_ENA,        "SS_OUTPUT_ENA" },
 };
 
-static void
-dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, int sz)
+static void dump_bits(char **p, const char *prefix,
+       unsigned int val, struct bittbl *bits, int sz)
 {
        char *b = *p;
        int i;
@@ -481,13 +487,14 @@ dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, i
  *
  * Returns: the number of characters added to the buffer
  */
-static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_status(
+       struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct soc_pcmcia_socket *skt =
                container_of(dev, struct soc_pcmcia_socket, socket.dev);
        char *p = buf;
 
-       p+=sprintf(p, "slot     : %d\n", skt->nr);
+       p += sprintf(p, "slot     : %d\n", skt->nr);
 
        dump_bits(&p, "status", skt->status,
                  status_bits, ARRAY_SIZE(status_bits));
@@ -496,12 +503,12 @@ static ssize_t show_status(struct device *dev, struct device_attribute *attr, ch
        dump_bits(&p, "cs_flags", skt->cs_state.flags,
                  conf_bits, ARRAY_SIZE(conf_bits));
 
-       p+=sprintf(p, "Vcc      : %d\n", skt->cs_state.Vcc);
-       p+=sprintf(p, "Vpp      : %d\n", skt->cs_state.Vpp);
-       p+=sprintf(p, "IRQ      : %d (%d)\n", skt->cs_state.io_irq,
+       p += sprintf(p, "Vcc      : %d\n", skt->cs_state.Vcc);
+       p += sprintf(p, "Vpp      : %d\n", skt->cs_state.Vpp);
+       p += sprintf(p, "IRQ      : %d (%d)\n", skt->cs_state.io_irq,
                skt->socket.pci_irq);
        if (skt->ops->show_timing)
-               p+=skt->ops->show_timing(skt, p);
+               p += skt->ops->show_timing(skt, p);
 
        return p-buf;
 }
@@ -594,7 +601,7 @@ soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
 
        mutex_lock(&soc_pcmcia_sockets_lock);
        list_for_each_entry(skt, &soc_pcmcia_sockets, node)
-               if ( skt->ops->frequency_change )
+               if (skt->ops->frequency_change)
                        ret += skt->ops->frequency_change(skt, val, freqs);
        mutex_unlock(&soc_pcmcia_sockets_lock);
 
@@ -620,7 +627,8 @@ fs_initcall(soc_pcmcia_cpufreq_register);
 
 static void soc_pcmcia_cpufreq_unregister(void)
 {
-       cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
+       cpufreq_unregister_notifier(&soc_pcmcia_notifier_block,
+               CPUFREQ_TRANSITION_NOTIFIER);
 }
 module_exit(soc_pcmcia_cpufreq_unregister);
 
index e4a44b641702677ba99884f03089477f1c04f3cd..88ea52b8647ad358bb99e9c032f7764a9841080b 100644 (file)
 #include <mach/regs-ost.h>
 #endif
 
-#define RTC_DEF_DIVIDER                32768 - 1
+#define RTC_DEF_DIVIDER                (32768 - 1)
 #define RTC_DEF_TRIM           0
 
-static unsigned long rtc_freq = 1024;
+static const unsigned long RTC_FREQ = 1024;
 static unsigned long timer_freq;
 static struct rtc_time rtc_alarm;
 static DEFINE_SPINLOCK(sa1100_rtc_lock);
@@ -61,7 +61,8 @@ static inline int rtc_periodic_alarm(struct rtc_time *tm)
  * Calculate the next alarm time given the requested alarm time mask
  * and the current time.
  */
-static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm)
+static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now,
+       struct rtc_time *alrm)
 {
        unsigned long next_time;
        unsigned long now_time;
@@ -116,7 +117,23 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
        rtsr = RTSR;
        /* clear interrupt sources */
        RTSR = 0;
-       RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2);
+       /* Fix for a nasty initialization problem the in SA11xx RTSR register.
+        * See also the comments in sa1100_rtc_probe(). */
+       if (rtsr & (RTSR_ALE | RTSR_HZE)) {
+               /* This is the original code, before there was the if test
+                * above. This code does not clear interrupts that were not
+                * enabled. */
+               RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2);
+       } else {
+               /* For some reason, it is possible to enter this routine
+                * without interruptions enabled, it has been tested with
+                * several units (Bug in SA11xx chip?).
+                *
+                * This situation leads to an infinite "loop" of interrupt
+                * routine calling and as a result the processor seems to
+                * lock on its first call to open(). */
+               RTSR = RTSR_AL | RTSR_HZ;
+       }
 
        /* clear alarm interrupt if it has occurred */
        if (rtsr & RTSR_AL)
@@ -139,8 +156,58 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+static int sa1100_irq_set_freq(struct device *dev, int freq)
+{
+       if (freq < 1 || freq > timer_freq) {
+               return -EINVAL;
+       } else {
+               struct rtc_device *rtc = (struct rtc_device *)dev;
+
+               rtc->irq_freq = freq;
+
+               return 0;
+       }
+}
+
 static int rtc_timer1_count;
 
+static int sa1100_irq_set_state(struct device *dev, int enabled)
+{
+       spin_lock_irq(&sa1100_rtc_lock);
+       if (enabled) {
+               struct rtc_device *rtc = (struct rtc_device *)dev;
+
+               OSMR1 = timer_freq / rtc->irq_freq + OSCR;
+               OIER |= OIER_E1;
+               rtc_timer1_count = 1;
+       } else {
+               OIER &= ~OIER_E1;
+       }
+       spin_unlock_irq(&sa1100_rtc_lock);
+
+       return 0;
+}
+
+static inline int sa1100_timer1_retrigger(struct rtc_device *rtc)
+{
+       unsigned long diff;
+       unsigned long period = timer_freq / rtc->irq_freq;
+
+       spin_lock_irq(&sa1100_rtc_lock);
+
+       do {
+               OSMR1 += period;
+               diff = OSMR1 - OSCR;
+               /* If OSCR > OSMR1, diff is a very large number (unsigned
+                * math). This means we have a lost interrupt. */
+       } while (diff > period);
+       OIER |= OIER_E1;
+
+       spin_unlock_irq(&sa1100_rtc_lock);
+
+       return 0;
+}
+
 static irqreturn_t timer1_interrupt(int irq, void *dev_id)
 {
        struct platform_device *pdev = to_platform_device(dev_id);
@@ -158,7 +225,11 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id)
        rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF);
 
        if (rtc_timer1_count == 1)
-               rtc_timer1_count = (rtc_freq * ((1 << 30) / (timer_freq >> 2)));
+               rtc_timer1_count =
+                       (rtc->irq_freq * ((1 << 30) / (timer_freq >> 2)));
+
+       /* retrigger. */
+       sa1100_timer1_retrigger(rtc);
 
        return IRQ_HANDLED;
 }
@@ -166,8 +237,10 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id)
 static int sa1100_rtc_read_callback(struct device *dev, int data)
 {
        if (data & RTC_PF) {
+               struct rtc_device *rtc = (struct rtc_device *)dev;
+
                /* interpolate missed periods and set match for the next */
-               unsigned long period = timer_freq / rtc_freq;
+               unsigned long period = timer_freq / rtc->irq_freq;
                unsigned long oscr = OSCR;
                unsigned long osmr1 = OSMR1;
                unsigned long missed = (oscr - osmr1)/period;
@@ -178,7 +251,7 @@ static int sa1100_rtc_read_callback(struct device *dev, int data)
                 * Here we compare (match - OSCR) 8 instead of 0 --
                 * see comment in pxa_timer_interrupt() for explanation.
                 */
-               while( (signed long)((osmr1 = OSMR1) - OSCR) <= 8 ) {
+               while ((signed long)((osmr1 = OSMR1) - OSCR) <= 8) {
                        data += 0x100;
                        OSSR = OSSR_M1; /* clear match on timer 1 */
                        OSMR1 = osmr1 + period;
@@ -190,25 +263,29 @@ static int sa1100_rtc_read_callback(struct device *dev, int data)
 static int sa1100_rtc_open(struct device *dev)
 {
        int ret;
+       struct rtc_device *rtc = (struct rtc_device *)dev;
 
        ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED,
-                               "rtc 1Hz", dev);
+               "rtc 1Hz", dev);
        if (ret) {
                dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz);
                goto fail_ui;
        }
        ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED,
-                               "rtc Alrm", dev);
+               "rtc Alrm", dev);
        if (ret) {
                dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm);
                goto fail_ai;
        }
        ret = request_irq(IRQ_OST1, timer1_interrupt, IRQF_DISABLED,
-                               "rtc timer", dev);
+               "rtc timer", dev);
        if (ret) {
                dev_err(dev, "IRQ %d already in use.\n", IRQ_OST1);
                goto fail_pi;
        }
+       rtc->max_user_freq = RTC_FREQ;
+       sa1100_irq_set_freq(dev, RTC_FREQ);
+
        return 0;
 
  fail_pi:
@@ -236,7 +313,7 @@ static void sa1100_rtc_release(struct device *dev)
 static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
                unsigned long arg)
 {
-       switch(cmd) {
+       switch (cmd) {
        case RTC_AIE_OFF:
                spin_lock_irq(&sa1100_rtc_lock);
                RTSR &= ~RTSR_ALE;
@@ -257,25 +334,6 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
                RTSR |= RTSR_HZE;
                spin_unlock_irq(&sa1100_rtc_lock);
                return 0;
-       case RTC_PIE_OFF:
-               spin_lock_irq(&sa1100_rtc_lock);
-               OIER &= ~OIER_E1;
-               spin_unlock_irq(&sa1100_rtc_lock);
-               return 0;
-       case RTC_PIE_ON:
-               spin_lock_irq(&sa1100_rtc_lock);
-               OSMR1 = timer_freq / rtc_freq + OSCR;
-               OIER |= OIER_E1;
-               rtc_timer1_count = 1;
-               spin_unlock_irq(&sa1100_rtc_lock);
-               return 0;
-       case RTC_IRQP_READ:
-               return put_user(rtc_freq, (unsigned long *)arg);
-       case RTC_IRQP_SET:
-               if (arg < 1 || arg > timer_freq)
-                       return -EINVAL;
-               rtc_freq = arg;
-               return 0;
        }
        return -ENOIOCTLCMD;
 }
@@ -327,12 +385,15 @@ static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
 static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq)
 {
+       struct rtc_device *rtc = (struct rtc_device *)dev;
+
        seq_printf(seq, "trim/divider\t: 0x%08x\n", (u32) RTTR);
        seq_printf(seq, "update_IRQ\t: %s\n",
                        (RTSR & RTSR_HZE) ? "yes" : "no");
        seq_printf(seq, "periodic_IRQ\t: %s\n",
                        (OIER & OIER_E1) ? "yes" : "no");
-       seq_printf(seq, "periodic_freq\t: %ld\n", rtc_freq);
+       seq_printf(seq, "periodic_freq\t: %d\n", rtc->irq_freq);
+       seq_printf(seq, "RTSR\t\t: 0x%08x\n", (u32)RTSR);
 
        return 0;
 }
@@ -347,6 +408,8 @@ static const struct rtc_class_ops sa1100_rtc_ops = {
        .read_alarm = sa1100_rtc_read_alarm,
        .set_alarm = sa1100_rtc_set_alarm,
        .proc = sa1100_rtc_proc,
+       .irq_set_freq = sa1100_irq_set_freq,
+       .irq_set_state = sa1100_irq_set_state,
 };
 
 static int sa1100_rtc_probe(struct platform_device *pdev)
@@ -364,7 +427,8 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
         */
        if (RTTR == 0) {
                RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
-               dev_warn(&pdev->dev, "warning: initializing default clock divider/trim value\n");
+               dev_warn(&pdev->dev, "warning: "
+                       "initializing default clock divider/trim value\n");
                /* The current RTC value probably doesn't make sense either */
                RCNR = 0;
        }
@@ -372,13 +436,42 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
        device_init_wakeup(&pdev->dev, 1);
 
        rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops,
-                               THIS_MODULE);
+               THIS_MODULE);
 
        if (IS_ERR(rtc))
                return PTR_ERR(rtc);
 
        platform_set_drvdata(pdev, rtc);
 
+       /* Set the irq_freq */
+       /*TODO: Find out who is messing with this value after we initialize
+        * it here.*/
+       rtc->irq_freq = RTC_FREQ;
+
+       /* Fix for a nasty initialization problem the in SA11xx RTSR register.
+        * See also the comments in sa1100_rtc_interrupt().
+        *
+        * Sometimes bit 1 of the RTSR (RTSR_HZ) will wake up 1, which means an
+        * interrupt pending, even though interrupts were never enabled.
+        * In this case, this bit it must be reset before enabling
+        * interruptions to avoid a nonexistent interrupt to occur.
+        *
+        * In principle, the same problem would apply to bit 0, although it has
+        * never been observed to happen.
+        *
+        * This issue is addressed both here and in sa1100_rtc_interrupt().
+        * If the issue is not addressed here, in the times when the processor
+        * wakes up with the bit set there will be one spurious interrupt.
+        *
+        * The issue is also dealt with in sa1100_rtc_interrupt() to be on the
+        * safe side, once the condition that lead to this strange
+        * initialization is unknown and could in principle happen during
+        * normal processing.
+        *
+        * Notice that clearing bit 1 and 0 is accomplished by writting ONES to
+        * the corresponding bits in RTSR. */
+       RTSR = RTSR_AL | RTSR_HZ;
+
        return 0;
 }
 
@@ -386,7 +479,7 @@ static int sa1100_rtc_remove(struct platform_device *pdev)
 {
        struct rtc_device *rtc = platform_get_drvdata(pdev);
 
-       if (rtc)
+       if (rtc)
                rtc_device_unregister(rtc);
 
        return 0;
index 2367fb3f70bc6ba468ab0ccb628b5b88fabac955..74802bc5ded95e09d510bcadfba94167e1390bc2 100644 (file)
@@ -499,7 +499,7 @@ static int __init parse_crash_elf64_headers(void)
        /* Do some basic Verification. */
        if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 ||
                (ehdr.e_type != ET_CORE) ||
-               !vmcore_elf_check_arch(&ehdr) ||
+               !vmcore_elf64_check_arch(&ehdr) ||
                ehdr.e_ident[EI_CLASS] != ELFCLASS64 ||
                ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
                ehdr.e_version != EV_CURRENT ||
index 0026f267da20d6e9f1a0dc5343b978c1e5f0b6f1..088cd4ace4ef756c542cffc66e9b8a42f5ad1b38 100644 (file)
@@ -20,7 +20,14 @@ extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
 #define vmcore_elf_check_arch_cross(x) 0
 #endif
 
-#define vmcore_elf_check_arch(x) (elf_check_arch(x) || vmcore_elf_check_arch_cross(x))
+/*
+ * Architecture code can redefine this if there are any special checks
+ * needed for 64-bit ELF vmcores. In case of 32-bit only architecture,
+ * this can be set to zero.
+ */
+#ifndef vmcore_elf64_check_arch
+#define vmcore_elf64_check_arch(x) (elf_check_arch(x) || vmcore_elf_check_arch_cross(x))
+#endif
 
 /*
  * is_kdump_kernel() checks whether this kernel is booting after a panic of
index f2f32eee2c5bbff3880b52be0769ca8a78cd171a..038b3d1e29814f789ec6728708c4f71858ef7234 100644 (file)
@@ -38,6 +38,7 @@ static void *ehdr_curr; /* current ElfXX_Ehdr *  for resource cleanup */
 static char gpfx;      /* prefix for global symbol name (sometimes '_') */
 static struct stat sb; /* Remember .st_size, etc. */
 static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */
+static const char *altmcount;  /* alternate mcount symbol name */
 
 /* setjmp() return values */
 enum {
@@ -299,7 +300,9 @@ do_file(char const *const fname)
                fail_file();
        } break;
        case EM_386:     reltype = R_386_32;                   break;
-       case EM_ARM:     reltype = R_ARM_ABS32;                break;
+       case EM_ARM:     reltype = R_ARM_ABS32;
+                        altmcount = "__gnu_mcount_nc";
+                        break;
        case EM_IA_64:   reltype = R_IA64_IMM64;   gpfx = '_'; break;
        case EM_MIPS:    /* reltype: e_class    */ gpfx = '_'; break;
        case EM_PPC:     reltype = R_PPC_ADDR32;   gpfx = '_'; break;
@@ -357,7 +360,7 @@ do_file(char const *const fname)
 int
 main(int argc, char const *argv[])
 {
-       const char ftrace[] = "kernel/trace/ftrace.o";
+       const char ftrace[] = "/ftrace.o";
        int ftrace_size = sizeof(ftrace) - 1;
        int n_error = 0;  /* gcc-4.3.0 false positive complaint */
 
index 39667174971d1eb86105edd927aa92d39c0954bf..baf187bee983c33b6323cfea1b8591ca963fc934 100644 (file)
@@ -275,11 +275,12 @@ static uint_t *sift_rel_mcount(uint_t *mlocp,
                        Elf_Sym const *const symp =
                                &sym0[Elf_r_sym(relp)];
                        char const *symname = &str0[w(symp->st_name)];
+                       char const *mcount = '_' == gpfx ? "_mcount" : "mcount";
 
                        if ('.' == symname[0])
                                ++symname;  /* ppc64 hack */
-                       if (0 == strcmp((('_' == gpfx) ? "_mcount" : "mcount"),
-                                       symname))
+                       if (0 == strcmp(mcount, symname) ||
+                           (altmcount && 0 == strcmp(altmcount, symname)))
                                mcountsym = Elf_r_sym(relp);
                }