]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 1 Mar 2010 17:15:15 +0000 (09:15 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 1 Mar 2010 17:15:15 +0000 (09:15 -0800)
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (100 commits)
  ARM: Eliminate decompressor -Dstatic= PIC hack
  ARM: 5958/1: ARM: U300: fix inverted clk round rate
  ARM: 5956/1: misplaced parentheses
  ARM: 5955/1: ep93xx: move timer defines into core.c and document
  ARM: 5954/1: ep93xx: move gpio interrupt support to gpio.c
  ARM: 5953/1: ep93xx: fix broken build of clock.c
  ARM: 5952/1: ARM: MM: Add ARM_L1_CACHE_SHIFT_6 for handle inside each ARCH Kconfig
  ARM: 5949/1: NUC900 add gpio virtual memory map
  ARM: 5948/1: Enable timer0 to time4 clock support for nuc910
  ARM: 5940/2: ARM: MMCI: remove custom DBG macro and printk
  ARM: make_coherent(): fix problems with highpte, part 2
  MM: Pass a PTE pointer to update_mmu_cache() rather than the PTE itself
  ARM: 5945/1: ep93xx: include correct irq.h in core.c
  ARM: 5933/1: amba-pl011: support hardware flow control
  ARM: 5930/1: Add PKMAP area description to memory.txt.
  ARM: 5929/1: Add checks to detect overlap of memory regions.
  ARM: 5928/1: Change type of VMALLOC_END to unsigned long.
  ARM: 5927/1: Make delimiters of DMA area globally visibly.
  ARM: 5926/1: Add "Virtual kernel memory..." printout.
  ARM: 5920/1: OMAP4: Enable L2 Cache
  ...

Fix up trivial conflict in arch/arm/mach-mx25/clock.c

318 files changed:
Documentation/arm/memory.txt
Documentation/cachetlb.txt
arch/alpha/include/asm/pgtable.h
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/decompress.c [new file with mode: 0644]
arch/arm/boot/compressed/head.S
arch/arm/boot/compressed/misc.c
arch/arm/boot/compressed/vmlinux.lds.in
arch/arm/common/clkdev.c
arch/arm/common/dmabounce.c
arch/arm/common/vic.c
arch/arm/configs/at572d940hfek_defconfig [new file with mode: 0644]
arch/arm/configs/omap_4430sdp_defconfig
arch/arm/include/asm/atomic.h
arch/arm/include/asm/cacheflush.h
arch/arm/include/asm/clkdev.h
arch/arm/include/asm/dma-mapping.h
arch/arm/include/asm/io.h
arch/arm/include/asm/mach/time.h
arch/arm/include/asm/memory.h
arch/arm/include/asm/mmu.h
arch/arm/include/asm/mmu_context.h
arch/arm/include/asm/page.h
arch/arm/include/asm/perf_event.h [new file with mode: 0644]
arch/arm/include/asm/pgtable-nommu.h
arch/arm/include/asm/pmu.h [new file with mode: 0644]
arch/arm/include/asm/setup.h
arch/arm/include/asm/smp_plat.h
arch/arm/include/asm/spinlock.h
arch/arm/include/asm/system.h
arch/arm/include/asm/thread_info.h
arch/arm/include/asm/tlbflush.h
arch/arm/kernel/Makefile
arch/arm/kernel/asm-offsets.c
arch/arm/kernel/debug.S
arch/arm/kernel/leds.c [new file with mode: 0644]
arch/arm/kernel/perf_event.c [new file with mode: 0644]
arch/arm/kernel/pmu.c [new file with mode: 0644]
arch/arm/kernel/ptrace.c
arch/arm/kernel/setup.c
arch/arm/kernel/time.c
arch/arm/kernel/traps.c
arch/arm/kernel/vmlinux.lds.S
arch/arm/mach-aaec2000/include/mach/debug-macro.S
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/at572d940hf.c [new file with mode: 0644]
arch/arm/mach-at91/at572d940hf_devices.c [new file with mode: 0644]
arch/arm/mach-at91/board-at572d940hf_ek.c [new file with mode: 0644]
arch/arm/mach-at91/clock.c
arch/arm/mach-at91/clock.h
arch/arm/mach-at91/generic.h
arch/arm/mach-at91/include/mach/at572d940hf.h [new file with mode: 0644]
arch/arm/mach-at91/include/mach/at572d940hf_matrix.h [new file with mode: 0644]
arch/arm/mach-at91/include/mach/at91_pmc.h
arch/arm/mach-at91/include/mach/board.h
arch/arm/mach-at91/include/mach/cpu.h
arch/arm/mach-at91/include/mach/debug-macro.S
arch/arm/mach-at91/include/mach/hardware.h
arch/arm/mach-at91/include/mach/timex.h
arch/arm/mach-bcmring/core.c
arch/arm/mach-clps711x/include/mach/debug-macro.S
arch/arm/mach-davinci/include/mach/debug-macro.S
arch/arm/mach-davinci/include/mach/hardware.h
arch/arm/mach-davinci/io.c
arch/arm/mach-dove/include/mach/debug-macro.S
arch/arm/mach-dove/include/mach/vmalloc.h
arch/arm/mach-ebsa110/include/mach/debug-macro.S
arch/arm/mach-ep93xx/Kconfig
arch/arm/mach-ep93xx/Makefile
arch/arm/mach-ep93xx/clock.c
arch/arm/mach-ep93xx/core.c
arch/arm/mach-ep93xx/dma-m2p.c
arch/arm/mach-ep93xx/edb93xx.c
arch/arm/mach-ep93xx/gpio.c
arch/arm/mach-ep93xx/include/mach/debug-macro.S
arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
arch/arm/mach-ep93xx/include/mach/vmalloc.h
arch/arm/mach-ep93xx/simone.c [new file with mode: 0644]
arch/arm/mach-ep93xx/snappercl15.c [new file with mode: 0644]
arch/arm/mach-footbridge/common.c
arch/arm/mach-footbridge/include/mach/debug-macro.S
arch/arm/mach-gemini/include/mach/debug-macro.S
arch/arm/mach-gemini/include/mach/vmalloc.h
arch/arm/mach-h720x/include/mach/debug-macro.S
arch/arm/mach-integrator/core.c
arch/arm/mach-integrator/include/mach/debug-macro.S
arch/arm/mach-integrator/integrator_cp.c
arch/arm/mach-iop13xx/include/mach/debug-macro.S
arch/arm/mach-iop13xx/io.c
arch/arm/mach-iop32x/include/mach/debug-macro.S
arch/arm/mach-iop32x/include/mach/vmalloc.h
arch/arm/mach-iop33x/include/mach/debug-macro.S
arch/arm/mach-iop33x/include/mach/vmalloc.h
arch/arm/mach-ixp2000/include/mach/debug-macro.S
arch/arm/mach-ixp2000/include/mach/vmalloc.h
arch/arm/mach-ixp23xx/include/mach/debug-macro.S
arch/arm/mach-ixp23xx/include/mach/vmalloc.h
arch/arm/mach-ixp4xx/common.c
arch/arm/mach-ixp4xx/include/mach/debug-macro.S
arch/arm/mach-ixp4xx/include/mach/vmalloc.h
arch/arm/mach-kirkwood/include/mach/debug-macro.S
arch/arm/mach-kirkwood/include/mach/vmalloc.h
arch/arm/mach-ks8695/include/mach/debug-macro.S
arch/arm/mach-l7200/include/mach/debug-macro.S
arch/arm/mach-lh7a40x/include/mach/debug-macro.S
arch/arm/mach-lh7a40x/include/mach/vmalloc.h
arch/arm/mach-loki/include/mach/debug-macro.S
arch/arm/mach-loki/include/mach/vmalloc.h
arch/arm/mach-mmp/clock.c
arch/arm/mach-mmp/clock.h
arch/arm/mach-mmp/include/mach/debug-macro.S
arch/arm/mach-mmp/include/mach/vmalloc.h
arch/arm/mach-mmp/pxa168.c
arch/arm/mach-mmp/pxa910.c
arch/arm/mach-msm/include/mach/debug-macro.S
arch/arm/mach-msm/io.c
arch/arm/mach-mv78xx0/include/mach/debug-macro.S
arch/arm/mach-mv78xx0/include/mach/vmalloc.h
arch/arm/mach-mx1/clock.c
arch/arm/mach-mx2/clock_imx21.c
arch/arm/mach-mx2/clock_imx27.c
arch/arm/mach-mx25/clock.c
arch/arm/mach-mx3/clock-imx35.c
arch/arm/mach-mx3/clock.c
arch/arm/mach-mxc91231/clock.c
arch/arm/mach-netx/include/mach/debug-macro.S
arch/arm/mach-nomadik/include/mach/debug-macro.S
arch/arm/mach-nomadik/include/mach/vmalloc.h
arch/arm/mach-ns9xxx/include/mach/debug-macro.S
arch/arm/mach-ns9xxx/include/mach/vmalloc.h
arch/arm/mach-nuc93x/Kconfig [new file with mode: 0644]
arch/arm/mach-nuc93x/Makefile [new file with mode: 0644]
arch/arm/mach-nuc93x/Makefile.boot [new file with mode: 0644]
arch/arm/mach-nuc93x/clock.c [new file with mode: 0644]
arch/arm/mach-nuc93x/clock.h [new file with mode: 0644]
arch/arm/mach-nuc93x/cpu.c [new file with mode: 0644]
arch/arm/mach-nuc93x/cpu.h [new file with mode: 0644]
arch/arm/mach-nuc93x/dev.c [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/clkdev.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/entry-macro.S [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/hardware.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/io.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/irqs.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/map.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/memory.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/regs-clock.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/regs-ebi.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/regs-irq.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/regs-serial.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/regs-timer.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/system.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/timex.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/uncompress.h [new file with mode: 0644]
arch/arm/mach-nuc93x/include/mach/vmalloc.h [new file with mode: 0644]
arch/arm/mach-nuc93x/irq.c [new file with mode: 0644]
arch/arm/mach-nuc93x/mach-nuc932evb.c [new file with mode: 0644]
arch/arm/mach-nuc93x/nuc932.c [new file with mode: 0644]
arch/arm/mach-nuc93x/nuc932.h [new file with mode: 0644]
arch/arm/mach-nuc93x/time.c [new file with mode: 0644]
arch/arm/mach-omap1/include/mach/debug-macro.S
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/include/mach/debug-macro.S
arch/arm/mach-orion5x/include/mach/debug-macro.S
arch/arm/mach-orion5x/include/mach/vmalloc.h
arch/arm/mach-pnx4008/clock.c
arch/arm/mach-pnx4008/clock.h
arch/arm/mach-pnx4008/i2c.c
arch/arm/mach-pnx4008/include/mach/clkdev.h [new file with mode: 0644]
arch/arm/mach-pnx4008/include/mach/debug-macro.S
arch/arm/mach-pnx4008/include/mach/timex.h
arch/arm/mach-pnx4008/pm.c
arch/arm/mach-pnx4008/time.c
arch/arm/mach-pnx4008/time.h [new file with mode: 0644]
arch/arm/mach-pxa/clock.c
arch/arm/mach-pxa/clock.h
arch/arm/mach-pxa/eseries.c
arch/arm/mach-pxa/include/mach/debug-macro.S
arch/arm/mach-pxa/include/mach/vmalloc.h
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/pxa300.c
arch/arm/mach-pxa/pxa320.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-realview/core.c
arch/arm/mach-realview/include/mach/debug-macro.S
arch/arm/mach-realview/include/mach/vmalloc.h
arch/arm/mach-rpc/include/mach/debug-macro.S
arch/arm/mach-s3c2410/include/mach/debug-macro.S
arch/arm/mach-s3c24a0/include/mach/debug-macro.S
arch/arm/mach-s3c24a0/include/mach/vmalloc.h
arch/arm/mach-s3c6400/include/mach/debug-macro.S
arch/arm/mach-s5pc100/include/mach/debug-macro.S
arch/arm/mach-sa1100/include/mach/debug-macro.S
arch/arm/mach-sa1100/include/mach/vmalloc.h
arch/arm/mach-shark/include/mach/debug-macro.S
arch/arm/mach-u300/clock.c
arch/arm/mach-u300/core.c
arch/arm/mach-u300/gpio.c
arch/arm/mach-u300/include/mach/debug-macro.S
arch/arm/mach-u300/include/mach/dma_channels.h [new file with mode: 0644]
arch/arm/mach-u300/include/mach/vmalloc.h
arch/arm/mach-ux500/board-mop500.c
arch/arm/mach-ux500/clock.c
arch/arm/mach-ux500/cpu-u8500.c
arch/arm/mach-ux500/include/mach/debug-macro.S
arch/arm/mach-ux500/include/mach/vmalloc.h
arch/arm/mach-versatile/core.c
arch/arm/mach-versatile/include/mach/debug-macro.S
arch/arm/mach-w90x900/clock.c
arch/arm/mach-w90x900/clock.h
arch/arm/mach-w90x900/cpu.c
arch/arm/mach-w90x900/include/mach/vmalloc.h
arch/arm/mm/Kconfig
arch/arm/mm/alignment.c
arch/arm/mm/cache-fa.S
arch/arm/mm/cache-l2x0.c
arch/arm/mm/cache-v3.S
arch/arm/mm/cache-v4.S
arch/arm/mm/cache-v4wb.S
arch/arm/mm/cache-v4wt.S
arch/arm/mm/cache-v6.S
arch/arm/mm/cache-v7.S
arch/arm/mm/context.c
arch/arm/mm/copypage-feroceon.c
arch/arm/mm/copypage-v3.c
arch/arm/mm/copypage-v4mc.c
arch/arm/mm/copypage-v4wb.c
arch/arm/mm/copypage-v4wt.c
arch/arm/mm/copypage-v6.c
arch/arm/mm/copypage-xsc3.c
arch/arm/mm/copypage-xscale.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/fault-armv.c
arch/arm/mm/fault.c
arch/arm/mm/flush.c
arch/arm/mm/init.c
arch/arm/mm/ioremap.c
arch/arm/mm/mmu.c
arch/arm/mm/nommu.c
arch/arm/mm/proc-arm1020.S
arch/arm/mm/proc-arm1020e.S
arch/arm/mm/proc-arm1022.S
arch/arm/mm/proc-arm1026.S
arch/arm/mm/proc-arm920.S
arch/arm/mm/proc-arm922.S
arch/arm/mm/proc-arm925.S
arch/arm/mm/proc-arm926.S
arch/arm/mm/proc-arm940.S
arch/arm/mm/proc-arm946.S
arch/arm/mm/proc-feroceon.S
arch/arm/mm/proc-mohawk.S
arch/arm/mm/proc-xsc3.S
arch/arm/mm/proc-xscale.S
arch/arm/oprofile/op_model_arm11_core.c
arch/arm/oprofile/op_model_arm11_core.h
arch/arm/oprofile/op_model_mpcore.c
arch/arm/oprofile/op_model_v6.c
arch/arm/oprofile/op_model_v7.c
arch/arm/oprofile/op_model_v7.h
arch/arm/oprofile/op_model_xscale.c
arch/arm/plat-iop/io.c
arch/arm/plat-mxc/include/mach/debug-macro.S
arch/arm/plat-mxc/include/mach/vmalloc.h
arch/arm/plat-nomadik/include/plat/i2c.h [new file with mode: 0644]
arch/arm/plat-omap/Kconfig
arch/arm/plat-omap/include/plat/omap44xx.h
arch/arm/plat-omap/io.c
arch/arm/plat-s3c/include/mach/vmalloc.h
arch/arm/plat-stmp3xxx/clock.c
arch/arm/plat-stmp3xxx/include/mach/debug-macro.S
arch/arm/plat-stmp3xxx/include/mach/vmalloc.h
arch/arm/vfp/vfpmodule.c
arch/avr32/include/asm/pgtable.h
arch/avr32/mm/tlb.c
arch/cris/include/asm/pgtable.h
arch/frv/include/asm/pgtable.h
arch/ia64/include/asm/pgtable.h
arch/m32r/include/asm/tlbflush.h
arch/m32r/mm/fault-nommu.c
arch/m32r/mm/fault.c
arch/m68k/include/asm/pgtable_mm.h
arch/microblaze/include/asm/tlbflush.h
arch/mips/include/asm/pgtable.h
arch/mn10300/include/asm/pgtable.h
arch/mn10300/mm/mmu-context.c
arch/parisc/include/asm/pgtable.h
arch/parisc/kernel/cache.c
arch/powerpc/include/asm/pgtable.h
arch/powerpc/mm/mem.c
arch/s390/include/asm/pgtable.h
arch/score/include/asm/pgtable.h
arch/sh/include/asm/pgtable.h
arch/sh/mm/fault_32.c
arch/sparc/include/asm/pgtable_32.h
arch/sparc/include/asm/pgtable_64.h
arch/sparc/mm/fault_32.c
arch/sparc/mm/init_64.c
arch/sparc/mm/nosun4c.c
arch/sparc/mm/srmmu.c
arch/sparc/mm/sun4c.c
arch/um/include/asm/pgtable.h
arch/x86/include/asm/pgtable_32.h
arch/x86/include/asm/pgtable_64.h
arch/xtensa/include/asm/pgtable.h
arch/xtensa/mm/cache.c
drivers/i2c/busses/i2c-pnx.c
drivers/mmc/host/mmci.c
drivers/rtc/rtc-pl031.c
drivers/serial/amba-pl011.c
drivers/spi/amba-pl022.c
drivers/watchdog/pnx4008_wdt.c
include/linux/i2c-pnx.h
mm/hugetlb.c
mm/memory.c
mm/migrate.c

index 9d58c7c5eddd082b9a22c087c7e0023e02fa4b02..eb0fae18ffb12a805bb81eb2c5005a773d499d2b 100644 (file)
@@ -59,7 +59,11 @@ PAGE_OFFSET  high_memory-1   Kernel direct-mapped RAM region.
                                This maps the platforms RAM, and typically
                                maps all platform RAM in a 1:1 relationship.
 
-TASK_SIZE      PAGE_OFFSET-1   Kernel module space
+PKMAP_BASE     PAGE_OFFSET-1   Permanent kernel mappings
+                               One way of mapping HIGHMEM pages into kernel
+                               space.
+
+MODULES_VADDR  MODULES_END-1   Kernel module space
                                Kernel modules inserted via insmod are
                                placed here using dynamic mappings.
 
index b231414bb8bc4b84d218fc2f2f75d5665d0a0761..2b5f823abd035fd180d94732c523671378c2ef9d 100644 (file)
@@ -88,12 +88,12 @@ changes occur:
        This is used primarily during fault processing.
 
 5) void update_mmu_cache(struct vm_area_struct *vma,
-                        unsigned long address, pte_t pte)
+                        unsigned long address, pte_t *ptep)
 
        At the end of every page fault, this routine is invoked to
        tell the architecture specific code that a translation
-       described by "pte" now exists at virtual address "address"
-       for address space "vma->vm_mm", in the software page tables.
+       now exists at virtual address "address" for address space
+       "vma->vm_mm", in the software page tables.
 
        A port may use this information in any way it so chooses.
        For example, it could use this event to pre-load TLB
index 3f0c59f6d8aa07dc5b68f96d1e928ac7f5b222d5..71a243294142a41f6a80c0a4dc1e7149aa338dcf 100644 (file)
@@ -329,7 +329,7 @@ extern pgd_t swapper_pg_dir[1024];
  * tables contain all the necessary information.
  */
 extern inline void update_mmu_cache(struct vm_area_struct * vma,
-       unsigned long address, pte_t pte)
+       unsigned long address, pte_t *ptep)
 {
 }
 
index 184a6bd548250aaeb6617618fd66e1a34305d144..3b181284970f6e970b76bdd653882df90eb17b01 100644 (file)
@@ -12,6 +12,7 @@ config ARM
        select HAVE_IDE
        select RTC_LIB
        select SYS_SUPPORTS_APM_EMULATION
+       select GENERIC_ATOMIC64 if (!CPU_32v6K)
        select HAVE_OPROFILE
        select HAVE_ARCH_KGDB
        select HAVE_KPROBES if (!XIP_KERNEL)
@@ -20,6 +21,8 @@ config ARM
        select HAVE_GENERIC_DMA_COHERENT
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_LZO
+       select HAVE_PERF_EVENTS
+       select PERF_USE_VMALLOC
        help
          The ARM series is a line of low-power-consumption RISC chip designs
          licensed by ARM Ltd and targeted at embedded applications and
@@ -52,6 +55,9 @@ config HAVE_TCM
        bool
        select GENERIC_ALLOCATOR
 
+config HAVE_PROC_CPU
+       bool
+
 config NO_IOPORT
        bool
 
@@ -161,6 +167,11 @@ config ARCH_MTD_XIP
 config GENERIC_HARDIRQS_NO__DO_IRQ
        def_bool y
 
+config ARM_L1_CACHE_SHIFT_6
+       bool
+       help
+         Setting ARM L1 cache line size to 64 Bytes.
+
 if OPROFILE
 
 config OPROFILE_ARMV6
@@ -550,10 +561,20 @@ config ARCH_W90X900
          <http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/
                ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller>
 
+config ARCH_NUC93X
+       bool "Nuvoton NUC93X CPU"
+       select CPU_ARM926T
+       select HAVE_CLK
+       select COMMON_CLKDEV
+       help
+         Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a
+         low-power and high performance MPEG-4/JPEG multimedia controller chip.
+
 config ARCH_PNX4008
        bool "Philips Nexperia PNX4008 Mobile"
        select CPU_ARM926T
        select HAVE_CLK
+       select COMMON_CLKDEV
        help
          This enables support for Philips PNX4008 mobile platform.
 
@@ -638,6 +659,7 @@ config ARCH_S5PC1XX
        select GENERIC_GPIO
        select HAVE_CLK
        select CPU_V7
+       select ARM_L1_CACHE_SHIFT_6
        help
          Samsung S5PC1XX series based systems
 
@@ -785,6 +807,8 @@ source "arch/arm/plat-nomadik/Kconfig"
 
 source "arch/arm/mach-ns9xxx/Kconfig"
 
+source "arch/arm/mach-nuc93x/Kconfig"
+
 source "arch/arm/plat-omap/Kconfig"
 
 source "arch/arm/mach-omap1/Kconfig"
@@ -867,6 +891,11 @@ config XSCALE_PMU
        depends on CPU_XSCALE && !XSCALE_PMU_TIMER
        default y
 
+config CPU_HAS_PMU
+       depends on CPU_V6 || CPU_V7 || XSCALE_PMU
+       default y
+       bool
+
 if !MMU
 source "arch/arm/Kconfig-nommu"
 endif
@@ -921,6 +950,19 @@ config ARM_ERRATA_460075
          ACTLR register. Note that setting specific bits in the ACTLR register
          may not be available in non-secure mode.
 
+config PL310_ERRATA_588369
+       bool "Clean & Invalidate maintenance operations do not invalidate clean lines"
+       depends on CACHE_L2X0 && ARCH_OMAP4
+       help
+          The PL310 L2 cache controller implements three types of Clean &
+          Invalidate maintenance operations: by Physical Address
+          (offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC).
+          They are architecturally defined to behave as the execution of a
+          clean operation followed immediately by an invalidate operation,
+          both performing to the same memory location. This functionality
+          is not correctly implemented in PL310 as clean lines are not
+          invalidated as a result of these operations. Note that this errata
+          uses Texas Instrument's secure monitor api.
 endmenu
 
 source "arch/arm/common/Kconfig"
@@ -1171,6 +1213,14 @@ config HIGHPTE
        depends on HIGHMEM
        depends on !OUTER_CACHE
 
+config HW_PERF_EVENTS
+       bool "Enable hardware performance counter support for perf events"
+       depends on PERF_EVENTS && CPU_HAS_PMU && (CPU_V6 || CPU_V7)
+       default y
+       help
+         Enable hardware performance counter support for perf events. If
+         disabled, perf events will use software events only.
+
 source "mm/Kconfig"
 
 config LEDS
@@ -1230,6 +1280,7 @@ config ALIGNMENT_TRAP
        bool
        depends on CPU_CP15_MMU
        default y if !ARCH_EBSA110
+       select HAVE_PROC_CPU if PROC_FS
        help
          ARM processors cannot fetch/store information which is not
          naturally aligned on the bus, i.e., a 4 byte fetch must start at an
index 356d702c080867183f9dd9f9c16dd5826426354a..81f54ca30788b7acfdae92e00595e5fd64e46aa0 100644 (file)
@@ -171,6 +171,7 @@ machine-$(CONFIG_ARCH_U300)         := u300
 machine-$(CONFIG_ARCH_U8500)           := ux500
 machine-$(CONFIG_ARCH_VERSATILE)       := versatile
 machine-$(CONFIG_ARCH_W90X900)         := w90x900
+machine-$(CONFIG_ARCH_NUC93X)          := nuc93x
 machine-$(CONFIG_FOOTBRIDGE)           := footbridge
 
 # Platform directory name.  This list is sorted alphanumerically
index 2d4d88ba73bf9533598b074b08cce94ee85ae26c..97c89e7de7d3a64d76fb5996595f3ef1a8d9db89 100644 (file)
@@ -5,7 +5,7 @@
 #
 
 HEAD   = head.o
-OBJS   = misc.o
+OBJS   = misc.o decompress.o
 FONTC  = $(srctree)/drivers/video/console/font_acorn_8x8.c
 
 #
@@ -106,10 +106,6 @@ lib1funcs = $(obj)/lib1funcs.o
 $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
        $(call cmd,shipped)
 
-# Don't allow any static data in misc.o, which
-# would otherwise mess up our GOT table
-CFLAGS_misc.o := -Dstatic=
-
 $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
                $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
        $(call if_changed,ld)
diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c
new file mode 100644 (file)
index 0000000..0da382f
--- /dev/null
@@ -0,0 +1,45 @@
+#define _LINUX_STRING_H_
+
+#include <linux/compiler.h>    /* for inline */
+#include <linux/types.h>       /* for size_t */
+#include <linux/stddef.h>      /* for NULL */
+#include <linux/linkage.h>
+#include <asm/string.h>
+
+extern unsigned long free_mem_ptr;
+extern unsigned long free_mem_end_ptr;
+extern void error(char *);
+
+#define STATIC static
+
+#define ARCH_HAS_DECOMP_WDOG
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) {if(!(cond)) error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+#ifdef CONFIG_KERNEL_GZIP
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
+
+void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
+{
+       decompress(input, len, NULL, NULL, output, NULL, error);
+}
index 4fddc509e78ed3e25a8d708521f6d20cd2282e96..99b75aa1c2ec734ffa438b0aeada6d8266adb0e0 100644 (file)
 #if defined(CONFIG_DEBUG_ICEDCC)
 
 #ifdef CONFIG_CPU_V6
-               .macro  loadsp, rb
+               .macro  loadsp, rb, tmp
                .endm
                .macro  writeb, ch, rb
                mcr     p14, 0, \ch, c0, c5, 0
                .endm
 #elif defined(CONFIG_CPU_V7)
-               .macro  loadsp, rb
+               .macro  loadsp, rb, tmp
                .endm
                .macro  writeb, ch, rb
 wait:          mrc     p14, 0, pc, c0, c1, 0
@@ -36,13 +36,13 @@ wait:               mrc     p14, 0, pc, c0, c1, 0
                mcr     p14, 0, \ch, c0, c5, 0
                .endm
 #elif defined(CONFIG_CPU_XSCALE)
-               .macro  loadsp, rb
+               .macro  loadsp, rb, tmp
                .endm
                .macro  writeb, ch, rb
                mcr     p14, 0, \ch, c8, c0, 0
                .endm
 #else
-               .macro  loadsp, rb
+               .macro  loadsp, rb, tmp
                .endm
                .macro  writeb, ch, rb
                mcr     p14, 0, \ch, c1, c0, 0
@@ -58,7 +58,7 @@ wait:         mrc     p14, 0, pc, c0, c1, 0
                .endm
 
 #if defined(CONFIG_ARCH_SA1100)
-               .macro  loadsp, rb
+               .macro  loadsp, rb, tmp
                mov     \rb, #0x80000000        @ physical base address
 #ifdef CONFIG_DEBUG_LL_SER3
                add     \rb, \rb, #0x00050000   @ Ser3
@@ -67,13 +67,13 @@ wait:               mrc     p14, 0, pc, c0, c1, 0
 #endif
                .endm
 #elif defined(CONFIG_ARCH_S3C2410)
-               .macro loadsp, rb
+               .macro loadsp, rb, tmp
                mov     \rb, #0x50000000
                add     \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
                .endm
 #else
-               .macro  loadsp, rb
-               addruart \rb
+               .macro  loadsp, rb, tmp
+               addruart \rb, \tmp
                .endm
 #endif
 #endif
@@ -1025,7 +1025,7 @@ phex:             adr     r3, phexbuf
                strb    r2, [r3, r1]
                b       1b
 
-puts:          loadsp  r3
+puts:          loadsp  r3, r1
 1:             ldrb    r2, [r0], #1
                teq     r2, #0
                moveq   pc, lr
@@ -1042,7 +1042,7 @@ puts:             loadsp  r3
 putc:
                mov     r2, r0
                mov     r0, #0
-               loadsp  r3
+               loadsp  r3, r1
                b       2b
 
 memdump:       mov     r12, r0
index 56a0d116d27147445a4f69aa18728074f431ef9a..d32bc71c1f787d8887b2a0d1c9a6cf41730dc23c 100644 (file)
@@ -23,8 +23,8 @@ unsigned int __machine_arch_type;
 #include <linux/compiler.h>    /* for inline */
 #include <linux/types.h>       /* for size_t */
 #include <linux/stddef.h>      /* for NULL */
-#include <asm/string.h>
 #include <linux/linkage.h>
+#include <asm/string.h>
 
 #include <asm/unaligned.h>
 
@@ -117,57 +117,7 @@ static void putstr(const char *ptr)
 
 #endif
 
-#define __ptr_t void *
-
-#define memzero(s,n) __memzero(s,n)
-
-/*
- * Optimised C version of memzero for the ARM.
- */
-void __memzero (__ptr_t s, size_t n)
-{
-       union { void *vp; unsigned long *ulp; unsigned char *ucp; } u;
-       int i;
-
-       u.vp = s;
-
-       for (i = n >> 5; i > 0; i--) {
-               *u.ulp++ = 0;
-               *u.ulp++ = 0;
-               *u.ulp++ = 0;
-               *u.ulp++ = 0;
-               *u.ulp++ = 0;
-               *u.ulp++ = 0;
-               *u.ulp++ = 0;
-               *u.ulp++ = 0;
-       }
-
-       if (n & 1 << 4) {
-               *u.ulp++ = 0;
-               *u.ulp++ = 0;
-               *u.ulp++ = 0;
-               *u.ulp++ = 0;
-       }
-
-       if (n & 1 << 3) {
-               *u.ulp++ = 0;
-               *u.ulp++ = 0;
-       }
-
-       if (n & 1 << 2)
-               *u.ulp++ = 0;
-
-       if (n & 1 << 1) {
-               *u.ucp++ = 0;
-               *u.ucp++ = 0;
-       }
-
-       if (n & 1)
-               *u.ucp++ = 0;
-}
-
-static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
-                           size_t __n)
+void *memcpy(void *__dest, __const void *__src, size_t __n)
 {
        int i = 0;
        unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
@@ -204,59 +154,20 @@ static inline __ptr_t memcpy(__ptr_t __dest, __const __ptr_t __src,
 /*
  * gzip delarations
  */
-#define STATIC static
-
-/* Diagnostic functions */
-#ifdef DEBUG
-#  define Assert(cond,msg) {if(!(cond)) error(msg);}
-#  define Trace(x) fprintf x
-#  define Tracev(x) {if (verbose) fprintf x ;}
-#  define Tracevv(x) {if (verbose>1) fprintf x ;}
-#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-#  define Assert(cond,msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c,x)
-#  define Tracecv(c,x)
-#endif
-
-static void error(char *m);
-
 extern char input_data[];
 extern char input_data_end[];
 
-static unsigned char *output_data;
-static unsigned long output_ptr;
-
-static void error(char *m);
+unsigned char *output_data;
+unsigned long output_ptr;
 
-static void putstr(const char *);
-
-static unsigned long free_mem_ptr;
-static unsigned long free_mem_end_ptr;
-
-#ifdef STANDALONE_DEBUG
-#define NO_INFLATE_MALLOC
-#endif
-
-#define ARCH_HAS_DECOMP_WDOG
-
-#ifdef CONFIG_KERNEL_GZIP
-#include "../../../../lib/decompress_inflate.c"
-#endif
-
-#ifdef CONFIG_KERNEL_LZO
-#include "../../../../lib/decompress_unlzo.c"
-#endif
+unsigned long free_mem_ptr;
+unsigned long free_mem_end_ptr;
 
 #ifndef arch_error
 #define arch_error(x)
 #endif
 
-static void error(char *x)
+void error(char *x)
 {
        arch_error(x);
 
@@ -272,6 +183,8 @@ asmlinkage void __div0(void)
        error("Attempting division by 0!");
 }
 
+extern void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
+
 #ifndef STANDALONE_DEBUG
 
 unsigned long
@@ -292,8 +205,8 @@ decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
        output_ptr = get_unaligned_le32(tmp);
 
        putstr("Uncompressing Linux...");
-       decompress(input_data, input_data_end - input_data,
-                       NULL, NULL, output_data, NULL, error);
+       do_decompress(input_data, input_data_end - input_data,
+                       output_data, error);
        putstr(" done, booting the kernel.\n");
        return output_ptr;
 }
index a5924b9b88bdbad7a2daea6489faf712152174b8..7ca9ecff652ff346bbdfec69bc03fb3752ef9a8c 100644 (file)
@@ -14,6 +14,13 @@ SECTIONS
   /DISCARD/ : {
     *(.ARM.exidx*)
     *(.ARM.extab*)
+    /*
+     * Discard any r/w data - this produces a link error if we have any,
+     * which is required for PIC decompression.  Local data generates
+     * GOTOFF relocations, which prevents it being relocated independently
+     * of the text/got segments.
+     */
+    *(.data)
   }
 
   . = TEXT_START;
@@ -40,7 +47,6 @@ SECTIONS
   .got                 : { *(.got) }
   _got_end = .;
   .got.plt             : { *(.got.plt) }
-  .data                        : { *(.data) }
   _edata = .;
 
   . = BSS_START;
index aae5bc01acc80d20d1f4cfe46c048d78455a67cb..446b696196e363858e66d12983b2bca21126d22d 100644 (file)
@@ -99,6 +99,16 @@ void clkdev_add(struct clk_lookup *cl)
 }
 EXPORT_SYMBOL(clkdev_add);
 
+void __init clkdev_add_table(struct clk_lookup *cl, size_t num)
+{
+       mutex_lock(&clocks_mutex);
+       while (num--) {
+               list_add_tail(&cl->node, &clocks);
+               cl++;
+       }
+       mutex_unlock(&clocks_mutex);
+}
+
 #define MAX_DEV_ID     20
 #define MAX_CON_ID     16
 
index cc32c1e54a59825dc93fcbba098fcdbd51d9c8f0..cc0a932bbea90780f659becc4ee7d93087ab61cf 100644 (file)
@@ -277,7 +277,7 @@ static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size,
                 * We don't need to sync the DMA buffer since
                 * it was allocated via the coherent allocators.
                 */
-               dma_cache_maint(ptr, size, dir);
+               __dma_single_cpu_to_dev(ptr, size, dir);
        }
 
        return dma_addr;
@@ -315,6 +315,8 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
                        __cpuc_flush_dcache_area(ptr, size);
                }
                free_safe_buffer(dev->archdata.dmabounce, buf);
+       } else {
+               __dma_single_dev_to_cpu(dma_to_virt(dev, dma_addr), size, dir);
        }
 }
 
index f232941de8abc4c56e9074d3f83ebbe672907be3..1cf999ade4bc181855379a10d724eac917b83da7 100644 (file)
@@ -18,6 +18,7 @@
  * 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/init.h>
 #include <linux/list.h>
 #include <linux/io.h>
 #include <asm/mach/irq.h>
 #include <asm/hardware/vic.h>
 
-static void vic_ack_irq(unsigned int irq)
-{
-       void __iomem *base = get_irq_chip_data(irq);
-       irq &= 31;
-       writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
-       /* moreover, clear the soft-triggered, in case it was the reason */
-       writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
-}
-
-static void vic_mask_irq(unsigned int irq)
-{
-       void __iomem *base = get_irq_chip_data(irq);
-       irq &= 31;
-       writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
-}
-
-static void vic_unmask_irq(unsigned int irq)
-{
-       void __iomem *base = get_irq_chip_data(irq);
-       irq &= 31;
-       writel(1 << irq, base + VIC_INT_ENABLE);
-}
-
-/**
- * vic_init2 - common initialisation code
- * @base: Base of the VIC.
- *
- * Common initialisation code for registeration
- * and resume.
-*/
-static void vic_init2(void __iomem *base)
-{
-       int i;
-
-       for (i = 0; i < 16; i++) {
-               void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
-               writel(VIC_VECT_CNTL_ENABLE | i, reg);
-       }
-
-       writel(32, base + VIC_PL190_DEF_VECT_ADDR);
-}
-
 #if defined(CONFIG_PM)
 /**
  * struct vic_device - VIC PM device
@@ -99,13 +58,34 @@ struct vic_device {
 /* we cannot allocate memory when VICs are initially registered */
 static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
 
+static int vic_id;
+
 static inline struct vic_device *to_vic(struct sys_device *sys)
 {
        return container_of(sys, struct vic_device, sysdev);
 }
+#endif /* CONFIG_PM */
 
-static int vic_id;
+/**
+ * vic_init2 - common initialisation code
+ * @base: Base of the VIC.
+ *
+ * Common initialisation code for registeration
+ * and resume.
+*/
+static void vic_init2(void __iomem *base)
+{
+       int i;
+
+       for (i = 0; i < 16; i++) {
+               void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
+               writel(VIC_VECT_CNTL_ENABLE | i, reg);
+       }
+
+       writel(32, base + VIC_PL190_DEF_VECT_ADDR);
+}
 
+#if defined(CONFIG_PM)
 static int vic_class_resume(struct sys_device *dev)
 {
        struct vic_device *vic = to_vic(dev);
@@ -158,31 +138,6 @@ struct sysdev_class vic_class = {
        .resume         = vic_class_resume,
 };
 
-/**
- * vic_pm_register - Register a VIC for later power management control
- * @base: The base address of the VIC.
- * @irq: The base IRQ for the VIC.
- * @resume_sources: bitmask of interrupts allowed for resume sources.
- *
- * Register the VIC with the system device tree so that it can be notified
- * of suspend and resume requests and ensure that the correct actions are
- * taken to re-instate the settings on resume.
- */
-static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
-{
-       struct vic_device *v;
-
-       if (vic_id >= ARRAY_SIZE(vic_devices))
-               printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
-       else {
-               v = &vic_devices[vic_id];
-               v->base = base;
-               v->resume_sources = resume_sources;
-               v->irq = irq;
-               vic_id++;
-       }
-}
-
 /**
  * vic_pm_init - initicall to register VIC pm
  *
@@ -219,9 +174,60 @@ static int __init vic_pm_init(void)
 
        return 0;
 }
-
 late_initcall(vic_pm_init);
 
+/**
+ * vic_pm_register - Register a VIC for later power management control
+ * @base: The base address of the VIC.
+ * @irq: The base IRQ for the VIC.
+ * @resume_sources: bitmask of interrupts allowed for resume sources.
+ *
+ * Register the VIC with the system device tree so that it can be notified
+ * of suspend and resume requests and ensure that the correct actions are
+ * taken to re-instate the settings on resume.
+ */
+static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
+{
+       struct vic_device *v;
+
+       if (vic_id >= ARRAY_SIZE(vic_devices))
+               printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
+       else {
+               v = &vic_devices[vic_id];
+               v->base = base;
+               v->resume_sources = resume_sources;
+               v->irq = irq;
+               vic_id++;
+       }
+}
+#else
+static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
+#endif /* CONFIG_PM */
+
+static void vic_ack_irq(unsigned int irq)
+{
+       void __iomem *base = get_irq_chip_data(irq);
+       irq &= 31;
+       writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
+       /* moreover, clear the soft-triggered, in case it was the reason */
+       writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
+}
+
+static void vic_mask_irq(unsigned int irq)
+{
+       void __iomem *base = get_irq_chip_data(irq);
+       irq &= 31;
+       writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
+}
+
+static void vic_unmask_irq(unsigned int irq)
+{
+       void __iomem *base = get_irq_chip_data(irq);
+       irq &= 31;
+       writel(1 << irq, base + VIC_INT_ENABLE);
+}
+
+#if defined(CONFIG_PM)
 static struct vic_device *vic_from_irq(unsigned int irq)
 {
         struct vic_device *v = vic_devices;
@@ -255,10 +261,7 @@ static int vic_set_wake(unsigned int irq, unsigned int on)
 
        return 0;
 }
-
 #else
-static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
-
 #define vic_set_wake NULL
 #endif /* CONFIG_PM */
 
@@ -270,9 +273,62 @@ static struct irq_chip vic_chip = {
        .set_wake = vic_set_wake,
 };
 
-/* The PL190 cell from ARM has been modified by ST, so handle both here */
-static void vik_init_st(void __iomem *base, unsigned int irq_start,
-                        u32 vic_sources);
+/*
+ * The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
+ * The original cell has 32 interrupts, while the modified one has 64,
+ * replocating two blocks 0x00..0x1f in 0x20..0x3f. In that case
+ * the probe function is called twice, with base set to offset 000
+ *  and 020 within the page. We call this "second block".
+ */
+static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
+                               u32 vic_sources)
+{
+       unsigned int i;
+       int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0;
+
+       /* Disable all interrupts initially. */
+
+       writel(0, base + VIC_INT_SELECT);
+       writel(0, base + VIC_INT_ENABLE);
+       writel(~0, base + VIC_INT_ENABLE_CLEAR);
+       writel(0, base + VIC_IRQ_STATUS);
+       writel(0, base + VIC_ITCR);
+       writel(~0, base + VIC_INT_SOFT_CLEAR);
+
+       /*
+        * Make sure we clear all existing interrupts. The vector registers
+        * in this cell are after the second block of general registers,
+        * so we can address them using standard offsets, but only from
+        * the second base address, which is 0x20 in the page
+        */
+       if (vic_2nd_block) {
+               writel(0, base + VIC_PL190_VECT_ADDR);
+               for (i = 0; i < 19; i++) {
+                       unsigned int value;
+
+                       value = readl(base + VIC_PL190_VECT_ADDR);
+                       writel(value, base + VIC_PL190_VECT_ADDR);
+               }
+               /* ST has 16 vectors as well, but we don't enable them by now */
+               for (i = 0; i < 16; i++) {
+                       void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
+                       writel(0, reg);
+               }
+
+               writel(32, base + VIC_PL190_DEF_VECT_ADDR);
+       }
+
+       for (i = 0; i < 32; i++) {
+               if (vic_sources & (1 << i)) {
+                       unsigned int irq = irq_start + i;
+
+                       set_irq_chip(irq, &vic_chip);
+                       set_irq_chip_data(irq, base);
+                       set_irq_handler(irq, handle_level_irq);
+                       set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+               }
+       }
+}
 
 /**
  * vic_init - initialise a vectored interrupt controller
@@ -299,7 +355,7 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
 
        switch(vendor) {
        case AMBA_VENDOR_ST:
-               vik_init_st(base, irq_start, vic_sources);
+               vic_init_st(base, irq_start, vic_sources);
                return;
        default:
                printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
@@ -343,60 +399,3 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
 
        vic_pm_register(base, irq_start, resume_sources);
 }
-
-/*
- * The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
- * The original cell has 32 interrupts, while the modified one has 64,
- * replocating two blocks 0x00..0x1f in 0x20..0x3f. In that case
- * the probe function is called twice, with base set to offset 000
- *  and 020 within the page. We call this "second block".
- */
-static void __init vik_init_st(void __iomem *base, unsigned int irq_start,
-                               u32 vic_sources)
-{
-       unsigned int i;
-       int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0;
-
-       /* Disable all interrupts initially. */
-
-       writel(0, base + VIC_INT_SELECT);
-       writel(0, base + VIC_INT_ENABLE);
-       writel(~0, base + VIC_INT_ENABLE_CLEAR);
-       writel(0, base + VIC_IRQ_STATUS);
-       writel(0, base + VIC_ITCR);
-       writel(~0, base + VIC_INT_SOFT_CLEAR);
-
-       /*
-        * Make sure we clear all existing interrupts. The vector registers
-        * in this cell are after the second block of general registers,
-        * so we can address them using standard offsets, but only from
-        * the second base address, which is 0x20 in the page
-        */
-       if (vic_2nd_block) {
-               writel(0, base + VIC_PL190_VECT_ADDR);
-               for (i = 0; i < 19; i++) {
-                       unsigned int value;
-
-                       value = readl(base + VIC_PL190_VECT_ADDR);
-                       writel(value, base + VIC_PL190_VECT_ADDR);
-               }
-               /* ST has 16 vectors as well, but we don't enable them by now */
-               for (i = 0; i < 16; i++) {
-                       void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
-                       writel(0, reg);
-               }
-
-               writel(32, base + VIC_PL190_DEF_VECT_ADDR);
-       }
-
-       for (i = 0; i < 32; i++) {
-               if (vic_sources & (1 << i)) {
-                       unsigned int irq = irq_start + i;
-
-                       set_irq_chip(irq, &vic_chip);
-                       set_irq_chip_data(irq, base);
-                       set_irq_handler(irq, handle_level_irq);
-                       set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-               }
-       }
-}
diff --git a/arch/arm/configs/at572d940hfek_defconfig b/arch/arm/configs/at572d940hfek_defconfig
new file mode 100644 (file)
index 0000000..76d724b
--- /dev/null
@@ -0,0 +1,1640 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28-rc7
+# Fri Dec  5 10:58:47 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION="-AT572D940HF"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+# CONFIG_TASK_DELAY_ACCT is not set
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_AUDIT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_NS is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+# CONFIG_USER_SCHED is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_CGROUP_CPUACCT=y
+# CONFIG_RESOURCE_COUNTERS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_MARKERS=y
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_KRETPROBES=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+CONFIG_BLK_DEV_IO_TRACE=y
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+# CONFIG_ARCH_AT91SAM9G20 is not set
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_ARCH_AT572D940HF=y
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT572D940HF Board Type
+#
+CONFIG_MACH_AT572D940HFEB=y
+
+#
+# AT91 Board Options
+#
+# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
+# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set
+CONFIG_NUM_SERIAL=3
+
+#
+# AT91 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_TIMER_HZ=100
+CONFIG_AT91_EARLY_DBGU=y
+# CONFIG_AT91_EARLY_USART0 is not set
+# CONFIG_AT91_EARLY_USART1 is not set
+# CONFIG_AT91_EARLY_USART2 is not set
+# CONFIG_AT91_EARLY_USART3 is not set
+# CONFIG_AT91_EARLY_USART4 is not set
+# CONFIG_AT91_EARLY_USART5 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_RESOURCES_64BIT=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="mem=48M console=ttyS0 initrd=0x21100000,3145728 root=/dev/ram0 rw ip=172.16.1.181"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+CONFIG_NET_TCPPROBE=m
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+
+#
+# CAN Device Drivers
+#
+CONFIG_CAN_VCAN=m
+CONFIG_CAN_DEBUG_DEVICES=y
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_MAC80211 is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=m
+CONFIG_MTD=m
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=1
+CONFIG_MTD_CONCAT=m
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_FTL=m
+CONFIG_NFTL=m
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=m
+CONFIG_RFD_FTL=m
+CONFIG_SSFDC=m
+CONFIG_MTD_OOPS=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=m
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x4000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+CONFIG_MTD_PLATRAM=m
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=m
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
+CONFIG_MTD_M25P80=m
+CONFIG_M25PXX_USE_FAST_READ=y
+CONFIG_MTD_SLRAM=m
+CONFIG_MTD_PHRAM=m
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=4096
+CONFIG_MTDRAM_ERASE_SIZE=128
+CONFIG_MTD_BLOCK2MTD=m
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=m
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=m
+CONFIG_MTD_NAND_DISKONCHIP=m
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+# CONFIG_MTD_NAND_ATMEL is not set
+CONFIG_MTD_NAND_NANDSIM=m
+CONFIG_MTD_NAND_PLATFORM=m
+CONFIG_MTD_ALAUDA=m
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=m
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+CONFIG_MTD_UBI_GLUEBI=y
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_TCB_CLKSRC=y
+CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+CONFIG_ATMEL_SSC=m
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=m
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_ICPLUS_PHY=m
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=m
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_MACB=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+CONFIG_WLAN_PRE80211=y
+CONFIG_STRIP=m
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_SDIO=m
+# CONFIG_LIBERTAS_DEBUG is not set
+CONFIG_USB_ZD1201=m
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_DM9601=m
+# CONFIG_USB_NET_SMSC95XX is not set
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+# CONFIG_USB_NET_ZAURUS is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_POLLDEV=m
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+CONFIG_KEYBOARD_SUNKBD=m
+CONFIG_KEYBOARD_LKKBD=m
+CONFIG_KEYBOARD_XTKBD=m
+CONFIG_KEYBOARD_NEWTON=m
+CONFIG_KEYBOARD_STOWAWAY=m
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_APPLETOUCH=m
+# CONFIG_MOUSE_BCM5974 is not set
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_MOUSE_GPIO=m
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_N_HDLC=m
+# CONFIG_RISCOM8 is not set
+CONFIG_SPECIALIX=m
+CONFIG_RIO=m
+# CONFIG_RIO_OLDPCI is not set
+CONFIG_STALDRV=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_IPMI_HANDLER=m
+# CONFIG_IPMI_PANIC_EVENT is not set
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+CONFIG_HW_RANDOM=y
+CONFIG_NVRAM=m
+CONFIG_R3964=m
+CONFIG_RAW_DRIVER=m
+CONFIG_MAX_RAW_DEVS=256
+CONFIG_TCG_TPM=m
+CONFIG_TCG_NSC=m
+CONFIG_TCG_ATMEL=m
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_DS1682=m
+# CONFIG_AT24 is not set
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_MAX6875=m
+CONFIG_SENSORS_TSL2550=m
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_BITBANG=m
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_AT25=m
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+# CONFIG_SND_PCM_OSS_PLUGINS is not set
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_SUPPORT_OLD_API=y
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_DRIVERS=y
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+# CONFIG_SND_AT73C213 is not set
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=m
+# CONFIG_HID_DEBUG is not set
+CONFIG_HIDRAW=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+CONFIG_USB_HIDDEV=y
+
+#
+# USB HID Boot Protocol drivers
+#
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_BRIGHT=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DELL=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_LOGITECH=m
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+CONFIG_USB_STORAGE_KARMA=y
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_EZUSB=y
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_OTI6858 is not set
+CONFIG_USB_SERIAL_SPCP8X5=m
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+CONFIG_USB_SERIAL_DEBUG=m
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_ADUTUX=m
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=m
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=m
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_MIDI_GADGET=m
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=m
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_AT91=y
+CONFIG_MMC_SPI=m
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=m
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=m
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+CONFIG_RTC_DRV_DS1305=y
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_AT91SAM9 is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_JBD_DEBUG=y
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_CHECK=y
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+# CONFIG_JFFS2_CMODE_PRIORITY is not set
+# CONFIG_JFFS2_CMODE_SIZE is not set
+CONFIG_JFFS2_CMODE_FAVOURLZO=y
+# CONFIG_UBIFS_FS is not set
+CONFIG_CRAMFS=m
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_LDM_DEBUG=y
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=m
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+# CONFIG_DLM_DEBUG is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+CONFIG_SECURITYFS=y
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_GF128MUL=m
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_REED_SOLOMON=m
+CONFIG_REED_SOLOMON_DEC16=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 3de640ac294b300cb874ef80e8b9f31a0bd3c4a3..c48d7b893869677bc4474e3fa2d70f256a6f2adb 100644 (file)
@@ -242,10 +242,13 @@ CONFIG_CPU_CP15_MMU=y
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_BPREDICT_DISABLE is not set
 CONFIG_HAS_TLS_REG=y
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_L2X0=y
 CONFIG_ARM_L1_CACHE_SHIFT=5
 # CONFIG_ARM_ERRATA_430973 is not set
 # CONFIG_ARM_ERRATA_458693 is not set
 # CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_PL310_ERRATA_588369=y
 CONFIG_ARM_GIC=y
 
 #
index d0daeab2234e34cc4ac8b466a037a176e188e5b7..e8ddec2cb158763d5d0a7741d44ee9e25d90696d 100644 (file)
@@ -235,6 +235,234 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
 #define smp_mb__before_atomic_inc()    smp_mb()
 #define smp_mb__after_atomic_inc()     smp_mb()
 
+#ifndef CONFIG_GENERIC_ATOMIC64
+typedef struct {
+       u64 __aligned(8) counter;
+} atomic64_t;
+
+#define ATOMIC64_INIT(i) { (i) }
+
+static inline u64 atomic64_read(atomic64_t *v)
+{
+       u64 result;
+
+       __asm__ __volatile__("@ atomic64_read\n"
+"      ldrexd  %0, %H0, [%1]"
+       : "=&r" (result)
+       : "r" (&v->counter)
+       );
+
+       return result;
+}
+
+static inline void atomic64_set(atomic64_t *v, u64 i)
+{
+       u64 tmp;
+
+       __asm__ __volatile__("@ atomic64_set\n"
+"1:    ldrexd  %0, %H0, [%1]\n"
+"      strexd  %0, %2, %H2, [%1]\n"
+"      teq     %0, #0\n"
+"      bne     1b"
+       : "=&r" (tmp)
+       : "r" (&v->counter), "r" (i)
+       : "cc");
+}
+
+static inline void atomic64_add(u64 i, atomic64_t *v)
+{
+       u64 result;
+       unsigned long tmp;
+
+       __asm__ __volatile__("@ atomic64_add\n"
+"1:    ldrexd  %0, %H0, [%2]\n"
+"      adds    %0, %0, %3\n"
+"      adc     %H0, %H0, %H3\n"
+"      strexd  %1, %0, %H0, [%2]\n"
+"      teq     %1, #0\n"
+"      bne     1b"
+       : "=&r" (result), "=&r" (tmp)
+       : "r" (&v->counter), "r" (i)
+       : "cc");
+}
+
+static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
+{
+       u64 result;
+       unsigned long tmp;
+
+       smp_mb();
+
+       __asm__ __volatile__("@ atomic64_add_return\n"
+"1:    ldrexd  %0, %H0, [%2]\n"
+"      adds    %0, %0, %3\n"
+"      adc     %H0, %H0, %H3\n"
+"      strexd  %1, %0, %H0, [%2]\n"
+"      teq     %1, #0\n"
+"      bne     1b"
+       : "=&r" (result), "=&r" (tmp)
+       : "r" (&v->counter), "r" (i)
+       : "cc");
+
+       smp_mb();
+
+       return result;
+}
+
+static inline void atomic64_sub(u64 i, atomic64_t *v)
+{
+       u64 result;
+       unsigned long tmp;
+
+       __asm__ __volatile__("@ atomic64_sub\n"
+"1:    ldrexd  %0, %H0, [%2]\n"
+"      subs    %0, %0, %3\n"
+"      sbc     %H0, %H0, %H3\n"
+"      strexd  %1, %0, %H0, [%2]\n"
+"      teq     %1, #0\n"
+"      bne     1b"
+       : "=&r" (result), "=&r" (tmp)
+       : "r" (&v->counter), "r" (i)
+       : "cc");
+}
+
+static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
+{
+       u64 result;
+       unsigned long tmp;
+
+       smp_mb();
+
+       __asm__ __volatile__("@ atomic64_sub_return\n"
+"1:    ldrexd  %0, %H0, [%2]\n"
+"      subs    %0, %0, %3\n"
+"      sbc     %H0, %H0, %H3\n"
+"      strexd  %1, %0, %H0, [%2]\n"
+"      teq     %1, #0\n"
+"      bne     1b"
+       : "=&r" (result), "=&r" (tmp)
+       : "r" (&v->counter), "r" (i)
+       : "cc");
+
+       smp_mb();
+
+       return result;
+}
+
+static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new)
+{
+       u64 oldval;
+       unsigned long res;
+
+       smp_mb();
+
+       do {
+               __asm__ __volatile__("@ atomic64_cmpxchg\n"
+               "ldrexd         %1, %H1, [%2]\n"
+               "mov            %0, #0\n"
+               "teq            %1, %3\n"
+               "teqeq          %H1, %H3\n"
+               "strexdeq       %0, %4, %H4, [%2]"
+               : "=&r" (res), "=&r" (oldval)
+               : "r" (&ptr->counter), "r" (old), "r" (new)
+               : "cc");
+       } while (res);
+
+       smp_mb();
+
+       return oldval;
+}
+
+static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
+{
+       u64 result;
+       unsigned long tmp;
+
+       smp_mb();
+
+       __asm__ __volatile__("@ atomic64_xchg\n"
+"1:    ldrexd  %0, %H0, [%2]\n"
+"      strexd  %1, %3, %H3, [%2]\n"
+"      teq     %1, #0\n"
+"      bne     1b"
+       : "=&r" (result), "=&r" (tmp)
+       : "r" (&ptr->counter), "r" (new)
+       : "cc");
+
+       smp_mb();
+
+       return result;
+}
+
+static inline u64 atomic64_dec_if_positive(atomic64_t *v)
+{
+       u64 result;
+       unsigned long tmp;
+
+       smp_mb();
+
+       __asm__ __volatile__("@ atomic64_dec_if_positive\n"
+"1:    ldrexd  %0, %H0, [%2]\n"
+"      subs    %0, %0, #1\n"
+"      sbc     %H0, %H0, #0\n"
+"      teq     %H0, #0\n"
+"      bmi     2f\n"
+"      strexd  %1, %0, %H0, [%2]\n"
+"      teq     %1, #0\n"
+"      bne     1b\n"
+"2:"
+       : "=&r" (result), "=&r" (tmp)
+       : "r" (&v->counter)
+       : "cc");
+
+       smp_mb();
+
+       return result;
+}
+
+static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
+{
+       u64 val;
+       unsigned long tmp;
+       int ret = 1;
+
+       smp_mb();
+
+       __asm__ __volatile__("@ atomic64_add_unless\n"
+"1:    ldrexd  %0, %H0, [%3]\n"
+"      teq     %0, %4\n"
+"      teqeq   %H0, %H4\n"
+"      moveq   %1, #0\n"
+"      beq     2f\n"
+"      adds    %0, %0, %5\n"
+"      adc     %H0, %H0, %H5\n"
+"      strexd  %2, %0, %H0, [%3]\n"
+"      teq     %2, #0\n"
+"      bne     1b\n"
+"2:"
+       : "=&r" (val), "=&r" (ret), "=&r" (tmp)
+       : "r" (&v->counter), "r" (u), "r" (a)
+       : "cc");
+
+       if (ret)
+               smp_mb();
+
+       return ret;
+}
+
+#define atomic64_add_negative(a, v)    (atomic64_add_return((a), (v)) < 0)
+#define atomic64_inc(v)                        atomic64_add(1LL, (v))
+#define atomic64_inc_return(v)         atomic64_add_return(1LL, (v))
+#define atomic64_inc_and_test(v)       (atomic64_inc_return(v) == 0)
+#define atomic64_sub_and_test(a, v)    (atomic64_sub_return((a), (v)) == 0)
+#define atomic64_dec(v)                        atomic64_sub(1LL, (v))
+#define atomic64_dec_return(v)         atomic64_sub_return(1LL, (v))
+#define atomic64_dec_and_test(v)       (atomic64_dec_return((v)) == 0)
+#define atomic64_inc_not_zero(v)       atomic64_add_unless((v), 1LL, 0LL)
+
+#else /* !CONFIG_GENERIC_ATOMIC64 */
+#include <asm-generic/atomic64.h>
+#endif
 #include <asm-generic/atomic-long.h>
 #endif
 #endif
index 5fe4a2ad7fa34deb2e7be770fdfa782359f6d245..72da7e045c6b306e4d2d40bbad1db22a603f4ed7 100644 (file)
  *     DMA Cache Coherency
  *     ===================
  *
- *     dma_inv_range(start, end)
- *
- *             Invalidate (discard) the specified virtual address range.
- *             May not write back any entries.  If 'start' or 'end'
- *             are not cache line aligned, those lines must be written
- *             back.
- *             - start  - virtual start address
- *             - end    - virtual end address
- *
- *     dma_clean_range(start, end)
- *
- *             Clean (write back) the specified virtual address range.
- *             - start  - virtual start address
- *             - end    - virtual end address
- *
  *     dma_flush_range(start, end)
  *
  *             Clean and invalidate the specified virtual address range.
@@ -228,8 +213,9 @@ struct cpu_cache_fns {
        void (*coherent_user_range)(unsigned long, unsigned long);
        void (*flush_kern_dcache_area)(void *, size_t);
 
-       void (*dma_inv_range)(const void *, const void *);
-       void (*dma_clean_range)(const void *, const void *);
+       void (*dma_map_area)(const void *, size_t, int);
+       void (*dma_unmap_area)(const void *, size_t, int);
+
        void (*dma_flush_range)(const void *, const void *);
 };
 
@@ -259,8 +245,8 @@ extern struct cpu_cache_fns cpu_cache;
  * is visible to DMA, or data written by DMA to system memory is
  * visible to the CPU.
  */
-#define dmac_inv_range                 cpu_cache.dma_inv_range
-#define dmac_clean_range               cpu_cache.dma_clean_range
+#define dmac_map_area                  cpu_cache.dma_map_area
+#define dmac_unmap_area                cpu_cache.dma_unmap_area
 #define dmac_flush_range               cpu_cache.dma_flush_range
 
 #else
@@ -285,12 +271,12 @@ extern void __cpuc_flush_dcache_area(void *, size_t);
  * is visible to DMA, or data written by DMA to system memory is
  * visible to the CPU.
  */
-#define dmac_inv_range                 __glue(_CACHE,_dma_inv_range)
-#define dmac_clean_range               __glue(_CACHE,_dma_clean_range)
+#define dmac_map_area                  __glue(_CACHE,_dma_map_area)
+#define dmac_unmap_area                __glue(_CACHE,_dma_unmap_area)
 #define dmac_flush_range               __glue(_CACHE,_dma_flush_range)
 
-extern void dmac_inv_range(const void *, const void *);
-extern void dmac_clean_range(const void *, const void *);
+extern void dmac_map_area(const void *, size_t, int);
+extern void dmac_unmap_area(const void *, size_t, int);
 extern void dmac_flush_range(const void *, const void *);
 
 #endif
@@ -331,12 +317,8 @@ static inline void outer_flush_range(unsigned long start, unsigned long end)
  * processes address space.  Really, we want to allow our "user
  * space" model to handle this.
  */
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-       do {                                                    \
-               memcpy(dst, src, len);                          \
-               flush_ptrace_access(vma, page, vaddr, dst, len, 1);\
-       } while (0)
-
+extern void copy_to_user_page(struct vm_area_struct *, struct page *,
+       unsigned long, void *, const void *, unsigned long);
 #define copy_from_user_page(vma, page, vaddr, dst, src, len) \
        do {                                                    \
                memcpy(dst, src, len);                          \
@@ -370,17 +352,6 @@ vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsig
        }
 }
 
-static inline void
-vivt_flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
-                        unsigned long uaddr, void *kaddr,
-                        unsigned long len, int write)
-{
-       if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
-               unsigned long addr = (unsigned long)kaddr;
-               __cpuc_coherent_kern_range(addr, addr + len);
-       }
-}
-
 #ifndef CONFIG_CPU_CACHE_VIPT
 #define flush_cache_mm(mm) \
                vivt_flush_cache_mm(mm)
@@ -388,15 +359,10 @@ vivt_flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
                vivt_flush_cache_range(vma,start,end)
 #define flush_cache_page(vma,addr,pfn) \
                vivt_flush_cache_page(vma,addr,pfn)
-#define flush_ptrace_access(vma,page,ua,ka,len,write) \
-               vivt_flush_ptrace_access(vma,page,ua,ka,len,write)
 #else
 extern void flush_cache_mm(struct mm_struct *mm);
 extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
 extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
-extern void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
-                               unsigned long uaddr, void *kaddr,
-                               unsigned long len, int write);
 #endif
 
 #define flush_cache_dup_mm(mm) flush_cache_mm(mm)
index b6ec7c627b393a794d1cfaf5549113d51057a7bc..7a0690da5e63235b6a8b1345adc2f396b29287c8 100644 (file)
@@ -27,4 +27,7 @@ struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
 void clkdev_add(struct clk_lookup *cl);
 void clkdev_drop(struct clk_lookup *cl);
 
+void clkdev_add_table(struct clk_lookup *, size_t);
+int clk_add_alias(const char *, const char *, char *, struct device *);
+
 #endif
index a96300bf83fd65f3c6058da9194eb71ef5e5a35f..256ee1c9f51aae017d2cef9139965aa3d4512cc9 100644 (file)
@@ -57,18 +57,58 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
 #endif
 
 /*
- * DMA-consistent mapping functions.  These allocate/free a region of
- * uncached, unwrite-buffered mapped memory space for use with DMA
- * devices.  This is the "generic" version.  The PCI specific version
- * is in pci.h
+ * The DMA API is built upon the notion of "buffer ownership".  A buffer
+ * is either exclusively owned by the CPU (and therefore may be accessed
+ * by it) or exclusively owned by the DMA device.  These helper functions
+ * represent the transitions between these two ownership states.
  *
- * Note: Drivers should NOT use this function directly, as it will break
- * platforms with CONFIG_DMABOUNCE.
- * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
+ * Note, however, that on later ARMs, this notion does not work due to
+ * speculative prefetches.  We model our approach on the assumption that
+ * the CPU does do speculative prefetches, which means we clean caches
+ * before transfers and delay cache invalidation until transfer completion.
+ *
+ * Private support functions: these are not part of the API and are
+ * liable to change.  Drivers must not use these.
  */
-extern void dma_cache_maint(const void *kaddr, size_t size, int rw);
-extern void dma_cache_maint_page(struct page *page, unsigned long offset,
-                                size_t size, int rw);
+static inline void __dma_single_cpu_to_dev(const void *kaddr, size_t size,
+       enum dma_data_direction dir)
+{
+       extern void ___dma_single_cpu_to_dev(const void *, size_t,
+               enum dma_data_direction);
+
+       if (!arch_is_coherent())
+               ___dma_single_cpu_to_dev(kaddr, size, dir);
+}
+
+static inline void __dma_single_dev_to_cpu(const void *kaddr, size_t size,
+       enum dma_data_direction dir)
+{
+       extern void ___dma_single_dev_to_cpu(const void *, size_t,
+               enum dma_data_direction);
+
+       if (!arch_is_coherent())
+               ___dma_single_dev_to_cpu(kaddr, size, dir);
+}
+
+static inline void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
+       size_t size, enum dma_data_direction dir)
+{
+       extern void ___dma_page_cpu_to_dev(struct page *, unsigned long,
+               size_t, enum dma_data_direction);
+
+       if (!arch_is_coherent())
+               ___dma_page_cpu_to_dev(page, off, size, dir);
+}
+
+static inline void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
+       size_t size, enum dma_data_direction dir)
+{
+       extern void ___dma_page_dev_to_cpu(struct page *, unsigned long,
+               size_t, enum dma_data_direction);
+
+       if (!arch_is_coherent())
+               ___dma_page_dev_to_cpu(page, off, size, dir);
+}
 
 /*
  * Return whether the given device DMA address mask can be supported
@@ -304,8 +344,7 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
 {
        BUG_ON(!valid_dma_direction(dir));
 
-       if (!arch_is_coherent())
-               dma_cache_maint(cpu_addr, size, dir);
+       __dma_single_cpu_to_dev(cpu_addr, size, dir);
 
        return virt_to_dma(dev, cpu_addr);
 }
@@ -329,8 +368,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
 {
        BUG_ON(!valid_dma_direction(dir));
 
-       if (!arch_is_coherent())
-               dma_cache_maint_page(page, offset, size, dir);
+       __dma_page_cpu_to_dev(page, offset, size, dir);
 
        return page_to_dma(dev, page) + offset;
 }
@@ -352,7 +390,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
 static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
                size_t size, enum dma_data_direction dir)
 {
-       /* nothing to do */
+       __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir);
 }
 
 /**
@@ -372,7 +410,8 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
 static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
                size_t size, enum dma_data_direction dir)
 {
-       /* nothing to do */
+       __dma_page_dev_to_cpu(dma_to_page(dev, handle), handle & ~PAGE_MASK,
+               size, dir);
 }
 #endif /* CONFIG_DMABOUNCE */
 
@@ -400,7 +439,10 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev,
 {
        BUG_ON(!valid_dma_direction(dir));
 
-       dmabounce_sync_for_cpu(dev, handle, offset, size, dir);
+       if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
+               return;
+
+       __dma_single_dev_to_cpu(dma_to_virt(dev, handle) + offset, size, dir);
 }
 
 static inline void dma_sync_single_range_for_device(struct device *dev,
@@ -412,8 +454,7 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
        if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
                return;
 
-       if (!arch_is_coherent())
-               dma_cache_maint(dma_to_virt(dev, handle) + offset, size, dir);
+       __dma_single_cpu_to_dev(dma_to_virt(dev, handle) + offset, size, dir);
 }
 
 static inline void dma_sync_single_for_cpu(struct device *dev,
index d2a59cfc30ce3f790ccc3b01a781f4fdf75c8baf..c980156f32638f8f031b93e730d0c2e8396aec40 100644 (file)
@@ -69,9 +69,16 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
 /*
  * __arm_ioremap takes CPU physical address.
  * __arm_ioremap_pfn takes a Page Frame Number and an offset into that page
+ * The _caller variety takes a __builtin_return_address(0) value for
+ * /proc/vmalloc to use - and should only be used in non-inline functions.
  */
-extern void __iomem * __arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
-extern void __iomem * __arm_ioremap(unsigned long, size_t, unsigned int);
+extern void __iomem *__arm_ioremap_pfn_caller(unsigned long, unsigned long,
+       size_t, unsigned int, void *);
+extern void __iomem *__arm_ioremap_caller(unsigned long, size_t, unsigned int,
+       void *);
+
+extern void __iomem *__arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
+extern void __iomem *__arm_ioremap(unsigned long, size_t, unsigned int);
 extern void __iounmap(volatile void __iomem *addr);
 
 /*
index b2cc1fcd040059f2381c8491dfe0d94568615372..8bffc3ff3acf794c0b3c046d89017067eeb10617 100644 (file)
@@ -46,12 +46,4 @@ struct sys_timer {
 extern struct sys_timer *system_timer;
 extern void timer_tick(void);
 
-/*
- * Kernel time keeping support.
- */
-struct timespec;
-extern int (*set_rtc)(void);
-extern void save_time_delta(struct timespec *delta, struct timespec *rtc);
-extern void restore_time_delta(struct timespec *delta, struct timespec *rtc);
-
 #endif
index 5421d82a2572475667189fd1e93e07e19359de25..4312ee5e3d0b6d97b83f0655435c7514d43da671 100644 (file)
  */
 #define IOREMAP_MAX_ORDER      24
 
+/*
+ * Size of DMA-consistent memory region.  Must be multiple of 2M,
+ * between 2MB and 14MB inclusive.
+ */
+#ifndef CONSISTENT_DMA_SIZE
+#define CONSISTENT_DMA_SIZE    SZ_2M
+#endif
+
+#define CONSISTENT_END         (0xffe00000UL)
+#define CONSISTENT_BASE                (CONSISTENT_END - CONSISTENT_DMA_SIZE)
+
 #else /* CONFIG_MMU */
 
 /*
 #endif
 
 #ifndef PHYS_OFFSET
-#define PHYS_OFFSET            (CONFIG_DRAM_BASE)
+#define PHYS_OFFSET            UL(CONFIG_DRAM_BASE)
 #endif
 
 #ifndef END_MEM
-#define END_MEM                (CONFIG_DRAM_BASE + CONFIG_DRAM_SIZE)
+#define END_MEM                (UL(CONFIG_DRAM_BASE) + CONFIG_DRAM_SIZE)
 #endif
 
 #ifndef PAGE_OFFSET
 
 #endif /* !CONFIG_MMU */
 
-/*
- * Size of DMA-consistent memory region.  Must be multiple of 2M,
- * between 2MB and 14MB inclusive.
- */
-#ifndef CONSISTENT_DMA_SIZE
-#define CONSISTENT_DMA_SIZE SZ_2M
-#endif
-
 /*
  * Physical vs virtual RAM address space conversion.  These are
  * private definitions which should NOT be used outside memory.h
index b561584d04a18ef6c631d1e05d69f6ff4b22d194..68870c7766712a4778b32278e64f82484d12f5e5 100644 (file)
@@ -6,6 +6,7 @@
 typedef struct {
 #ifdef CONFIG_CPU_HAS_ASID
        unsigned int id;
+       spinlock_t id_lock;
 #endif
        unsigned int kvm_seq;
 } mm_context_t;
index de6cefb329dd4aa24cd42731730915938a33aaf4..a0b3cac0547c0a9949c30cc919adcf5e08fcf500 100644 (file)
@@ -43,12 +43,23 @@ void __check_kvm_seq(struct mm_struct *mm);
 #define ASID_FIRST_VERSION     (1 << ASID_BITS)
 
 extern unsigned int cpu_last_asid;
+#ifdef CONFIG_SMP
+DECLARE_PER_CPU(struct mm_struct *, current_mm);
+#endif
 
 void __init_new_context(struct task_struct *tsk, struct mm_struct *mm);
 void __new_context(struct mm_struct *mm);
 
 static inline void check_context(struct mm_struct *mm)
 {
+       /*
+        * This code is executed with interrupts enabled. Therefore,
+        * mm->context.id cannot be updated to the latest ASID version
+        * on a different CPU (and condition below not triggered)
+        * without first getting an IPI to reset the context. The
+        * alternative is to take a read_lock on mm->context.id_lock
+        * (after changing its type to rwlock_t).
+        */
        if (unlikely((mm->context.id ^ cpu_last_asid) >> ASID_BITS))
                __new_context(mm);
 
@@ -108,6 +119,10 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
                __flush_icache_all();
 #endif
        if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {
+#ifdef CONFIG_SMP
+               struct mm_struct **crt_mm = &per_cpu(current_mm, cpu);
+               *crt_mm = next;
+#endif
                check_context(next);
                cpu_switch_mm(next->pgd, next);
                if (cache_is_vivt())
index 3a32af4cce30ac2ec0da9eb3089cbcf0082b193f..a485ac3c8696d2cdbc2e9a857ba4298de63e1428 100644 (file)
 #endif
 
 struct page;
+struct vm_area_struct;
 
 struct cpu_user_fns {
        void (*cpu_clear_user_highpage)(struct page *page, unsigned long vaddr);
        void (*cpu_copy_user_highpage)(struct page *to, struct page *from,
-                       unsigned long vaddr);
+                       unsigned long vaddr, struct vm_area_struct *vma);
 };
 
 #ifdef MULTI_USER
@@ -137,7 +138,7 @@ extern struct cpu_user_fns cpu_user;
 
 extern void __cpu_clear_user_highpage(struct page *page, unsigned long vaddr);
 extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
-                       unsigned long vaddr);
+                       unsigned long vaddr, struct vm_area_struct *vma);
 #endif
 
 #define clear_user_highpage(page,vaddr)                \
@@ -145,7 +146,7 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
 
 #define __HAVE_ARCH_COPY_USER_HIGHPAGE
 #define copy_user_highpage(to,from,vaddr,vma)  \
-       __cpu_copy_user_highpage(to, from, vaddr)
+       __cpu_copy_user_highpage(to, from, vaddr, vma)
 
 #define clear_page(page)       memset((void *)(page), 0, PAGE_SIZE)
 extern void copy_page(void *to, const void *from);
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
new file mode 100644 (file)
index 0000000..49e3049
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  linux/arch/arm/include/asm/perf_event.h
+ *
+ *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
+ *
+ * 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 __ARM_PERF_EVENT_H__
+#define __ARM_PERF_EVENT_H__
+
+/*
+ * NOP: on *most* (read: all supported) ARM platforms, the performance
+ * counter interrupts are regular interrupts and not an NMI. This
+ * means that when we receive the interrupt we can call
+ * perf_event_do_pending() that handles all of the work with
+ * interrupts enabled.
+ */
+static inline void
+set_perf_event_pending(void)
+{
+}
+
+/* ARM performance counters start from 1 (in the cp15 accesses) so use the
+ * same indexes here for consistency. */
+#define PERF_EVENT_INDEX_OFFSET 1
+
+#endif /* __ARM_PERF_EVENT_H__ */
index b011f2e939aa703da1366306bfa75a980d217c37..013cfcdc4839a2df6b5f0e842515c0a0c166f524 100644 (file)
@@ -86,8 +86,8 @@ extern unsigned int kobjsize(const void *objp);
  * All 32bit addresses are effectively valid for vmalloc...
  * Sort of meaningless for non-VM targets.
  */
-#define        VMALLOC_START   0
-#define        VMALLOC_END     0xffffffff
+#define        VMALLOC_START   0UL
+#define        VMALLOC_END     0xffffffffUL
 
 #define FIRST_USER_ADDRESS      (0)
 
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
new file mode 100644 (file)
index 0000000..2829b9f
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  linux/arch/arm/include/asm/pmu.h
+ *
+ *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
+ *
+ * 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 __ARM_PMU_H__
+#define __ARM_PMU_H__
+
+#ifdef CONFIG_CPU_HAS_PMU
+
+struct pmu_irqs {
+       const int   *irqs;
+       int         num_irqs;
+};
+
+/**
+ * reserve_pmu() - reserve the hardware performance counters
+ *
+ * Reserve the hardware performance counters in the system for exclusive use.
+ * The 'struct pmu_irqs' for the system is returned on success, ERR_PTR()
+ * encoded error on failure.
+ */
+extern const struct pmu_irqs *
+reserve_pmu(void);
+
+/**
+ * release_pmu() - Relinquish control of the performance counters
+ *
+ * Release the performance counters and allow someone else to use them.
+ * Callers must have disabled the counters and released IRQs before calling
+ * this. The 'struct pmu_irqs' returned from reserve_pmu() must be passed as
+ * a cookie.
+ */
+extern int
+release_pmu(const struct pmu_irqs *irqs);
+
+/**
+ * init_pmu() - Initialise the PMU.
+ *
+ * Initialise the system ready for PMU enabling. This should typically set the
+ * IRQ affinity and nothing else. The users (oprofile/perf events etc) will do
+ * the actual hardware initialisation.
+ */
+extern int
+init_pmu(void);
+
+#else /* CONFIG_CPU_HAS_PMU */
+
+static inline const struct pmu_irqs *
+reserve_pmu(void)
+{
+       return ERR_PTR(-ENODEV);
+}
+
+static inline int
+release_pmu(const struct pmu_irqs *irqs)
+{
+       return -ENODEV;
+}
+
+static inline int
+init_pmu(void)
+{
+       return -ENODEV;
+}
+
+#endif /* CONFIG_CPU_HAS_PMU */
+
+#endif /* __ARM_PMU_H__ */
index 5ccce0a9b03cdfd6a054b4c43b429d3bbce922d9..f392fb4437afbd86b35807f16a152ab773df17f4 100644 (file)
@@ -223,18 +223,6 @@ extern struct meminfo meminfo;
 #define bank_phys_end(bank)    ((bank)->start + (bank)->size)
 #define bank_phys_size(bank)   (bank)->size
 
-/*
- * Early command line parameters.
- */
-struct early_params {
-       const char *arg;
-       void (*fn)(char **p);
-};
-
-#define __early_param(name,fn)                                 \
-static struct early_params __early_##fn __used                 \
-__attribute__((__section__(".early_param.init"))) = { name, fn }
-
 #endif  /*  __KERNEL__  */
 
 #endif
index 59303e2008457763334a6e2306de382280030ab7..e6215305544aa9c63db768c53a7c194fe38c6747 100644 (file)
@@ -13,4 +13,9 @@ static inline int tlb_ops_need_broadcast(void)
        return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
 }
 
+static inline int cache_ops_need_broadcast(void)
+{
+       return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
+}
+
 #endif
index c91c64cab922c908186511a530f72673dd82d3b0..17eb355707dd321643ed995e848d4cebcb087508 100644 (file)
@@ -5,6 +5,22 @@
 #error SMP not supported on pre-ARMv6 CPUs
 #endif
 
+static inline void dsb_sev(void)
+{
+#if __LINUX_ARM_ARCH__ >= 7
+       __asm__ __volatile__ (
+               "dsb\n"
+               "sev"
+       );
+#elif defined(CONFIG_CPU_32v6K)
+       __asm__ __volatile__ (
+               "mcr p15, 0, %0, c7, c10, 4\n"
+               "sev"
+               : : "r" (0)
+       );
+#endif
+}
+
 /*
  * ARMv6 Spin-locking.
  *
@@ -69,13 +85,11 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 
        __asm__ __volatile__(
 "      str     %1, [%0]\n"
-#ifdef CONFIG_CPU_32v6K
-"      mcr     p15, 0, %1, c7, c10, 4\n" /* DSB */
-"      sev"
-#endif
        :
        : "r" (&lock->lock), "r" (0)
        : "cc");
+
+       dsb_sev();
 }
 
 /*
@@ -132,13 +146,11 @@ static inline void arch_write_unlock(arch_rwlock_t *rw)
 
        __asm__ __volatile__(
        "str    %1, [%0]\n"
-#ifdef CONFIG_CPU_32v6K
-"      mcr     p15, 0, %1, c7, c10, 4\n" /* DSB */
-"      sev\n"
-#endif
        :
        : "r" (&rw->lock), "r" (0)
        : "cc");
+
+       dsb_sev();
 }
 
 /* write_can_lock - would write_trylock() succeed? */
@@ -188,14 +200,12 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
 "      strex   %1, %0, [%2]\n"
 "      teq     %1, #0\n"
 "      bne     1b"
-#ifdef CONFIG_CPU_32v6K
-"\n    cmp     %0, #0\n"
-"      mcreq   p15, 0, %0, c7, c10, 4\n"
-"      seveq"
-#endif
        : "=&r" (tmp), "=&r" (tmp2)
        : "r" (&rw->lock)
        : "cc");
+
+       if (tmp == 0)
+               dsb_sev();
 }
 
 static inline int arch_read_trylock(arch_rwlock_t *rw)
index 058e7e90881d6a86103df826f43ec9ab2563682b..ca88e6a84707350bad0b1ab3bd7eefcd116be506 100644 (file)
@@ -73,8 +73,7 @@ extern unsigned int mem_fclk_21285;
 
 struct pt_regs;
 
-void die(const char *msg, struct pt_regs *regs, int err)
-               __attribute__((noreturn));
+void die(const char *msg, struct pt_regs *regs, int err);
 
 struct siginfo;
 void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
index 2dfb7d7a66e988b285629011527c406d00a94cc5..b74970ec02c4431ae1636289ffb3728d5d6bcc8f 100644 (file)
@@ -115,7 +115,8 @@ extern void iwmmxt_task_restore(struct thread_info *, void *);
 extern void iwmmxt_task_release(struct thread_info *);
 extern void iwmmxt_task_switch(struct thread_info *);
 
-extern void vfp_sync_state(struct thread_info *thread);
+extern void vfp_sync_hwstate(struct thread_info *);
+extern void vfp_flush_hwstate(struct thread_info *);
 
 #endif
 
index c2f1605de35902df4378b1e77898cc796441b4db..e085e2c545ebabad792dfa6e25fb149eb3cada27 100644 (file)
@@ -529,7 +529,8 @@ extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
  * cache entries for the kernels virtual memory range are written
  * back to the page.
  */
-extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte);
+extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
+       pte_t *ptep);
 
 #endif
 
index dd00f747e2ad00aeb844dd6b8c8373dd34b2a853..26d302c28e1318b4aa5db81a491fcd6a82b0e6fa 100644 (file)
@@ -17,6 +17,7 @@ obj-y         := compat.o elf.o entry-armv.o entry-common.o irq.o \
                   process.o ptrace.o return_address.o setup.o signal.o \
                   sys_arm.o stacktrace.o time.o traps.o
 
+obj-$(CONFIG_LEDS)             += leds.o
 obj-$(CONFIG_OC_ETM)           += etm.o
 
 obj-$(CONFIG_ISA_DMA_API)      += dma.o
@@ -46,6 +47,8 @@ obj-$(CONFIG_CPU_XSCALE)      += xscale-cp0.o
 obj-$(CONFIG_CPU_XSC3)         += xscale-cp0.o
 obj-$(CONFIG_CPU_MOHAWK)       += xscale-cp0.o
 obj-$(CONFIG_IWMMXT)           += iwmmxt.o
+obj-$(CONFIG_CPU_HAS_PMU)      += pmu.o
+obj-$(CONFIG_HW_PERF_EVENTS)   += perf_event.o
 AFLAGS_iwmmxt.o                        := -Wa,-mcpu=iwmmxt
 
 ifneq ($(CONFIG_ARCH_EBSA110),y)
index 4a881258bb171f7c14828d12fdc4ef9bf91b0186..883511522fca9e83be970c2611fd2ce5a1a75a41 100644 (file)
@@ -12,6 +12,7 @@
  */
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/dma-mapping.h>
 #include <asm/mach/arch.h>
 #include <asm/thread_info.h>
 #include <asm/memory.h>
@@ -112,5 +113,9 @@ int main(void)
 #ifdef MULTI_PABORT
   DEFINE(PROCESSOR_PABT_FUNC,  offsetof(struct processor, _prefetch_abort));
 #endif
+  BLANK();
+  DEFINE(DMA_BIDIRECTIONAL,    DMA_BIDIRECTIONAL);
+  DEFINE(DMA_TO_DEVICE,                DMA_TO_DEVICE);
+  DEFINE(DMA_FROM_DEVICE,      DMA_FROM_DEVICE);
   return 0; 
 }
index 5c91addcaebcb2d8d207a4deb920e3cb7ea48729..a38b4879441d1715b42c4e7994f9f4d8e67b7fe4 100644 (file)
@@ -24,7 +24,7 @@
 
 #if defined(CONFIG_CPU_V6)
 
-               .macro  addruart, rx
+               .macro  addruart, rx, tmp
                .endm
 
                .macro  senduart, rd, rx
@@ -51,7 +51,7 @@
 
 #elif defined(CONFIG_CPU_V7)
 
-               .macro  addruart, rx
+               .macro  addruart, rx, tmp
                .endm
 
                .macro  senduart, rd, rx
@@ -71,7 +71,7 @@ wait:         mrc     p14, 0, pc, c0, c1, 0
 
 #elif defined(CONFIG_CPU_XSCALE)
 
-               .macro  addruart, rx
+               .macro  addruart, rx, tmp
                .endm
 
                .macro  senduart, rd, rx
@@ -98,7 +98,7 @@ wait:         mrc     p14, 0, pc, c0, c1, 0
 
 #else
 
-               .macro  addruart, rx
+               .macro  addruart, rx, tmp
                .endm
 
                .macro  senduart, rd, rx
@@ -164,7 +164,7 @@ ENDPROC(printhex2)
                .ltorg
 
 ENTRY(printascii)
-               addruart r3
+               addruart r3, r1
                b       2f
 1:             waituart r2, r3
                senduart r1, r3
@@ -180,7 +180,7 @@ ENTRY(printascii)
 ENDPROC(printascii)
 
 ENTRY(printch)
-               addruart r3
+               addruart r3, r1
                mov     r1, r0
                mov     r0, #0
                b       1b
diff --git a/arch/arm/kernel/leds.c b/arch/arm/kernel/leds.c
new file mode 100644 (file)
index 0000000..31a316c
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * LED support code, ripped out of arch/arm/kernel/time.c
+ *
+ *  Copyright (C) 1994-2001 Russell King
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+
+#include <asm/leds.h>
+
+static void dummy_leds_event(led_event_t evt)
+{
+}
+
+void (*leds_event)(led_event_t) = dummy_leds_event;
+
+struct leds_evt_name {
+       const char      name[8];
+       int             on;
+       int             off;
+};
+
+static const struct leds_evt_name evt_names[] = {
+       { "amber", led_amber_on, led_amber_off },
+       { "blue",  led_blue_on,  led_blue_off  },
+       { "green", led_green_on, led_green_off },
+       { "red",   led_red_on,   led_red_off   },
+};
+
+static ssize_t leds_store(struct sys_device *dev,
+                       struct sysdev_attribute *attr,
+                       const char *buf, size_t size)
+{
+       int ret = -EINVAL, len = strcspn(buf, " ");
+
+       if (len > 0 && buf[len] == '\0')
+               len--;
+
+       if (strncmp(buf, "claim", len) == 0) {
+               leds_event(led_claim);
+               ret = size;
+       } else if (strncmp(buf, "release", len) == 0) {
+               leds_event(led_release);
+               ret = size;
+       } else {
+               int i;
+
+               for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
+                       if (strlen(evt_names[i].name) != len ||
+                           strncmp(buf, evt_names[i].name, len) != 0)
+                               continue;
+                       if (strncmp(buf+len, " on", 3) == 0) {
+                               leds_event(evt_names[i].on);
+                               ret = size;
+                       } else if (strncmp(buf+len, " off", 4) == 0) {
+                               leds_event(evt_names[i].off);
+                               ret = size;
+                       }
+                       break;
+               }
+       }
+       return ret;
+}
+
+static SYSDEV_ATTR(event, 0200, NULL, leds_store);
+
+static int leds_suspend(struct sys_device *dev, pm_message_t state)
+{
+       leds_event(led_stop);
+       return 0;
+}
+
+static int leds_resume(struct sys_device *dev)
+{
+       leds_event(led_start);
+       return 0;
+}
+
+static int leds_shutdown(struct sys_device *dev)
+{
+       leds_event(led_halted);
+       return 0;
+}
+
+static struct sysdev_class leds_sysclass = {
+       .name           = "leds",
+       .shutdown       = leds_shutdown,
+       .suspend        = leds_suspend,
+       .resume         = leds_resume,
+};
+
+static struct sys_device leds_device = {
+       .id             = 0,
+       .cls            = &leds_sysclass,
+};
+
+static int __init leds_init(void)
+{
+       int ret;
+       ret = sysdev_class_register(&leds_sysclass);
+       if (ret == 0)
+               ret = sysdev_register(&leds_device);
+       if (ret == 0)
+               ret = sysdev_create_file(&leds_device, &attr_event);
+       return ret;
+}
+
+device_initcall(leds_init);
+
+EXPORT_SYMBOL(leds_event);
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
new file mode 100644 (file)
index 0000000..c54ceb3
--- /dev/null
@@ -0,0 +1,2276 @@
+#undef DEBUG
+
+/*
+ * ARM performance counter support.
+ *
+ * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles
+ *
+ * ARMv7 support: Jean Pihet <jpihet@mvista.com>
+ * 2010 (c) MontaVista Software, LLC.
+ *
+ * This code is based on the sparc64 perf event code, which is in turn based
+ * on the x86 code. Callchain code is based on the ARM OProfile backtrace
+ * code.
+ */
+#define pr_fmt(fmt) "hw perfevents: " fmt
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+
+#include <asm/cputype.h>
+#include <asm/irq.h>
+#include <asm/irq_regs.h>
+#include <asm/pmu.h>
+#include <asm/stacktrace.h>
+
+static const struct pmu_irqs *pmu_irqs;
+
+/*
+ * Hardware lock to serialize accesses to PMU registers. Needed for the
+ * read/modify/write sequences.
+ */
+DEFINE_SPINLOCK(pmu_lock);
+
+/*
+ * ARMv6 supports a maximum of 3 events, starting from index 1. If we add
+ * another platform that supports more, we need to increase this to be the
+ * largest of all platforms.
+ *
+ * ARMv7 supports up to 32 events:
+ *  cycle counter CCNT + 31 events counters CNT0..30.
+ *  Cortex-A8 has 1+4 counters, Cortex-A9 has 1+6 counters.
+ */
+#define ARMPMU_MAX_HWEVENTS            33
+
+/* The events for a given CPU. */
+struct cpu_hw_events {
+       /*
+        * The events that are active on the CPU for the given index. Index 0
+        * is reserved.
+        */
+       struct perf_event       *events[ARMPMU_MAX_HWEVENTS];
+
+       /*
+        * A 1 bit for an index indicates that the counter is being used for
+        * an event. A 0 means that the counter can be used.
+        */
+       unsigned long           used_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)];
+
+       /*
+        * A 1 bit for an index indicates that the counter is actively being
+        * used.
+        */
+       unsigned long           active_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)];
+};
+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
+
+struct arm_pmu {
+       char            *name;
+       irqreturn_t     (*handle_irq)(int irq_num, void *dev);
+       void            (*enable)(struct hw_perf_event *evt, int idx);
+       void            (*disable)(struct hw_perf_event *evt, int idx);
+       int             (*event_map)(int evt);
+       u64             (*raw_event)(u64);
+       int             (*get_event_idx)(struct cpu_hw_events *cpuc,
+                                        struct hw_perf_event *hwc);
+       u32             (*read_counter)(int idx);
+       void            (*write_counter)(int idx, u32 val);
+       void            (*start)(void);
+       void            (*stop)(void);
+       int             num_events;
+       u64             max_period;
+};
+
+/* Set at runtime when we know what CPU type we are. */
+static const struct arm_pmu *armpmu;
+
+#define HW_OP_UNSUPPORTED              0xFFFF
+
+#define C(_x) \
+       PERF_COUNT_HW_CACHE_##_x
+
+#define CACHE_OP_UNSUPPORTED           0xFFFF
+
+static unsigned armpmu_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+                                    [PERF_COUNT_HW_CACHE_OP_MAX]
+                                    [PERF_COUNT_HW_CACHE_RESULT_MAX];
+
+static int
+armpmu_map_cache_event(u64 config)
+{
+       unsigned int cache_type, cache_op, cache_result, ret;
+
+       cache_type = (config >>  0) & 0xff;
+       if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
+               return -EINVAL;
+
+       cache_op = (config >>  8) & 0xff;
+       if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
+               return -EINVAL;
+
+       cache_result = (config >> 16) & 0xff;
+       if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+               return -EINVAL;
+
+       ret = (int)armpmu_perf_cache_map[cache_type][cache_op][cache_result];
+
+       if (ret == CACHE_OP_UNSUPPORTED)
+               return -ENOENT;
+
+       return ret;
+}
+
+static int
+armpmu_event_set_period(struct perf_event *event,
+                       struct hw_perf_event *hwc,
+                       int idx)
+{
+       s64 left = atomic64_read(&hwc->period_left);
+       s64 period = hwc->sample_period;
+       int ret = 0;
+
+       if (unlikely(left <= -period)) {
+               left = period;
+               atomic64_set(&hwc->period_left, left);
+               hwc->last_period = period;
+               ret = 1;
+       }
+
+       if (unlikely(left <= 0)) {
+               left += period;
+               atomic64_set(&hwc->period_left, left);
+               hwc->last_period = period;
+               ret = 1;
+       }
+
+       if (left > (s64)armpmu->max_period)
+               left = armpmu->max_period;
+
+       atomic64_set(&hwc->prev_count, (u64)-left);
+
+       armpmu->write_counter(idx, (u64)(-left) & 0xffffffff);
+
+       perf_event_update_userpage(event);
+
+       return ret;
+}
+
+static u64
+armpmu_event_update(struct perf_event *event,
+                   struct hw_perf_event *hwc,
+                   int idx)
+{
+       int shift = 64 - 32;
+       s64 prev_raw_count, new_raw_count;
+       s64 delta;
+
+again:
+       prev_raw_count = atomic64_read(&hwc->prev_count);
+       new_raw_count = armpmu->read_counter(idx);
+
+       if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
+                            new_raw_count) != prev_raw_count)
+               goto again;
+
+       delta = (new_raw_count << shift) - (prev_raw_count << shift);
+       delta >>= shift;
+
+       atomic64_add(delta, &event->count);
+       atomic64_sub(delta, &hwc->period_left);
+
+       return new_raw_count;
+}
+
+static void
+armpmu_disable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
+       int idx = hwc->idx;
+
+       WARN_ON(idx < 0);
+
+       clear_bit(idx, cpuc->active_mask);
+       armpmu->disable(hwc, idx);
+
+       barrier();
+
+       armpmu_event_update(event, hwc, idx);
+       cpuc->events[idx] = NULL;
+       clear_bit(idx, cpuc->used_mask);
+
+       perf_event_update_userpage(event);
+}
+
+static void
+armpmu_read(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+
+       /* Don't read disabled counters! */
+       if (hwc->idx < 0)
+               return;
+
+       armpmu_event_update(event, hwc, hwc->idx);
+}
+
+static void
+armpmu_unthrottle(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+
+       /*
+        * Set the period again. Some counters can't be stopped, so when we
+        * were throttled we simply disabled the IRQ source and the counter
+        * may have been left counting. If we don't do this step then we may
+        * get an interrupt too soon or *way* too late if the overflow has
+        * happened since disabling.
+        */
+       armpmu_event_set_period(event, hwc, hwc->idx);
+       armpmu->enable(hwc, hwc->idx);
+}
+
+static int
+armpmu_enable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
+       int idx;
+       int err = 0;
+
+       /* If we don't have a space for the counter then finish early. */
+       idx = armpmu->get_event_idx(cpuc, hwc);
+       if (idx < 0) {
+               err = idx;
+               goto out;
+       }
+
+       /*
+        * If there is an event in the counter we are going to use then make
+        * sure it is disabled.
+        */
+       event->hw.idx = idx;
+       armpmu->disable(hwc, idx);
+       cpuc->events[idx] = event;
+       set_bit(idx, cpuc->active_mask);
+
+       /* Set the period for the event. */
+       armpmu_event_set_period(event, hwc, idx);
+
+       /* Enable the event. */
+       armpmu->enable(hwc, idx);
+
+       /* Propagate our changes to the userspace mapping. */
+       perf_event_update_userpage(event);
+
+out:
+       return err;
+}
+
+static struct pmu pmu = {
+       .enable     = armpmu_enable,
+       .disable    = armpmu_disable,
+       .unthrottle = armpmu_unthrottle,
+       .read       = armpmu_read,
+};
+
+static int
+validate_event(struct cpu_hw_events *cpuc,
+              struct perf_event *event)
+{
+       struct hw_perf_event fake_event = event->hw;
+
+       if (event->pmu && event->pmu != &pmu)
+               return 0;
+
+       return armpmu->get_event_idx(cpuc, &fake_event) >= 0;
+}
+
+static int
+validate_group(struct perf_event *event)
+{
+       struct perf_event *sibling, *leader = event->group_leader;
+       struct cpu_hw_events fake_pmu;
+
+       memset(&fake_pmu, 0, sizeof(fake_pmu));
+
+       if (!validate_event(&fake_pmu, leader))
+               return -ENOSPC;
+
+       list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+               if (!validate_event(&fake_pmu, sibling))
+                       return -ENOSPC;
+       }
+
+       if (!validate_event(&fake_pmu, event))
+               return -ENOSPC;
+
+       return 0;
+}
+
+static int
+armpmu_reserve_hardware(void)
+{
+       int i;
+       int err;
+
+       pmu_irqs = reserve_pmu();
+       if (IS_ERR(pmu_irqs)) {
+               pr_warning("unable to reserve pmu\n");
+               return PTR_ERR(pmu_irqs);
+       }
+
+       init_pmu();
+
+       if (pmu_irqs->num_irqs < 1) {
+               pr_err("no irqs for PMUs defined\n");
+               return -ENODEV;
+       }
+
+       for (i = 0; i < pmu_irqs->num_irqs; ++i) {
+               err = request_irq(pmu_irqs->irqs[i], armpmu->handle_irq,
+                                 IRQF_DISABLED, "armpmu", NULL);
+               if (err) {
+                       pr_warning("unable to request IRQ%d for ARM "
+                                  "perf counters\n", pmu_irqs->irqs[i]);
+                       break;
+               }
+       }
+
+       if (err) {
+               for (i = i - 1; i >= 0; --i)
+                       free_irq(pmu_irqs->irqs[i], NULL);
+               release_pmu(pmu_irqs);
+               pmu_irqs = NULL;
+       }
+
+       return err;
+}
+
+static void
+armpmu_release_hardware(void)
+{
+       int i;
+
+       for (i = pmu_irqs->num_irqs - 1; i >= 0; --i)
+               free_irq(pmu_irqs->irqs[i], NULL);
+       armpmu->stop();
+
+       release_pmu(pmu_irqs);
+       pmu_irqs = NULL;
+}
+
+static atomic_t active_events = ATOMIC_INIT(0);
+static DEFINE_MUTEX(pmu_reserve_mutex);
+
+static void
+hw_perf_event_destroy(struct perf_event *event)
+{
+       if (atomic_dec_and_mutex_lock(&active_events, &pmu_reserve_mutex)) {
+               armpmu_release_hardware();
+               mutex_unlock(&pmu_reserve_mutex);
+       }
+}
+
+static int
+__hw_perf_event_init(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+       int mapping, err;
+
+       /* Decode the generic type into an ARM event identifier. */
+       if (PERF_TYPE_HARDWARE == event->attr.type) {
+               mapping = armpmu->event_map(event->attr.config);
+       } else if (PERF_TYPE_HW_CACHE == event->attr.type) {
+               mapping = armpmu_map_cache_event(event->attr.config);
+       } else if (PERF_TYPE_RAW == event->attr.type) {
+               mapping = armpmu->raw_event(event->attr.config);
+       } else {
+               pr_debug("event type %x not supported\n", event->attr.type);
+               return -EOPNOTSUPP;
+       }
+
+       if (mapping < 0) {
+               pr_debug("event %x:%llx not supported\n", event->attr.type,
+                        event->attr.config);
+               return mapping;
+       }
+
+       /*
+        * Check whether we need to exclude the counter from certain modes.
+        * The ARM performance counters are on all of the time so if someone
+        * has asked us for some excludes then we have to fail.
+        */
+       if (event->attr.exclude_kernel || event->attr.exclude_user ||
+           event->attr.exclude_hv || event->attr.exclude_idle) {
+               pr_debug("ARM performance counters do not support "
+                        "mode exclusion\n");
+               return -EPERM;
+       }
+
+       /*
+        * We don't assign an index until we actually place the event onto
+        * hardware. Use -1 to signify that we haven't decided where to put it
+        * yet. For SMP systems, each core has it's own PMU so we can't do any
+        * clever allocation or constraints checking at this point.
+        */
+       hwc->idx = -1;
+
+       /*
+        * Store the event encoding into the config_base field. config and
+        * event_base are unused as the only 2 things we need to know are
+        * the event mapping and the counter to use. The counter to use is
+        * also the indx and the config_base is the event type.
+        */
+       hwc->config_base            = (unsigned long)mapping;
+       hwc->config                 = 0;
+       hwc->event_base             = 0;
+
+       if (!hwc->sample_period) {
+               hwc->sample_period  = armpmu->max_period;
+               hwc->last_period    = hwc->sample_period;
+               atomic64_set(&hwc->period_left, hwc->sample_period);
+       }
+
+       err = 0;
+       if (event->group_leader != event) {
+               err = validate_group(event);
+               if (err)
+                       return -EINVAL;
+       }
+
+       return err;
+}
+
+const struct pmu *
+hw_perf_event_init(struct perf_event *event)
+{
+       int err = 0;
+
+       if (!armpmu)
+               return ERR_PTR(-ENODEV);
+
+       event->destroy = hw_perf_event_destroy;
+
+       if (!atomic_inc_not_zero(&active_events)) {
+               if (atomic_read(&active_events) > perf_max_events) {
+                       atomic_dec(&active_events);
+                       return ERR_PTR(-ENOSPC);
+               }
+
+               mutex_lock(&pmu_reserve_mutex);
+               if (atomic_read(&active_events) == 0) {
+                       err = armpmu_reserve_hardware();
+               }
+
+               if (!err)
+                       atomic_inc(&active_events);
+               mutex_unlock(&pmu_reserve_mutex);
+       }
+
+       if (err)
+               return ERR_PTR(err);
+
+       err = __hw_perf_event_init(event);
+       if (err)
+               hw_perf_event_destroy(event);
+
+       return err ? ERR_PTR(err) : &pmu;
+}
+
+void
+hw_perf_enable(void)
+{
+       /* Enable all of the perf events on hardware. */
+       int idx;
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (!armpmu)
+               return;
+
+       for (idx = 0; idx <= armpmu->num_events; ++idx) {
+               struct perf_event *event = cpuc->events[idx];
+
+               if (!event)
+                       continue;
+
+               armpmu->enable(&event->hw, idx);
+       }
+
+       armpmu->start();
+}
+
+void
+hw_perf_disable(void)
+{
+       if (armpmu)
+               armpmu->stop();
+}
+
+/*
+ * ARMv6 Performance counter handling code.
+ *
+ * ARMv6 has 2 configurable performance counters and a single cycle counter.
+ * They all share a single reset bit but can be written to zero so we can use
+ * that for a reset.
+ *
+ * The counters can't be individually enabled or disabled so when we remove
+ * one event and replace it with another we could get spurious counts from the
+ * wrong event. However, we can take advantage of the fact that the
+ * performance counters can export events to the event bus, and the event bus
+ * itself can be monitored. This requires that we *don't* export the events to
+ * the event bus. The procedure for disabling a configurable counter is:
+ *     - change the counter to count the ETMEXTOUT[0] signal (0x20). This
+ *       effectively stops the counter from counting.
+ *     - disable the counter's interrupt generation (each counter has it's
+ *       own interrupt enable bit).
+ * Once stopped, the counter value can be written as 0 to reset.
+ *
+ * To enable a counter:
+ *     - enable the counter's interrupt generation.
+ *     - set the new event type.
+ *
+ * Note: the dedicated cycle counter only counts cycles and can't be
+ * enabled/disabled independently of the others. When we want to disable the
+ * cycle counter, we have to just disable the interrupt reporting and start
+ * ignoring that counter. When re-enabling, we have to reset the value and
+ * enable the interrupt.
+ */
+
+enum armv6_perf_types {
+       ARMV6_PERFCTR_ICACHE_MISS           = 0x0,
+       ARMV6_PERFCTR_IBUF_STALL            = 0x1,
+       ARMV6_PERFCTR_DDEP_STALL            = 0x2,
+       ARMV6_PERFCTR_ITLB_MISS             = 0x3,
+       ARMV6_PERFCTR_DTLB_MISS             = 0x4,
+       ARMV6_PERFCTR_BR_EXEC               = 0x5,
+       ARMV6_PERFCTR_BR_MISPREDICT         = 0x6,
+       ARMV6_PERFCTR_INSTR_EXEC            = 0x7,
+       ARMV6_PERFCTR_DCACHE_HIT            = 0x9,
+       ARMV6_PERFCTR_DCACHE_ACCESS         = 0xA,
+       ARMV6_PERFCTR_DCACHE_MISS           = 0xB,
+       ARMV6_PERFCTR_DCACHE_WBACK          = 0xC,
+       ARMV6_PERFCTR_SW_PC_CHANGE          = 0xD,
+       ARMV6_PERFCTR_MAIN_TLB_MISS         = 0xF,
+       ARMV6_PERFCTR_EXPL_D_ACCESS         = 0x10,
+       ARMV6_PERFCTR_LSU_FULL_STALL        = 0x11,
+       ARMV6_PERFCTR_WBUF_DRAINED          = 0x12,
+       ARMV6_PERFCTR_CPU_CYCLES            = 0xFF,
+       ARMV6_PERFCTR_NOP                   = 0x20,
+};
+
+enum armv6_counters {
+       ARMV6_CYCLE_COUNTER = 1,
+       ARMV6_COUNTER0,
+       ARMV6_COUNTER1,
+};
+
+/*
+ * The hardware events that we support. We do support cache operations but
+ * we have harvard caches and no way to combine instruction and data
+ * accesses/misses in hardware.
+ */
+static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV6_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV6_PERFCTR_INSTR_EXEC,
+       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
+       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV6_PERFCTR_BR_MISPREDICT,
+       [PERF_COUNT_HW_BUS_CYCLES]          = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+                                         [PERF_COUNT_HW_CACHE_OP_MAX]
+                                         [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+       [C(L1D)] = {
+               /*
+                * The performance counters don't differentiate between read
+                * and write accesses/misses so this isn't strictly correct,
+                * but it's the best we can do. Writes and reads get
+                * combined.
+                */
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV6_PERFCTR_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV6_PERFCTR_DCACHE_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV6_PERFCTR_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV6_PERFCTR_DCACHE_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(L1I)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV6_PERFCTR_ICACHE_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV6_PERFCTR_ICACHE_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(LL)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(DTLB)] = {
+               /*
+                * The ARM performance counters can count micro DTLB misses,
+                * micro ITLB misses and main TLB misses. There isn't an event
+                * for TLB misses, so use the micro misses here and if users
+                * want the main TLB misses they can use a raw counter.
+                */
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV6_PERFCTR_DTLB_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV6_PERFCTR_DTLB_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(ITLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV6_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV6_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(BPU)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+};
+
+enum armv6mpcore_perf_types {
+       ARMV6MPCORE_PERFCTR_ICACHE_MISS     = 0x0,
+       ARMV6MPCORE_PERFCTR_IBUF_STALL      = 0x1,
+       ARMV6MPCORE_PERFCTR_DDEP_STALL      = 0x2,
+       ARMV6MPCORE_PERFCTR_ITLB_MISS       = 0x3,
+       ARMV6MPCORE_PERFCTR_DTLB_MISS       = 0x4,
+       ARMV6MPCORE_PERFCTR_BR_EXEC         = 0x5,
+       ARMV6MPCORE_PERFCTR_BR_NOTPREDICT   = 0x6,
+       ARMV6MPCORE_PERFCTR_BR_MISPREDICT   = 0x7,
+       ARMV6MPCORE_PERFCTR_INSTR_EXEC      = 0x8,
+       ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS = 0xA,
+       ARMV6MPCORE_PERFCTR_DCACHE_RDMISS   = 0xB,
+       ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS = 0xC,
+       ARMV6MPCORE_PERFCTR_DCACHE_WRMISS   = 0xD,
+       ARMV6MPCORE_PERFCTR_DCACHE_EVICTION = 0xE,
+       ARMV6MPCORE_PERFCTR_SW_PC_CHANGE    = 0xF,
+       ARMV6MPCORE_PERFCTR_MAIN_TLB_MISS   = 0x10,
+       ARMV6MPCORE_PERFCTR_EXPL_MEM_ACCESS = 0x11,
+       ARMV6MPCORE_PERFCTR_LSU_FULL_STALL  = 0x12,
+       ARMV6MPCORE_PERFCTR_WBUF_DRAINED    = 0x13,
+       ARMV6MPCORE_PERFCTR_CPU_CYCLES      = 0xFF,
+};
+
+/*
+ * The hardware events that we support. We do support cache operations but
+ * we have harvard caches and no way to combine instruction and data
+ * accesses/misses in hardware.
+ */
+static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
+       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
+       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
+       [PERF_COUNT_HW_BUS_CYCLES]          = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+                                       [PERF_COUNT_HW_CACHE_OP_MAX]
+                                       [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+       [C(L1D)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]  =
+                               ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS,
+                       [C(RESULT_MISS)]    =
+                               ARMV6MPCORE_PERFCTR_DCACHE_RDMISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]  =
+                               ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS,
+                       [C(RESULT_MISS)]    =
+                               ARMV6MPCORE_PERFCTR_DCACHE_WRMISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(L1I)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(LL)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(DTLB)] = {
+               /*
+                * The ARM performance counters can count micro DTLB misses,
+                * micro ITLB misses and main TLB misses. There isn't an event
+                * for TLB misses, so use the micro misses here and if users
+                * want the main TLB misses they can use a raw counter.
+                */
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_DTLB_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_DTLB_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(ITLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = ARMV6MPCORE_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(BPU)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]  = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]    = CACHE_OP_UNSUPPORTED,
+               },
+       },
+};
+
+static inline unsigned long
+armv6_pmcr_read(void)
+{
+       u32 val;
+       asm volatile("mrc   p15, 0, %0, c15, c12, 0" : "=r"(val));
+       return val;
+}
+
+static inline void
+armv6_pmcr_write(unsigned long val)
+{
+       asm volatile("mcr   p15, 0, %0, c15, c12, 0" : : "r"(val));
+}
+
+#define ARMV6_PMCR_ENABLE              (1 << 0)
+#define ARMV6_PMCR_CTR01_RESET         (1 << 1)
+#define ARMV6_PMCR_CCOUNT_RESET                (1 << 2)
+#define ARMV6_PMCR_CCOUNT_DIV          (1 << 3)
+#define ARMV6_PMCR_COUNT0_IEN          (1 << 4)
+#define ARMV6_PMCR_COUNT1_IEN          (1 << 5)
+#define ARMV6_PMCR_CCOUNT_IEN          (1 << 6)
+#define ARMV6_PMCR_COUNT0_OVERFLOW     (1 << 8)
+#define ARMV6_PMCR_COUNT1_OVERFLOW     (1 << 9)
+#define ARMV6_PMCR_CCOUNT_OVERFLOW     (1 << 10)
+#define ARMV6_PMCR_EVT_COUNT0_SHIFT    20
+#define ARMV6_PMCR_EVT_COUNT0_MASK     (0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT)
+#define ARMV6_PMCR_EVT_COUNT1_SHIFT    12
+#define ARMV6_PMCR_EVT_COUNT1_MASK     (0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT)
+
+#define ARMV6_PMCR_OVERFLOWED_MASK \
+       (ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \
+        ARMV6_PMCR_CCOUNT_OVERFLOW)
+
+static inline int
+armv6_pmcr_has_overflowed(unsigned long pmcr)
+{
+       return (pmcr & ARMV6_PMCR_OVERFLOWED_MASK);
+}
+
+static inline int
+armv6_pmcr_counter_has_overflowed(unsigned long pmcr,
+                                 enum armv6_counters counter)
+{
+       int ret = 0;
+
+       if (ARMV6_CYCLE_COUNTER == counter)
+               ret = pmcr & ARMV6_PMCR_CCOUNT_OVERFLOW;
+       else if (ARMV6_COUNTER0 == counter)
+               ret = pmcr & ARMV6_PMCR_COUNT0_OVERFLOW;
+       else if (ARMV6_COUNTER1 == counter)
+               ret = pmcr & ARMV6_PMCR_COUNT1_OVERFLOW;
+       else
+               WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+
+       return ret;
+}
+
+static inline u32
+armv6pmu_read_counter(int counter)
+{
+       unsigned long value = 0;
+
+       if (ARMV6_CYCLE_COUNTER == counter)
+               asm volatile("mrc   p15, 0, %0, c15, c12, 1" : "=r"(value));
+       else if (ARMV6_COUNTER0 == counter)
+               asm volatile("mrc   p15, 0, %0, c15, c12, 2" : "=r"(value));
+       else if (ARMV6_COUNTER1 == counter)
+               asm volatile("mrc   p15, 0, %0, c15, c12, 3" : "=r"(value));
+       else
+               WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+
+       return value;
+}
+
+static inline void
+armv6pmu_write_counter(int counter,
+                      u32 value)
+{
+       if (ARMV6_CYCLE_COUNTER == counter)
+               asm volatile("mcr   p15, 0, %0, c15, c12, 1" : : "r"(value));
+       else if (ARMV6_COUNTER0 == counter)
+               asm volatile("mcr   p15, 0, %0, c15, c12, 2" : : "r"(value));
+       else if (ARMV6_COUNTER1 == counter)
+               asm volatile("mcr   p15, 0, %0, c15, c12, 3" : : "r"(value));
+       else
+               WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+}
+
+void
+armv6pmu_enable_event(struct hw_perf_event *hwc,
+                     int idx)
+{
+       unsigned long val, mask, evt, flags;
+
+       if (ARMV6_CYCLE_COUNTER == idx) {
+               mask    = 0;
+               evt     = ARMV6_PMCR_CCOUNT_IEN;
+       } else if (ARMV6_COUNTER0 == idx) {
+               mask    = ARMV6_PMCR_EVT_COUNT0_MASK;
+               evt     = (hwc->config_base << ARMV6_PMCR_EVT_COUNT0_SHIFT) |
+                         ARMV6_PMCR_COUNT0_IEN;
+       } else if (ARMV6_COUNTER1 == idx) {
+               mask    = ARMV6_PMCR_EVT_COUNT1_MASK;
+               evt     = (hwc->config_base << ARMV6_PMCR_EVT_COUNT1_SHIFT) |
+                         ARMV6_PMCR_COUNT1_IEN;
+       } else {
+               WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+               return;
+       }
+
+       /*
+        * Mask out the current event and set the counter to count the event
+        * that we're interested in.
+        */
+       spin_lock_irqsave(&pmu_lock, flags);
+       val = armv6_pmcr_read();
+       val &= ~mask;
+       val |= evt;
+       armv6_pmcr_write(val);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static irqreturn_t
+armv6pmu_handle_irq(int irq_num,
+                   void *dev)
+{
+       unsigned long pmcr = armv6_pmcr_read();
+       struct perf_sample_data data;
+       struct cpu_hw_events *cpuc;
+       struct pt_regs *regs;
+       int idx;
+
+       if (!armv6_pmcr_has_overflowed(pmcr))
+               return IRQ_NONE;
+
+       regs = get_irq_regs();
+
+       /*
+        * The interrupts are cleared by writing the overflow flags back to
+        * the control register. All of the other bits don't have any effect
+        * if they are rewritten, so write the whole value back.
+        */
+       armv6_pmcr_write(pmcr);
+
+       data.addr = 0;
+
+       cpuc = &__get_cpu_var(cpu_hw_events);
+       for (idx = 0; idx <= armpmu->num_events; ++idx) {
+               struct perf_event *event = cpuc->events[idx];
+               struct hw_perf_event *hwc;
+
+               if (!test_bit(idx, cpuc->active_mask))
+                       continue;
+
+               /*
+                * We have a single interrupt for all counters. Check that
+                * each counter has overflowed before we process it.
+                */
+               if (!armv6_pmcr_counter_has_overflowed(pmcr, idx))
+                       continue;
+
+               hwc = &event->hw;
+               armpmu_event_update(event, hwc, idx);
+               data.period = event->hw.last_period;
+               if (!armpmu_event_set_period(event, hwc, idx))
+                       continue;
+
+               if (perf_event_overflow(event, 0, &data, regs))
+                       armpmu->disable(hwc, idx);
+       }
+
+       /*
+        * Handle the pending perf events.
+        *
+        * Note: this call *must* be run with interrupts enabled. For
+        * platforms that can have the PMU interrupts raised as a PMI, this
+        * will not work.
+        */
+       perf_event_do_pending();
+
+       return IRQ_HANDLED;
+}
+
+static void
+armv6pmu_start(void)
+{
+       unsigned long flags, val;
+
+       spin_lock_irqsave(&pmu_lock, flags);
+       val = armv6_pmcr_read();
+       val |= ARMV6_PMCR_ENABLE;
+       armv6_pmcr_write(val);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+void
+armv6pmu_stop(void)
+{
+       unsigned long flags, val;
+
+       spin_lock_irqsave(&pmu_lock, flags);
+       val = armv6_pmcr_read();
+       val &= ~ARMV6_PMCR_ENABLE;
+       armv6_pmcr_write(val);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static inline int
+armv6pmu_event_map(int config)
+{
+       int mapping = armv6_perf_map[config];
+       if (HW_OP_UNSUPPORTED == mapping)
+               mapping = -EOPNOTSUPP;
+       return mapping;
+}
+
+static inline int
+armv6mpcore_pmu_event_map(int config)
+{
+       int mapping = armv6mpcore_perf_map[config];
+       if (HW_OP_UNSUPPORTED == mapping)
+               mapping = -EOPNOTSUPP;
+       return mapping;
+}
+
+static u64
+armv6pmu_raw_event(u64 config)
+{
+       return config & 0xff;
+}
+
+static int
+armv6pmu_get_event_idx(struct cpu_hw_events *cpuc,
+                      struct hw_perf_event *event)
+{
+       /* Always place a cycle counter into the cycle counter. */
+       if (ARMV6_PERFCTR_CPU_CYCLES == event->config_base) {
+               if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask))
+                       return -EAGAIN;
+
+               return ARMV6_CYCLE_COUNTER;
+       } else {
+               /*
+                * For anything other than a cycle counter, try and use
+                * counter0 and counter1.
+                */
+               if (!test_and_set_bit(ARMV6_COUNTER1, cpuc->used_mask)) {
+                       return ARMV6_COUNTER1;
+               }
+
+               if (!test_and_set_bit(ARMV6_COUNTER0, cpuc->used_mask)) {
+                       return ARMV6_COUNTER0;
+               }
+
+               /* The counters are all in use. */
+               return -EAGAIN;
+       }
+}
+
+static void
+armv6pmu_disable_event(struct hw_perf_event *hwc,
+                      int idx)
+{
+       unsigned long val, mask, evt, flags;
+
+       if (ARMV6_CYCLE_COUNTER == idx) {
+               mask    = ARMV6_PMCR_CCOUNT_IEN;
+               evt     = 0;
+       } else if (ARMV6_COUNTER0 == idx) {
+               mask    = ARMV6_PMCR_COUNT0_IEN | ARMV6_PMCR_EVT_COUNT0_MASK;
+               evt     = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT0_SHIFT;
+       } else if (ARMV6_COUNTER1 == idx) {
+               mask    = ARMV6_PMCR_COUNT1_IEN | ARMV6_PMCR_EVT_COUNT1_MASK;
+               evt     = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT1_SHIFT;
+       } else {
+               WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+               return;
+       }
+
+       /*
+        * Mask out the current event and set the counter to count the number
+        * of ETM bus signal assertion cycles. The external reporting should
+        * be disabled and so this should never increment.
+        */
+       spin_lock_irqsave(&pmu_lock, flags);
+       val = armv6_pmcr_read();
+       val &= ~mask;
+       val |= evt;
+       armv6_pmcr_write(val);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
+                             int idx)
+{
+       unsigned long val, mask, flags, evt = 0;
+
+       if (ARMV6_CYCLE_COUNTER == idx) {
+               mask    = ARMV6_PMCR_CCOUNT_IEN;
+       } else if (ARMV6_COUNTER0 == idx) {
+               mask    = ARMV6_PMCR_COUNT0_IEN;
+       } else if (ARMV6_COUNTER1 == idx) {
+               mask    = ARMV6_PMCR_COUNT1_IEN;
+       } else {
+               WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+               return;
+       }
+
+       /*
+        * Unlike UP ARMv6, we don't have a way of stopping the counters. We
+        * simply disable the interrupt reporting.
+        */
+       spin_lock_irqsave(&pmu_lock, flags);
+       val = armv6_pmcr_read();
+       val &= ~mask;
+       val |= evt;
+       armv6_pmcr_write(val);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static const struct arm_pmu armv6pmu = {
+       .name                   = "v6",
+       .handle_irq             = armv6pmu_handle_irq,
+       .enable                 = armv6pmu_enable_event,
+       .disable                = armv6pmu_disable_event,
+       .event_map              = armv6pmu_event_map,
+       .raw_event              = armv6pmu_raw_event,
+       .read_counter           = armv6pmu_read_counter,
+       .write_counter          = armv6pmu_write_counter,
+       .get_event_idx          = armv6pmu_get_event_idx,
+       .start                  = armv6pmu_start,
+       .stop                   = armv6pmu_stop,
+       .num_events             = 3,
+       .max_period             = (1LLU << 32) - 1,
+};
+
+/*
+ * ARMv6mpcore is almost identical to single core ARMv6 with the exception
+ * that some of the events have different enumerations and that there is no
+ * *hack* to stop the programmable counters. To stop the counters we simply
+ * disable the interrupt reporting and update the event. When unthrottling we
+ * reset the period and enable the interrupt reporting.
+ */
+static const struct arm_pmu armv6mpcore_pmu = {
+       .name                   = "v6mpcore",
+       .handle_irq             = armv6pmu_handle_irq,
+       .enable                 = armv6pmu_enable_event,
+       .disable                = armv6mpcore_pmu_disable_event,
+       .event_map              = armv6mpcore_pmu_event_map,
+       .raw_event              = armv6pmu_raw_event,
+       .read_counter           = armv6pmu_read_counter,
+       .write_counter          = armv6pmu_write_counter,
+       .get_event_idx          = armv6pmu_get_event_idx,
+       .start                  = armv6pmu_start,
+       .stop                   = armv6pmu_stop,
+       .num_events             = 3,
+       .max_period             = (1LLU << 32) - 1,
+};
+
+/*
+ * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code.
+ *
+ * Copied from ARMv6 code, with the low level code inspired
+ *  by the ARMv7 Oprofile code.
+ *
+ * Cortex-A8 has up to 4 configurable performance counters and
+ *  a single cycle counter.
+ * Cortex-A9 has up to 31 configurable performance counters and
+ *  a single cycle counter.
+ *
+ * All counters can be enabled/disabled and IRQ masked separately. The cycle
+ *  counter and all 4 performance counters together can be reset separately.
+ */
+
+#define ARMV7_PMU_CORTEX_A8_NAME               "ARMv7 Cortex-A8"
+
+#define ARMV7_PMU_CORTEX_A9_NAME               "ARMv7 Cortex-A9"
+
+/* Common ARMv7 event types */
+enum armv7_perf_types {
+       ARMV7_PERFCTR_PMNC_SW_INCR              = 0x00,
+       ARMV7_PERFCTR_IFETCH_MISS               = 0x01,
+       ARMV7_PERFCTR_ITLB_MISS                 = 0x02,
+       ARMV7_PERFCTR_DCACHE_REFILL             = 0x03,
+       ARMV7_PERFCTR_DCACHE_ACCESS             = 0x04,
+       ARMV7_PERFCTR_DTLB_REFILL               = 0x05,
+       ARMV7_PERFCTR_DREAD                     = 0x06,
+       ARMV7_PERFCTR_DWRITE                    = 0x07,
+
+       ARMV7_PERFCTR_EXC_TAKEN                 = 0x09,
+       ARMV7_PERFCTR_EXC_EXECUTED              = 0x0A,
+       ARMV7_PERFCTR_CID_WRITE                 = 0x0B,
+       /* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
+        * It counts:
+        *  - all branch instructions,
+        *  - instructions that explicitly write the PC,
+        *  - exception generating instructions.
+        */
+       ARMV7_PERFCTR_PC_WRITE                  = 0x0C,
+       ARMV7_PERFCTR_PC_IMM_BRANCH             = 0x0D,
+       ARMV7_PERFCTR_UNALIGNED_ACCESS          = 0x0F,
+       ARMV7_PERFCTR_PC_BRANCH_MIS_PRED        = 0x10,
+       ARMV7_PERFCTR_CLOCK_CYCLES              = 0x11,
+
+       ARMV7_PERFCTR_PC_BRANCH_MIS_USED        = 0x12,
+
+       ARMV7_PERFCTR_CPU_CYCLES                = 0xFF
+};
+
+/* ARMv7 Cortex-A8 specific event types */
+enum armv7_a8_perf_types {
+       ARMV7_PERFCTR_INSTR_EXECUTED            = 0x08,
+
+       ARMV7_PERFCTR_PC_PROC_RETURN            = 0x0E,
+
+       ARMV7_PERFCTR_WRITE_BUFFER_FULL         = 0x40,
+       ARMV7_PERFCTR_L2_STORE_MERGED           = 0x41,
+       ARMV7_PERFCTR_L2_STORE_BUFF             = 0x42,
+       ARMV7_PERFCTR_L2_ACCESS                 = 0x43,
+       ARMV7_PERFCTR_L2_CACH_MISS              = 0x44,
+       ARMV7_PERFCTR_AXI_READ_CYCLES           = 0x45,
+       ARMV7_PERFCTR_AXI_WRITE_CYCLES          = 0x46,
+       ARMV7_PERFCTR_MEMORY_REPLAY             = 0x47,
+       ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY   = 0x48,
+       ARMV7_PERFCTR_L1_DATA_MISS              = 0x49,
+       ARMV7_PERFCTR_L1_INST_MISS              = 0x4A,
+       ARMV7_PERFCTR_L1_DATA_COLORING          = 0x4B,
+       ARMV7_PERFCTR_L1_NEON_DATA              = 0x4C,
+       ARMV7_PERFCTR_L1_NEON_CACH_DATA         = 0x4D,
+       ARMV7_PERFCTR_L2_NEON                   = 0x4E,
+       ARMV7_PERFCTR_L2_NEON_HIT               = 0x4F,
+       ARMV7_PERFCTR_L1_INST                   = 0x50,
+       ARMV7_PERFCTR_PC_RETURN_MIS_PRED        = 0x51,
+       ARMV7_PERFCTR_PC_BRANCH_FAILED          = 0x52,
+       ARMV7_PERFCTR_PC_BRANCH_TAKEN           = 0x53,
+       ARMV7_PERFCTR_PC_BRANCH_EXECUTED        = 0x54,
+       ARMV7_PERFCTR_OP_EXECUTED               = 0x55,
+       ARMV7_PERFCTR_CYCLES_INST_STALL         = 0x56,
+       ARMV7_PERFCTR_CYCLES_INST               = 0x57,
+       ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL    = 0x58,
+       ARMV7_PERFCTR_CYCLES_NEON_INST_STALL    = 0x59,
+       ARMV7_PERFCTR_NEON_CYCLES               = 0x5A,
+
+       ARMV7_PERFCTR_PMU0_EVENTS               = 0x70,
+       ARMV7_PERFCTR_PMU1_EVENTS               = 0x71,
+       ARMV7_PERFCTR_PMU_EVENTS                = 0x72,
+};
+
+/* ARMv7 Cortex-A9 specific event types */
+enum armv7_a9_perf_types {
+       ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC     = 0x40,
+       ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC     = 0x41,
+       ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC       = 0x42,
+
+       ARMV7_PERFCTR_COHERENT_LINE_MISS        = 0x50,
+       ARMV7_PERFCTR_COHERENT_LINE_HIT         = 0x51,
+
+       ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES   = 0x60,
+       ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES   = 0x61,
+       ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES = 0x62,
+       ARMV7_PERFCTR_STREX_EXECUTED_PASSED     = 0x63,
+       ARMV7_PERFCTR_STREX_EXECUTED_FAILED     = 0x64,
+       ARMV7_PERFCTR_DATA_EVICTION             = 0x65,
+       ARMV7_PERFCTR_ISSUE_STAGE_NO_INST       = 0x66,
+       ARMV7_PERFCTR_ISSUE_STAGE_EMPTY         = 0x67,
+       ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE  = 0x68,
+
+       ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS = 0x6E,
+
+       ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST   = 0x70,
+       ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST = 0x71,
+       ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST  = 0x72,
+       ARMV7_PERFCTR_FP_EXECUTED_INST          = 0x73,
+       ARMV7_PERFCTR_NEON_EXECUTED_INST        = 0x74,
+
+       ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES = 0x80,
+       ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES  = 0x81,
+       ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES        = 0x82,
+       ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES        = 0x83,
+       ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES  = 0x84,
+       ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES  = 0x85,
+       ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES      = 0x86,
+
+       ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES  = 0x8A,
+       ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES = 0x8B,
+
+       ARMV7_PERFCTR_ISB_INST                  = 0x90,
+       ARMV7_PERFCTR_DSB_INST                  = 0x91,
+       ARMV7_PERFCTR_DMB_INST                  = 0x92,
+       ARMV7_PERFCTR_EXT_INTERRUPTS            = 0x93,
+
+       ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED     = 0xA0,
+       ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED       = 0xA1,
+       ARMV7_PERFCTR_PLE_FIFO_FLUSH            = 0xA2,
+       ARMV7_PERFCTR_PLE_RQST_COMPLETED        = 0xA3,
+       ARMV7_PERFCTR_PLE_FIFO_OVERFLOW         = 0xA4,
+       ARMV7_PERFCTR_PLE_RQST_PROG             = 0xA5
+};
+
+/*
+ * Cortex-A8 HW events mapping
+ *
+ * The hardware events that we support. We do support cache operations but
+ * we have harvard caches and no way to combine instruction and data
+ * accesses/misses in hardware.
+ */
+static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV7_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV7_PERFCTR_INSTR_EXECUTED,
+       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
+       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+       [PERF_COUNT_HW_BUS_CYCLES]          = ARMV7_PERFCTR_CLOCK_CYCLES,
+};
+
+static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+                                         [PERF_COUNT_HW_CACHE_OP_MAX]
+                                         [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+       [C(L1D)] = {
+               /*
+                * The performance counters don't differentiate between read
+                * and write accesses/misses so this isn't strictly correct,
+                * but it's the best we can do. Writes and reads get
+                * combined.
+                */
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DCACHE_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DCACHE_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(L1I)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_INST,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_INST_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_INST,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L1_INST_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(LL)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L2_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L2_CACH_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L2_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_L2_CACH_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(DTLB)] = {
+               /*
+                * Only ITLB misses and DTLB refills are supported.
+                * If users want the DTLB refills misses a raw counter
+                * must be used.
+                */
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DTLB_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DTLB_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(ITLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(BPU)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_WRITE,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_WRITE,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+};
+
+/*
+ * Cortex-A9 HW events mapping
+ */
+static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV7_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]        =
+                                       ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
+       [PERF_COUNT_HW_CACHE_REFERENCES]    = ARMV7_PERFCTR_COHERENT_LINE_HIT,
+       [PERF_COUNT_HW_CACHE_MISSES]        = ARMV7_PERFCTR_COHERENT_LINE_MISS,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
+       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+       [PERF_COUNT_HW_BUS_CYCLES]          = ARMV7_PERFCTR_CLOCK_CYCLES,
+};
+
+static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+                                         [PERF_COUNT_HW_CACHE_OP_MAX]
+                                         [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+       [C(L1D)] = {
+               /*
+                * The performance counters don't differentiate between read
+                * and write accesses/misses so this isn't strictly correct,
+                * but it's the best we can do. Writes and reads get
+                * combined.
+                */
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DCACHE_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DCACHE_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(L1I)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_IFETCH_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_IFETCH_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(LL)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(DTLB)] = {
+               /*
+                * Only ITLB misses and DTLB refills are supported.
+                * If users want the DTLB refills misses a raw counter
+                * must be used.
+                */
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DTLB_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DTLB_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(ITLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(BPU)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_WRITE,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_WRITE,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+};
+
+/*
+ * Perf Events counters
+ */
+enum armv7_counters {
+       ARMV7_CYCLE_COUNTER             = 1,    /* Cycle counter */
+       ARMV7_COUNTER0                  = 2,    /* First event counter */
+};
+
+/*
+ * The cycle counter is ARMV7_CYCLE_COUNTER.
+ * The first event counter is ARMV7_COUNTER0.
+ * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1).
+ */
+#define        ARMV7_COUNTER_LAST      (ARMV7_COUNTER0 + armpmu->num_events - 1)
+
+/*
+ * ARMv7 low level PMNC access
+ */
+
+/*
+ * Per-CPU PMNC: config reg
+ */
+#define ARMV7_PMNC_E           (1 << 0) /* Enable all counters */
+#define ARMV7_PMNC_P           (1 << 1) /* Reset all counters */
+#define ARMV7_PMNC_C           (1 << 2) /* Cycle counter reset */
+#define ARMV7_PMNC_D           (1 << 3) /* CCNT counts every 64th cpu cycle */
+#define ARMV7_PMNC_X           (1 << 4) /* Export to ETM */
+#define ARMV7_PMNC_DP          (1 << 5) /* Disable CCNT if non-invasive debug*/
+#define        ARMV7_PMNC_N_SHIFT      11       /* Number of counters supported */
+#define        ARMV7_PMNC_N_MASK       0x1f
+#define        ARMV7_PMNC_MASK         0x3f     /* Mask for writable bits */
+
+/*
+ * Available counters
+ */
+#define ARMV7_CNT0             0       /* First event counter */
+#define ARMV7_CCNT             31      /* Cycle counter */
+
+/* Perf Event to low level counters mapping */
+#define ARMV7_EVENT_CNT_TO_CNTx        (ARMV7_COUNTER0 - ARMV7_CNT0)
+
+/*
+ * CNTENS: counters enable reg
+ */
+#define ARMV7_CNTENS_P(idx)    (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_CNTENS_C         (1 << ARMV7_CCNT)
+
+/*
+ * CNTENC: counters disable reg
+ */
+#define ARMV7_CNTENC_P(idx)    (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_CNTENC_C         (1 << ARMV7_CCNT)
+
+/*
+ * INTENS: counters overflow interrupt enable reg
+ */
+#define ARMV7_INTENS_P(idx)    (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_INTENS_C         (1 << ARMV7_CCNT)
+
+/*
+ * INTENC: counters overflow interrupt disable reg
+ */
+#define ARMV7_INTENC_P(idx)    (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_INTENC_C         (1 << ARMV7_CCNT)
+
+/*
+ * EVTSEL: Event selection reg
+ */
+#define        ARMV7_EVTSEL_MASK       0x7f            /* Mask for writable bits */
+
+/*
+ * SELECT: Counter selection reg
+ */
+#define        ARMV7_SELECT_MASK       0x1f            /* Mask for writable bits */
+
+/*
+ * FLAG: counters overflow flag status reg
+ */
+#define ARMV7_FLAG_P(idx)      (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_FLAG_C           (1 << ARMV7_CCNT)
+#define        ARMV7_FLAG_MASK         0xffffffff      /* Mask for writable bits */
+#define        ARMV7_OVERFLOWED_MASK   ARMV7_FLAG_MASK
+
+static inline unsigned long armv7_pmnc_read(void)
+{
+       u32 val;
+       asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
+       return val;
+}
+
+static inline void armv7_pmnc_write(unsigned long val)
+{
+       val &= ARMV7_PMNC_MASK;
+       asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
+}
+
+static inline int armv7_pmnc_has_overflowed(unsigned long pmnc)
+{
+       return pmnc & ARMV7_OVERFLOWED_MASK;
+}
+
+static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc,
+                                       enum armv7_counters counter)
+{
+       int ret;
+
+       if (counter == ARMV7_CYCLE_COUNTER)
+               ret = pmnc & ARMV7_FLAG_C;
+       else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST))
+               ret = pmnc & ARMV7_FLAG_P(counter);
+       else
+               pr_err("CPU%u checking wrong counter %d overflow status\n",
+                       smp_processor_id(), counter);
+
+       return ret;
+}
+
+static inline int armv7_pmnc_select_counter(unsigned int idx)
+{
+       u32 val;
+
+       if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) {
+               pr_err("CPU%u selecting wrong PMNC counter"
+                       " %d\n", smp_processor_id(), idx);
+               return -1;
+       }
+
+       val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK;
+       asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
+
+       return idx;
+}
+
+static inline u32 armv7pmu_read_counter(int idx)
+{
+       unsigned long value = 0;
+
+       if (idx == ARMV7_CYCLE_COUNTER)
+               asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
+       else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
+               if (armv7_pmnc_select_counter(idx) == idx)
+                       asm volatile("mrc p15, 0, %0, c9, c13, 2"
+                                    : "=r" (value));
+       } else
+               pr_err("CPU%u reading wrong counter %d\n",
+                       smp_processor_id(), idx);
+
+       return value;
+}
+
+static inline void armv7pmu_write_counter(int idx, u32 value)
+{
+       if (idx == ARMV7_CYCLE_COUNTER)
+               asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
+       else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
+               if (armv7_pmnc_select_counter(idx) == idx)
+                       asm volatile("mcr p15, 0, %0, c9, c13, 2"
+                                    : : "r" (value));
+       } else
+               pr_err("CPU%u writing wrong counter %d\n",
+                       smp_processor_id(), idx);
+}
+
+static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val)
+{
+       if (armv7_pmnc_select_counter(idx) == idx) {
+               val &= ARMV7_EVTSEL_MASK;
+               asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
+       }
+}
+
+static inline u32 armv7_pmnc_enable_counter(unsigned int idx)
+{
+       u32 val;
+
+       if ((idx != ARMV7_CYCLE_COUNTER) &&
+           ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+               pr_err("CPU%u enabling wrong PMNC counter"
+                       " %d\n", smp_processor_id(), idx);
+               return -1;
+       }
+
+       if (idx == ARMV7_CYCLE_COUNTER)
+               val = ARMV7_CNTENS_C;
+       else
+               val = ARMV7_CNTENS_P(idx);
+
+       asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
+
+       return idx;
+}
+
+static inline u32 armv7_pmnc_disable_counter(unsigned int idx)
+{
+       u32 val;
+
+
+       if ((idx != ARMV7_CYCLE_COUNTER) &&
+           ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+               pr_err("CPU%u disabling wrong PMNC counter"
+                       " %d\n", smp_processor_id(), idx);
+               return -1;
+       }
+
+       if (idx == ARMV7_CYCLE_COUNTER)
+               val = ARMV7_CNTENC_C;
+       else
+               val = ARMV7_CNTENC_P(idx);
+
+       asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
+
+       return idx;
+}
+
+static inline u32 armv7_pmnc_enable_intens(unsigned int idx)
+{
+       u32 val;
+
+       if ((idx != ARMV7_CYCLE_COUNTER) &&
+           ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+               pr_err("CPU%u enabling wrong PMNC counter"
+                       " interrupt enable %d\n", smp_processor_id(), idx);
+               return -1;
+       }
+
+       if (idx == ARMV7_CYCLE_COUNTER)
+               val = ARMV7_INTENS_C;
+       else
+               val = ARMV7_INTENS_P(idx);
+
+       asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
+
+       return idx;
+}
+
+static inline u32 armv7_pmnc_disable_intens(unsigned int idx)
+{
+       u32 val;
+
+       if ((idx != ARMV7_CYCLE_COUNTER) &&
+           ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+               pr_err("CPU%u disabling wrong PMNC counter"
+                       " interrupt enable %d\n", smp_processor_id(), idx);
+               return -1;
+       }
+
+       if (idx == ARMV7_CYCLE_COUNTER)
+               val = ARMV7_INTENC_C;
+       else
+               val = ARMV7_INTENC_P(idx);
+
+       asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val));
+
+       return idx;
+}
+
+static inline u32 armv7_pmnc_getreset_flags(void)
+{
+       u32 val;
+
+       /* Read */
+       asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
+
+       /* Write to clear flags */
+       val &= ARMV7_FLAG_MASK;
+       asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
+
+       return val;
+}
+
+#ifdef DEBUG
+static void armv7_pmnc_dump_regs(void)
+{
+       u32 val;
+       unsigned int cnt;
+
+       printk(KERN_INFO "PMNC registers dump:\n");
+
+       asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
+       printk(KERN_INFO "PMNC  =0x%08x\n", val);
+
+       asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
+       printk(KERN_INFO "CNTENS=0x%08x\n", val);
+
+       asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
+       printk(KERN_INFO "INTENS=0x%08x\n", val);
+
+       asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
+       printk(KERN_INFO "FLAGS =0x%08x\n", val);
+
+       asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
+       printk(KERN_INFO "SELECT=0x%08x\n", val);
+
+       asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
+       printk(KERN_INFO "CCNT  =0x%08x\n", val);
+
+       for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) {
+               armv7_pmnc_select_counter(cnt);
+               asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
+               printk(KERN_INFO "CNT[%d] count =0x%08x\n",
+                       cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
+               asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
+               printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
+                       cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
+       }
+}
+#endif
+
+void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+       unsigned long flags;
+
+       /*
+        * Enable counter and interrupt, and set the counter to count
+        * the event that we're interested in.
+        */
+       spin_lock_irqsave(&pmu_lock, flags);
+
+       /*
+        * Disable counter
+        */
+       armv7_pmnc_disable_counter(idx);
+
+       /*
+        * Set event (if destined for PMNx counters)
+        * We don't need to set the event if it's a cycle count
+        */
+       if (idx != ARMV7_CYCLE_COUNTER)
+               armv7_pmnc_write_evtsel(idx, hwc->config_base);
+
+       /*
+        * Enable interrupt for this counter
+        */
+       armv7_pmnc_enable_intens(idx);
+
+       /*
+        * Enable counter
+        */
+       armv7_pmnc_enable_counter(idx);
+
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+       unsigned long flags;
+
+       /*
+        * Disable counter and interrupt
+        */
+       spin_lock_irqsave(&pmu_lock, flags);
+
+       /*
+        * Disable counter
+        */
+       armv7_pmnc_disable_counter(idx);
+
+       /*
+        * Disable interrupt for this counter
+        */
+       armv7_pmnc_disable_intens(idx);
+
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
+{
+       unsigned long pmnc;
+       struct perf_sample_data data;
+       struct cpu_hw_events *cpuc;
+       struct pt_regs *regs;
+       int idx;
+
+       /*
+        * Get and reset the IRQ flags
+        */
+       pmnc = armv7_pmnc_getreset_flags();
+
+       /*
+        * Did an overflow occur?
+        */
+       if (!armv7_pmnc_has_overflowed(pmnc))
+               return IRQ_NONE;
+
+       /*
+        * Handle the counter(s) overflow(s)
+        */
+       regs = get_irq_regs();
+
+       data.addr = 0;
+
+       cpuc = &__get_cpu_var(cpu_hw_events);
+       for (idx = 0; idx <= armpmu->num_events; ++idx) {
+               struct perf_event *event = cpuc->events[idx];
+               struct hw_perf_event *hwc;
+
+               if (!test_bit(idx, cpuc->active_mask))
+                       continue;
+
+               /*
+                * We have a single interrupt for all counters. Check that
+                * each counter has overflowed before we process it.
+                */
+               if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
+                       continue;
+
+               hwc = &event->hw;
+               armpmu_event_update(event, hwc, idx);
+               data.period = event->hw.last_period;
+               if (!armpmu_event_set_period(event, hwc, idx))
+                       continue;
+
+               if (perf_event_overflow(event, 0, &data, regs))
+                       armpmu->disable(hwc, idx);
+       }
+
+       /*
+        * Handle the pending perf events.
+        *
+        * Note: this call *must* be run with interrupts enabled. For
+        * platforms that can have the PMU interrupts raised as a PMI, this
+        * will not work.
+        */
+       perf_event_do_pending();
+
+       return IRQ_HANDLED;
+}
+
+static void armv7pmu_start(void)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&pmu_lock, flags);
+       /* Enable all counters */
+       armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void armv7pmu_stop(void)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&pmu_lock, flags);
+       /* Disable all counters */
+       armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static inline int armv7_a8_pmu_event_map(int config)
+{
+       int mapping = armv7_a8_perf_map[config];
+       if (HW_OP_UNSUPPORTED == mapping)
+               mapping = -EOPNOTSUPP;
+       return mapping;
+}
+
+static inline int armv7_a9_pmu_event_map(int config)
+{
+       int mapping = armv7_a9_perf_map[config];
+       if (HW_OP_UNSUPPORTED == mapping)
+               mapping = -EOPNOTSUPP;
+       return mapping;
+}
+
+static u64 armv7pmu_raw_event(u64 config)
+{
+       return config & 0xff;
+}
+
+static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc,
+                                 struct hw_perf_event *event)
+{
+       int idx;
+
+       /* Always place a cycle counter into the cycle counter. */
+       if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) {
+               if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask))
+                       return -EAGAIN;
+
+               return ARMV7_CYCLE_COUNTER;
+       } else {
+               /*
+                * For anything other than a cycle counter, try and use
+                * the events counters
+                */
+               for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) {
+                       if (!test_and_set_bit(idx, cpuc->used_mask))
+                               return idx;
+               }
+
+               /* The counters are all in use. */
+               return -EAGAIN;
+       }
+}
+
+static struct arm_pmu armv7pmu = {
+       .handle_irq             = armv7pmu_handle_irq,
+       .enable                 = armv7pmu_enable_event,
+       .disable                = armv7pmu_disable_event,
+       .raw_event              = armv7pmu_raw_event,
+       .read_counter           = armv7pmu_read_counter,
+       .write_counter          = armv7pmu_write_counter,
+       .get_event_idx          = armv7pmu_get_event_idx,
+       .start                  = armv7pmu_start,
+       .stop                   = armv7pmu_stop,
+       .max_period             = (1LLU << 32) - 1,
+};
+
+static u32 __init armv7_reset_read_pmnc(void)
+{
+       u32 nb_cnt;
+
+       /* Initialize & Reset PMNC: C and P bits */
+       armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
+
+       /* Read the nb of CNTx counters supported from PMNC */
+       nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
+
+       /* Add the CPU cycles counter and return */
+       return nb_cnt + 1;
+}
+
+static int __init
+init_hw_perf_events(void)
+{
+       unsigned long cpuid = read_cpuid_id();
+       unsigned long implementor = (cpuid & 0xFF000000) >> 24;
+       unsigned long part_number = (cpuid & 0xFFF0);
+
+       /* We only support ARM CPUs implemented by ARM at the moment. */
+       if (0x41 == implementor) {
+               switch (part_number) {
+               case 0xB360:    /* ARM1136 */
+               case 0xB560:    /* ARM1156 */
+               case 0xB760:    /* ARM1176 */
+                       armpmu = &armv6pmu;
+                       memcpy(armpmu_perf_cache_map, armv6_perf_cache_map,
+                                       sizeof(armv6_perf_cache_map));
+                       perf_max_events = armv6pmu.num_events;
+                       break;
+               case 0xB020:    /* ARM11mpcore */
+                       armpmu = &armv6mpcore_pmu;
+                       memcpy(armpmu_perf_cache_map,
+                              armv6mpcore_perf_cache_map,
+                              sizeof(armv6mpcore_perf_cache_map));
+                       perf_max_events = armv6mpcore_pmu.num_events;
+                       break;
+               case 0xC080:    /* Cortex-A8 */
+                       armv7pmu.name = ARMV7_PMU_CORTEX_A8_NAME;
+                       memcpy(armpmu_perf_cache_map, armv7_a8_perf_cache_map,
+                               sizeof(armv7_a8_perf_cache_map));
+                       armv7pmu.event_map = armv7_a8_pmu_event_map;
+                       armpmu = &armv7pmu;
+
+                       /* Reset PMNC and read the nb of CNTx counters
+                           supported */
+                       armv7pmu.num_events = armv7_reset_read_pmnc();
+                       perf_max_events = armv7pmu.num_events;
+                       break;
+               case 0xC090:    /* Cortex-A9 */
+                       armv7pmu.name = ARMV7_PMU_CORTEX_A9_NAME;
+                       memcpy(armpmu_perf_cache_map, armv7_a9_perf_cache_map,
+                               sizeof(armv7_a9_perf_cache_map));
+                       armv7pmu.event_map = armv7_a9_pmu_event_map;
+                       armpmu = &armv7pmu;
+
+                       /* Reset PMNC and read the nb of CNTx counters
+                           supported */
+                       armv7pmu.num_events = armv7_reset_read_pmnc();
+                       perf_max_events = armv7pmu.num_events;
+                       break;
+               default:
+                       pr_info("no hardware support available\n");
+                       perf_max_events = -1;
+               }
+       }
+
+       if (armpmu)
+               pr_info("enabled with %s PMU driver, %d counters available\n",
+                       armpmu->name, armpmu->num_events);
+
+       return 0;
+}
+arch_initcall(init_hw_perf_events);
+
+/*
+ * Callchain handling code.
+ */
+static inline void
+callchain_store(struct perf_callchain_entry *entry,
+               u64 ip)
+{
+       if (entry->nr < PERF_MAX_STACK_DEPTH)
+               entry->ip[entry->nr++] = ip;
+}
+
+/*
+ * The registers we're interested in are at the end of the variable
+ * length saved register structure. The fp points at the end of this
+ * structure so the address of this struct is:
+ * (struct frame_tail *)(xxx->fp)-1
+ *
+ * This code has been adapted from the ARM OProfile support.
+ */
+struct frame_tail {
+       struct frame_tail   *fp;
+       unsigned long       sp;
+       unsigned long       lr;
+} __attribute__((packed));
+
+/*
+ * Get the return address for a single stackframe and return a pointer to the
+ * next frame tail.
+ */
+static struct frame_tail *
+user_backtrace(struct frame_tail *tail,
+              struct perf_callchain_entry *entry)
+{
+       struct frame_tail buftail;
+
+       /* Also check accessibility of one struct frame_tail beyond */
+       if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
+               return NULL;
+       if (__copy_from_user_inatomic(&buftail, tail, sizeof(buftail)))
+               return NULL;
+
+       callchain_store(entry, buftail.lr);
+
+       /*
+        * Frame pointers should strictly progress back up the stack
+        * (towards higher addresses).
+        */
+       if (tail >= buftail.fp)
+               return NULL;
+
+       return buftail.fp - 1;
+}
+
+static void
+perf_callchain_user(struct pt_regs *regs,
+                   struct perf_callchain_entry *entry)
+{
+       struct frame_tail *tail;
+
+       callchain_store(entry, PERF_CONTEXT_USER);
+
+       if (!user_mode(regs))
+               regs = task_pt_regs(current);
+
+       tail = (struct frame_tail *)regs->ARM_fp - 1;
+
+       while (tail && !((unsigned long)tail & 0x3))
+               tail = user_backtrace(tail, entry);
+}
+
+/*
+ * Gets called by walk_stackframe() for every stackframe. This will be called
+ * whist unwinding the stackframe and is like a subroutine return so we use
+ * the PC.
+ */
+static int
+callchain_trace(struct stackframe *fr,
+               void *data)
+{
+       struct perf_callchain_entry *entry = data;
+       callchain_store(entry, fr->pc);
+       return 0;
+}
+
+static void
+perf_callchain_kernel(struct pt_regs *regs,
+                     struct perf_callchain_entry *entry)
+{
+       struct stackframe fr;
+
+       callchain_store(entry, PERF_CONTEXT_KERNEL);
+       fr.fp = regs->ARM_fp;
+       fr.sp = regs->ARM_sp;
+       fr.lr = regs->ARM_lr;
+       fr.pc = regs->ARM_pc;
+       walk_stackframe(&fr, callchain_trace, entry);
+}
+
+static void
+perf_do_callchain(struct pt_regs *regs,
+                 struct perf_callchain_entry *entry)
+{
+       int is_user;
+
+       if (!regs)
+               return;
+
+       is_user = user_mode(regs);
+
+       if (!current || !current->pid)
+               return;
+
+       if (is_user && current->state != TASK_RUNNING)
+               return;
+
+       if (!is_user)
+               perf_callchain_kernel(regs, entry);
+
+       if (current->mm)
+               perf_callchain_user(regs, entry);
+}
+
+static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry);
+
+struct perf_callchain_entry *
+perf_callchain(struct pt_regs *regs)
+{
+       struct perf_callchain_entry *entry = &__get_cpu_var(pmc_irq_entry);
+
+       entry->nr = 0;
+       perf_do_callchain(regs, entry);
+       return entry;
+}
diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c
new file mode 100644 (file)
index 0000000..a124312
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ *  linux/arch/arm/kernel/pmu.c
+ *
+ *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
+ *
+ * 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/cpumask.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/pmu.h>
+
+/*
+ * Define the IRQs for the system. We could use something like a platform
+ * device but that seems fairly heavyweight for this. Also, the performance
+ * counters can't be removed or hotplugged.
+ *
+ * Ordering is important: init_pmu() will use the ordering to set the affinity
+ * to the corresponding core. e.g. the first interrupt will go to cpu 0, the
+ * second goes to cpu 1 etc.
+ */
+static const int irqs[] = {
+#if defined(CONFIG_ARCH_OMAP2)
+       3,
+#elif defined(CONFIG_ARCH_BCMRING)
+       IRQ_PMUIRQ,
+#elif defined(CONFIG_MACH_REALVIEW_EB)
+       IRQ_EB11MP_PMU_CPU0,
+       IRQ_EB11MP_PMU_CPU1,
+       IRQ_EB11MP_PMU_CPU2,
+       IRQ_EB11MP_PMU_CPU3,
+#elif defined(CONFIG_ARCH_OMAP3)
+       INT_34XX_BENCH_MPU_EMUL,
+#elif defined(CONFIG_ARCH_IOP32X)
+       IRQ_IOP32X_CORE_PMU,
+#elif defined(CONFIG_ARCH_IOP33X)
+       IRQ_IOP33X_CORE_PMU,
+#elif defined(CONFIG_ARCH_PXA)
+       IRQ_PMU,
+#endif
+};
+
+static const struct pmu_irqs pmu_irqs = {
+       .irqs       = irqs,
+       .num_irqs   = ARRAY_SIZE(irqs),
+};
+
+static volatile long pmu_lock;
+
+const struct pmu_irqs *
+reserve_pmu(void)
+{
+       return test_and_set_bit_lock(0, &pmu_lock) ? ERR_PTR(-EBUSY) :
+               &pmu_irqs;
+}
+EXPORT_SYMBOL_GPL(reserve_pmu);
+
+int
+release_pmu(const struct pmu_irqs *irqs)
+{
+       if (WARN_ON(irqs != &pmu_irqs))
+               return -EINVAL;
+       clear_bit_unlock(0, &pmu_lock);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(release_pmu);
+
+static int
+set_irq_affinity(int irq,
+                unsigned int cpu)
+{
+#ifdef CONFIG_SMP
+       int err = irq_set_affinity(irq, cpumask_of(cpu));
+       if (err)
+               pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
+                          irq, cpu);
+       return err;
+#else
+       return 0;
+#endif
+}
+
+int
+init_pmu(void)
+{
+       int i, err = 0;
+
+       for (i = 0; i < pmu_irqs.num_irqs; ++i) {
+               err = set_irq_affinity(pmu_irqs.irqs[i], i);
+               if (err)
+                       break;
+       }
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(init_pmu);
index a2ea3854cb3c8379120abaa94ab6c47fdc91ad67..08f899fb76a69d0ab48026950642fb8e733e4d92 100644 (file)
@@ -499,10 +499,41 @@ static struct undef_hook thumb_break_hook = {
        .fn             = break_trap,
 };
 
+static int thumb2_break_trap(struct pt_regs *regs, unsigned int instr)
+{
+       unsigned int instr2;
+       void __user *pc;
+
+       /* Check the second half of the instruction.  */
+       pc = (void __user *)(instruction_pointer(regs) + 2);
+
+       if (processor_mode(regs) == SVC_MODE) {
+               instr2 = *(u16 *) pc;
+       } else {
+               get_user(instr2, (u16 __user *)pc);
+       }
+
+       if (instr2 == 0xa000) {
+               ptrace_break(current, regs);
+               return 0;
+       } else {
+               return 1;
+       }
+}
+
+static struct undef_hook thumb2_break_hook = {
+       .instr_mask     = 0xffff,
+       .instr_val      = 0xf7f0,
+       .cpsr_mask      = PSR_T_BIT,
+       .cpsr_val       = PSR_T_BIT,
+       .fn             = thumb2_break_trap,
+};
+
 static int __init ptrace_break_init(void)
 {
        register_undef_hook(&arm_break_hook);
        register_undef_hook(&thumb_break_hook);
+       register_undef_hook(&thumb2_break_hook);
        return 0;
 }
 
@@ -669,7 +700,7 @@ static int ptrace_getvfpregs(struct task_struct *tsk, void __user *data)
        union vfp_state *vfp = &thread->vfpstate;
        struct user_vfp __user *ufp = data;
 
-       vfp_sync_state(thread);
+       vfp_sync_hwstate(thread);
 
        /* copy the floating point registers */
        if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs,
@@ -692,7 +723,7 @@ static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data)
        union vfp_state *vfp = &thread->vfpstate;
        struct user_vfp __user *ufp = data;
 
-       vfp_sync_state(thread);
+       vfp_sync_hwstate(thread);
 
        /* copy the floating point registers */
        if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs,
@@ -703,6 +734,8 @@ static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data)
        if (get_user(vfp->hard.fpscr, &ufp->fpscr))
                return -EFAULT;
 
+       vfp_flush_hwstate(thread);
+
        return 0;
 }
 #endif
@@ -712,26 +745,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
        int ret;
 
        switch (request) {
-               /*
-                * read word at location "addr" in the child process.
-                */
-               case PTRACE_PEEKTEXT:
-               case PTRACE_PEEKDATA:
-                       ret = generic_ptrace_peekdata(child, addr, data);
-                       break;
-
                case PTRACE_PEEKUSR:
                        ret = ptrace_read_user(child, addr, (unsigned long __user *)data);
                        break;
 
-               /*
-                * write the word at location addr.
-                */
-               case PTRACE_POKETEXT:
-               case PTRACE_POKEDATA:
-                       ret = generic_ptrace_pokedata(child, addr, data);
-                       break;
-
                case PTRACE_POKEUSR:
                        ret = ptrace_write_user(child, addr, data);
                        break;
index 621acad8ea43c274b948c275c9de46177a42542e..c91c77b54dea151be9e04bee8355d0d78d3b1445 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/smp.h>
 #include <linux/fs.h>
+#include <linux/proc_fs.h>
 
 #include <asm/unified.h>
 #include <asm/cpu.h>
@@ -118,7 +119,7 @@ EXPORT_SYMBOL(elf_platform);
 
 static const char *cpu_name;
 static const char *machine_name;
-static char __initdata command_line[COMMAND_LINE_SIZE];
+static char __initdata cmd_line[COMMAND_LINE_SIZE];
 
 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
 static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
@@ -418,10 +419,11 @@ static int __init arm_add_memory(unsigned long start, unsigned long size)
  * Pick out the memory size.  We look for mem=size@start,
  * where start and size are "size[KkMm]"
  */
-static void __init early_mem(char **p)
+static int __init early_mem(char *p)
 {
        static int usermem __initdata = 0;
        unsigned long size, start;
+       char *endp;
 
        /*
         * If the user specifies memory size, we
@@ -434,52 +436,15 @@ static void __init early_mem(char **p)
        }
 
        start = PHYS_OFFSET;
-       size  = memparse(*p, p);
-       if (**p == '@')
-               start = memparse(*p + 1, p);
+       size  = memparse(p, &endp);
+       if (*endp == '@')
+               start = memparse(endp + 1, NULL);
 
        arm_add_memory(start, size);
-}
-__early_param("mem=", early_mem);
 
-/*
- * Initial parsing of the command line.
- */
-static void __init parse_cmdline(char **cmdline_p, char *from)
-{
-       char c = ' ', *to = command_line;
-       int len = 0;
-
-       for (;;) {
-               if (c == ' ') {
-                       extern struct early_params __early_begin, __early_end;
-                       struct early_params *p;
-
-                       for (p = &__early_begin; p < &__early_end; p++) {
-                               int arglen = strlen(p->arg);
-
-                               if (memcmp(from, p->arg, arglen) == 0) {
-                                       if (to != command_line)
-                                               to -= 1;
-                                       from += arglen;
-                                       p->fn(&from);
-
-                                       while (*from != ' ' && *from != '\0')
-                                               from++;
-                                       break;
-                               }
-                       }
-               }
-               c = *from++;
-               if (!c)
-                       break;
-               if (COMMAND_LINE_SIZE <= ++len)
-                       break;
-               *to++ = c;
-       }
-       *to = '\0';
-       *cmdline_p = command_line;
+       return 0;
 }
+early_param("mem", early_mem);
 
 static void __init
 setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
@@ -740,9 +705,15 @@ void __init setup_arch(char **cmdline_p)
        init_mm.end_data   = (unsigned long) _edata;
        init_mm.brk        = (unsigned long) _end;
 
-       memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
-       boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
-       parse_cmdline(cmdline_p, from);
+       /* parse_early_param needs a boot_command_line */
+       strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
+
+       /* populate cmd_line too for later use, preserving boot_command_line */
+       strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
+       *cmdline_p = cmd_line;
+
+       parse_early_param();
+
        paging_init(mdesc);
        request_standard_resources(&meminfo, mdesc);
 
@@ -783,9 +754,21 @@ static int __init topology_init(void)
 
        return 0;
 }
-
 subsys_initcall(topology_init);
 
+#ifdef CONFIG_HAVE_PROC_CPU
+static int __init proc_cpu_init(void)
+{
+       struct proc_dir_entry *res;
+
+       res = proc_mkdir("cpu", NULL);
+       if (!res)
+               return -ENOMEM;
+       return 0;
+}
+fs_initcall(proc_cpu_init);
+#endif
+
 static const char *hwcap_str[] = {
        "swp",
        "half",
index d38cdf2c8276e6e23c769b9cf494dad5ff803d1f..28753805d2d16f7cffa9fd25b4164011432b014b 100644 (file)
  *
  *  This file contains the ARM-specific time handling details:
  *  reading the RTC at bootup, etc...
- *
- *  1994-07-02  Alan Modra
- *              fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
- *  1998-12-20  Updated NTP code according to technical memorandum Jan '96
- *              "A Kernel Model for Precision Timekeeping" by Dave Mills
  */
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -77,11 +72,6 @@ unsigned long profile_pc(struct pt_regs *regs)
 EXPORT_SYMBOL(profile_pc);
 #endif
 
-/*
- * hook for setting the RTC's idea of the current time.
- */
-int (*set_rtc)(void);
-
 #ifndef CONFIG_GENERIC_TIME
 static unsigned long dummy_gettimeoffset(void)
 {
@@ -89,140 +79,6 @@ static unsigned long dummy_gettimeoffset(void)
 }
 #endif
 
-static unsigned long next_rtc_update;
-
-/*
- * If we have an externally synchronized linux clock, then update
- * CMOS clock accordingly every ~11 minutes.  set_rtc() has to be
- * called as close as possible to 500 ms before the new second
- * starts.
- */
-static inline void do_set_rtc(void)
-{
-       if (!ntp_synced() || set_rtc == NULL)
-               return;
-
-       if (next_rtc_update &&
-           time_before((unsigned long)xtime.tv_sec, next_rtc_update))
-               return;
-
-       if (xtime.tv_nsec < 500000000 - ((unsigned) tick_nsec >> 1) &&
-           xtime.tv_nsec >= 500000000 + ((unsigned) tick_nsec >> 1))
-               return;
-
-       if (set_rtc())
-               /*
-                * rtc update failed.  Try again in 60s
-                */
-               next_rtc_update = xtime.tv_sec + 60;
-       else
-               next_rtc_update = xtime.tv_sec + 660;
-}
-
-#ifdef CONFIG_LEDS
-
-static void dummy_leds_event(led_event_t evt)
-{
-}
-
-void (*leds_event)(led_event_t) = dummy_leds_event;
-
-struct leds_evt_name {
-       const char      name[8];
-       int             on;
-       int             off;
-};
-
-static const struct leds_evt_name evt_names[] = {
-       { "amber", led_amber_on, led_amber_off },
-       { "blue",  led_blue_on,  led_blue_off  },
-       { "green", led_green_on, led_green_off },
-       { "red",   led_red_on,   led_red_off   },
-};
-
-static ssize_t leds_store(struct sys_device *dev,
-                       struct sysdev_attribute *attr,
-                       const char *buf, size_t size)
-{
-       int ret = -EINVAL, len = strcspn(buf, " ");
-
-       if (len > 0 && buf[len] == '\0')
-               len--;
-
-       if (strncmp(buf, "claim", len) == 0) {
-               leds_event(led_claim);
-               ret = size;
-       } else if (strncmp(buf, "release", len) == 0) {
-               leds_event(led_release);
-               ret = size;
-       } else {
-               int i;
-
-               for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
-                       if (strlen(evt_names[i].name) != len ||
-                           strncmp(buf, evt_names[i].name, len) != 0)
-                               continue;
-                       if (strncmp(buf+len, " on", 3) == 0) {
-                               leds_event(evt_names[i].on);
-                               ret = size;
-                       } else if (strncmp(buf+len, " off", 4) == 0) {
-                               leds_event(evt_names[i].off);
-                               ret = size;
-                       }
-                       break;
-               }
-       }
-       return ret;
-}
-
-static SYSDEV_ATTR(event, 0200, NULL, leds_store);
-
-static int leds_suspend(struct sys_device *dev, pm_message_t state)
-{
-       leds_event(led_stop);
-       return 0;
-}
-
-static int leds_resume(struct sys_device *dev)
-{
-       leds_event(led_start);
-       return 0;
-}
-
-static int leds_shutdown(struct sys_device *dev)
-{
-       leds_event(led_halted);
-       return 0;
-}
-
-static struct sysdev_class leds_sysclass = {
-       .name           = "leds",
-       .shutdown       = leds_shutdown,
-       .suspend        = leds_suspend,
-       .resume         = leds_resume,
-};
-
-static struct sys_device leds_device = {
-       .id             = 0,
-       .cls            = &leds_sysclass,
-};
-
-static int __init leds_init(void)
-{
-       int ret;
-       ret = sysdev_class_register(&leds_sysclass);
-       if (ret == 0)
-               ret = sysdev_register(&leds_device);
-       if (ret == 0)
-               ret = sysdev_create_file(&leds_device, &attr_event);
-       return ret;
-}
-
-device_initcall(leds_init);
-
-EXPORT_SYMBOL(leds_event);
-#endif
-
 #ifdef CONFIG_LEDS_TIMER
 static inline void do_leds(void)
 {
@@ -295,39 +151,6 @@ int do_settimeofday(struct timespec *tv)
 EXPORT_SYMBOL(do_settimeofday);
 #endif /* !CONFIG_GENERIC_TIME */
 
-/**
- * save_time_delta - Save the offset between system time and RTC time
- * @delta: pointer to timespec to store delta
- * @rtc: pointer to timespec for current RTC time
- *
- * Return a delta between the system time and the RTC time, such
- * that system time can be restored later with restore_time_delta()
- */
-void save_time_delta(struct timespec *delta, struct timespec *rtc)
-{
-       set_normalized_timespec(delta,
-                               xtime.tv_sec - rtc->tv_sec,
-                               xtime.tv_nsec - rtc->tv_nsec);
-}
-EXPORT_SYMBOL(save_time_delta);
-
-/**
- * restore_time_delta - Restore the current system time
- * @delta: delta returned by save_time_delta()
- * @rtc: pointer to timespec for current RTC time
- */
-void restore_time_delta(struct timespec *delta, struct timespec *rtc)
-{
-       struct timespec ts;
-
-       set_normalized_timespec(&ts,
-                               delta->tv_sec + rtc->tv_sec,
-                               delta->tv_nsec + rtc->tv_nsec);
-
-       do_settimeofday(&ts);
-}
-EXPORT_SYMBOL(restore_time_delta);
-
 #ifndef CONFIG_GENERIC_CLOCKEVENTS
 /*
  * Kernel system timer support.
@@ -336,7 +159,6 @@ void timer_tick(void)
 {
        profile_tick(CPU_PROFILING);
        do_leds();
-       do_set_rtc();
        write_seqlock(&xtime_lock);
        do_timer(1);
        write_sequnlock(&xtime_lock);
index 3f361a783f43a6b9bea075e035e5405649b185dd..1621e5327b2a72a6c9197e95615928e749aa5f41 100644 (file)
  *  'linux/arch/arm/lib/traps.S'.  Mostly a debugging aid, but will probably
  *  kill the offending process.
  */
-#include <linux/module.h>
 #include <linux/signal.h>
-#include <linux/spinlock.h>
 #include <linux/personality.h>
 #include <linux/kallsyms.h>
-#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
 #include <linux/hardirq.h>
+#include <linux/kdebug.h>
+#include <linux/module.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
 #include <linux/init.h>
-#include <linux/uaccess.h>
 
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
@@ -224,14 +226,21 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
 #define S_SMP ""
 #endif
 
-static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
+static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
 {
        struct task_struct *tsk = thread->task;
        static int die_counter;
+       int ret;
 
        printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
               str, err, ++die_counter);
        sysfs_printk_last_file();
+
+       /* trap and error numbers are mostly meaningless on ARM */
+       ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
+       if (ret == NOTIFY_STOP)
+               return ret;
+
        print_modules();
        __show_regs(regs);
        printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
@@ -243,6 +252,8 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p
                dump_backtrace(regs, tsk);
                dump_instr(KERN_EMERG, regs);
        }
+
+       return ret;
 }
 
 DEFINE_SPINLOCK(die_lock);
@@ -250,16 +261,21 @@ DEFINE_SPINLOCK(die_lock);
 /*
  * This function is protected against re-entrancy.
  */
-NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
+void die(const char *str, struct pt_regs *regs, int err)
 {
        struct thread_info *thread = current_thread_info();
+       int ret;
 
        oops_enter();
 
        spin_lock_irq(&die_lock);
        console_verbose();
        bust_spinlocks(1);
-       __die(str, err, thread, regs);
+       ret = __die(str, err, thread, regs);
+
+       if (regs && kexec_should_crash(thread->task))
+               crash_kexec(regs);
+
        bust_spinlocks(0);
        add_taint(TAINT_DIE);
        spin_unlock_irq(&die_lock);
@@ -267,11 +283,10 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
 
        if (in_interrupt())
                panic("Fatal exception in interrupt");
-
        if (panic_on_oops)
                panic("Fatal exception");
-
-       do_exit(SIGSEGV);
+       if (ret != NOTIFY_STOP)
+               do_exit(SIGSEGV);
 }
 
 void arm_notify_die(const char *str, struct pt_regs *regs,
index 4957e13ef55ba6be1d396f5dc72d3eebb2b43450..b16c07914b55bb0215592a7727e0974b62108dd6 100644 (file)
@@ -43,10 +43,6 @@ SECTIONS
 
                INIT_SETUP(16)
 
-               __early_begin = .;
-                       *(.early_param.init)
-               __early_end = .;
-
                INIT_CALLS
                CON_INITCALL
                SECURITY_INITCALL
index 0b6351d7c38973e7431c601e291afab173d54551..a9cac368bfe69f184c85ce7058ec29cfe10c83a2 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "hardware.h"
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0x80000000                @ physical
index 0b2ee953f1641d75d4d0fc9ddcc655758a9b02df..2db43a5ddd9b7b752b054ded6ff3c32f2c6c3de7 100644 (file)
@@ -89,6 +89,12 @@ config ARCH_AT91CAP9
        select GENERIC_CLOCKEVENTS
        select HAVE_FB_ATMEL
 
+config ARCH_AT572D940HF
+       bool "AT572D940HF"
+       select CPU_ARM926T
+       select GENERIC_TIME
+       select GENERIC_CLOCKEVENTS
+
 config ARCH_AT91X40
        bool "AT91x40"
 
@@ -390,6 +396,23 @@ endif
 
 # ----------------------------------------------------------
 
+if ARCH_AT572D940HF
+
+comment "AT572D940HF Board Type"
+
+config MACH_AT572D940HFEB
+       bool "AT572D940HF-EK"
+       depends on ARCH_AT572D940HF
+       select HAVE_AT91_DATAFLASH_CARD
+       select HAVE_NAND_ATMEL_BUSWIDTH_16
+       help
+         Select this if you are using Atmel's AT572D940HF-EK evaluation kit.
+         <http://www.atmel.com/products/diopsis/default.asp>
+
+endif
+
+# ----------------------------------------------------------
+
 if ARCH_AT91X40
 
 comment "AT91X40 Board Type"
index 709fbad4a3ee2b28b14ec7fd0281dc4382702c76..027dd570dcc30231059d3530f5a33293f168dce7 100644 (file)
@@ -19,6 +19,7 @@ obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devi
 obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o  sam9_smc.o
  obj-$(CONFIG_ARCH_AT91SAM9G45)        += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91CAP9)    += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT572D940HF)  += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91X40)     += at91x40.o at91x40_time.o
 
 # AT91RM9200 board-specific support
@@ -69,6 +70,9 @@ obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
 # AT91CAP9 board-specific support
 obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
 
+# AT572D940HF board-specific support
+obj-$(CONFIG_MACH_AT572D940HFEB) += board-at572d940hf_ek.o
+
 # AT91X40 board-specific support
 obj-$(CONFIG_MACH_AT91EB01)    += board-eb01.o
 
diff --git a/arch/arm/mach-at91/at572d940hf.c b/arch/arm/mach-at91/at572d940hf.c
new file mode 100644 (file)
index 0000000..a6b9c68
--- /dev/null
@@ -0,0 +1,377 @@
+/*
+ * arch/arm/mach-at91/at572d940hf.c
+ *
+ * Antonio R. Costa <costa.antonior@gmail.com>
+ * Copyright (C) 2008 Atmel
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * 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/module.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/at572d940hf.h>
+#include <mach/at91_pmc.h>
+#include <mach/at91_rstc.h>
+
+#include "generic.h"
+#include "clock.h"
+
+static struct map_desc at572d940hf_io_desc[] __initdata = {
+       {
+               .virtual        = AT91_VA_BASE_SYS,
+               .pfn            = __phys_to_pfn(AT91_BASE_SYS),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = AT91_IO_VIRT_BASE - AT572D940HF_SRAM_SIZE,
+               .pfn            = __phys_to_pfn(AT572D940HF_SRAM_BASE),
+               .length         = AT572D940HF_SRAM_SIZE,
+               .type           = MT_DEVICE,
+       },
+};
+
+/* --------------------------------------------------------------------
+ *  Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk pioA_clk = {
+       .name           = "pioA_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_PIOA,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioB_clk = {
+       .name           = "pioB_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_PIOB,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioC_clk = {
+       .name           = "pioC_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_PIOC,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk macb_clk = {
+       .name           = "macb_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_EMAC,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+       .name           = "usart0_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_US0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+       .name           = "usart1_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_US1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+       .name           = "usart2_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_US2,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc_clk = {
+       .name           = "mci_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_MCI,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk udc_clk = {
+       .name           = "udc_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_UDP,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi0_clk = {
+       .name           = "twi0_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_TWI0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi0_clk = {
+       .name           = "spi0_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_SPI0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi1_clk = {
+       .name           = "spi1_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_SPI1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc0_clk = {
+       .name           = "ssc0_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_SSC0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+       .name           = "ssc1_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_SSC1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc2_clk = {
+       .name           = "ssc2_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_SSC2,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc0_clk = {
+       .name           = "tc0_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_TC0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc1_clk = {
+       .name           = "tc1_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_TC1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc2_clk = {
+       .name           = "tc2_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_TC2,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ohci_clk = {
+       .name           = "ohci_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_UHP,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc3_clk = {
+       .name           = "ssc3_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_SSC3,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi1_clk = {
+       .name           = "twi1_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_TWI1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk can0_clk = {
+       .name           = "can0_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_CAN0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk can1_clk = {
+       .name           = "can1_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_CAN1,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mAgicV_clk = {
+       .name           = "mAgicV_clk",
+       .pmc_mask       = 1 << AT572D940HF_ID_MSIRQ0,
+       .type           = CLK_TYPE_PERIPHERAL,
+};
+
+
+static struct clk *periph_clocks[] __initdata = {
+       &pioA_clk,
+       &pioB_clk,
+       &pioC_clk,
+       &macb_clk,
+       &usart0_clk,
+       &usart1_clk,
+       &usart2_clk,
+       &mmc_clk,
+       &udc_clk,
+       &twi0_clk,
+       &spi0_clk,
+       &spi1_clk,
+       &ssc0_clk,
+       &ssc1_clk,
+       &ssc2_clk,
+       &tc0_clk,
+       &tc1_clk,
+       &tc2_clk,
+       &ohci_clk,
+       &ssc3_clk,
+       &twi1_clk,
+       &can0_clk,
+       &can1_clk,
+       &mAgicV_clk,
+       /* irq0 .. irq2 */
+};
+
+/*
+ * The five programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+       .name           = "pck0",
+       .pmc_mask       = AT91_PMC_PCK0,
+       .type           = CLK_TYPE_PROGRAMMABLE,
+       .id             = 0,
+};
+static struct clk pck1 = {
+       .name           = "pck1",
+       .pmc_mask       = AT91_PMC_PCK1,
+       .type           = CLK_TYPE_PROGRAMMABLE,
+       .id             = 1,
+};
+static struct clk pck2 = {
+       .name           = "pck2",
+       .pmc_mask       = AT91_PMC_PCK2,
+       .type           = CLK_TYPE_PROGRAMMABLE,
+       .id             = 2,
+};
+static struct clk pck3 = {
+       .name           = "pck3",
+       .pmc_mask       = AT91_PMC_PCK3,
+       .type           = CLK_TYPE_PROGRAMMABLE,
+       .id             = 3,
+};
+
+static struct clk mAgicV_mem_clk = {
+       .name           = "mAgicV_mem_clk",
+       .pmc_mask       = AT91_PMC_PCK4,
+       .type           = CLK_TYPE_PROGRAMMABLE,
+       .id             = 4,
+};
+
+/* HClocks */
+static struct clk hck0 = {
+       .name           = "hck0",
+       .pmc_mask       = AT91_PMC_HCK0,
+       .type           = CLK_TYPE_SYSTEM,
+       .id             = 0,
+};
+static struct clk hck1 = {
+       .name           = "hck1",
+       .pmc_mask       = AT91_PMC_HCK1,
+       .type           = CLK_TYPE_SYSTEM,
+       .id             = 1,
+};
+
+static void __init at572d940hf_register_clocks(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+               clk_register(periph_clocks[i]);
+
+       clk_register(&pck0);
+       clk_register(&pck1);
+       clk_register(&pck2);
+       clk_register(&pck3);
+       clk_register(&mAgicV_mem_clk);
+
+       clk_register(&hck0);
+       clk_register(&hck1);
+}
+
+/* --------------------------------------------------------------------
+ *  GPIO
+ * -------------------------------------------------------------------- */
+
+static struct at91_gpio_bank at572d940hf_gpio[] = {
+       {
+               .id             = AT572D940HF_ID_PIOA,
+               .offset         = AT91_PIOA,
+               .clock          = &pioA_clk,
+       }, {
+               .id             = AT572D940HF_ID_PIOB,
+               .offset         = AT91_PIOB,
+               .clock          = &pioB_clk,
+       }, {
+               .id             = AT572D940HF_ID_PIOC,
+               .offset         = AT91_PIOC,
+               .clock          = &pioC_clk,
+       }
+};
+
+static void at572d940hf_reset(void)
+{
+       at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
+}
+
+
+/* --------------------------------------------------------------------
+ *  AT572D940HF processor initialization
+ * -------------------------------------------------------------------- */
+
+void __init at572d940hf_initialize(unsigned long main_clock)
+{
+       /* Map peripherals */
+       iotable_init(at572d940hf_io_desc, ARRAY_SIZE(at572d940hf_io_desc));
+
+       at91_arch_reset = at572d940hf_reset;
+       at91_extern_irq = (1 << AT572D940HF_ID_IRQ0) | (1 << AT572D940HF_ID_IRQ1)
+                       | (1 << AT572D940HF_ID_IRQ2);
+
+       /* Init clock subsystem */
+       at91_clock_init(main_clock);
+
+       /* Register the processor-specific clocks */
+       at572d940hf_register_clocks();
+
+       /* Register GPIO subsystem */
+       at91_gpio_init(at572d940hf_gpio, 3);
+}
+
+/* --------------------------------------------------------------------
+ *  Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at572d940hf_default_irq_priority[NR_AIC_IRQS] __initdata = {
+       7,      /* Advanced Interrupt Controller */
+       7,      /* System Peripherals */
+       0,      /* Parallel IO Controller A */
+       0,      /* Parallel IO Controller B */
+       0,      /* Parallel IO Controller C */
+       3,      /* Ethernet */
+       6,      /* USART 0 */
+       6,      /* USART 1 */
+       6,      /* USART 2 */
+       0,      /* Multimedia Card Interface */
+       4,      /* USB Device Port */
+       0,      /* Two-Wire Interface 0 */
+       6,      /* Serial Peripheral Interface 0 */
+       6,      /* Serial Peripheral Interface 1 */
+       5,      /* Serial Synchronous Controller 0 */
+       5,      /* Serial Synchronous Controller 1 */
+       5,      /* Serial Synchronous Controller 2 */
+       0,      /* Timer Counter 0 */
+       0,      /* Timer Counter 1 */
+       0,      /* Timer Counter 2 */
+       3,      /* USB Host port */
+       3,      /* Serial Synchronous Controller 3 */
+       0,      /* Two-Wire Interface 1 */
+       0,      /* CAN Controller 0 */
+       0,      /* CAN Controller 1 */
+       0,      /* mAgicV HALT line */
+       0,      /* mAgicV SIRQ0 line */
+       0,      /* mAgicV exception line */
+       0,      /* mAgicV end of DMA line */
+       0,      /* Advanced Interrupt Controller */
+       0,      /* Advanced Interrupt Controller */
+       0,      /* Advanced Interrupt Controller */
+};
+
+void __init at572d940hf_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+       if (!priority)
+               priority = at572d940hf_default_irq_priority;
+
+       /* Initialize the AIC interrupt controller */
+       at91_aic_init(priority);
+
+       /* Enable GPIO interrupts */
+       at91_gpio_irq_setup();
+}
+
diff --git a/arch/arm/mach-at91/at572d940hf_devices.c b/arch/arm/mach-at91/at572d940hf_devices.c
new file mode 100644 (file)
index 0000000..0fc20a2
--- /dev/null
@@ -0,0 +1,970 @@
+/*
+ * arch/arm/mach-at91/at572d940hf_devices.c
+ *
+ * Copyright (C) 2008 Atmel Antonio R. Costa <costa.antonior@gmail.com>
+ * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ * Copyright (C) 2005 David Brownell
+ *
+ * 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 <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at572d940hf.h>
+#include <mach/at572d940hf_matrix.h>
+#include <mach/at91sam9_smc.h>
+
+#include "generic.h"
+#include "sam9_smc.h"
+
+
+/* --------------------------------------------------------------------
+ *  USB Host
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_data;
+
+static struct resource usbh_resources[] = {
+       [0] = {
+               .start  = AT572D940HF_UHP_BASE,
+               .end    = AT572D940HF_UHP_BASE + SZ_1M - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT572D940HF_ID_UHP,
+               .end    = AT572D940HF_ID_UHP,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at572d940hf_usbh_device = {
+       .name           = "at91_ohci",
+       .id             = -1,
+       .dev            = {
+                               .dma_mask               = &ohci_dmamask,
+                               .coherent_dma_mask      = DMA_BIT_MASK(32),
+                               .platform_data          = &usbh_data,
+       },
+       .resource       = usbh_resources,
+       .num_resources  = ARRAY_SIZE(usbh_resources),
+};
+
+void __init at91_add_device_usbh(struct at91_usbh_data *data)
+{
+       if (!data)
+               return;
+
+       usbh_data = *data;
+       platform_device_register(&at572d940hf_usbh_device);
+
+}
+#else
+void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  USB Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_USB_GADGET_AT91
+static struct at91_udc_data udc_data;
+
+static struct resource udc_resources[] = {
+       [0] = {
+               .start  = AT572D940HF_BASE_UDP,
+               .end    = AT572D940HF_BASE_UDP + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT572D940HF_ID_UDP,
+               .end    = AT572D940HF_ID_UDP,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at572d940hf_udc_device = {
+       .name           = "at91_udc",
+       .id             = -1,
+       .dev            = {
+                               .platform_data          = &udc_data,
+       },
+       .resource       = udc_resources,
+       .num_resources  = ARRAY_SIZE(udc_resources),
+};
+
+void __init at91_add_device_udc(struct at91_udc_data *data)
+{
+       if (!data)
+               return;
+
+       if (data->vbus_pin) {
+               at91_set_gpio_input(data->vbus_pin, 0);
+               at91_set_deglitch(data->vbus_pin, 1);
+       }
+
+       /* Pullup pin is handled internally */
+
+       udc_data = *data;
+       platform_device_register(&at572d940hf_udc_device);
+}
+#else
+void __init at91_add_device_udc(struct at91_udc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  Ethernet
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
+static u64 eth_dmamask = DMA_BIT_MASK(32);
+static struct at91_eth_data eth_data;
+
+static struct resource eth_resources[] = {
+       [0] = {
+               .start  = AT572D940HF_BASE_EMAC,
+               .end    = AT572D940HF_BASE_EMAC + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT572D940HF_ID_EMAC,
+               .end    = AT572D940HF_ID_EMAC,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at572d940hf_eth_device = {
+       .name           = "macb",
+       .id             = -1,
+       .dev            = {
+                       .dma_mask               = &eth_dmamask,
+                       .coherent_dma_mask      = DMA_BIT_MASK(32),
+                       .platform_data          = &eth_data,
+       },
+       .resource       = eth_resources,
+       .num_resources  = ARRAY_SIZE(eth_resources),
+};
+
+void __init at91_add_device_eth(struct at91_eth_data *data)
+{
+       if (!data)
+               return;
+
+       if (data->phy_irq_pin) {
+               at91_set_gpio_input(data->phy_irq_pin, 0);
+               at91_set_deglitch(data->phy_irq_pin, 1);
+       }
+
+       /* Only RMII is supported */
+       data->is_rmii = 1;
+
+       /* Pins used for RMII */
+       at91_set_A_periph(AT91_PIN_PA16, 0);    /* ETXCK_EREFCK */
+       at91_set_A_periph(AT91_PIN_PA17, 0);    /* ERXDV */
+       at91_set_A_periph(AT91_PIN_PA18, 0);    /* ERX0 */
+       at91_set_A_periph(AT91_PIN_PA19, 0);    /* ERX1 */
+       at91_set_A_periph(AT91_PIN_PA20, 0);    /* ERXER */
+       at91_set_A_periph(AT91_PIN_PA23, 0);    /* ETXEN */
+       at91_set_A_periph(AT91_PIN_PA21, 0);    /* ETX0 */
+       at91_set_A_periph(AT91_PIN_PA22, 0);    /* ETX1 */
+       at91_set_A_periph(AT91_PIN_PA13, 0);    /* EMDIO */
+       at91_set_A_periph(AT91_PIN_PA14, 0);    /* EMDC */
+
+       eth_data = *data;
+       platform_device_register(&at572d940hf_eth_device);
+}
+#else
+void __init at91_add_device_eth(struct at91_eth_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  MMC / SD
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct at91_mmc_data mmc_data;
+
+static struct resource mmc_resources[] = {
+       [0] = {
+               .start  = AT572D940HF_BASE_MCI,
+               .end    = AT572D940HF_BASE_MCI + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT572D940HF_ID_MCI,
+               .end    = AT572D940HF_ID_MCI,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at572d940hf_mmc_device = {
+       .name           = "at91_mci",
+       .id             = -1,
+       .dev            = {
+                               .dma_mask               = &mmc_dmamask,
+                               .coherent_dma_mask      = DMA_BIT_MASK(32),
+                               .platform_data          = &mmc_data,
+       },
+       .resource       = mmc_resources,
+       .num_resources  = ARRAY_SIZE(mmc_resources),
+};
+
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
+{
+       if (!data)
+               return;
+
+       /* input/irq */
+       if (data->det_pin) {
+               at91_set_gpio_input(data->det_pin, 1);
+               at91_set_deglitch(data->det_pin, 1);
+       }
+       if (data->wp_pin)
+               at91_set_gpio_input(data->wp_pin, 1);
+       if (data->vcc_pin)
+               at91_set_gpio_output(data->vcc_pin, 0);
+
+       /* CLK */
+       at91_set_A_periph(AT91_PIN_PC22, 0);
+
+       /* CMD */
+       at91_set_A_periph(AT91_PIN_PC23, 1);
+
+       /* DAT0, maybe DAT1..DAT3 */
+       at91_set_A_periph(AT91_PIN_PC24, 1);
+       if (data->wire4) {
+               at91_set_A_periph(AT91_PIN_PC25, 1);
+               at91_set_A_periph(AT91_PIN_PC26, 1);
+               at91_set_A_periph(AT91_PIN_PC27, 1);
+       }
+
+       mmc_data = *data;
+       platform_device_register(&at572d940hf_mmc_device);
+}
+#else
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  NAND / SmartMedia
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
+static struct atmel_nand_data nand_data;
+
+#define NAND_BASE      AT91_CHIPSELECT_3
+
+static struct resource nand_resources[] = {
+       {
+               .start  = NAND_BASE,
+               .end    = NAND_BASE + SZ_256M - 1,
+               .flags  = IORESOURCE_MEM,
+       }
+};
+
+static struct platform_device at572d940hf_nand_device = {
+       .name           = "atmel_nand",
+       .id             = -1,
+       .dev            = {
+                               .platform_data  = &nand_data,
+       },
+       .resource       = nand_resources,
+       .num_resources  = ARRAY_SIZE(nand_resources),
+};
+
+void __init at91_add_device_nand(struct atmel_nand_data *data)
+{
+       unsigned long csa;
+
+       if (!data)
+               return;
+
+       csa = at91_sys_read(AT91_MATRIX_EBICSA);
+       at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
+
+       /* enable pin */
+       if (data->enable_pin)
+               at91_set_gpio_output(data->enable_pin, 1);
+
+       /* ready/busy pin */
+       if (data->rdy_pin)
+               at91_set_gpio_input(data->rdy_pin, 1);
+
+       /* card detect pin */
+       if (data->det_pin)
+               at91_set_gpio_input(data->det_pin, 1);
+
+       at91_set_A_periph(AT91_PIN_PB28, 0);            /* A[22] */
+       at91_set_B_periph(AT91_PIN_PA28, 0);            /* NANDOE */
+       at91_set_B_periph(AT91_PIN_PA29, 0);            /* NANDWE */
+
+       nand_data = *data;
+       platform_device_register(&at572d940hf_nand_device);
+}
+
+#else
+void __init at91_add_device_nand(struct atmel_nand_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  TWI (i2c)
+ * -------------------------------------------------------------------- */
+
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+       .sda_pin                = AT91_PIN_PC7,
+       .sda_is_open_drain      = 1,
+       .scl_pin                = AT91_PIN_PC8,
+       .scl_is_open_drain      = 1,
+       .udelay                 = 2,            /* ~100 kHz */
+};
+
+static struct platform_device at572d940hf_twi_device {
+       .name                   = "i2c-gpio",
+       .id                     = -1,
+       .dev.platform_data      = &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+       at91_set_GPIO_periph(AT91_PIN_PC7, 1);          /* TWD (SDA) */
+       at91_set_multi_drive(AT91_PIN_PC7, 1);
+
+       at91_set_GPIO_periph(AT91_PIN_PA8, 1);          /* TWCK (SCL) */
+       at91_set_multi_drive(AT91_PIN_PC8, 1);
+
+       i2c_register_board_info(0, devices, nr_devices);
+       platform_device_register(&at572d940hf_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+
+static struct resource twi0_resources[] = {
+       [0] = {
+               .start  = AT572D940HF_BASE_TWI0,
+               .end    = AT572D940HF_BASE_TWI0 + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT572D940HF_ID_TWI0,
+               .end    = AT572D940HF_ID_TWI0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at572d940hf_twi0_device = {
+       .name           = "at91_i2c",
+       .id             = 0,
+       .resource       = twi0_resources,
+       .num_resources  = ARRAY_SIZE(twi0_resources),
+};
+
+static struct resource twi1_resources[] = {
+       [0] = {
+               .start  = AT572D940HF_BASE_TWI1,
+               .end    = AT572D940HF_BASE_TWI1 + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT572D940HF_ID_TWI1,
+               .end    = AT572D940HF_ID_TWI1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at572d940hf_twi1_device = {
+       .name           = "at91_i2c",
+       .id             = 1,
+       .resource       = twi1_resources,
+       .num_resources  = ARRAY_SIZE(twi1_resources),
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+       /* pins used for TWI0 interface */
+       at91_set_A_periph(AT91_PIN_PC7, 0);             /* TWD */
+       at91_set_multi_drive(AT91_PIN_PC7, 1);
+
+       at91_set_A_periph(AT91_PIN_PC8, 0);             /* TWCK */
+       at91_set_multi_drive(AT91_PIN_PC8, 1);
+
+       /* pins used for TWI1 interface */
+       at91_set_A_periph(AT91_PIN_PC20, 0);            /* TWD */
+       at91_set_multi_drive(AT91_PIN_PC20, 1);
+
+       at91_set_A_periph(AT91_PIN_PC21, 0);            /* TWCK */
+       at91_set_multi_drive(AT91_PIN_PC21, 1);
+
+       i2c_register_board_info(0, devices, nr_devices);
+       platform_device_register(&at572d940hf_twi0_device);
+       platform_device_register(&at572d940hf_twi1_device);
+}
+#else
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  SPI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct resource spi0_resources[] = {
+       [0] = {
+               .start  = AT572D940HF_BASE_SPI0,
+               .end    = AT572D940HF_BASE_SPI0 + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT572D940HF_ID_SPI0,
+               .end    = AT572D940HF_ID_SPI0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at572d940hf_spi0_device = {
+       .name           = "atmel_spi",
+       .id             = 0,
+       .dev            = {
+                               .dma_mask               = &spi_dmamask,
+                               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+       .resource       = spi0_resources,
+       .num_resources  = ARRAY_SIZE(spi0_resources),
+};
+
+static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 };
+
+static struct resource spi1_resources[] = {
+       [0] = {
+               .start  = AT572D940HF_BASE_SPI1,
+               .end    = AT572D940HF_BASE_SPI1 + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT572D940HF_ID_SPI1,
+               .end    = AT572D940HF_ID_SPI1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at572d940hf_spi1_device = {
+       .name           = "atmel_spi",
+       .id             = 1,
+       .dev            = {
+                               .dma_mask               = &spi_dmamask,
+                               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+       .resource       = spi1_resources,
+       .num_resources  = ARRAY_SIZE(spi1_resources),
+};
+
+static const unsigned spi1_standard_cs[4] = { AT91_PIN_PC3, AT91_PIN_PC4, AT91_PIN_PC5, AT91_PIN_PC6 };
+
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+{
+       int i;
+       unsigned long cs_pin;
+       short enable_spi0 = 0;
+       short enable_spi1 = 0;
+
+       /* Choose SPI chip-selects */
+       for (i = 0; i < nr_devices; i++) {
+               if (devices[i].controller_data)
+                       cs_pin = (unsigned long) devices[i].controller_data;
+               else if (devices[i].bus_num == 0)
+                       cs_pin = spi0_standard_cs[devices[i].chip_select];
+               else
+                       cs_pin = spi1_standard_cs[devices[i].chip_select];
+
+               if (devices[i].bus_num == 0)
+                       enable_spi0 = 1;
+               else
+                       enable_spi1 = 1;
+
+               /* enable chip-select pin */
+               at91_set_gpio_output(cs_pin, 1);
+
+               /* pass chip-select pin to driver */
+               devices[i].controller_data = (void *) cs_pin;
+       }
+
+       spi_register_board_info(devices, nr_devices);
+
+       /* Configure SPI bus(es) */
+       if (enable_spi0) {
+               at91_set_A_periph(AT91_PIN_PA0, 0);     /* SPI0_MISO */
+               at91_set_A_periph(AT91_PIN_PA1, 0);     /* SPI0_MOSI */
+               at91_set_A_periph(AT91_PIN_PA2, 0);     /* SPI0_SPCK */
+
+               at91_clock_associate("spi0_clk", &at572d940hf_spi0_device.dev, "spi_clk");
+               platform_device_register(&at572d940hf_spi0_device);
+       }
+       if (enable_spi1) {
+               at91_set_A_periph(AT91_PIN_PC0, 0);     /* SPI1_MISO */
+               at91_set_A_periph(AT91_PIN_PC1, 0);     /* SPI1_MOSI */
+               at91_set_A_periph(AT91_PIN_PC2, 0);     /* SPI1_SPCK */
+
+               at91_clock_associate("spi1_clk", &at572d940hf_spi1_device.dev, "spi_clk");
+               platform_device_register(&at572d940hf_spi1_device);
+       }
+}
+#else
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  Timer/Counter blocks
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb_resources[] = {
+       [0] = {
+               .start  = AT572D940HF_BASE_TCB,
+               .end    = AT572D940HF_BASE_TCB + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT572D940HF_ID_TC0,
+               .end    = AT572D940HF_ID_TC0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start  = AT572D940HF_ID_TC1,
+               .end    = AT572D940HF_ID_TC1,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [3] = {
+               .start  = AT572D940HF_ID_TC2,
+               .end    = AT572D940HF_ID_TC2,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at572d940hf_tcb_device = {
+       .name           = "atmel_tcb",
+       .id             = 0,
+       .resource       = tcb_resources,
+       .num_resources  = ARRAY_SIZE(tcb_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+       /* this chip has a separate clock and irq for each TC channel */
+       at91_clock_associate("tc0_clk", &at572d940hf_tcb_device.dev, "t0_clk");
+       at91_clock_associate("tc1_clk", &at572d940hf_tcb_device.dev, "t1_clk");
+       at91_clock_associate("tc2_clk", &at572d940hf_tcb_device.dev, "t2_clk");
+       platform_device_register(&at572d940hf_tcb_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  RTT
+ * -------------------------------------------------------------------- */
+
+static struct resource rtt_resources[] = {
+       {
+               .start  = AT91_BASE_SYS + AT91_RTT,
+               .end    = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
+               .flags  = IORESOURCE_MEM,
+       }
+};
+
+static struct platform_device at572d940hf_rtt_device = {
+       .name           = "at91_rtt",
+       .id             = 0,
+       .resource       = rtt_resources,
+       .num_resources  = ARRAY_SIZE(rtt_resources),
+};
+
+static void __init at91_add_device_rtt(void)
+{
+       platform_device_register(&at572d940hf_rtt_device);
+}
+
+
+/* --------------------------------------------------------------------
+ *  Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
+static struct platform_device at572d940hf_wdt_device = {
+       .name           = "at91_wdt",
+       .id             = -1,
+       .num_resources  = 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+       platform_device_register(&at572d940hf_wdt_device);
+}
+#else
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  UART
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SERIAL_ATMEL)
+static struct resource dbgu_resources[] = {
+       [0] = {
+               .start  = AT91_VA_BASE_SYS + AT91_DBGU,
+               .end    = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT91_ID_SYS,
+               .end    = AT91_ID_SYS,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct atmel_uart_data dbgu_data = {
+       .use_dma_tx     = 0,
+       .use_dma_rx     = 0,            /* DBGU not capable of receive DMA */
+       .regs           = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
+};
+
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at572d940hf_dbgu_device = {
+       .name           = "atmel_usart",
+       .id             = 0,
+       .dev            = {
+                               .dma_mask               = &dbgu_dmamask,
+                               .coherent_dma_mask      = DMA_BIT_MASK(32),
+                               .platform_data          = &dbgu_data,
+       },
+       .resource       = dbgu_resources,
+       .num_resources  = ARRAY_SIZE(dbgu_resources),
+};
+
+static inline void configure_dbgu_pins(void)
+{
+       at91_set_A_periph(AT91_PIN_PC31, 1);            /* DTXD */
+       at91_set_A_periph(AT91_PIN_PC30, 0);            /* DRXD */
+}
+
+static struct resource uart0_resources[] = {
+       [0] = {
+               .start  = AT572D940HF_BASE_US0,
+               .end    = AT572D940HF_BASE_US0 + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT572D940HF_ID_US0,
+               .end    = AT572D940HF_ID_US0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct atmel_uart_data uart0_data = {
+       .use_dma_tx     = 1,
+       .use_dma_rx     = 1,
+};
+
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at572d940hf_uart0_device = {
+       .name           = "atmel_usart",
+       .id             = 1,
+       .dev            = {
+                               .dma_mask               = &uart0_dmamask,
+                               .coherent_dma_mask      = DMA_BIT_MASK(32),
+                               .platform_data          = &uart0_data,
+       },
+       .resource       = uart0_resources,
+       .num_resources  = ARRAY_SIZE(uart0_resources),
+};
+
+static inline void configure_usart0_pins(unsigned pins)
+{
+       at91_set_A_periph(AT91_PIN_PA8, 1);             /* TXD0 */
+       at91_set_A_periph(AT91_PIN_PA7, 0);             /* RXD0 */
+
+       if (pins & ATMEL_UART_RTS)
+               at91_set_A_periph(AT91_PIN_PA10, 0);    /* RTS0 */
+       if (pins & ATMEL_UART_CTS)
+               at91_set_A_periph(AT91_PIN_PA9, 0);     /* CTS0 */
+}
+
+static struct resource uart1_resources[] = {
+       [0] = {
+               .start  = AT572D940HF_BASE_US1,
+               .end    = AT572D940HF_BASE_US1 + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT572D940HF_ID_US1,
+               .end    = AT572D940HF_ID_US1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct atmel_uart_data uart1_data = {
+       .use_dma_tx     = 1,
+       .use_dma_rx     = 1,
+};
+
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at572d940hf_uart1_device = {
+       .name           = "atmel_usart",
+       .id             = 2,
+       .dev            = {
+                               .dma_mask               = &uart1_dmamask,
+                               .coherent_dma_mask      = DMA_BIT_MASK(32),
+                               .platform_data          = &uart1_data,
+       },
+       .resource       = uart1_resources,
+       .num_resources  = ARRAY_SIZE(uart1_resources),
+};
+
+static inline void configure_usart1_pins(unsigned pins)
+{
+       at91_set_A_periph(AT91_PIN_PC10, 1);            /* TXD1 */
+       at91_set_A_periph(AT91_PIN_PC9 , 0);            /* RXD1 */
+
+       if (pins & ATMEL_UART_RTS)
+               at91_set_A_periph(AT91_PIN_PC12, 0);    /* RTS1 */
+       if (pins & ATMEL_UART_CTS)
+               at91_set_A_periph(AT91_PIN_PC11, 0);    /* CTS1 */
+}
+
+static struct resource uart2_resources[] = {
+       [0] = {
+               .start  = AT572D940HF_BASE_US2,
+               .end    = AT572D940HF_BASE_US2 + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT572D940HF_ID_US2,
+               .end    = AT572D940HF_ID_US2,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct atmel_uart_data uart2_data = {
+       .use_dma_tx     = 1,
+       .use_dma_rx     = 1,
+};
+
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at572d940hf_uart2_device = {
+       .name           = "atmel_usart",
+       .id             = 3,
+       .dev            = {
+                               .dma_mask               = &uart2_dmamask,
+                               .coherent_dma_mask      = DMA_BIT_MASK(32),
+                               .platform_data          = &uart2_data,
+       },
+       .resource       = uart2_resources,
+       .num_resources  = ARRAY_SIZE(uart2_resources),
+};
+
+static inline void configure_usart2_pins(unsigned pins)
+{
+       at91_set_A_periph(AT91_PIN_PC15, 1);            /* TXD2 */
+       at91_set_A_periph(AT91_PIN_PC14, 0);            /* RXD2 */
+
+       if (pins & ATMEL_UART_RTS)
+               at91_set_A_periph(AT91_PIN_PC17, 0);    /* RTS2 */
+       if (pins & ATMEL_UART_CTS)
+               at91_set_A_periph(AT91_PIN_PC16, 0);    /* CTS2 */
+}
+
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];  /* the UARTs to use */
+struct platform_device *atmel_default_console_device;  /* the serial console device */
+
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+       struct platform_device *pdev;
+
+       switch (id) {
+               case 0:         /* DBGU */
+                       pdev = &at572d940hf_dbgu_device;
+                       configure_dbgu_pins();
+                       at91_clock_associate("mck", &pdev->dev, "usart");
+                       break;
+               case AT572D940HF_ID_US0:
+                       pdev = &at572d940hf_uart0_device;
+                       configure_usart0_pins(pins);
+                       at91_clock_associate("usart0_clk", &pdev->dev, "usart");
+                       break;
+               case AT572D940HF_ID_US1:
+                       pdev = &at572d940hf_uart1_device;
+                       configure_usart1_pins(pins);
+                       at91_clock_associate("usart1_clk", &pdev->dev, "usart");
+                       break;
+               case AT572D940HF_ID_US2:
+                       pdev = &at572d940hf_uart2_device;
+                       configure_usart2_pins(pins);
+                       at91_clock_associate("usart2_clk", &pdev->dev, "usart");
+                       break;
+               default:
+                       return;
+       }
+       pdev->id = portnr;              /* update to mapped ID */
+
+       if (portnr < ATMEL_MAX_UART)
+               at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+       if (portnr < ATMEL_MAX_UART)
+               atmel_default_console_device = at91_uarts[portnr];
+}
+
+void __init at91_add_device_serial(void)
+{
+       int i;
+
+       for (i = 0; i < ATMEL_MAX_UART; i++) {
+               if (at91_uarts[i])
+                       platform_device_register(at91_uarts[i]);
+       }
+
+       if (!atmel_default_console_device)
+               printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+
+#else
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
+void __init at91_add_device_serial(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  mAgic
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_MAGICV
+static struct resource mAgic_resources[] = {
+       {
+               .start = AT91_MAGIC_PM_BASE,
+               .end   = AT91_MAGIC_PM_BASE + AT91_MAGIC_PM_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = AT91_MAGIC_DM_I_BASE,
+               .end   = AT91_MAGIC_DM_I_BASE + AT91_MAGIC_DM_I_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = AT91_MAGIC_DM_F_BASE,
+               .end   = AT91_MAGIC_DM_F_BASE + AT91_MAGIC_DM_F_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = AT91_MAGIC_DM_DB_BASE,
+               .end   = AT91_MAGIC_DM_DB_BASE + AT91_MAGIC_DM_DB_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = AT91_MAGIC_REGS_BASE,
+               .end   = AT91_MAGIC_REGS_BASE + AT91_MAGIC_REGS_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = AT91_MAGIC_EXTPAGE_BASE,
+               .end   = AT91_MAGIC_EXTPAGE_BASE + AT91_MAGIC_EXTPAGE_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start  = AT572D940HF_ID_MSIRQ0,
+               .end    = AT572D940HF_ID_MSIRQ0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = AT572D940HF_ID_MHALT,
+               .end    = AT572D940HF_ID_MHALT,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = AT572D940HF_ID_MEXC,
+               .end    = AT572D940HF_ID_MEXC,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = AT572D940HF_ID_MEDMA,
+               .end    = AT572D940HF_ID_MEDMA,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mAgic_device = {
+       .name           = "mAgic",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(mAgic_resources),
+       .resource       = mAgic_resources,
+};
+
+void __init at91_add_device_mAgic(void)
+{
+       platform_device_register(&mAgic_device);
+}
+#else
+void __init at91_add_device_mAgic(void) {}
+#endif
+
+
+/* -------------------------------------------------------------------- */
+
+/*
+ * These devices are always present and don't need any board-specific
+ * setup.
+ */
+static int __init at91_add_standard_devices(void)
+{
+       at91_add_device_rtt();
+       at91_add_device_watchdog();
+       at91_add_device_tc();
+       return 0;
+}
+
+arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/board-at572d940hf_ek.c b/arch/arm/mach-at91/board-at572d940hf_ek.c
new file mode 100644 (file)
index 0000000..5daff27
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * linux/arch/arm/mach-at91/board-at572d940hf_ek.c
+ *
+ * Copyright (C) 2008 Atmel Antonio R. Costa <costa.antonior@gmail.com>
+ * Copyright (C) 2005 SAN People
+ *
+ * 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/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ds1305.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init eb_map_io(void)
+{
+       /* Initialize processor: 12.500 MHz crystal */
+       at572d940hf_initialize(12000000);
+
+       /* DBGU on ttyS0. (Rx & Tx only) */
+       at91_register_uart(0, 0, 0);
+
+       /* USART0 on ttyS1. (Rx & Tx only) */
+       at91_register_uart(AT572D940HF_ID_US0, 1, 0);
+
+       /* USART1 on ttyS2. (Rx & Tx only) */
+       at91_register_uart(AT572D940HF_ID_US1, 2, 0);
+
+       /* USART2 on ttyS3. (Tx & Rx only */
+       at91_register_uart(AT572D940HF_ID_US2, 3, 0);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
+}
+
+static void __init eb_init_irq(void)
+{
+       at572d940hf_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host Port
+ */
+static struct at91_usbh_data __initdata eb_usbh_data = {
+       .ports          = 2,
+};
+
+
+/*
+ * USB Device Port
+ */
+static struct at91_udc_data __initdata eb_udc_data = {
+       .vbus_pin       = 0,            /* no VBUS detection,UDC always on */
+       .pullup_pin     = 0,            /* pull-up driven by UDC */
+};
+
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata eb_mmc_data = {
+       .wire4          = 1,
+/*     .det_pin        = ... not connected */
+/*     .wp_pin         = ... not connected */
+/*     .vcc_pin        = ... not connected */
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata eb_eth_data = {
+       .phy_irq_pin    = AT91_PIN_PB25,
+       .is_rmii        = 1,
+};
+
+/*
+ * NOR flash
+ */
+
+static struct mtd_partition eb_nor_partitions[] = {
+       {
+               .name           = "Raw Environment",
+               .offset         = 0,
+               .size           = SZ_4M,
+               .mask_flags     = 0,
+       },
+       {
+               .name           = "OS FS",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = 3 * SZ_1M,
+               .mask_flags     = 0,
+       },
+       {
+               .name           = "APP FS",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = MTDPART_SIZ_FULL,
+               .mask_flags     = 0,
+       },
+};
+
+static void nor_flash_set_vpp(struct map_info* mi, int i) {
+};
+
+static struct physmap_flash_data nor_flash_data = {
+       .width          = 4,
+       .parts          = eb_nor_partitions,
+       .nr_parts       = ARRAY_SIZE(eb_nor_partitions),
+       .set_vpp        = nor_flash_set_vpp,
+};
+
+static struct resource nor_flash_resources[] = {
+       {
+               .start  = AT91_CHIPSELECT_0,
+               .end    = AT91_CHIPSELECT_0 + SZ_16M - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device nor_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+                               .platform_data = &nor_flash_data,
+                       },
+       .resource       = nor_flash_resources,
+       .num_resources  = ARRAY_SIZE(nor_flash_resources),
+};
+
+static struct sam9_smc_config __initdata eb_nor_smc_config = {
+       .ncs_read_setup         = 1,
+       .nrd_setup              = 1,
+       .ncs_write_setup        = 1,
+       .nwe_setup              = 1,
+
+       .ncs_read_pulse         = 7,
+       .nrd_pulse              = 7,
+       .ncs_write_pulse        = 7,
+       .nwe_pulse              = 7,
+
+       .read_cycle             = 9,
+       .write_cycle            = 9,
+
+       .mode                   = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_32,
+       .tdf_cycles             = 1,
+};
+
+static void __init eb_add_device_nor(void)
+{
+       /* configure chip-select 0 (NOR) */
+       sam9_smc_configure(0, &eb_nor_smc_config);
+       platform_device_register(&nor_flash);
+}
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata eb_nand_partition[] = {
+       {
+               .name   = "Partition 1",
+               .offset = 0,
+               .size   = SZ_16M,
+       },
+       {
+               .name   = "Partition 2",
+               .offset = MTDPART_OFS_NXTBLK,
+               .size   = MTDPART_SIZ_FULL,
+       }
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+       *num_partitions = ARRAY_SIZE(eb_nand_partition);
+       return eb_nand_partition;
+}
+
+static struct atmel_nand_data __initdata eb_nand_data = {
+       .ale            = 22,
+       .cle            = 21,
+/*     .det_pin        = ... not connected */
+/*     .rdy_pin        = AT91_PIN_PC16, */
+       .enable_pin     = AT91_PIN_PA15,
+       .partition_info = nand_partitions,
+#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+       .bus_width_16   = 1,
+#else
+       .bus_width_16   = 0,
+#endif
+};
+
+static struct sam9_smc_config __initdata eb_nand_smc_config = {
+       .ncs_read_setup         = 0,
+       .nrd_setup              = 0,
+       .ncs_write_setup        = 1,
+       .nwe_setup              = 1,
+
+       .ncs_read_pulse         = 3,
+       .nrd_pulse              = 3,
+       .ncs_write_pulse        = 3,
+       .nwe_pulse              = 3,
+
+       .read_cycle             = 5,
+       .write_cycle            = 5,
+
+       .mode                   = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
+       .tdf_cycles             = 12,
+};
+
+static void __init eb_add_device_nand(void)
+{
+       /* setup bus-width (8 or 16) */
+       if (eb_nand_data.bus_width_16)
+               eb_nand_smc_config.mode |= AT91_SMC_DBW_16;
+       else
+               eb_nand_smc_config.mode |= AT91_SMC_DBW_8;
+
+       /* configure chip-select 3 (NAND) */
+       sam9_smc_configure(3, &eb_nand_smc_config);
+
+       at91_add_device_nand(&eb_nand_data);
+}
+
+
+/*
+ * SPI devices
+ */
+static struct resource rtc_resources[] = {
+       [0] = {
+               .start  = AT572D940HF_ID_IRQ1,
+               .end    = AT572D940HF_ID_IRQ1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct ds1305_platform_data ds1306_data = {
+       .is_ds1306      = true,
+       .en_1hz         = false,
+};
+
+static struct spi_board_info eb_spi_devices[] = {
+       {       /* RTC Dallas DS1306 */
+               .modalias       = "rtc-ds1305",
+               .chip_select    = 3,
+               .mode           = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA,
+               .max_speed_hz   = 500000,
+               .bus_num        = 0,
+               .irq            = AT572D940HF_ID_IRQ1,
+               .platform_data  = (void *) &ds1306_data,
+       },
+#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
+       {       /* Dataflash card */
+               .modalias       = "mtd_dataflash",
+               .chip_select    = 0,
+               .max_speed_hz   = 15 * 1000 * 1000,
+               .bus_num        = 0,
+       },
+#endif
+};
+
+static void __init eb_board_init(void)
+{
+       /* Serial */
+       at91_add_device_serial();
+       /* USB Host */
+       at91_add_device_usbh(&eb_usbh_data);
+       /* USB Device */
+       at91_add_device_udc(&eb_udc_data);
+       /* I2C */
+       at91_add_device_i2c(NULL, 0);
+       /* NOR */
+       eb_add_device_nor();
+       /* NAND */
+       eb_add_device_nand();
+       /* SPI */
+       at91_add_device_spi(eb_spi_devices, ARRAY_SIZE(eb_spi_devices));
+       /* MMC */
+       at91_add_device_mmc(0, &eb_mmc_data);
+       /* Ethernet */
+       at91_add_device_eth(&eb_eth_data);
+       /* mAgic */
+       at91_add_device_mAgic();
+}
+
+MACHINE_START(AT572D940HFEB, "Atmel AT91D940HF-EB")
+       /* Maintainer: Atmel <costa.antonior@gmail.com> */
+       .phys_io        = AT91_BASE_SYS,
+       .io_pg_offst    = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+       .boot_params    = AT91_SDRAM_BASE + 0x100,
+       .timer          = &at91sam926x_timer,
+       .map_io         = eb_map_io,
+       .init_irq       = eb_init_irq,
+       .init_machine   = eb_board_init,
+MACHINE_END
index c042dcf4725fc8ec3166cb9ddc7436109f1fca6c..7f7da439341fabc4e85b6febeb8b1f3e2cd6f4ee 100644 (file)
@@ -29,6 +29,7 @@
 #include <mach/cpu.h>
 
 #include "clock.h"
+#include "generic.h"
 
 
 /*
@@ -628,7 +629,7 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
                at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
        } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() ||
                   cpu_is_at91sam9263() || cpu_is_at91sam9g20() ||
-                  cpu_is_at91sam9g10()) {
+                  cpu_is_at91sam9g10() || cpu_is_at572d940hf()) {
                uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
                udpck.pmc_mask = AT91SAM926x_PMC_UDP;
        } else if (cpu_is_at91cap9()) {
@@ -711,12 +712,13 @@ int __init at91_clock_init(unsigned long main_clock)
        /*
         * USB HS clock init
         */
-       if (cpu_has_utmi())
+       if (cpu_has_utmi()) {
                /*
                 * multiplier is hard-wired to 40
                 * (obtain the USB High Speed 480 MHz when input is 12 MHz)
                 */
                utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz;
+       }
 
        /*
         * USB FS clock init
@@ -746,7 +748,7 @@ int __init at91_clock_init(unsigned long main_clock)
                mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
                        freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
        } else {
-               mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));      /* mdiv */
+               mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));              /* mdiv */
        }
 
        /* Register the PMC's standard clocks */
index 1ba3b95ff3594f10cd30c7b433b38e0f0e497d4e..6cf4b78e175d7a47775463d03f4f6c7146a2910e 100644 (file)
@@ -22,7 +22,7 @@ struct clk {
        struct clk      *parent;
        u32             pmc_mask;
        void            (*mode)(struct clk *, int);
-       unsigned        id:2;           /* PCK0..3, or 32k/main/a/b */
+       unsigned        id:3;           /* PCK0..4, or 32k/main/a/b */
        unsigned        type;           /* clock type */
        u16             users;
 };
index 88e413b38480233f40d61bf5b8edbb1a8d46d432..65c3dc5ba0d0c608e649565121ac59e3ce4d1159 100644 (file)
@@ -17,6 +17,7 @@ extern void __init at91sam9rl_initialize(unsigned long main_clock);
 extern void __init at91sam9g45_initialize(unsigned long main_clock);
 extern void __init at91x40_initialize(unsigned long main_clock);
 extern void __init at91cap9_initialize(unsigned long main_clock);
+extern void __init at572d940hf_initialize(unsigned long main_clock);
 
  /* Interrupts */
 extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
@@ -27,6 +28,7 @@ extern void __init at91sam9rl_init_interrupts(unsigned int priority[]);
 extern void __init at91sam9g45_init_interrupts(unsigned int priority[]);
 extern void __init at91x40_init_interrupts(unsigned int priority[]);
 extern void __init at91cap9_init_interrupts(unsigned int priority[]);
+extern void __init at572d940hf_init_interrupts(unsigned int priority[]);
 extern void __init at91_aic_init(unsigned int priority[]);
 
  /* Timer */
diff --git a/arch/arm/mach-at91/include/mach/at572d940hf.h b/arch/arm/mach-at91/include/mach/at572d940hf.h
new file mode 100644 (file)
index 0000000..2d9b0af
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * include/mach/at572d940hf.h
+ *
+ * Antonio R. Costa <costa.antonior@gmail.com>
+ * Copyright (C) 2008 Atmel
+ *
+ * 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
+ *
+ */
+
+#ifndef AT572D940HF_H
+#define AT572D940HF_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91_ID_FIQ            0       /* Advanced Interrupt Controller (FIQ) */
+#define AT91_ID_SYS            1       /* System Peripherals */
+#define AT572D940HF_ID_PIOA    2       /* Parallel IO Controller A */
+#define AT572D940HF_ID_PIOB    3       /* Parallel IO Controller B */
+#define AT572D940HF_ID_PIOC    4       /* Parallel IO Controller C */
+#define AT572D940HF_ID_EMAC    5       /* MACB ethernet controller */
+#define AT572D940HF_ID_US0     6       /* USART 0 */
+#define AT572D940HF_ID_US1     7       /* USART 1 */
+#define AT572D940HF_ID_US2     8       /* USART 2 */
+#define AT572D940HF_ID_MCI     9       /* Multimedia Card Interface */
+#define AT572D940HF_ID_UDP     10      /* USB Device Port */
+#define AT572D940HF_ID_TWI0    11      /* Two-Wire Interface 0 */
+#define AT572D940HF_ID_SPI0    12      /* Serial Peripheral Interface 0 */
+#define AT572D940HF_ID_SPI1    13      /* Serial Peripheral Interface 1 */
+#define AT572D940HF_ID_SSC0    14      /* Serial Synchronous Controller 0 */
+#define AT572D940HF_ID_SSC1    15      /* Serial Synchronous Controller 1 */
+#define AT572D940HF_ID_SSC2    16      /* Serial Synchronous Controller 2 */
+#define AT572D940HF_ID_TC0     17      /* Timer Counter 0 */
+#define AT572D940HF_ID_TC1     18      /* Timer Counter 1 */
+#define AT572D940HF_ID_TC2     19      /* Timer Counter 2 */
+#define AT572D940HF_ID_UHP     20      /* USB Host port */
+#define AT572D940HF_ID_SSC3    21      /* Serial Synchronous Controller 3 */
+#define AT572D940HF_ID_TWI1    22      /* Two-Wire Interface 1 */
+#define AT572D940HF_ID_CAN0    23      /* CAN Controller 0 */
+#define AT572D940HF_ID_CAN1    24      /* CAN Controller 1 */
+#define AT572D940HF_ID_MHALT   25      /* mAgicV HALT line */
+#define AT572D940HF_ID_MSIRQ0  26      /* mAgicV SIRQ0 line */
+#define AT572D940HF_ID_MEXC    27      /* mAgicV exception line */
+#define AT572D940HF_ID_MEDMA   28      /* mAgicV end of DMA line */
+#define AT572D940HF_ID_IRQ0    29      /* External Interrupt Source (IRQ0) */
+#define AT572D940HF_ID_IRQ1    30      /* External Interrupt Source (IRQ1) */
+#define AT572D940HF_ID_IRQ2    31      /* External Interrupt Source (IRQ2) */
+
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT572D940HF_BASE_TCB   0xfffa0000
+#define AT572D940HF_BASE_TC0   0xfffa0000
+#define AT572D940HF_BASE_TC1   0xfffa0040
+#define AT572D940HF_BASE_TC2   0xfffa0080
+#define AT572D940HF_BASE_UDP   0xfffa4000
+#define AT572D940HF_BASE_MCI   0xfffa8000
+#define AT572D940HF_BASE_TWI0  0xfffac000
+#define AT572D940HF_BASE_US0   0xfffb0000
+#define AT572D940HF_BASE_US1   0xfffb4000
+#define AT572D940HF_BASE_US2   0xfffb8000
+#define AT572D940HF_BASE_SSC0  0xfffbc000
+#define AT572D940HF_BASE_SSC1  0xfffc0000
+#define AT572D940HF_BASE_SSC2  0xfffc4000
+#define AT572D940HF_BASE_SPI0  0xfffc8000
+#define AT572D940HF_BASE_SPI1  0xfffcc000
+#define AT572D940HF_BASE_SSC3  0xfffd0000
+#define AT572D940HF_BASE_TWI1  0xfffd4000
+#define AT572D940HF_BASE_EMAC  0xfffd8000
+#define AT572D940HF_BASE_CAN0  0xfffdc000
+#define AT572D940HF_BASE_CAN1  0xfffe0000
+#define AT91_BASE_SYS          0xffffea00
+
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_SDRAMC    (0xffffea00 - AT91_BASE_SYS)
+#define AT91_SMC       (0xffffec00 - AT91_BASE_SYS)
+#define AT91_MATRIX    (0xffffee00 - AT91_BASE_SYS)
+#define AT91_AIC       (0xfffff000 - AT91_BASE_SYS)
+#define AT91_DBGU      (0xfffff200 - AT91_BASE_SYS)
+#define AT91_PIOA      (0xfffff400 - AT91_BASE_SYS)
+#define AT91_PIOB      (0xfffff600 - AT91_BASE_SYS)
+#define AT91_PIOC      (0xfffff800 - AT91_BASE_SYS)
+#define AT91_PMC       (0xfffffc00 - AT91_BASE_SYS)
+#define AT91_RSTC      (0xfffffd00 - AT91_BASE_SYS)
+#define AT91_RTT       (0xfffffd20 - AT91_BASE_SYS)
+#define AT91_PIT       (0xfffffd30 - AT91_BASE_SYS)
+#define AT91_WDT       (0xfffffd40 - AT91_BASE_SYS)
+
+#define AT91_USART0    AT572D940HF_ID_US0
+#define AT91_USART1    AT572D940HF_ID_US1
+#define AT91_USART2    AT572D940HF_ID_US2
+
+
+/*
+ * Internal Memory.
+ */
+#define AT572D940HF_SRAM_BASE  0x00300000      /* Internal SRAM base address */
+#define AT572D940HF_SRAM_SIZE  (48 * SZ_1K)    /* Internal SRAM size (48Kb) */
+
+#define AT572D940HF_ROM_BASE   0x00400000      /* Internal ROM base address */
+#define AT572D940HF_ROM_SIZE   SZ_32K          /* Internal ROM size (32Kb) */
+
+#define AT572D940HF_UHP_BASE   0x00500000      /* USB Host controller */
+
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at572d940hf_matrix.h b/arch/arm/mach-at91/include/mach/at572d940hf_matrix.h
new file mode 100644 (file)
index 0000000..b6751df
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * include/mach//at572d940hf_matrix.h
+ *
+ * Antonio R. Costa <costa.antonior@gmail.com>
+ * Copyright (C) 2008 Atmel
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * 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
+ */
+
+#ifndef AT572D940HF_MATRIX_H
+#define AT572D940HF_MATRIX_H
+
+#define AT91_MATRIX_MCFG0      (AT91_MATRIX + 0x00)    /* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1      (AT91_MATRIX + 0x04)    /* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2      (AT91_MATRIX + 0x08)    /* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3      (AT91_MATRIX + 0x0C)    /* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4      (AT91_MATRIX + 0x10)    /* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5      (AT91_MATRIX + 0x14)    /* Master Configuration Register 5 */
+
+#define                AT91_MATRIX_ULBT        (7 << 0)        /* Undefined Length Burst Type */
+#define                        AT91_MATRIX_ULBT_INFINITE       (0 << 0)
+#define                        AT91_MATRIX_ULBT_SINGLE         (1 << 0)
+#define                        AT91_MATRIX_ULBT_FOUR           (2 << 0)
+#define                        AT91_MATRIX_ULBT_EIGHT          (3 << 0)
+#define                        AT91_MATRIX_ULBT_SIXTEEN        (4 << 0)
+
+#define AT91_MATRIX_SCFG0      (AT91_MATRIX + 0x40)    /* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1      (AT91_MATRIX + 0x44)    /* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2      (AT91_MATRIX + 0x48)    /* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3      (AT91_MATRIX + 0x4C)    /* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4      (AT91_MATRIX + 0x50)    /* Slave Configuration Register 4 */
+#define                AT91_MATRIX_SLOT_CYCLE          (0xff << 0)     /* Maximum Number of Allowed Cycles for a Burst */
+#define                AT91_MATRIX_DEFMSTR_TYPE        (3    << 16)    /* Default Master Type */
+#define                        AT91_MATRIX_DEFMSTR_TYPE_NONE   (0 << 16)
+#define                        AT91_MATRIX_DEFMSTR_TYPE_LAST   (1 << 16)
+#define                        AT91_MATRIX_DEFMSTR_TYPE_FIXED  (2 << 16)
+#define                AT91_MATRIX_FIXED_DEFMSTR       (0x7  << 18)    /* Fixed Index of Default Master */
+#define                AT91_MATRIX_ARBT                (3    << 24)    /* Arbitration Type */
+#define                        AT91_MATRIX_ARBT_ROUND_ROBIN    (0 << 24)
+#define                        AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
+
+#define AT91_MATRIX_PRAS0      (AT91_MATRIX + 0x80)    /* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRAS1      (AT91_MATRIX + 0x88)    /* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRAS2      (AT91_MATRIX + 0x90)    /* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRAS3      (AT91_MATRIX + 0x98)    /* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRAS4      (AT91_MATRIX + 0xA0)    /* Priority Register A for Slave 4 */
+
+#define                AT91_MATRIX_M0PR                (3 << 0)        /* Master 0 Priority */
+#define                AT91_MATRIX_M1PR                (3 << 4)        /* Master 1 Priority */
+#define                AT91_MATRIX_M2PR                (3 << 8)        /* Master 2 Priority */
+#define                AT91_MATRIX_M3PR                (3 << 12)       /* Master 3 Priority */
+#define                AT91_MATRIX_M4PR                (3 << 16)       /* Master 4 Priority */
+#define                AT91_MATRIX_M5PR                (3 << 20)       /* Master 5 Priority */
+#define                AT91_MATRIX_M6PR                (3 << 24)       /* Master 6 Priority */
+
+#define AT91_MATRIX_MRCR       (AT91_MATRIX + 0x100)   /* Master Remap Control Register */
+#define                AT91_MATRIX_RCB0                (1 << 0)        /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
+#define                AT91_MATRIX_RCB1                (1 << 1)        /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
+
+#define AT91_MATRIX_SFR0       (AT91_MATRIX + 0x110)   /* Special Function Register 0 */
+#define AT91_MATRIX_SFR1       (AT91_MATRIX + 0x114)   /* Special Function Register 1 */
+#define AT91_MATRIX_SFR2       (AT91_MATRIX + 0x118)   /* Special Function Register 2 */
+#define AT91_MATRIX_SFR3       (AT91_MATRIX + 0x11C)   /* Special Function Register 3 */
+#define AT91_MATRIX_SFR4       (AT91_MATRIX + 0x120)   /* Special Function Register 4 */
+#define AT91_MATRIX_SFR5       (AT91_MATRIX + 0x124)   /* Special Function Register 5 */
+#define AT91_MATRIX_SFR6       (AT91_MATRIX + 0x128)   /* Special Function Register 6 */
+#define AT91_MATRIX_SFR7       (AT91_MATRIX + 0x12C)   /* Special Function Register 7 */
+#define AT91_MATRIX_SFR8       (AT91_MATRIX + 0x130)   /* Special Function Register 8 */
+#define AT91_MATRIX_SFR9       (AT91_MATRIX + 0x134)   /* Special Function Register 9 */
+#define AT91_MATRIX_SFR10      (AT91_MATRIX + 0x138)   /* Special Function Register 10 */
+#define AT91_MATRIX_SFR11      (AT91_MATRIX + 0x13C)   /* Special Function Register 11 */
+#define AT91_MATRIX_SFR12      (AT91_MATRIX + 0x140)   /* Special Function Register 12 */
+#define AT91_MATRIX_SFR13      (AT91_MATRIX + 0x144)   /* Special Function Register 13 */
+#define AT91_MATRIX_SFR14      (AT91_MATRIX + 0x148)   /* Special Function Register 14 */
+#define AT91_MATRIX_SFR15      (AT91_MATRIX + 0x14C)   /* Special Function Register 15 */
+
+
+/*
+ * The following registers / bits are not defined in the Datasheet (Revision A)
+ */
+
+#define AT91_MATRIX_TCR                (AT91_MATRIX + 0x100)   /* TCM Configuration Register */
+#define                AT91_MATRIX_ITCM_SIZE           (0xf << 0)      /* Size of ITCM enabled memory block */
+#define                        AT91_MATRIX_ITCM_0              (0 << 0)
+#define                        AT91_MATRIX_ITCM_16             (5 << 0)
+#define                        AT91_MATRIX_ITCM_32             (6 << 0)
+#define                        AT91_MATRIX_ITCM_64             (7 << 0)
+#define                AT91_MATRIX_DTCM_SIZE           (0xf << 4)      /* Size of DTCM enabled memory block */
+#define                        AT91_MATRIX_DTCM_0              (0 << 4)
+#define                        AT91_MATRIX_DTCM_16             (5 << 4)
+#define                        AT91_MATRIX_DTCM_32             (6 << 4)
+#define                        AT91_MATRIX_DTCM_64             (7 << 4)
+
+#define AT91_MATRIX_EBICSA     (AT91_MATRIX + 0x11C)   /* EBI Chip Select Assignment Register */
+#define                AT91_MATRIX_CS1A                (1 << 1)        /* Chip Select 1 Assignment */
+#define                        AT91_MATRIX_CS1A_SMC            (0 << 1)
+#define                        AT91_MATRIX_CS1A_SDRAMC         (1 << 1)
+#define                AT91_MATRIX_CS3A                (1 << 3)        /* Chip Select 3 Assignment */
+#define                        AT91_MATRIX_CS3A_SMC            (0 << 3)
+#define                        AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3)
+#define                AT91_MATRIX_CS4A                (1 << 4)        /* Chip Select 4 Assignment */
+#define                        AT91_MATRIX_CS4A_SMC            (0 << 4)
+#define                        AT91_MATRIX_CS4A_SMC_CF1        (1 << 4)
+#define                AT91_MATRIX_CS5A                (1 << 5)        /* Chip Select 5 Assignment */
+#define                        AT91_MATRIX_CS5A_SMC            (0 << 5)
+#define                        AT91_MATRIX_CS5A_SMC_CF2        (1 << 5)
+#define                AT91_MATRIX_DBPUC               (1 << 8)        /* Data Bus Pull-up Configuration */
+
+#endif
index 64589eaaaee8f8d57ae9044ed587eaa2bd329f66..e46f93e34aab4666b14932a9c6c451847b2c8b54 100644 (file)
@@ -32,6 +32,7 @@
 #define                AT91_PMC_PCK1           (1 <<  9)               /* Programmable Clock 1 */
 #define                AT91_PMC_PCK2           (1 << 10)               /* Programmable Clock 2 */
 #define                AT91_PMC_PCK3           (1 << 11)               /* Programmable Clock 3 */
+#define                AT91_PMC_PCK4           (1 << 12)               /* Programmable Clock 4 [AT572D940HF only] */
 #define                AT91_PMC_HCK0           (1 << 16)               /* AHB Clock (USB host) [AT91SAM9261 only] */
 #define                AT91_PMC_HCK1           (1 << 17)               /* AHB Clock (LCD) [AT91SAM9261 only] */
 
index bb6f6a7ba5e0bf387ed00985caa03e65f2e988a2..ceaec6c16eb2d801e68f50f8ea6975293027af42 100644 (file)
@@ -87,7 +87,7 @@ struct at91_eth_data {
 extern void __init at91_add_device_eth(struct at91_eth_data *data);
 
 #if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \
-       || defined(CONFIG_ARCH_AT91SAM9G45)
+       || defined(CONFIG_ARCH_AT91SAM9G45) || defined(CONFIG_ARCH_AT572D940HF)
 #define eth_platform_data      at91_eth_data
 #endif
 
@@ -205,6 +205,9 @@ extern void __init at91_init_leds(u8 cpu_led, u8 timer_led);
 extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
 extern void __init at91_pwm_leds(struct gpio_led *leds, int nr);
 
+ /* AT572D940HF DSP */
+extern void __init at91_add_device_mAgic(void);
+
 /* FIXME: this needs a better location, but gets stuff building again */
 extern int at91_suspend_entering_slow_clock(void);
 
index c22df30ed5e5d5784a6d7f09350ea17cd6b53706..5a0650101d45f20112b46cb31bddb1b32000a430 100644 (file)
@@ -33,6 +33,8 @@
 #define ARCH_ID_AT91SAM9XE256  0x329a93a0
 #define ARCH_ID_AT91SAM9XE512  0x329aa3a0
 
+#define ARCH_ID_AT572D940HF    0x0e0303e0
+
 #define ARCH_ID_AT91M40800     0x14080044
 #define ARCH_ID_AT91R40807     0x44080746
 #define ARCH_ID_AT91M40807     0x14080745
@@ -141,6 +143,12 @@ static inline unsigned long at91cap9_rev_identify(void)
 #define cpu_is_at91cap9_revC() (0)
 #endif
 
+#ifdef CONFIG_ARCH_AT572D940HF
+#define cpu_is_at572d940hf() (at91_cpu_identify() == ARCH_ID_AT572D940HF)
+#else
+#define cpu_is_at572d940hf() (0)
+#endif
+
 /*
  * Since this is ARM, we will never run on any AVR32 CPU. But these
  * definitions may reduce clutter in common drivers.
index 29052ba66adac42eb0ee585ecd8bc64e09d9da59..9e750a1c1b5a80fbab076f70314f8ffd7f5a1bd2 100644 (file)
@@ -14,7 +14,7 @@
 #include <mach/hardware.h>
 #include <mach/at91_dbgu.h>
 
-       .macro  addruart,rx
+       .macro  addruart, rx, tmp
        mrc     p15, 0, \rx, c1, c0
        tst     \rx, #1                                         @ MMU enabled?
        ldreq   \rx, =(AT91_BASE_SYS + AT91_DBGU)               @ System peripherals (phys address)
index a0df8b022df27bd3ede5e22aa2d3dff3f9c98fd3..3d64a75e3ed5be8a0566b343653b3af965a47c6f 100644 (file)
@@ -32,6 +32,8 @@
 #include <mach/at91cap9.h>
 #elif defined(CONFIG_ARCH_AT91X40)
 #include <mach/at91x40.h>
+#elif defined(CONFIG_ARCH_AT572D940HF)
+#include <mach/at572d940hf.h>
 #else
 #error "Unsupported AT91 processor"
 #endif
index 31ac2d97f14cb24b85371b259a2c70b27fc6a461..05a6e8af80c4e1f3c4b4983c88821c1e1bd0ad26 100644 (file)
 #define AT91X40_MASTER_CLOCK   40000000
 #define CLOCK_TICK_RATE                (AT91X40_MASTER_CLOCK)
 
+#elif defined(CONFIG_ARCH_AT572D940HF)
+
+#define AT572D940HF_MASTER_CLOCK       80000000
+#define CLOCK_TICK_RATE                (AT572D940HF_MASTER_CLOCK/16)
+
 #endif
 
 #endif
index e590bbe0a7b46acb51e42baba1c5344239a29753..72e405df0fb07dd4b363153f149742875725f7ad 100644 (file)
@@ -142,8 +142,7 @@ void __init bcmring_amba_init(void)
 
        chipcHw_busInterfaceClockEnable(bus_clock);
 
-       for (i = 0; i < ARRAY_SIZE(lookups); i++)
-               clkdev_add(&lookups[i]);
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
                struct amba_device *d = amba_devs[i];
index 64baf9f874087c8df7f7fc47e83c4c189f592978..fedd8076a689a3555a986b5e96bc9348cf4ae77f 100644 (file)
@@ -13,7 +13,7 @@
 
 #include <asm/hardware/clps7111.h>
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #CLPS7111_PHYS_BASE
index 17ab5236da6618af1a9ee2ebd32968692b050252..3cd93a801d9b94ba84689147d48c26e12df4ccfd 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/serial_reg.h>
 #define UART_SHIFT     2
 
-               .macro addruart, rx
+               .macro addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0x01000000        @ physical base address
index 41c89386e39b46f416aa4c9e12ee6332364ce21b..c45ba1f62a11a3b32d70b44e291a1f0bc8b98764 100644 (file)
@@ -27,7 +27,7 @@
 /*
  * I/O mapping
  */
-#define IO_PHYS                                0x01c00000
+#define IO_PHYS                                0x01c00000UL
 #define IO_OFFSET                      0xfd000000 /* Virtual IO = 0xfec00000 */
 #define IO_SIZE                                0x00400000
 #define IO_VIRT                                (IO_PHYS + IO_OFFSET)
index 49912b48b1b0f7a26c2b65729686687f84bb460a..a1c0b6b99edf03e1fa4ad6847797995a8a349d0f 100644 (file)
@@ -24,7 +24,7 @@ void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type)
        if (BETWEEN(p, IO_PHYS, IO_SIZE))
                return XLATE(p, IO_PHYS, IO_VIRT);
 
-       return __arm_ioremap(p, size, type);
+       return __arm_ioremap_caller(p, size, type, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(davinci_ioremap);
 
index 9b89ec7d3040fe272c1a1c5e7ab9b9b8e889d932..1521d13f1d14928a12a1a8b79ad4fd4d5037e3c1 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <mach/bridge-regs.h>
 
-       .macro  addruart,rx
+       .macro  addruart, rx, tmp
        mrc     p15, 0, \rx, c1, c0
        tst     \rx, #1                                 @ MMU enabled?
        ldreq   \rx, =DOVE_SB_REGS_PHYS_BASE
index 8b2c974755c6d0045cf0ff4ee7fb9d6b05005a41..a28792cf761e1618dbd66bdde8115dd3b3bc60b1 100644 (file)
@@ -2,4 +2,4 @@
  * arch/arm/mach-dove/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END    0xfd800000
+#define VMALLOC_END    0xfd800000UL
index 1dde8227f3a274d33d32f28a4b9d89cf9b56ac9f..ebbd89f0e6c0e8967171396e4113e82c6826d266 100644 (file)
@@ -11,7 +11,7 @@
  *
 **/
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mov     \rx, #0xf0000000
                orr     \rx, \rx, #0x00000be0
                .endm
index 9167c3d2a5edaf02ef6b74df0a00cab5572341ba..3a08b18f6433e28a35d3e2b4568bc6758c502082 100644 (file)
@@ -161,6 +161,20 @@ config MACH_MICRO9S
          Say 'Y' here if you want your kernel to support the
          Contec Micro9-Slim board.
 
+config MACH_SIM_ONE
+        bool "Support Simplemachines Sim.One board"
+        depends on EP93XX_SDCE0_PHYS_OFFSET
+        help
+          Say 'Y' here if you want your kernel to support the
+          Simplemachines Sim.One board.
+
+config MACH_SNAPPER_CL15
+       bool "Support Bluewater Systems Snapper CL15 Module"
+       depends on EP93XX_SDCE0_PHYS_OFFSET
+       help
+         Say 'Y' here if you want your kernel to support the Bluewater
+         Systems Snapper CL15 Module.
+
 config MACH_TS72XX
        bool "Support Technologic Systems TS-72xx SBC"
        depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
index eae6199a9891af49845774d9ddfc5f9b9e903007..33ee2c863d1808a1015098975fed81fe238e30d7 100644 (file)
@@ -10,4 +10,6 @@ obj-$(CONFIG_MACH_ADSSPHERE)  += adssphere.o
 obj-$(CONFIG_MACH_EDB93XX)     += edb93xx.o
 obj-$(CONFIG_MACH_GESBC9312)   += gesbc9312.o
 obj-$(CONFIG_MACH_MICRO9)      += micro9.o
+obj-$(CONFIG_MACH_SIM_ONE)     += simone.o
+obj-$(CONFIG_MACH_SNAPPER_CL15)        += snappercl15.o
 obj-$(CONFIG_MACH_TS72XX)      += ts72xx.o
index 1d0f9d8aff2e93583ba5ff0793f80d0f991f4786..5f80092b6ace0ec1c9c6b0fea7c334a83029e67a 100644 (file)
@@ -10,6 +10,8 @@
  * your option) any later version.
  */
 
+#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/err.h>
@@ -445,37 +447,39 @@ static void __init ep93xx_dma_clock_init(void)
 static int __init ep93xx_clock_init(void)
 {
        u32 value;
-       int i;
 
-       value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1);
-       if (!(value & 0x00800000)) {                    /* PLL1 bypassed?  */
+       /* Determine the bootloader configured pll1 rate */
+       value = __raw_readl(EP93XX_SYSCON_CLKSET1);
+       if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1))
                clk_pll1.rate = clk_xtali.rate;
-       } else {
+       else
                clk_pll1.rate = calc_pll_rate(value);
-       }
+
+       /* Initialize the pll1 derived clocks */
        clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
        clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
        clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
        ep93xx_dma_clock_init();
 
-       value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2);
-       if (!(value & 0x00080000)) {                    /* PLL2 bypassed?  */
+       /* Determine the bootloader configured pll2 rate */
+       value = __raw_readl(EP93XX_SYSCON_CLKSET2);
+       if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
                clk_pll2.rate = clk_xtali.rate;
-       } else if (value & 0x00040000) {                /* PLL2 enabled?  */
+       else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
                clk_pll2.rate = calc_pll_rate(value);
-       } else {
+       else
                clk_pll2.rate = 0;
-       }
+
+       /* Initialize the pll2 derived clocks */
        clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
 
-       printk(KERN_INFO "ep93xx: PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
+       pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
                clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
-       printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
+       pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
                clk_f.rate / 1000000, clk_h.rate / 1000000,
                clk_p.rate / 1000000);
 
-       for (i = 0; i < ARRAY_SIZE(clocks); i++)
-               clkdev_add(&clocks[i]);
+       clkdev_add_table(clocks, ARRAY_SIZE(clocks));
        return 0;
 }
 arch_initcall(ep93xx_clock_init);
index 1f0d66561bbe158b49fdd9c3e47d3b400e340ecb..90fb591cbffa6066e0b5fb732a0079834471c357 100644 (file)
  * your option) any later version.
  */
 
+#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
 #include <linux/timex.h>
+#include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
@@ -35,7 +38,6 @@
 
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
-#include <asm/mach/irq.h>
 
 #include <asm/hardware/vic.h>
 
@@ -82,13 +84,40 @@ void __init ep93xx_map_io(void)
  * to use this timer for something else.  We also use timer 4 for keeping
  * track of lost jiffies.
  */
-static unsigned int last_jiffy_time;
-
+#define EP93XX_TIMER_REG(x)            (EP93XX_TIMER_BASE + (x))
+#define EP93XX_TIMER1_LOAD             EP93XX_TIMER_REG(0x00)
+#define EP93XX_TIMER1_VALUE            EP93XX_TIMER_REG(0x04)
+#define EP93XX_TIMER1_CONTROL          EP93XX_TIMER_REG(0x08)
+#define EP93XX_TIMER123_CONTROL_ENABLE (1 << 7)
+#define EP93XX_TIMER123_CONTROL_MODE   (1 << 6)
+#define EP93XX_TIMER123_CONTROL_CLKSEL (1 << 3)
+#define EP93XX_TIMER1_CLEAR            EP93XX_TIMER_REG(0x0c)
+#define EP93XX_TIMER2_LOAD             EP93XX_TIMER_REG(0x20)
+#define EP93XX_TIMER2_VALUE            EP93XX_TIMER_REG(0x24)
+#define EP93XX_TIMER2_CONTROL          EP93XX_TIMER_REG(0x28)
+#define EP93XX_TIMER2_CLEAR            EP93XX_TIMER_REG(0x2c)
+#define EP93XX_TIMER4_VALUE_LOW                EP93XX_TIMER_REG(0x60)
+#define EP93XX_TIMER4_VALUE_HIGH       EP93XX_TIMER_REG(0x64)
+#define EP93XX_TIMER4_VALUE_HIGH_ENABLE        (1 << 8)
+#define EP93XX_TIMER3_LOAD             EP93XX_TIMER_REG(0x80)
+#define EP93XX_TIMER3_VALUE            EP93XX_TIMER_REG(0x84)
+#define EP93XX_TIMER3_CONTROL          EP93XX_TIMER_REG(0x88)
+#define EP93XX_TIMER3_CLEAR            EP93XX_TIMER_REG(0x8c)
+
+#define EP93XX_TIMER123_CLOCK          508469
+#define EP93XX_TIMER4_CLOCK            983040
+
+#define TIMER1_RELOAD                  ((EP93XX_TIMER123_CLOCK / HZ) - 1)
 #define TIMER4_TICKS_PER_JIFFY         DIV_ROUND_CLOSEST(CLOCK_TICK_RATE, HZ)
 
+static unsigned int last_jiffy_time;
+
 static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
 {
+       /* Writing any value clears the timer interrupt */
        __raw_writel(1, EP93XX_TIMER1_CLEAR);
+
+       /* Recover lost jiffies */
        while ((signed long)
                (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
                                                >= TIMER4_TICKS_PER_JIFFY) {
@@ -107,13 +136,18 @@ static struct irqaction ep93xx_timer_irq = {
 
 static void __init ep93xx_timer_init(void)
 {
+       u32 tmode = EP93XX_TIMER123_CONTROL_MODE |
+                   EP93XX_TIMER123_CONTROL_CLKSEL;
+
        /* Enable periodic HZ timer.  */
-       __raw_writel(0x48, EP93XX_TIMER1_CONTROL);
-       __raw_writel((508469 / HZ) - 1, EP93XX_TIMER1_LOAD);
-       __raw_writel(0xc8, EP93XX_TIMER1_CONTROL);
+       __raw_writel(tmode, EP93XX_TIMER1_CONTROL);
+       __raw_writel(TIMER1_RELOAD, EP93XX_TIMER1_LOAD);
+       __raw_writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE,
+                       EP93XX_TIMER1_CONTROL);
 
        /* Enable lost jiffy timer.  */
-       __raw_writel(0x100, EP93XX_TIMER4_VALUE_HIGH);
+       __raw_writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE,
+                       EP93XX_TIMER4_VALUE_HIGH);
 
        setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq);
 }
@@ -134,238 +168,17 @@ struct sys_timer ep93xx_timer = {
 };
 
 
-/*************************************************************************
- * GPIO handling for EP93xx
- *************************************************************************/
-static unsigned char gpio_int_unmasked[3];
-static unsigned char gpio_int_enabled[3];
-static unsigned char gpio_int_type1[3];
-static unsigned char gpio_int_type2[3];
-static unsigned char gpio_int_debounce[3];
-
-/* Port ordering is: A B F */
-static const u8 int_type1_register_offset[3]   = { 0x90, 0xac, 0x4c };
-static const u8 int_type2_register_offset[3]   = { 0x94, 0xb0, 0x50 };
-static const u8 eoi_register_offset[3]         = { 0x98, 0xb4, 0x54 };
-static const u8 int_en_register_offset[3]      = { 0x9c, 0xb8, 0x58 };
-static const u8 int_debounce_register_offset[3]        = { 0xa8, 0xc4, 0x64 };
-
-void ep93xx_gpio_update_int_params(unsigned port)
-{
-       BUG_ON(port > 2);
-
-       __raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
-
-       __raw_writeb(gpio_int_type2[port],
-               EP93XX_GPIO_REG(int_type2_register_offset[port]));
-
-       __raw_writeb(gpio_int_type1[port],
-               EP93XX_GPIO_REG(int_type1_register_offset[port]));
-
-       __raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
-               EP93XX_GPIO_REG(int_en_register_offset[port]));
-}
-
-void ep93xx_gpio_int_mask(unsigned line)
-{
-       gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
-}
-
-void ep93xx_gpio_int_debounce(unsigned int irq, int enable)
-{
-       int line = irq_to_gpio(irq);
-       int port = line >> 3;
-       int port_mask = 1 << (line & 7);
-
-       if (enable)
-               gpio_int_debounce[port] |= port_mask;
-       else
-               gpio_int_debounce[port] &= ~port_mask;
-
-       __raw_writeb(gpio_int_debounce[port],
-               EP93XX_GPIO_REG(int_debounce_register_offset[port]));
-}
-EXPORT_SYMBOL(ep93xx_gpio_int_debounce);
-
 /*************************************************************************
  * EP93xx IRQ handling
  *************************************************************************/
-static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-       unsigned char status;
-       int i;
-
-       status = __raw_readb(EP93XX_GPIO_A_INT_STATUS);
-       for (i = 0; i < 8; i++) {
-               if (status & (1 << i)) {
-                       int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
-                       generic_handle_irq(gpio_irq);
-               }
-       }
-
-       status = __raw_readb(EP93XX_GPIO_B_INT_STATUS);
-       for (i = 0; i < 8; i++) {
-               if (status & (1 << i)) {
-                       int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
-                       generic_handle_irq(gpio_irq);
-               }
-       }
-}
-
-static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-       /*
-        * map discontiguous hw irq range to continous sw irq range:
-        *
-        *  IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
-        */
-       int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
-       int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
-
-       generic_handle_irq(gpio_irq);
-}
-
-static void ep93xx_gpio_irq_ack(unsigned int irq)
-{
-       int line = irq_to_gpio(irq);
-       int port = line >> 3;
-       int port_mask = 1 << (line & 7);
-
-       if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
-               gpio_int_type2[port] ^= port_mask; /* switch edge direction */
-               ep93xx_gpio_update_int_params(port);
-       }
-
-       __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
-}
-
-static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
-{
-       int line = irq_to_gpio(irq);
-       int port = line >> 3;
-       int port_mask = 1 << (line & 7);
-
-       if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
-               gpio_int_type2[port] ^= port_mask; /* switch edge direction */
-
-       gpio_int_unmasked[port] &= ~port_mask;
-       ep93xx_gpio_update_int_params(port);
-
-       __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
-}
-
-static void ep93xx_gpio_irq_mask(unsigned int irq)
-{
-       int line = irq_to_gpio(irq);
-       int port = line >> 3;
-
-       gpio_int_unmasked[port] &= ~(1 << (line & 7));
-       ep93xx_gpio_update_int_params(port);
-}
-
-static void ep93xx_gpio_irq_unmask(unsigned int irq)
-{
-       int line = irq_to_gpio(irq);
-       int port = line >> 3;
-
-       gpio_int_unmasked[port] |= 1 << (line & 7);
-       ep93xx_gpio_update_int_params(port);
-}
-
-
-/*
- * gpio_int_type1 controls whether the interrupt is level (0) or
- * edge (1) triggered, while gpio_int_type2 controls whether it
- * triggers on low/falling (0) or high/rising (1).
- */
-static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
-{
-       struct irq_desc *desc = irq_desc + irq;
-       const int gpio = irq_to_gpio(irq);
-       const int port = gpio >> 3;
-       const int port_mask = 1 << (gpio & 7);
-
-       gpio_direction_input(gpio);
-
-       switch (type) {
-       case IRQ_TYPE_EDGE_RISING:
-               gpio_int_type1[port] |= port_mask;
-               gpio_int_type2[port] |= port_mask;
-               desc->handle_irq = handle_edge_irq;
-               break;
-       case IRQ_TYPE_EDGE_FALLING:
-               gpio_int_type1[port] |= port_mask;
-               gpio_int_type2[port] &= ~port_mask;
-               desc->handle_irq = handle_edge_irq;
-               break;
-       case IRQ_TYPE_LEVEL_HIGH:
-               gpio_int_type1[port] &= ~port_mask;
-               gpio_int_type2[port] |= port_mask;
-               desc->handle_irq = handle_level_irq;
-               break;
-       case IRQ_TYPE_LEVEL_LOW:
-               gpio_int_type1[port] &= ~port_mask;
-               gpio_int_type2[port] &= ~port_mask;
-               desc->handle_irq = handle_level_irq;
-               break;
-       case IRQ_TYPE_EDGE_BOTH:
-               gpio_int_type1[port] |= port_mask;
-               /* set initial polarity based on current input level */
-               if (gpio_get_value(gpio))
-                       gpio_int_type2[port] &= ~port_mask; /* falling */
-               else
-                       gpio_int_type2[port] |= port_mask; /* rising */
-               desc->handle_irq = handle_edge_irq;
-               break;
-       default:
-               pr_err("ep93xx: failed to set irq type %d for gpio %d\n",
-                      type, gpio);
-               return -EINVAL;
-       }
-
-       gpio_int_enabled[port] |= port_mask;
-
-       desc->status &= ~IRQ_TYPE_SENSE_MASK;
-       desc->status |= type & IRQ_TYPE_SENSE_MASK;
-
-       ep93xx_gpio_update_int_params(port);
-
-       return 0;
-}
-
-static struct irq_chip ep93xx_gpio_irq_chip = {
-       .name           = "GPIO",
-       .ack            = ep93xx_gpio_irq_ack,
-       .mask_ack       = ep93xx_gpio_irq_mask_ack,
-       .mask           = ep93xx_gpio_irq_mask,
-       .unmask         = ep93xx_gpio_irq_unmask,
-       .set_type       = ep93xx_gpio_irq_type,
-};
-
+extern void ep93xx_gpio_init_irq(void);
 
 void __init ep93xx_init_irq(void)
 {
-       int gpio_irq;
-
        vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0);
        vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0);
 
-       for (gpio_irq = gpio_to_irq(0);
-            gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
-               set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip);
-               set_irq_handler(gpio_irq, handle_level_irq);
-               set_irq_flags(gpio_irq, IRQF_VALID);
-       }
-
-       set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
-       set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler);
-       set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler);
-       set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler);
-       set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler);
-       set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler);
-       set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler);
-       set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler);
-       set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler);
+       ep93xx_gpio_init_irq();
 }
 
 
@@ -572,9 +385,9 @@ void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
         * CMOS driver.
         */
        if (data->sda_is_open_drain && data->sda_pin != EP93XX_GPIO_LINE_EEDAT)
-               pr_warning("ep93xx: sda != EEDAT, open drain has no effect\n");
+               pr_warning("sda != EEDAT, open drain has no effect\n");
        if (data->scl_is_open_drain && data->scl_pin != EP93XX_GPIO_LINE_EECLK)
-               pr_warning("ep93xx: scl != EECLK, open drain has no effect\n");
+               pr_warning("scl != EECLK, open drain has no effect\n");
 
        __raw_writel((data->sda_is_open_drain << 1) |
                     (data->scl_is_open_drain << 0),
index dbcac9c40a28883df558565be3c7e52c37426053..8904ca4e2e24fc9a4984bd0b88ce9d3eab52e7ea 100644 (file)
@@ -28,6 +28,8 @@
  * with this implementation.
  */
 
+#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/err.h>
@@ -173,7 +175,7 @@ static irqreturn_t m2p_irq(int irq, void *dev_id)
 
        switch (m2p_channel_state(ch)) {
        case STATE_IDLE:
-               pr_crit("m2p_irq: dma interrupt without a dma buffer\n");
+               pr_crit("dma interrupt without a dma buffer\n");
                BUG();
                break;
 
@@ -197,7 +199,7 @@ static irqreturn_t m2p_irq(int irq, void *dev_id)
                break;
 
        case STATE_NEXT:
-               pr_crit("m2p_irq: dma interrupt while next\n");
+               pr_crit("dma interrupt while next\n");
                BUG();
                break;
        }
index a4a7be3080002cb2c1577eeb2cb1cfb40ec4b68c..d22d67ac8b9938cd444fa6d212cf0acdaa8beba8 100644 (file)
@@ -118,12 +118,33 @@ static void __init edb93xx_register_i2c(void)
        }
 }
 
+
+/*************************************************************************
+ * EDB93xx pwm
+ *************************************************************************/
+static void __init edb93xx_register_pwm(void)
+{
+       if (machine_is_edb9301() ||
+           machine_is_edb9302() || machine_is_edb9302a()) {
+               /* EP9301 and EP9302 only have pwm.1 (EGPIO14) */
+               ep93xx_register_pwm(0, 1);
+       } else if (machine_is_edb9307() || machine_is_edb9307a()) {
+               /* EP9307 only has pwm.0 (PWMOUT) */
+               ep93xx_register_pwm(1, 0);
+       } else {
+               /* EP9312 and EP9315 have both */
+               ep93xx_register_pwm(1, 1);
+       }
+}
+
+
 static void __init edb93xx_init_machine(void)
 {
        ep93xx_init_devices();
        edb93xx_register_flash();
        ep93xx_register_eth(&edb93xx_eth_data, 1);
        edb93xx_register_i2c();
+       edb93xx_register_pwm();
 }
 
 
index 1ea8871e03a96db862ef27ebca06fc325baeb6aa..cc377ae8c4281324926f6d8f9c6ac645cd53b487 100644 (file)
@@ -13,6 +13,8 @@
  *  published by the Free Software Foundation.
  */
 
+#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/seq_file.h>
 
 #include <mach/hardware.h>
 
+/*************************************************************************
+ * GPIO handling for EP93xx
+ *************************************************************************/
+static unsigned char gpio_int_unmasked[3];
+static unsigned char gpio_int_enabled[3];
+static unsigned char gpio_int_type1[3];
+static unsigned char gpio_int_type2[3];
+static unsigned char gpio_int_debounce[3];
+
+/* Port ordering is: A B F */
+static const u8 int_type1_register_offset[3]   = { 0x90, 0xac, 0x4c };
+static const u8 int_type2_register_offset[3]   = { 0x94, 0xb0, 0x50 };
+static const u8 eoi_register_offset[3]         = { 0x98, 0xb4, 0x54 };
+static const u8 int_en_register_offset[3]      = { 0x9c, 0xb8, 0x58 };
+static const u8 int_debounce_register_offset[3]        = { 0xa8, 0xc4, 0x64 };
+
+void ep93xx_gpio_update_int_params(unsigned port)
+{
+       BUG_ON(port > 2);
+
+       __raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
+
+       __raw_writeb(gpio_int_type2[port],
+               EP93XX_GPIO_REG(int_type2_register_offset[port]));
+
+       __raw_writeb(gpio_int_type1[port],
+               EP93XX_GPIO_REG(int_type1_register_offset[port]));
+
+       __raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
+               EP93XX_GPIO_REG(int_en_register_offset[port]));
+}
+
+void ep93xx_gpio_int_mask(unsigned line)
+{
+       gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
+}
+
+void ep93xx_gpio_int_debounce(unsigned int irq, int enable)
+{
+       int line = irq_to_gpio(irq);
+       int port = line >> 3;
+       int port_mask = 1 << (line & 7);
+
+       if (enable)
+               gpio_int_debounce[port] |= port_mask;
+       else
+               gpio_int_debounce[port] &= ~port_mask;
+
+       __raw_writeb(gpio_int_debounce[port],
+               EP93XX_GPIO_REG(int_debounce_register_offset[port]));
+}
+EXPORT_SYMBOL(ep93xx_gpio_int_debounce);
+
+static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+       unsigned char status;
+       int i;
+
+       status = __raw_readb(EP93XX_GPIO_A_INT_STATUS);
+       for (i = 0; i < 8; i++) {
+               if (status & (1 << i)) {
+                       int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
+                       generic_handle_irq(gpio_irq);
+               }
+       }
+
+       status = __raw_readb(EP93XX_GPIO_B_INT_STATUS);
+       for (i = 0; i < 8; i++) {
+               if (status & (1 << i)) {
+                       int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
+                       generic_handle_irq(gpio_irq);
+               }
+       }
+}
+
+static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+       /*
+        * map discontiguous hw irq range to continous sw irq range:
+        *
+        *  IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
+        */
+       int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
+       int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
+
+       generic_handle_irq(gpio_irq);
+}
+
+static void ep93xx_gpio_irq_ack(unsigned int irq)
+{
+       int line = irq_to_gpio(irq);
+       int port = line >> 3;
+       int port_mask = 1 << (line & 7);
+
+       if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
+               gpio_int_type2[port] ^= port_mask; /* switch edge direction */
+               ep93xx_gpio_update_int_params(port);
+       }
+
+       __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
+}
+
+static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
+{
+       int line = irq_to_gpio(irq);
+       int port = line >> 3;
+       int port_mask = 1 << (line & 7);
+
+       if ((irq_desc[irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
+               gpio_int_type2[port] ^= port_mask; /* switch edge direction */
+
+       gpio_int_unmasked[port] &= ~port_mask;
+       ep93xx_gpio_update_int_params(port);
+
+       __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
+}
+
+static void ep93xx_gpio_irq_mask(unsigned int irq)
+{
+       int line = irq_to_gpio(irq);
+       int port = line >> 3;
+
+       gpio_int_unmasked[port] &= ~(1 << (line & 7));
+       ep93xx_gpio_update_int_params(port);
+}
+
+static void ep93xx_gpio_irq_unmask(unsigned int irq)
+{
+       int line = irq_to_gpio(irq);
+       int port = line >> 3;
+
+       gpio_int_unmasked[port] |= 1 << (line & 7);
+       ep93xx_gpio_update_int_params(port);
+}
+
+/*
+ * gpio_int_type1 controls whether the interrupt is level (0) or
+ * edge (1) triggered, while gpio_int_type2 controls whether it
+ * triggers on low/falling (0) or high/rising (1).
+ */
+static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
+{
+       struct irq_desc *desc = irq_desc + irq;
+       const int gpio = irq_to_gpio(irq);
+       const int port = gpio >> 3;
+       const int port_mask = 1 << (gpio & 7);
+
+       gpio_direction_input(gpio);
+
+       switch (type) {
+       case IRQ_TYPE_EDGE_RISING:
+               gpio_int_type1[port] |= port_mask;
+               gpio_int_type2[port] |= port_mask;
+               desc->handle_irq = handle_edge_irq;
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+               gpio_int_type1[port] |= port_mask;
+               gpio_int_type2[port] &= ~port_mask;
+               desc->handle_irq = handle_edge_irq;
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+               gpio_int_type1[port] &= ~port_mask;
+               gpio_int_type2[port] |= port_mask;
+               desc->handle_irq = handle_level_irq;
+               break;
+       case IRQ_TYPE_LEVEL_LOW:
+               gpio_int_type1[port] &= ~port_mask;
+               gpio_int_type2[port] &= ~port_mask;
+               desc->handle_irq = handle_level_irq;
+               break;
+       case IRQ_TYPE_EDGE_BOTH:
+               gpio_int_type1[port] |= port_mask;
+               /* set initial polarity based on current input level */
+               if (gpio_get_value(gpio))
+                       gpio_int_type2[port] &= ~port_mask; /* falling */
+               else
+                       gpio_int_type2[port] |= port_mask; /* rising */
+               desc->handle_irq = handle_edge_irq;
+               break;
+       default:
+               pr_err("failed to set irq type %d for gpio %d\n", type, gpio);
+               return -EINVAL;
+       }
+
+       gpio_int_enabled[port] |= port_mask;
+
+       desc->status &= ~IRQ_TYPE_SENSE_MASK;
+       desc->status |= type & IRQ_TYPE_SENSE_MASK;
+
+       ep93xx_gpio_update_int_params(port);
+
+       return 0;
+}
+
+static struct irq_chip ep93xx_gpio_irq_chip = {
+       .name           = "GPIO",
+       .ack            = ep93xx_gpio_irq_ack,
+       .mask_ack       = ep93xx_gpio_irq_mask_ack,
+       .mask           = ep93xx_gpio_irq_mask,
+       .unmask         = ep93xx_gpio_irq_unmask,
+       .set_type       = ep93xx_gpio_irq_type,
+};
+
+void __init ep93xx_gpio_init_irq(void)
+{
+       int gpio_irq;
+
+       for (gpio_irq = gpio_to_irq(0);
+            gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
+               set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip);
+               set_irq_handler(gpio_irq, handle_level_irq);
+               set_irq_flags(gpio_irq, IRQF_VALID);
+       }
+
+       set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler);
+       set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler);
+}
+
+
+/*************************************************************************
+ * gpiolib interface for EP93xx on-chip GPIOs
+ *************************************************************************/
 struct ep93xx_gpio_chip {
        struct gpio_chip        chip;
 
@@ -31,10 +262,6 @@ struct ep93xx_gpio_chip {
 
 #define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip)
 
-/* From core.c */
-extern void ep93xx_gpio_int_mask(unsigned line);
-extern void ep93xx_gpio_update_int_params(unsigned port);
-
 static int ep93xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 {
        struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
index 802858bc80958b90358aec6ac399d509efe73193..5cd22444e2236ae8fb73e59641e8dd82347f0fdf 100644 (file)
@@ -11,7 +11,7 @@
  */
 #include <mach/ep93xx-regs.h>
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                         @ MMU enabled?
                ldreq   \rx, =EP93XX_APB_PHYS_BASE      @ Physical base
index d55194a4c0934391cb096027969a08791e37cadf..93e2ecc79ceb14896e2665acc97a15eac0fd162d 100644 (file)
 
 /* APB peripherals */
 #define EP93XX_TIMER_BASE              EP93XX_APB_IOMEM(0x00010000)
-#define EP93XX_TIMER_REG(x)            (EP93XX_TIMER_BASE + (x))
-#define EP93XX_TIMER1_LOAD             EP93XX_TIMER_REG(0x00)
-#define EP93XX_TIMER1_VALUE            EP93XX_TIMER_REG(0x04)
-#define EP93XX_TIMER1_CONTROL          EP93XX_TIMER_REG(0x08)
-#define EP93XX_TIMER1_CLEAR            EP93XX_TIMER_REG(0x0c)
-#define EP93XX_TIMER2_LOAD             EP93XX_TIMER_REG(0x20)
-#define EP93XX_TIMER2_VALUE            EP93XX_TIMER_REG(0x24)
-#define EP93XX_TIMER2_CONTROL          EP93XX_TIMER_REG(0x28)
-#define EP93XX_TIMER2_CLEAR            EP93XX_TIMER_REG(0x2c)
-#define EP93XX_TIMER4_VALUE_LOW                EP93XX_TIMER_REG(0x60)
-#define EP93XX_TIMER4_VALUE_HIGH       EP93XX_TIMER_REG(0x64)
-#define EP93XX_TIMER3_LOAD             EP93XX_TIMER_REG(0x80)
-#define EP93XX_TIMER3_VALUE            EP93XX_TIMER_REG(0x84)
-#define EP93XX_TIMER3_CONTROL          EP93XX_TIMER_REG(0x88)
-#define EP93XX_TIMER3_CLEAR            EP93XX_TIMER_REG(0x8c)
 
 #define EP93XX_I2S_BASE                        EP93XX_APB_IOMEM(0x00020000)
 
 #define EP93XX_SYSCON_PWRCNT_DMA_M2P1  (1<<16)
 #define EP93XX_SYSCON_HALT             EP93XX_SYSCON_REG(0x08)
 #define EP93XX_SYSCON_STANDBY          EP93XX_SYSCON_REG(0x0c)
-#define EP93XX_SYSCON_CLOCK_SET1       EP93XX_SYSCON_REG(0x20)
-#define EP93XX_SYSCON_CLOCK_SET2       EP93XX_SYSCON_REG(0x24)
+#define EP93XX_SYSCON_CLKSET1          EP93XX_SYSCON_REG(0x20)
+#define EP93XX_SYSCON_CLKSET1_NBYP1    (1<<23)
+#define EP93XX_SYSCON_CLKSET2          EP93XX_SYSCON_REG(0x24)
+#define EP93XX_SYSCON_CLKSET2_NBYP2    (1<<19)
+#define EP93XX_SYSCON_CLKSET2_PLL2_EN  (1<<18)
 #define EP93XX_SYSCON_DEVCFG           EP93XX_SYSCON_REG(0x80)
 #define EP93XX_SYSCON_DEVCFG_SWRST     (1<<31)
 #define EP93XX_SYSCON_DEVCFG_D1ONG     (1<<30)
index aed21cd3fe2d85ba006fe10970cced78a72ba7c9..1b3f25d03d39134d69a6043f257dcc300c04373b 100644 (file)
@@ -2,4 +2,4 @@
  * arch/arm/mach-ep93xx/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END    0xfe800000
+#define VMALLOC_END    0xfe800000UL
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
new file mode 100644 (file)
index 0000000..cd93990
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * arch/arm/mach-ep93xx/simone.c
+ * Simplemachines Sim.One support.
+ *
+ * Copyright (C) 2010 Ryan Mallon <ryan@bluewatersys.com>
+ *
+ * Based on the 2.6.24.7 support:
+ *   Copyright (C) 2009 Simplemachines
+ *   MMC support by Peter Ivanov <ivanovp@gmail.com>, 2007
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/fb.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct physmap_flash_data simone_flash_data = {
+       .width          = 2,
+};
+
+static struct resource simone_flash_resource = {
+       .start          = EP93XX_CS6_PHYS_BASE,
+       .end            = EP93XX_CS6_PHYS_BASE + SZ_8M - 1,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device simone_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .num_resources  = 1,
+       .resource       = &simone_flash_resource,
+       .dev = {
+               .platform_data  = &simone_flash_data,
+       },
+};
+
+static struct ep93xx_eth_data simone_eth_data = {
+       .phy_id         = 1,
+};
+
+static struct ep93xxfb_mach_info simone_fb_info = {
+       .num_modes      = EP93XXFB_USE_MODEDB,
+       .bpp            = 16,
+       .flags          = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
+};
+
+static struct i2c_gpio_platform_data simone_i2c_gpio_data = {
+       .sda_pin                = EP93XX_GPIO_LINE_EEDAT,
+       .sda_is_open_drain      = 0,
+       .scl_pin                = EP93XX_GPIO_LINE_EECLK,
+       .scl_is_open_drain      = 0,
+       .udelay                 = 0,
+       .timeout                = 0,
+};
+
+static struct i2c_board_info __initdata simone_i2c_board_info[] = {
+       {
+               I2C_BOARD_INFO("ds1337", 0x68),
+       },
+};
+
+static void __init simone_init_machine(void)
+{
+       ep93xx_init_devices();
+
+       platform_device_register(&simone_flash);
+       ep93xx_register_eth(&simone_eth_data, 1);
+       ep93xx_register_fb(&simone_fb_info);
+       ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
+                           ARRAY_SIZE(simone_i2c_board_info));
+}
+
+MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")
+/* Maintainer: Ryan Mallon <ryan@bluewatersys.com> */
+       .phys_io        = EP93XX_APB_PHYS_BASE,
+       .io_pg_offst    = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
+       .boot_params    = EP93XX_SDCE0_PHYS_BASE + 0x100,
+       .map_io         = ep93xx_map_io,
+       .init_irq       = ep93xx_init_irq,
+       .timer          = &ep93xx_timer,
+       .init_machine   = simone_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c
new file mode 100644 (file)
index 0000000..51134b0
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * arch/arm/mach-ep93xx/snappercl15.c
+ * Bluewater Systems Snapper CL15 system module
+ *
+ * Copyright (C) 2009 Bluewater Systems Ltd
+ * Author: Ryan Mallon <ryan@bluewatersys.com>
+ *
+ * NAND code adapted from driver by:
+ *   Andre Renaud <andre@bluewatersys.com>
+ *   James R. McKaskill
+ *
+ * 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.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/fb.h>
+
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+
+#include <mach/hardware.h>
+#include <mach/fb.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#define SNAPPERCL15_NAND_BASE  (EP93XX_CS7_PHYS_BASE + SZ_16M)
+
+#define SNAPPERCL15_NAND_WPN   (1 << 8)  /* Write protect (active low) */
+#define SNAPPERCL15_NAND_ALE   (1 << 9)  /* Address latch */
+#define SNAPPERCL15_NAND_CLE   (1 << 10) /* Command latch */
+#define SNAPPERCL15_NAND_CEN   (1 << 11) /* Chip enable (active low) */
+#define SNAPPERCL15_NAND_RDY   (1 << 14) /* Device ready */
+
+#define NAND_CTRL_ADDR(chip)   (chip->IO_ADDR_W + 0x40)
+
+static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+                                     unsigned int ctrl)
+{
+       struct nand_chip *chip = mtd->priv;
+       static u16 nand_state = SNAPPERCL15_NAND_WPN;
+       u16 set;
+
+       if (ctrl & NAND_CTRL_CHANGE) {
+               set = SNAPPERCL15_NAND_CEN | SNAPPERCL15_NAND_WPN;
+
+               if (ctrl & NAND_NCE)
+                       set &= ~SNAPPERCL15_NAND_CEN;
+               if (ctrl & NAND_CLE)
+                       set |= SNAPPERCL15_NAND_CLE;
+               if (ctrl & NAND_ALE)
+                       set |= SNAPPERCL15_NAND_ALE;
+
+               nand_state &= ~(SNAPPERCL15_NAND_CEN |
+                               SNAPPERCL15_NAND_CLE |
+                               SNAPPERCL15_NAND_ALE);
+               nand_state |= set;
+               __raw_writew(nand_state, NAND_CTRL_ADDR(chip));
+       }
+
+       if (cmd != NAND_CMD_NONE)
+               __raw_writew((cmd & 0xff) | nand_state, chip->IO_ADDR_W);
+}
+
+static int snappercl15_nand_dev_ready(struct mtd_info *mtd)
+{
+       struct nand_chip *chip = mtd->priv;
+
+       return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY);
+}
+
+static const char *snappercl15_nand_part_probes[] = {"cmdlinepart", NULL};
+
+static struct mtd_partition snappercl15_nand_parts[] = {
+       {
+               .name           = "Kernel",
+               .offset         = 0,
+               .size           = SZ_2M,
+       },
+       {
+               .name           = "Filesystem",
+               .offset         = MTDPART_OFS_APPEND,
+               .size           = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct platform_nand_data snappercl15_nand_data = {
+       .chip = {
+               .nr_chips               = 1,
+               .part_probe_types       = snappercl15_nand_part_probes,
+               .partitions             = snappercl15_nand_parts,
+               .nr_partitions          = ARRAY_SIZE(snappercl15_nand_parts),
+               .options                = NAND_NO_AUTOINCR,
+               .chip_delay             = 25,
+       },
+       .ctrl = {
+               .dev_ready              = snappercl15_nand_dev_ready,
+               .cmd_ctrl               = snappercl15_nand_cmd_ctrl,
+       },
+};
+
+static struct resource snappercl15_nand_resource[] = {
+       {
+               .start          = SNAPPERCL15_NAND_BASE,
+               .end            = SNAPPERCL15_NAND_BASE + SZ_4K - 1,
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device snappercl15_nand_device = {
+       .name                   = "gen_nand",
+       .id                     = -1,
+       .dev.platform_data      = &snappercl15_nand_data,
+       .resource               = snappercl15_nand_resource,
+       .num_resources          = ARRAY_SIZE(snappercl15_nand_resource),
+};
+
+static struct ep93xx_eth_data snappercl15_eth_data = {
+       .phy_id                 = 1,
+};
+
+static struct i2c_gpio_platform_data snappercl15_i2c_gpio_data = {
+       .sda_pin                = EP93XX_GPIO_LINE_EEDAT,
+       .sda_is_open_drain      = 0,
+       .scl_pin                = EP93XX_GPIO_LINE_EECLK,
+       .scl_is_open_drain      = 0,
+       .udelay                 = 0,
+       .timeout                = 0,
+};
+
+static struct i2c_board_info __initdata snappercl15_i2c_data[] = {
+       {
+               /* Audio codec */
+               I2C_BOARD_INFO("tlv320aic23", 0x1a),
+       },
+};
+
+static struct ep93xxfb_mach_info snappercl15_fb_info = {
+       .num_modes              = EP93XXFB_USE_MODEDB,
+       .bpp                    = 16,
+};
+
+static void __init snappercl15_init_machine(void)
+{
+       ep93xx_init_devices();
+       ep93xx_register_eth(&snappercl15_eth_data, 1);
+       ep93xx_register_i2c(&snappercl15_i2c_gpio_data, snappercl15_i2c_data,
+                           ARRAY_SIZE(snappercl15_i2c_data));
+       ep93xx_register_fb(&snappercl15_fb_info);
+       platform_device_register(&snappercl15_nand_device);
+}
+
+MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15")
+       /* Maintainer: Ryan Mallon <ryan@bluewatersys.com> */
+       .phys_io        = EP93XX_APB_PHYS_BASE,
+       .io_pg_offst    = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
+       .boot_params    = EP93XX_SDCE0_PHYS_BASE + 0x100,
+       .map_io         = ep93xx_map_io,
+       .init_irq       = ep93xx_init_irq,
+       .timer          = &ep93xx_timer,
+       .init_machine   = snappercl15_init_machine,
+MACHINE_END
index 41febc796b1c7e1564684eccc910516568fb54ad..e3bc3f6f6b105d42c8d4f73d33b4d5f92fc15a81 100644 (file)
@@ -32,12 +32,13 @@ unsigned int mem_fclk_21285 = 50000000;
 
 EXPORT_SYMBOL(mem_fclk_21285);
 
-static void __init early_fclk(char **arg)
+static int __init early_fclk(char *arg)
 {
-       mem_fclk_21285 = simple_strtoul(*arg, arg, 0);
+       mem_fclk_21285 = simple_strtoul(arg, NULL, 0);
+       return 0;
 }
 
-__early_param("mem_fclk_21285=", early_fclk);
+early_param("mem_fclk_21285", early_fclk);
 
 static int __init parse_tag_memclk(const struct tag *tag)
 {
index 4329b81235708637cb6bc003638f7c3090a5c9f2..60dda1318f2285785829c46c399889d5da495c89 100644 (file)
@@ -15,7 +15,7 @@
 
 #ifndef CONFIG_DEBUG_DC21285_PORT
        /* For NetWinder debugging */
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0x7c000000        @ physical
@@ -32,7 +32,7 @@
                .equ    dc21285_high, ARMCSR_BASE & 0xff000000
                .equ    dc21285_low,  ARMCSR_BASE & 0x00ffffff
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0x42000000
index d04a6eaeae14ad8e0545585c15b1a397c1e3a668..ad477047069ddc9188e33657f3ad0b5338b83e11 100644 (file)
@@ -11,7 +11,7 @@
  */
 #include <mach/hardware.h>
 
-       .macro  addruart,rx
+       .macro  addruart, rx, tmp
        mrc     p15, 0, \rx, c1, c0
        tst     \rx, #1                                 @ MMU enabled?
        ldreq   \rx, =GEMINI_UART_BASE                  @ physical
index 83e536d9436c02c7742edb78bd2906dbbc4338ca..45371eb86fcbf332020a9bb4a8e29a53b39b41ef 100644 (file)
@@ -7,4 +7,4 @@
  * (at your option) any later version.
  */
 
-#define VMALLOC_END    0xF0000000
+#define VMALLOC_END    0xf0000000UL
index 6294a1344dda80f81d89a1191f4a733ef4095f0f..a9ee8f0d48b7f6792ea5004844649c3acb3a5bd0 100644 (file)
@@ -14,7 +14,7 @@
                .equ    io_virt, IO_BASE
                .equ    io_phys, IO_START
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                @ MMU enabled?
                moveq   \rx, #io_phys          @ physical base address
index a0f60e55da6a8a2bb7c1cf05fc6bd889e605721f..8b390e36ba69db77a44fd228b6e17a1909b4ca8a 100644 (file)
@@ -144,8 +144,7 @@ static int __init integrator_init(void)
 {
        int i;
 
-       for (i = 0; i < ARRAY_SIZE(lookups); i++)
-               clkdev_add(&lookups[i]);
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
                struct amba_device *d = amba_devs[i];
index d347d659ea308c74edc6aa5870aae9b05e5f85d2..87a6888ae011ba71e3764f02ab97a1b74260e839 100644 (file)
@@ -11,7 +11,7 @@
  *
 */
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0x16000000        @ physical base address
index 3f35293d457a3cf0d44a6dc2ace58a918ea4c520..66ef86d6d9e3d0d80aa46f2e6f09d4314a491426 100644 (file)
@@ -558,9 +558,7 @@ static void __init intcp_init(void)
 {
        int i;
 
-       for (i = 0; i < ARRAY_SIZE(cp_lookups); i++)
-               clkdev_add(&cp_lookups[i]);
-
+       clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
        platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
 
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
index 9037d2e8557cbb163a07d2b47cbe967f959cf4fb..c9d6ba46963da99c4f5c8ede984a27f470238024 100644 (file)
@@ -11,7 +11,7 @@
  * published by the Free Software Foundation.
  */
 
-       .macro  addruart, rx
+       .macro  addruart, rx, tmp
        mrc     p15, 0, \rx, c1, c0
        tst     \rx, #1                 @ mmu enabled?
        moveq   \rx, #0xff000000        @ physical
index 52958099781400702fa380324148c842eefaa823..48642e66c5663007129db7bec7cd909e6749fa49 100644 (file)
@@ -61,9 +61,9 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
                                 (cookie - IOP13XX_PCIE_LOWER_MEM_RA));
                break;
        case IOP13XX_PBI_LOWER_MEM_RA ... IOP13XX_PBI_UPPER_MEM_RA:
-               retval = __arm_ioremap(IOP13XX_PBI_LOWER_MEM_PA +
+               retval = __arm_ioremap_caller(IOP13XX_PBI_LOWER_MEM_PA +
                                       (cookie - IOP13XX_PBI_LOWER_MEM_RA),
-                                      size, mtype);
+                                      size, mtype, __builtin_return_address(0));
                break;
        case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
                retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie);
@@ -75,7 +75,8 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
                retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie);
                break;
        default:
-               retval = __arm_ioremap(cookie, size, mtype);
+               retval = __arm_ioremap_caller(cookie, size, mtype,
+                               __builtin_return_address(0));
        }
 
        return retval;
index 58b01664ffba5edc93f81e002bc79259f418b374..736afe1edd1f668c4f84850b1604a3fc98a699b2 100644 (file)
@@ -11,7 +11,7 @@
  * published by the Free Software Foundation.
  */
 
-               .macro  addruart, rx
+               .macro  addruart, rx, tmp
                mov     \rx, #0xfe000000        @ physical as well as virtual
                orr     \rx, \rx, #0x00800000   @ location of the UART
                .endm
index 85ceb09d85f031f9d77397a12d8c298130929b2c..c4862d48e583165bfb1ee2185a35742851a6ad71 100644 (file)
@@ -2,4 +2,4 @@
  * arch/arm/mach-iop32x/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END    0xfe000000
+#define VMALLOC_END    0xfe000000UL
index a60c9ef05cc3cf16d3097ec94f1789b9e3097f7f..addb2da78422b0ff58df52a64dce48fe57bdd169 100644 (file)
@@ -11,7 +11,7 @@
  * published by the Free Software Foundation.
  */
 
-               .macro  addruart, rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ mmu enabled?
                moveq   \rx, #0xff000000        @ physical
index f9f99dea9bc44db39dd671bf66047077015856e0..48331dc2370411ca75db48058ea1ca8f5966a763 100644 (file)
@@ -2,4 +2,4 @@
  * arch/arm/mach-iop33x/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END    0xfe000000
+#define VMALLOC_END    0xfe000000UL
index 904ff56d2246e9c91671b09dfdcee60598504f58..6a827681680fe20b833c07bc1990c488d1c20dae 100644 (file)
@@ -11,7 +11,7 @@
  *
 */
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0xc0000000        @ Physical base
index d195e35aed3bfe88a40ba18c9591433e63454883..61c8dae24f959f5311cc1c12ac651ca88fb2a67f 100644 (file)
@@ -17,4 +17,4 @@
  * The vmalloc() routines leaves a hole of 4kB between each vmalloced
  * area for the same reason. ;)
  */
-#define VMALLOC_END        0xfb000000
+#define VMALLOC_END        0xfb000000UL
index 905db3188724372ea1ff0ed0e5983050d1263fbf..a82e375465e283651c4f8e96ea7913c4a77f4b35 100644 (file)
@@ -12,7 +12,7 @@
  */
 #include <mach/ixp23xx.h>
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                         @ mmu enabled?
                ldreq   \rx, =IXP23XX_PERIPHERAL_PHYS   @ physical
index dd519f678d10fda041407d400ff5a732e0192ae1..896c56a1c00e4df2caa9a22192a2b6288cb3931a 100644 (file)
@@ -7,4 +7,4 @@
  * specific static I/O.
  */
 
-#define VMALLOC_END    (0xec000000)
+#define VMALLOC_END    (0xec000000UL)
index 3bbf40f6d964b277a7a153fa6a93e694c73ff9da..71728d36d501887f35fdff0ed67dd6714e2f9a3b 100644 (file)
@@ -426,6 +426,17 @@ static void __init ixp4xx_clocksource_init(void)
        clocksource_register(&clocksource_ixp4xx);
 }
 
+/*
+ * sched_clock()
+ */
+unsigned long long sched_clock(void)
+{
+       cycle_t cyc = ixp4xx_get_cycles(NULL);
+       struct clocksource *cs = &clocksource_ixp4xx;
+
+       return clocksource_cyc2ns(cyc, cs->mult, cs->shift);
+}
+
 /*
  * clockevents
  */
index 7c6a6912acdeef809e1e1296b187cf905c4d637a..893873eb2a0d9b584da49485af9819bdeac68ae9 100644 (file)
@@ -10,7 +10,7 @@
  * published by the Free Software Foundation.
 */
 
-                .macro  addruart,rx
+                .macro  addruart, rx, tmp
                 mrc     p15, 0, \rx, c1, c0
                 tst     \rx, #1                 @ MMU enabled?
                 moveq   \rx, #0xc8000000
index 7b3580b53adf3689a542d26670b550698d44bda4..9bcd64d59854559aad55acd19438d7c70927d4dc 100644 (file)
@@ -1,5 +1,5 @@
 /*
  * arch/arm/mach-ixp4xx/include/mach/vmalloc.h
  */
-#define VMALLOC_END       (0xFF000000)
+#define VMALLOC_END       (0xff000000UL)
 
index a4a55c199d77638d92f8b48b62a8e9e39cbfa8c3..d0606774dea7de3baa03e4291dd016b0825dde07 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <mach/bridge-regs.h>
 
-       .macro  addruart,rx
+       .macro  addruart, rx, tmp
        mrc     p15, 0, \rx, c1, c0
        tst     \rx, #1                                 @ MMU enabled?
        ldreq   \rx, =KIRKWOOD_REGS_PHYS_BASE
index 8f48260dcdadbe6ea3eeeef07b3c13d12d2a75a7..bf162ca3d2c16b625f819fb6cdc3bb4be43a38d1 100644 (file)
@@ -2,4 +2,4 @@
  * arch/arm/mach-kirkwood/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END    0xfe800000
+#define VMALLOC_END    0xfe800000UL
index 3782c3559497e52464d0aca8ba56a917b8198078..cf2095da2372cddfb0e3105f1ab04ac4fc4fc61c 100644 (file)
@@ -14,7 +14,7 @@
 #include <mach/hardware.h>
 #include <mach/regs-uart.h>
 
-       .macro  addruart, rx
+       .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                         @ MMU enabled?
                ldreq   \rx, =KS8695_UART_PA            @ physical base address
index 34eed2a63e69951eda7db9f8ea291dd04ba5be1b..b69ed344c7c981a4c6b94e2564a16be411849401 100644 (file)
@@ -14,7 +14,7 @@
                .equ    io_virt, IO_BASE
                .equ    io_phys, IO_START
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #io_phys           @ physical base address
index 85141ed5383d1c355af041622099d545c5c1dfef..c0dcbbba22ba6f7eeb0af9893579f7aedc870879 100644 (file)
@@ -14,7 +14,7 @@
        @ It is not known if this will be appropriate for every 40x
        @ board.
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                mov     \rx, #0x00000700        @ offset from base
index 3fbd49490bb9d7290165aba3e6d67fa425d41a4e..d62da7358b16c05ad716cb7d91dabfbce914721a 100644 (file)
@@ -7,4 +7,4 @@
  *  version 2 as published by the Free Software Foundation.
  *
  */
-#define VMALLOC_END       (0xe8000000)
+#define VMALLOC_END       (0xe8000000UL)
index a8c20bd2f9514d87ca5acef76b0ce75ddf250d05..3136c913a92c2c4886cbcd232f145f9aac2572f2 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <mach/loki.h>
 
-       .macro  addruart,rx
+       .macro  addruart, rx, tmp
        mrc     p15, 0, \rx, c1, c0
        tst     \rx, #1                                 @ MMU enabled?
        ldreq   \rx, =LOKI_REGS_PHYS_BASE
index 8dc3bfcbf9f07eb1754411d4ca82adfade746200..5dcbd865443f0bae5415dc5288d195854c1178a0 100644 (file)
@@ -2,4 +2,4 @@
  * arch/arm/mach-loki/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END    0xfe800000
+#define VMALLOC_END    0xfe800000UL
index 2a46ed5cc2a297e0356529b7465e0a8c52a06231..886e05648f08a5a4975bc0257b2b0929e9fffc1f 100644 (file)
@@ -88,11 +88,3 @@ unsigned long clk_get_rate(struct clk *clk)
        return rate;
 }
 EXPORT_SYMBOL(clk_get_rate);
-
-void clks_register(struct clk_lookup *clks, size_t num)
-{
-       int i;
-
-       for (i = 0; i < num; i++)
-               clkdev_add(&clks[i]);
-}
index eefffbe683b0263e4c053833b7f1025b3ed83f27..016ae94691c04cd42838c9b0af352b68a6e7cacc 100644 (file)
@@ -68,5 +68,3 @@ struct clk clk_##_name = {                                    \
 
 extern struct clk clk_pxa168_gpio;
 extern struct clk clk_pxa168_timers;
-
-extern void clks_register(struct clk_lookup *, size_t);
index a850f87de51d90c68030f5dd5e256a33d69382af..76deff238e1c5f394505a0a413d3fb98577d0645 100644 (file)
@@ -11,7 +11,7 @@
 
 #include <mach/addr-map.h>
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                         @ MMU enabled?
                ldreq   \rx, =APB_PHYS_BASE             @ physical
index b60ccaf9fee75dff3da8e152c8d69e72dc002351..1d0bac003ad0bb984b1430e9ba01531b37777bf7 100644 (file)
@@ -2,4 +2,4 @@
  * linux/arch/arm/mach-mmp/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END    0xfe000000
+#define VMALLOC_END    0xfe000000UL
index 37dbdde17fac5b83bc739edc5b0493986fd9bf9c..1873c821df9051ebd37fe65a154ed437cb8a3608 100644 (file)
@@ -94,7 +94,7 @@ static int __init pxa168_init(void)
                mfp_init_base(MFPR_VIRT_BASE);
                mfp_init_addr(pxa168_mfp_addr_map);
                pxa_init_dma(IRQ_PXA168_DMA_INT0, 32);
-               clks_register(ARRAY_AND_SIZE(pxa168_clkregs));
+               clkdev_add_table(ARRAY_AND_SIZE(pxa168_clkregs));
        }
 
        return 0;
index d4049508a4df5cf71725bca0178f2ab754fce7bb..46f2d69bef3cf01dd3778a380fa2b1801799cef1 100644 (file)
@@ -131,7 +131,7 @@ static int __init pxa910_init(void)
                mfp_init_base(MFPR_VIRT_BASE);
                mfp_init_addr(pxa910_mfp_addr_map);
                pxa_init_dma(IRQ_PXA910_DMA_INT0, 32);
-               clks_register(ARRAY_AND_SIZE(pxa910_clkregs));
+               clkdev_add_table(ARRAY_AND_SIZE(pxa910_clkregs));
        }
 
        return 0;
index d48747ebcd3dc64be6df5bbd0409a5e6705f43bf..528750f307e9428433c97101153be1933d495ba8 100644 (file)
@@ -20,7 +20,7 @@
 #include <mach/msm_iomap.h>
 
 #ifdef CONFIG_MSM_DEBUG_UART
-       .macro  addruart,rx
+       .macro  addruart, rx, tmp
        @ see if the MMU is enabled and select appropriate base address
        mrc     p15, 0, \rx, c1, c0
        tst     \rx, #1
@@ -40,7 +40,7 @@
        beq     1001b
        .endm
 #else
-       .macro  addruart,rx
+       .macro  addruart, rx, tmp
        .endm
 
        .macro  senduart,rd,rx
index 1c5e7dac086f1892d9a6c831f8d5cf99dee90453..05f96b780aa6a811584fa3d25cfc4e2ce5ce6e0f 100644 (file)
@@ -76,5 +76,6 @@ __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
                        mtype = MT_DEVICE_NONSHARED;
        }
 
-       return __arm_ioremap(phys_addr, size, mtype);
+       return __arm_ioremap_caller(phys_addr, size, mtype,
+               __builtin_return_address(0));
 }
index a06442fbd3415b9bd935daf71b809685cc36e75c..cd81689c4621dad5bfa9b08d2b1a35bed5049b8a 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <mach/mv78xx0.h>
 
-       .macro  addruart,rx
+       .macro  addruart, rx, tmp
        mrc     p15, 0, \rx, c1, c0
        tst     \rx, #1                                 @ MMU enabled?
        ldreq   \rx, =MV78XX0_REGS_PHYS_BASE
index 1c4954386a847beeec73102dd0fbafff730e05c7..ba26fe98e640097371b348d34a1d6c49ce53e529 100644 (file)
@@ -2,4 +2,4 @@
  * arch/arm/mach-mv78xx0/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END    0xfe000000
+#define VMALLOC_END    0xfe000000UL
index d1b588519ad23b8dc230fb343d8b3596b99f3c96..6cf2d4a7511dc441561c80fe80ca432cf886d3b5 100644 (file)
@@ -570,7 +570,6 @@ static struct clk_lookup lookups[] __initdata = {
 int __init mx1_clocks_init(unsigned long fref)
 {
        unsigned int reg;
-       int i;
 
        /* disable clocks we are able to */
        __raw_writel(0, SCM_GCCR);
@@ -592,8 +591,7 @@ int __init mx1_clocks_init(unsigned long fref)
        reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET;
        clko_clk.parent = (struct clk *)clko_clocks[reg];
 
-       for (i = 0; i < ARRAY_SIZE(lookups); i++)
-               clkdev_add(&lookups[i]);
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        clk_enable(&hclk);
        clk_enable(&fclk);
index 91901b5d56c2e63a871da04fbb489140f83ec3ea..e82b489d12150fd8a80c362b744538fcb494dca3 100644 (file)
@@ -968,7 +968,6 @@ static struct clk_lookup lookups[] = {
  */
 int __init mx21_clocks_init(unsigned long lref, unsigned long href)
 {
-       int i;
        u32 cscr;
 
        external_low_reference = lref;
@@ -986,8 +985,7 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href)
        else
                spll_clk.parent = &fpm_clk;
 
-       for (i = 0; i < ARRAY_SIZE(lookups); i++)
-               clkdev_add(&lookups[i]);
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        /* Turn off all clock gates */
        __raw_writel(0, CCM_PCCR0);
index b010bf9ceaaba1f4d18168fccdc31de2d7d26d2e..18c53a6487fafc7234d37cc494f04ff6c7250c49 100644 (file)
@@ -719,7 +719,6 @@ static void __init to2_adjust_clocks(void)
 int __init mx27_clocks_init(unsigned long fref)
 {
        u32 cscr = __raw_readl(CCM_CSCR);
-       int i;
 
        external_high_reference = fref;
 
@@ -736,8 +735,7 @@ int __init mx27_clocks_init(unsigned long fref)
 
        to2_adjust_clocks();
 
-       for (i = 0; i < ARRAY_SIZE(lookups); i++)
-               clkdev_add(&lookups[i]);
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        /* Turn off all clocks we do not need */
        __raw_writel(0, CCM_PCCR0);
index 6acc88bcdc403f415ff8526228e7ebca92303792..37e1359ad0c0596ac8193e7d1263c11550250c4e 100644 (file)
@@ -218,10 +218,7 @@ static struct clk_lookup lookups[] = {
 
 int __init mx25_clocks_init(void)
 {
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(lookups); i++)
-               clkdev_add(&lookups[i]);
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        /* Turn off all clocks except the ones we need to survive, namely:
         * EMI, GPIO1-3 (CCM_CGCR1[18:16]), GPT1, IOMUXC (CCM_CGCR1[27]), IIM,
index 7584b4c6c556d6a23d3d7fa30567d0de4fdbd6c3..f3f41fa4f21bd4541400082519b5b449a8bfa696 100644 (file)
@@ -485,15 +485,13 @@ static struct clk_lookup lookups[] = {
 
 int __init mx35_clocks_init()
 {
-       int i;
        unsigned int ll = 0;
 
 #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
        ll = (3 << 16);
 #endif
 
-       for (i = 0; i < ARRAY_SIZE(lookups); i++)
-               clkdev_add(&lookups[i]);
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        /* Turn off all clocks except the ones we need to survive, namely:
         * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart
index 27a318af0d200640215a7ef01c1272119ea69748..b5c39a016db78a6459a4edc8b4f5153db6f45582 100644 (file)
@@ -578,12 +578,10 @@ static struct clk_lookup lookups[] = {
 int __init mx31_clocks_init(unsigned long fref)
 {
        u32 reg;
-       int i;
 
        ckih_rate = fref;
 
-       for (i = 0; i < ARRAY_SIZE(lookups); i++)
-               clkdev_add(&lookups[i]);
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        /* change the csi_clk parent if necessary */
        reg = __raw_readl(MXC_CCM_CCMR);
index ecfa37fef8ade52accc9f14a0839d4f6af9afea0..5c85075d8a56b9b6c40059785dd9a4cd69658632 100644 (file)
@@ -624,7 +624,6 @@ static struct clk_lookup lookups[] = {
 int __init mxc91231_clocks_init(unsigned long fref)
 {
        void __iomem *gpt_base;
-       int i;
 
        ckih_rate = fref;
 
@@ -632,8 +631,7 @@ int __init mxc91231_clocks_init(unsigned long fref)
        sdhc_clk[0].parent = clk_sdhc_parent(&sdhc_clk[0]);
        sdhc_clk[1].parent = clk_sdhc_parent(&sdhc_clk[1]);
 
-       for (i = 0; i < ARRAY_SIZE(lookups); i++)
-               clkdev_add(&lookups[i]);
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        gpt_base = MXC91231_IO_ADDRESS(MXC91231_GPT1_BASE_ADDR);
        mxc_timer_init(&gpt_clk, gpt_base, MXC91231_INT_GPT);
index 11b9d5b46390daf54a2294c1925a832d3ecfb330..e96339e71d88fec6cbf56e72f08ba9d0dd4d9008 100644 (file)
@@ -13,7 +13,7 @@
 
 #include "hardware.h"
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0x00100000                @ physical
index e876990e156971def6d5e7304cc2d6914b1ba2cd..4f92acfba9545aaf5f9043925b51d8fcd1334ac0 100644 (file)
@@ -10,7 +10,7 @@
  *
 */
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0x10000000        @ physical base address
index be12e31ea52886d520eb88fcdd39fbdc5725f6fe..f83d574d9445728ec374d96db6decf288a47cab2 100644 (file)
@@ -1,2 +1,2 @@
 
-#define VMALLOC_END       0xe8000000
+#define VMALLOC_END       0xe8000000UL
index c9530fba00aa54866ffdba2372a1324bcd8bea4b..0859336a8e6d1be71a8090c1e8ef53b1640c87bc 100644 (file)
@@ -11,7 +11,7 @@
 
 #include <mach/regs-board-a9m9750dev.h>
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1
                ldreq   \rx, =NS9XXX_CSxSTAT_PHYS(0)
index fe964d3bcc477d9710c6929f8a41d3da6fc52f08..c8651974c4b0f0a3a2c9560cbcb17e95cc8eb606 100644 (file)
@@ -11,6 +11,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END     (0xf0000000)
+#define VMALLOC_END     (0xf0000000UL)
 
 #endif /* ifndef __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-nuc93x/Kconfig b/arch/arm/mach-nuc93x/Kconfig
new file mode 100644 (file)
index 0000000..2bc40a2
--- /dev/null
@@ -0,0 +1,19 @@
+if ARCH_NUC93X
+
+config CPU_NUC932
+       bool
+       help
+         Support for NUC932 of Nuvoton NUC93X CPUs.
+
+menu "NUC932 Machines"
+
+config MACH_NUC932EVB
+       bool "Nuvoton NUC932 Evaluation Board"
+       default y
+       select CPU_NUC932
+       help
+          Say Y here if you are using the Nuvoton NUC932EVB
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-nuc93x/Makefile b/arch/arm/mach-nuc93x/Makefile
new file mode 100644 (file)
index 0000000..440e2de
--- /dev/null
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y                          := irq.o time.o dev.o cpu.o clock.o
+# NUC932 CPU support files
+
+obj-$(CONFIG_CPU_NUC932)       += nuc932.o
+
+# machine support
+
+obj-$(CONFIG_MACH_NUC932EVB)   += mach-nuc932evb.o
diff --git a/arch/arm/mach-nuc93x/Makefile.boot b/arch/arm/mach-nuc93x/Makefile.boot
new file mode 100644 (file)
index 0000000..a057b54
--- /dev/null
@@ -0,0 +1,3 @@
+zreladdr-y     := 0x00008000
+params_phys-y  := 0x00000100
+
diff --git a/arch/arm/mach-nuc93x/clock.c b/arch/arm/mach-nuc93x/clock.c
new file mode 100644 (file)
index 0000000..0521efb
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * linux/arch/arm/mach-nuc93x/clock.c
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#include "clock.h"
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+int clk_enable(struct clk *clk)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       if (clk->enabled++ == 0)
+               (clk->enable)(clk, 1);
+       spin_unlock_irqrestore(&clocks_lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+       unsigned long flags;
+
+       WARN_ON(clk->enabled == 0);
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       if (--clk->enabled == 0)
+               (clk->enable)(clk, 0);
+       spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+       return 27000000;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void nuc93x_clk_enable(struct clk *clk, int enable)
+{
+       unsigned int clocks = clk->cken;
+       unsigned long clken;
+
+       clken = __raw_readl(NUC93X_VA_CLKPWR);
+
+       if (enable)
+               clken |= clocks;
+       else
+               clken &= ~clocks;
+
+       __raw_writel(clken, NUC93X_VA_CLKPWR);
+}
+
+void clks_register(struct clk_lookup *clks, size_t num)
+{
+       int i;
+
+       for (i = 0; i < num; i++)
+               clkdev_add(&clks[i]);
+}
diff --git a/arch/arm/mach-nuc93x/clock.h b/arch/arm/mach-nuc93x/clock.h
new file mode 100644 (file)
index 0000000..18e51be
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/mach-nuc93x/clock.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ */
+
+#include <asm/clkdev.h>
+
+void nuc93x_clk_enable(struct clk *clk, int enable);
+void clks_register(struct clk_lookup *clks, size_t num);
+
+struct clk {
+       unsigned long           cken;
+       unsigned int            enabled;
+       void                    (*enable)(struct clk *, int enable);
+};
+
+#define DEFINE_CLK(_name, _ctrlbit)                    \
+struct clk clk_##_name = {                             \
+               .enable = nuc93x_clk_enable,            \
+               .cken   = (1 << _ctrlbit),              \
+       }
+
+#define DEF_CLKLOOK(_clk, _devname, _conname)          \
+       {                                               \
+               .clk            = _clk,                 \
+               .dev_id         = _devname,             \
+               .con_id         = _conname,             \
+       }
+
diff --git a/arch/arm/mach-nuc93x/cpu.c b/arch/arm/mach-nuc93x/cpu.c
new file mode 100644 (file)
index 0000000..f6ff5d8
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * linux/arch/arm/mach-nuc93x/cpu.c
+ *
+ * Copyright (c) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC93x series cpu common support
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/serial_8250.h>
+#include <linux/delay.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-ebi.h>
+
+#include "cpu.h"
+#include "clock.h"
+
+/* Initial IO mappings */
+
+static struct map_desc nuc93x_iodesc[] __initdata = {
+       IODESC_ENT(IRQ),
+       IODESC_ENT(GCR),
+       IODESC_ENT(UART),
+       IODESC_ENT(TIMER),
+       IODESC_ENT(EBI),
+};
+
+/* Initial nuc932 clock declarations. */
+static DEFINE_CLK(audio, 2);
+static DEFINE_CLK(sd, 3);
+static DEFINE_CLK(jpg, 4);
+static DEFINE_CLK(video, 5);
+static DEFINE_CLK(vpost, 6);
+static DEFINE_CLK(2d, 7);
+static DEFINE_CLK(gpu, 8);
+static DEFINE_CLK(gdma, 9);
+static DEFINE_CLK(adc, 10);
+static DEFINE_CLK(uart, 11);
+static DEFINE_CLK(spi, 12);
+static DEFINE_CLK(pwm, 13);
+static DEFINE_CLK(timer, 14);
+static DEFINE_CLK(wdt, 15);
+static DEFINE_CLK(ac97, 16);
+static DEFINE_CLK(i2s, 16);
+static DEFINE_CLK(usbck, 17);
+static DEFINE_CLK(usb48, 18);
+static DEFINE_CLK(usbh, 19);
+static DEFINE_CLK(i2c, 20);
+static DEFINE_CLK(ext, 0);
+
+static struct clk_lookup nuc932_clkregs[] = {
+       DEF_CLKLOOK(&clk_audio, "nuc932-audio", NULL),
+       DEF_CLKLOOK(&clk_sd, "nuc932-sd", NULL),
+       DEF_CLKLOOK(&clk_jpg, "nuc932-jpg", "NULL"),
+       DEF_CLKLOOK(&clk_video, "nuc932-video", "NULL"),
+       DEF_CLKLOOK(&clk_vpost, "nuc932-vpost", NULL),
+       DEF_CLKLOOK(&clk_2d, "nuc932-2d", NULL),
+       DEF_CLKLOOK(&clk_gpu, "nuc932-gpu", NULL),
+       DEF_CLKLOOK(&clk_gdma, "nuc932-gdma", "NULL"),
+       DEF_CLKLOOK(&clk_adc, "nuc932-adc", NULL),
+       DEF_CLKLOOK(&clk_uart, NULL, "uart"),
+       DEF_CLKLOOK(&clk_spi, "nuc932-spi", NULL),
+       DEF_CLKLOOK(&clk_pwm, "nuc932-pwm", NULL),
+       DEF_CLKLOOK(&clk_timer, NULL, "timer"),
+       DEF_CLKLOOK(&clk_wdt, "nuc932-wdt", NULL),
+       DEF_CLKLOOK(&clk_ac97, "nuc932-ac97", NULL),
+       DEF_CLKLOOK(&clk_i2s, "nuc932-i2s", NULL),
+       DEF_CLKLOOK(&clk_usbck, "nuc932-usbck", NULL),
+       DEF_CLKLOOK(&clk_usb48, "nuc932-usb48", NULL),
+       DEF_CLKLOOK(&clk_usbh, "nuc932-usbh", NULL),
+       DEF_CLKLOOK(&clk_i2c, "nuc932-i2c", NULL),
+       DEF_CLKLOOK(&clk_ext, NULL, "ext"),
+};
+
+/* Initial serial platform data */
+
+struct plat_serial8250_port nuc93x_uart_data[] = {
+       NUC93X_8250PORT(UART0),
+       {},
+};
+
+struct platform_device nuc93x_serial_device = {
+       .name                   = "serial8250",
+       .id                     = PLAT8250_DEV_PLATFORM,
+       .dev                    = {
+               .platform_data  = nuc93x_uart_data,
+       },
+};
+
+/*Init NUC93x evb io*/
+
+void __init nuc93x_map_io(struct map_desc *mach_desc, int mach_size)
+{
+       unsigned long idcode = 0x0;
+
+       iotable_init(mach_desc, mach_size);
+       iotable_init(nuc93x_iodesc, ARRAY_SIZE(nuc93x_iodesc));
+
+       idcode = __raw_readl(NUC93XPDID);
+       if (idcode == NUC932_CPUID)
+               printk(KERN_INFO "CPU type 0x%08lx is NUC910\n", idcode);
+       else
+               printk(KERN_ERR "CPU type detect error!\n");
+
+}
+
+/*Init NUC93x clock*/
+
+void __init nuc93x_init_clocks(void)
+{
+       clks_register(nuc932_clkregs, ARRAY_SIZE(nuc932_clkregs));
+}
+
diff --git a/arch/arm/mach-nuc93x/cpu.h b/arch/arm/mach-nuc93x/cpu.h
new file mode 100644 (file)
index 0000000..9def281
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/mach-nuc93x/cpu.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Header file for NUC93X CPU support
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#define IODESC_ENT(y)                                  \
+{                                                      \
+       .virtual = (unsigned long)NUC93X_VA_##y,        \
+       .pfn     = __phys_to_pfn(NUC93X_PA_##y),        \
+       .length  = NUC93X_SZ_##y,                       \
+       .type    = MT_DEVICE,                           \
+}
+
+#define NUC93X_8250PORT(name)                                  \
+{                                                              \
+       .membase        = name##_BA,                            \
+       .mapbase        = name##_PA,                            \
+       .irq            = IRQ_##name,                           \
+       .uartclk        = 57139200,                             \
+       .regshift       = 2,                                    \
+       .iotype         = UPIO_MEM,                             \
+       .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,    \
+}
+
+/*Cpu identifier register*/
+
+#define NUC93XPDID     NUC93X_VA_GCR
+#define NUC932_CPUID   0x29550091
+
+/* extern file from cpu.c */
+
+extern void nuc93x_clock_source(struct device *dev, unsigned char *src);
+extern void nuc93x_init_clocks(void);
+extern void nuc93x_map_io(struct map_desc *mach_desc, int mach_size);
+extern void nuc93x_board_init(struct platform_device **device, int size);
+extern struct platform_device nuc93x_serial_device;
+
diff --git a/arch/arm/mach-nuc93x/dev.c b/arch/arm/mach-nuc93x/dev.c
new file mode 100644 (file)
index 0000000..a962ae9
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * linux/arch/arm/mach-nuc93x/dev.c
+ *
+ * Copyright (C) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+
+#include "cpu.h"
+
+/*Here should be your evb resourse,such as LCD*/
+
+static struct platform_device *nuc93x_public_dev[] __initdata = {
+       &nuc93x_serial_device,
+};
+
+/* Provide adding specific CPU platform devices API */
+
+void __init nuc93x_board_init(struct platform_device **device, int size)
+{
+       platform_add_devices(device, size);
+       platform_add_devices(nuc93x_public_dev, ARRAY_SIZE(nuc93x_public_dev));
+}
+
diff --git a/arch/arm/mach-nuc93x/include/mach/clkdev.h b/arch/arm/mach-nuc93x/include/mach/clkdev.h
new file mode 100644 (file)
index 0000000..04b37a8
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-nuc93x/include/mach/entry-macro.S b/arch/arm/mach-nuc93x/include/mach/entry-macro.S
new file mode 100644 (file)
index 0000000..1352cbd
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/entry-macro.S
+ *
+ * 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 <mach/hardware.h>
+#include <mach/regs-irq.h>
+
+       .macro  get_irqnr_preamble, base, tmp
+       .endm
+
+       .macro  arch_ret_to_user, tmp1, tmp2
+       .endm
+
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+               mov     \base, #AIC_BA
+
+               ldr     \irqnr, [ \base, #AIC_IPER]
+               ldr     \irqnr, [ \base, #AIC_ISNR]
+               cmp     \irqnr, #0
+
+       .endm
+
+       /* currently don't need an disable_fiq macro */
+
+       .macro  disable_fiq
+       .endm
diff --git a/arch/arm/mach-nuc93x/include/mach/hardware.h b/arch/arm/mach-nuc93x/include/mach/hardware.h
new file mode 100644 (file)
index 0000000..fb5c6fc
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/hardware.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/io.h b/arch/arm/mach-nuc93x/include/mach/io.h
new file mode 100644 (file)
index 0000000..72e5051
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/io.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * 1:1 mapping for ioremapped regions.
+ */
+
+#define __mem_pci(a)   (a)
+#define __io(a)                __typesafe_io(a)
+
+#endif
diff --git a/arch/arm/mach-nuc93x/include/mach/irqs.h b/arch/arm/mach-nuc93x/include/mach/irqs.h
new file mode 100644 (file)
index 0000000..7c4aa71
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/irqs.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define NUC93X_IRQ(x)  (x)
+
+/* Main cpu interrupts */
+
+#define IRQ_WDT                NUC93X_IRQ(1)
+#define IRQ_IRQ0       NUC93X_IRQ(2)
+#define IRQ_IRQ1       NUC93X_IRQ(3)
+#define IRQ_IRQ2       NUC93X_IRQ(4)
+#define IRQ_IRQ3       NUC93X_IRQ(5)
+#define IRQ_USBH       NUC93X_IRQ(6)
+#define IRQ_APU                NUC93X_IRQ(7)
+#define IRQ_VPOST      NUC93X_IRQ(8)
+#define IRQ_ADC                NUC93X_IRQ(9)
+#define IRQ_UART0      NUC93X_IRQ(10)
+#define IRQ_TIMER0     NUC93X_IRQ(11)
+#define IRQ_GPU0       NUC93X_IRQ(12)
+#define IRQ_GPU1       NUC93X_IRQ(13)
+#define IRQ_GPU2       NUC93X_IRQ(14)
+#define IRQ_GPU3       NUC93X_IRQ(15)
+#define IRQ_GPU4       NUC93X_IRQ(16)
+#define IRQ_VIN                NUC93X_IRQ(17)
+#define IRQ_USBD       NUC93X_IRQ(18)
+#define IRQ_VRAMLD     NUC93X_IRQ(19)
+#define IRQ_GDMA0      NUC93X_IRQ(20)
+#define IRQ_GDMA1      NUC93X_IRQ(21)
+#define IRQ_SDIO       NUC93X_IRQ(22)
+#define IRQ_FMI                NUC93X_IRQ(22)
+#define IRQ_JPEG       NUC93X_IRQ(23)
+#define IRQ_SPI0       NUC93X_IRQ(24)
+#define IRQ_SPI1       NUC93X_IRQ(25)
+#define IRQ_RTC                NUC93X_IRQ(26)
+#define IRQ_PWM0       NUC93X_IRQ(27)
+#define IRQ_PWM1       NUC93X_IRQ(28)
+#define IRQ_PWM2       NUC93X_IRQ(29)
+#define IRQ_PWM3       NUC93X_IRQ(30)
+#define IRQ_I2SAC97    NUC93X_IRQ(31)
+#define IRQ_CAP0       IRQ_PWM0
+#define IRQ_CAP1       IRQ_PWM1
+#define IRQ_CAP2       IRQ_PWM2
+#define IRQ_CAP3       IRQ_PWM3
+#define NR_IRQS                (IRQ_I2SAC97 + 1)
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/map.h b/arch/arm/mach-nuc93x/include/mach/map.h
new file mode 100644 (file)
index 0000000..fd0b5e8
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/map.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H
+
+#define MAP_OFFSET     (0xfff00000)
+#define CLK_OFFSET     (0x10)
+
+#ifndef __ASSEMBLY__
+#define NUC93X_ADDR(x) ((void __iomem *)(0xF0000000 + ((x)&(~MAP_OFFSET))))
+#else
+#define NUC93X_ADDR(x) (0xF0000000 + ((x)&(~MAP_OFFSET)))
+#endif
+
+ /*
+  * nuc932 hardware register definition
+  */
+
+#define NUC93X_PA_IRQ          (0xFFF83000)
+#define NUC93X_PA_GCR          (0xFFF00000)
+#define NUC93X_PA_EBI          (0xFFF01000)
+#define NUC93X_PA_UART         (0xFFF80000)
+#define NUC93X_PA_TIMER                (0xFFF81000)
+#define NUC93X_PA_GPIO         (0xFFF84000)
+#define NUC93X_PA_GDMA         (0xFFF03000)
+#define NUC93X_PA_USBHOST      (0xFFF0d000)
+#define NUC93X_PA_I2C          (0xFFF89000)
+#define NUC93X_PA_LCD          (0xFFF06000)
+#define NUC93X_PA_GE           (0xFFF05000)
+#define NUC93X_PA_ADC          (0xFFF85000)
+#define NUC93X_PA_RTC          (0xFFF87000)
+#define NUC93X_PA_PWM          (0xFFF82000)
+#define NUC93X_PA_ACTL         (0xFFF0a000)
+#define NUC93X_PA_USBDEV       (0xFFF0C000)
+#define NUC93X_PA_JEPEG                (0xFFF0e000)
+#define NUC93X_PA_CACHE_T      (0xFFF60000)
+#define NUC93X_PA_VRAM         (0xFFF0b000)
+#define NUC93X_PA_DMAC         (0xFFF09000)
+#define NUC93X_PA_I2SM         (0xFFF08000)
+#define NUC93X_PA_CACHE                (0xFFF02000)
+#define NUC93X_PA_GPU          (0xFFF04000)
+#define NUC93X_PA_VIDEOIN      (0xFFF07000)
+#define NUC93X_PA_SPI0         (0xFFF86000)
+#define NUC93X_PA_SPI1         (0xFFF88000)
+
+ /*
+  * nuc932 virtual address mapping.
+  * interrupt controller is the first thing we put in, to make
+  * the assembly code for the irq detection easier
+  */
+
+#define NUC93X_VA_IRQ          NUC93X_ADDR(0x00000000)
+#define NUC93X_SZ_IRQ          SZ_4K
+
+#define NUC93X_VA_GCR          NUC93X_ADDR(NUC93X_PA_IRQ)
+#define NUC93X_VA_CLKPWR       (NUC93X_VA_GCR+CLK_OFFSET)
+#define NUC93X_SZ_GCR          SZ_4K
+
+/* EBI management */
+
+#define NUC93X_VA_EBI          NUC93X_ADDR(NUC93X_PA_EBI)
+#define NUC93X_SZ_EBI          SZ_4K
+
+/* UARTs */
+
+#define NUC93X_VA_UART         NUC93X_ADDR(NUC93X_PA_UART)
+#define NUC93X_SZ_UART         SZ_4K
+
+/* Timers */
+
+#define NUC93X_VA_TIMER        NUC93X_ADDR(NUC93X_PA_TIMER)
+#define NUC93X_SZ_TIMER        SZ_4K
+
+/* GPIO ports */
+
+#define NUC93X_VA_GPIO         NUC93X_ADDR(NUC93X_PA_GPIO)
+#define NUC93X_SZ_GPIO         SZ_4K
+
+/* GDMA control */
+
+#define NUC93X_VA_GDMA         NUC93X_ADDR(NUC93X_PA_GDMA)
+#define NUC93X_SZ_GDMA         SZ_4K
+
+/* I2C hardware controller */
+
+#define NUC93X_VA_I2C          NUC93X_ADDR(NUC93X_PA_I2C)
+#define NUC93X_SZ_I2C          SZ_4K
+
+/* LCD controller*/
+
+#define NUC93X_VA_LCD          NUC93X_ADDR(NUC93X_PA_LCD)
+#define NUC93X_SZ_LCD          SZ_4K
+
+/* 2D controller*/
+
+#define NUC93X_VA_GE           NUC93X_ADDR(NUC93X_PA_GE)
+#define NUC93X_SZ_GE           SZ_4K
+
+/* ADC */
+
+#define NUC93X_VA_ADC          NUC93X_ADDR(NUC93X_PA_ADC)
+#define NUC93X_SZ_ADC          SZ_4K
+
+/* RTC */
+
+#define NUC93X_VA_RTC          NUC93X_ADDR(NUC93X_PA_RTC)
+#define NUC93X_SZ_RTC          SZ_4K
+
+/* Pulse Width Modulation(PWM) Registers */
+
+#define NUC93X_VA_PWM          NUC93X_ADDR(NUC93X_PA_PWM)
+#define NUC93X_SZ_PWM          SZ_4K
+
+/* Audio Controller controller */
+
+#define NUC93X_VA_ACTL         NUC93X_ADDR(NUC93X_PA_ACTL)
+#define NUC93X_SZ_ACTL         SZ_4K
+
+/* USB Device port */
+
+#define NUC93X_VA_USBDEV       NUC93X_ADDR(NUC93X_PA_USBDEV)
+#define NUC93X_SZ_USBDEV       SZ_4K
+
+/* USB host controller*/
+#define NUC93X_VA_USBHOST      NUC93X_ADDR(NUC93X_PA_USBHOST)
+#define NUC93X_SZ_USBHOST      SZ_4K
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/memory.h b/arch/arm/mach-nuc93x/include/mach/memory.h
new file mode 100644 (file)
index 0000000..323ab0d
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/memory.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET    UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-nuc93x/include/mach/regs-clock.h b/arch/arm/mach-nuc93x/include/mach/regs-clock.h
new file mode 100644 (file)
index 0000000..5cb2954
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H
+
+/* Clock Control Registers  */
+#define CLK_BA         NUC93X_VA_CLKPWR
+#define REG_CLKEN      (CLK_BA + 0x00)
+#define REG_CLKSEL     (CLK_BA + 0x04)
+#define REG_CLKDIV     (CLK_BA + 0x08)
+#define REG_PLLCON0    (CLK_BA + 0x0C)
+#define REG_PLLCON1    (CLK_BA + 0x10)
+#define REG_PMCON      (CLK_BA + 0x14)
+#define REG_IRQWAKECON (CLK_BA + 0x18)
+#define REG_IRQWAKEFLAG        (CLK_BA + 0x1C)
+#define REG_IPSRST     (CLK_BA + 0x20)
+#define REG_CLKEN1     (CLK_BA + 0x24)
+#define REG_CLKDIV1    (CLK_BA + 0x28)
+
+/* Define PLL freq setting */
+#define PLL_DISABLE            0x12B63
+#define        PLL_66MHZ               0x2B63
+#define        PLL_100MHZ              0x4F64
+#define PLL_120MHZ             0x4F63
+#define        PLL_166MHZ              0x4124
+#define        PLL_200MHZ              0x4F24
+
+/* Define AHB:CPUFREQ ratio */
+#define        AHB_CPUCLK_1_1          0x00
+#define        AHB_CPUCLK_1_2          0x01
+#define        AHB_CPUCLK_1_4          0x02
+#define        AHB_CPUCLK_1_8          0x03
+
+/* Define APB:AHB ratio */
+#define APB_AHB_1_2            0x01
+#define APB_AHB_1_4            0x02
+#define APB_AHB_1_8            0x03
+
+/* Define clock skew */
+#define DEFAULTSKEW            0x48
+
+#endif /*  __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/regs-ebi.h b/arch/arm/mach-nuc93x/include/mach/regs-ebi.h
new file mode 100644 (file)
index 0000000..3c72550
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-ebi.h
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_EBI_H
+#define __ASM_ARCH_REGS_EBI_H
+
+/* EBI Control Registers */
+
+#define EBI_BA         NUC93X_VA_EBI
+#define REG_EBICON     (EBI_BA + 0x00)
+#define REG_ROMCON     (EBI_BA + 0x04)
+#define REG_SDCONF0    (EBI_BA + 0x08)
+#define REG_SDCONF1    (EBI_BA + 0x0C)
+#define REG_SDTIME0    (EBI_BA + 0x10)
+#define REG_SDTIME1    (EBI_BA + 0x14)
+#define REG_EXT0CON    (EBI_BA + 0x18)
+#define REG_EXT1CON    (EBI_BA + 0x1C)
+#define REG_EXT2CON    (EBI_BA + 0x20)
+#define REG_EXT3CON    (EBI_BA + 0x24)
+#define REG_EXT4CON    (EBI_BA + 0x28)
+#define REG_CKSKEW     (EBI_BA + 0x2C)
+
+#endif /*  __ASM_ARCH_REGS_EBI_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/regs-irq.h b/arch/arm/mach-nuc93x/include/mach/regs-irq.h
new file mode 100644 (file)
index 0000000..2302159
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef ___ASM_ARCH_REGS_IRQ_H
+#define ___ASM_ARCH_REGS_IRQ_H
+
+/* Advance Interrupt Controller (AIC) Registers */
+
+#define AIC_BA                 NUC93X_VA_IRQ
+
+#define REG_AIC_IRQSC          (AIC_BA+0x80)
+#define REG_AIC_GEN            (AIC_BA+0x84)
+#define REG_AIC_GASR           (AIC_BA+0x88)
+#define REG_AIC_GSCR           (AIC_BA+0x8C)
+#define REG_AIC_IRSR           (AIC_BA+0x100)
+#define REG_AIC_IASR           (AIC_BA+0x104)
+#define REG_AIC_ISR            (AIC_BA+0x108)
+#define REG_AIC_IPER           (AIC_BA+0x10C)
+#define REG_AIC_ISNR           (AIC_BA+0x110)
+#define REG_AIC_IMR            (AIC_BA+0x114)
+#define REG_AIC_OISR           (AIC_BA+0x118)
+#define REG_AIC_MECR           (AIC_BA+0x120)
+#define REG_AIC_MDCR           (AIC_BA+0x124)
+#define REG_AIC_SSCR           (AIC_BA+0x128)
+#define REG_AIC_SCCR           (AIC_BA+0x12C)
+#define REG_AIC_EOSCR          (AIC_BA+0x130)
+#define AIC_IPER               (0x10C)
+#define AIC_ISNR               (0x110)
+
+#endif /* ___ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/regs-serial.h b/arch/arm/mach-nuc93x/include/mach/regs-serial.h
new file mode 100644 (file)
index 0000000..767a047
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-serial.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARM_REGS_SERIAL_H
+#define __ASM_ARM_REGS_SERIAL_H
+
+#define UART0_BA       NUC93X_VA_UART
+#define UART1_BA       (NUC93X_VA_UART+0x100)
+
+#define UART0_PA       NUC93X_PA_UART
+#define UART1_PA       (NUC93X_PA_UART+0x100)
+
+
+#ifndef __ASSEMBLY__
+
+struct nuc93x_uart_clksrc {
+       const char      *name;
+       unsigned int    divisor;
+       unsigned int    min_baud;
+       unsigned int    max_baud;
+};
+
+struct nuc93x_uartcfg {
+       unsigned char   hwport;
+       unsigned char   unused;
+       unsigned short  flags;
+       unsigned long   uart_flags;
+
+       unsigned long   ucon;
+       unsigned long   ulcon;
+       unsigned long   ufcon;
+
+       struct nuc93x_uart_clksrc *clocks;
+       unsigned int    clocks_size;
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_ARM_REGS_SERIAL_H */
+
diff --git a/arch/arm/mach-nuc93x/include/mach/regs-timer.h b/arch/arm/mach-nuc93x/include/mach/regs-timer.h
new file mode 100644 (file)
index 0000000..394be96
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-timer.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_TIMER_H
+#define __ASM_ARCH_REGS_TIMER_H
+
+/* Timer Registers */
+
+#define TMR_BA                 NUC93X_VA_TIMER
+#define REG_TCSR0              (TMR_BA+0x00)
+#define REG_TICR0              (TMR_BA+0x08)
+#define REG_TDR0               (TMR_BA+0x10)
+#define REG_TISR               (TMR_BA+0x18)
+#define REG_WTCR               (TMR_BA+0x1C)
+
+#endif /*  __ASM_ARCH_REGS_TIMER_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/system.h b/arch/arm/mach-nuc93x/include/mach/system.h
new file mode 100644 (file)
index 0000000..d26bd9a
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/machnuc93x/include/mach/system.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/system.h
+ *
+ * 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.
+ *
+ */
+
+#include <asm/proc-fns.h>
+
+static void arch_idle(void)
+{
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+       cpu_reset(0);
+}
+
diff --git a/arch/arm/mach-nuc93x/include/mach/timex.h b/arch/arm/mach-nuc93x/include/mach/timex.h
new file mode 100644 (file)
index 0000000..0c719cc
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/timex.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/timex.h
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE Now, I don't use it. */
+
+#define CLOCK_TICK_RATE 27000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/uncompress.h b/arch/arm/mach-nuc93x/include/mach/uncompress.h
new file mode 100644 (file)
index 0000000..73082cd
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/uncompress.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/uncompress.h
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+/* Defines for UART registers */
+
+#include <mach/regs-serial.h>
+#include <mach/map.h>
+#include <linux/serial_reg.h>
+
+#define arch_decomp_wdog()
+
+#define TX_DONE        (UART_LSR_TEMT | UART_LSR_THRE)
+static u32 * uart_base = (u32 *)UART0_PA;
+
+static void putc(int ch)
+{
+       /* Check THRE and TEMT bits before we transmit the character.
+        */
+       while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
+               barrier();
+
+       *uart_base = ch;
+}
+
+static inline void flush(void)
+{
+}
+
+static void arch_decomp_setup(void)
+{
+}
+
+#endif/* __ASM_NUC93X_UNCOMPRESS_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/vmalloc.h b/arch/arm/mach-nuc93x/include/mach/vmalloc.h
new file mode 100644 (file)
index 0000000..98a21b8
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/vmalloc.h
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END      (0xE0000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-nuc93x/irq.c b/arch/arm/mach-nuc93x/irq.c
new file mode 100644 (file)
index 0000000..a7a88ea
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * linux/arch/arm/mach-nuc93x/irq.c
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+
+static void nuc93x_irq_mask(unsigned int irq)
+{
+       __raw_writel(1 << irq, REG_AIC_MDCR);
+}
+
+/*
+ * By the w90p910 spec,any irq,only write 1
+ * to REG_AIC_EOSCR for ACK
+ */
+
+static void nuc93x_irq_ack(unsigned int irq)
+{
+       __raw_writel(0x01, REG_AIC_EOSCR);
+}
+
+static void nuc93x_irq_unmask(unsigned int irq)
+{
+       __raw_writel(1 << irq, REG_AIC_MECR);
+
+}
+
+static struct irq_chip nuc93x_irq_chip = {
+       .ack       = nuc93x_irq_ack,
+       .mask      = nuc93x_irq_mask,
+       .unmask    = nuc93x_irq_unmask,
+};
+
+void __init nuc93x_init_irq(void)
+{
+       int irqno;
+
+       __raw_writel(0xFFFFFFFE, REG_AIC_MDCR);
+
+       for (irqno = IRQ_WDT; irqno <= NR_IRQS; irqno++) {
+               set_irq_chip(irqno, &nuc93x_irq_chip);
+               set_irq_handler(irqno, handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+}
diff --git a/arch/arm/mach-nuc93x/mach-nuc932evb.c b/arch/arm/mach-nuc93x/mach-nuc932evb.c
new file mode 100644 (file)
index 0000000..9f79266
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * linux/arch/arm/mach-w90x900/mach-nuc910evb.c
+ *
+ * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
+ *
+ * Copyright (C) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <mach/map.h>
+
+#include "nuc932.h"
+
+static void __init nuc932evb_map_io(void)
+{
+       nuc932_map_io();
+       nuc932_init_clocks();
+       nuc932_init_uartclk();
+}
+
+static void __init nuc932evb_init(void)
+{
+       nuc932_board_init();
+}
+
+MACHINE_START(NUC932EVB, "NUC932EVB")
+       /* Maintainer: Wan ZongShun */
+       .phys_io        = NUC93X_PA_UART,
+       .io_pg_offst    = (((u32)NUC93X_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = 0,
+       .map_io         = nuc932evb_map_io,
+       .init_irq       = nuc93x_init_irq,
+       .init_machine   = nuc932evb_init,
+       .timer          = &nuc93x_timer,
+MACHINE_END
diff --git a/arch/arm/mach-nuc93x/nuc932.c b/arch/arm/mach-nuc93x/nuc932.c
new file mode 100644 (file)
index 0000000..3966ead
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * linux/arch/arm/mach-nuc93x/nuc932.c
+ *
+ * Copyright (c) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC932 cpu support
+ *
+ * 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.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+
+#include "cpu.h"
+#include "clock.h"
+
+/* define specific CPU platform device */
+
+static struct platform_device *nuc932_dev[] __initdata = {
+};
+
+/* define specific CPU platform io map */
+
+static struct map_desc nuc932evb_iodesc[] __initdata = {
+};
+
+/*Init NUC932 evb io*/
+
+void __init nuc932_map_io(void)
+{
+       nuc93x_map_io(nuc932evb_iodesc, ARRAY_SIZE(nuc932evb_iodesc));
+}
+
+/*Init NUC932 clock*/
+
+void __init nuc932_init_clocks(void)
+{
+       nuc93x_init_clocks();
+}
+
+/*enable NUC932 uart clock*/
+
+void __init nuc932_init_uartclk(void)
+{
+       struct clk *ck_uart = clk_get(NULL, "uart");
+       BUG_ON(IS_ERR(ck_uart));
+
+       clk_enable(ck_uart);
+}
+
+/*Init NUC932 board info*/
+
+void __init nuc932_board_init(void)
+{
+       nuc93x_board_init(nuc932_dev, ARRAY_SIZE(nuc932_dev));
+}
diff --git a/arch/arm/mach-nuc93x/nuc932.h b/arch/arm/mach-nuc93x/nuc932.h
new file mode 100644 (file)
index 0000000..9a66edd
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-nuc93x/nuc932.h
+ *
+ * Copyright (c) 2008 Nuvoton corporation
+ *
+ * Header file for NUC93x CPU support
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+struct map_desc;
+struct sys_timer;
+
+/* core initialisation functions */
+
+extern void nuc93x_init_irq(void);
+extern struct sys_timer nuc93x_timer;
+
+/* extern file from nuc932.c */
+
+extern void nuc932_board_init(void);
+extern void nuc932_init_clocks(void);
+extern void nuc932_map_io(void);
+extern void nuc932_init_uartclk(void);
diff --git a/arch/arm/mach-nuc93x/time.c b/arch/arm/mach-nuc93x/time.c
new file mode 100644 (file)
index 0000000..2f90f9d
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * linux/arch/arm/mach-nuc93x/time.c
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+#include <mach/system.h>
+#include <mach/map.h>
+#include <mach/regs-timer.h>
+
+#define RESETINT       0x01
+#define PERIOD         (0x01 << 27)
+#define ONESHOT                (0x00 << 27)
+#define COUNTEN                (0x01 << 30)
+#define INTEN          (0x01 << 29)
+
+#define TICKS_PER_SEC  100
+#define PRESCALE       0x63 /* Divider = prescale + 1 */
+
+unsigned int timer0_load;
+
+static unsigned long nuc93x_gettimeoffset(void)
+{
+       return 0;
+}
+
+/*IRQ handler for the timer*/
+
+static irqreturn_t nuc93x_timer_interrupt(int irq, void *dev_id)
+{
+       timer_tick();
+       __raw_writel(0x01, REG_TISR); /* clear TIF0 */
+       return IRQ_HANDLED;
+}
+
+static struct irqaction nuc93x_timer_irq = {
+       .name           = "nuc93x Timer Tick",
+       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .handler        = nuc93x_timer_interrupt,
+};
+
+/*Set up timer reg.*/
+
+static void nuc93x_timer_setup(void)
+{
+       struct clk *ck_ext = clk_get(NULL, "ext");
+       struct clk *ck_timer = clk_get(NULL, "timer");
+       unsigned int rate, val = 0;
+
+       BUG_ON(IS_ERR(ck_ext) || IS_ERR(ck_timer));
+
+       clk_enable(ck_timer);
+       rate = clk_get_rate(ck_ext);
+       clk_put(ck_ext);
+       rate = rate / (PRESCALE + 0x01);
+
+        /* set a known state */
+       __raw_writel(0x00, REG_TCSR0);
+       __raw_writel(RESETINT, REG_TISR);
+
+       timer0_load = (rate / TICKS_PER_SEC);
+       __raw_writel(timer0_load, REG_TICR0);
+
+       val |= (PERIOD | COUNTEN | INTEN | PRESCALE);;
+       __raw_writel(val, REG_TCSR0);
+
+}
+
+static void __init nuc93x_timer_init(void)
+{
+       nuc93x_timer_setup();
+       setup_irq(IRQ_TIMER0, &nuc93x_timer_irq);
+}
+
+struct sys_timer nuc93x_timer = {
+       .init           = nuc93x_timer_init,
+       .offset         = nuc93x_gettimeoffset,
+       .resume         = nuc93x_timer_setup
+};
index aedb746fc33c950c0e4d5579681f52018c86675c..8c74cab2fa8b92b809bfbba4bd3ddad66a8d8b35 100644 (file)
@@ -11,7 +11,7 @@
  *
 */
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0xff000000        @ physical base address
index 0c6be6b4a7e2b6f3fc40ba803c7f574289ebf0a8..8ba8fb5b2514cdb09343f98ea45676aff0b8fab8 100644 (file)
@@ -28,6 +28,7 @@
 #include <plat/control.h>
 #include <plat/timer-gp.h>
 #include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
 
 static struct platform_device sdp4430_lcd_device = {
        .name           = "sdp4430_lcd",
@@ -50,6 +51,59 @@ static struct omap_board_config_kernel sdp4430_config[] __initdata = {
        { OMAP_TAG_LCD,         &sdp4430_lcd_config },
 };
 
+#ifdef CONFIG_CACHE_L2X0
+noinline void omap_smc1(u32 fn, u32 arg)
+{
+       register u32 r12 asm("r12") = fn;
+       register u32 r0 asm("r0") = arg;
+
+       /* This is common routine cache secure monitor API used to
+        * modify the PL310 secure registers.
+        * r0 contains the value to be modified and "r12" contains
+        * the monitor API number. It uses few CPU registers
+        * internally and hence they need be backed up including
+        * link register "lr".
+        * Explicitly save r11 and r12 the compiler generated code
+        * won't save it.
+        */
+       asm volatile(
+               "stmfd r13!, {r11,r12}\n"
+               "dsb\n"
+               "smc\n"
+               "ldmfd r13!, {r11,r12}\n"
+               : "+r" (r0), "+r" (r12)
+               :
+               : "r4", "r5", "r10", "lr", "cc");
+}
+EXPORT_SYMBOL(omap_smc1);
+
+static int __init omap_l2_cache_init(void)
+{
+       void __iomem *l2cache_base;
+
+       /* To avoid code running on other OMAPs in
+        * multi-omap builds
+        */
+       if (!cpu_is_omap44xx())
+               return -ENODEV;
+
+       /* Static mapping, never released */
+       l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
+       BUG_ON(!l2cache_base);
+
+       /* Enable PL310 L2 Cache controller */
+       omap_smc1(0x102, 0x1);
+
+       /* 32KB way size, 16-way associativity,
+       * parity disabled
+       */
+       l2x0_init(l2cache_base, 0x0e050000, 0xc0000fff);
+
+       return 0;
+}
+early_initcall(omap_l2_cache_init);
+#endif
+
 static void __init gic_init_irq(void)
 {
        void __iomem *base;
index e9f255df9163b827c6a9fc300b0b65345e79d329..86979d7bd8714d8715586e254163c2345af72394 100644 (file)
@@ -11,7 +11,7 @@
  *
 */
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
 #ifdef  CONFIG_ARCH_OMAP2
index c7f808bfe272fa1caa477182e91cb566ff9b2c4a..91e0e39bb23f1602a98068234c28268f262e455c 100644 (file)
@@ -10,7 +10,7 @@
 
 #include <mach/orion5x.h>
 
-       .macro  addruart,rx
+       .macro  addruart, rx, tmp
        mrc     p15, 0, \rx, c1, c0
        tst     \rx, #1                                 @ MMU enabled?
        ldreq   \rx, =ORION5X_REGS_PHYS_BASE
index 7147a297e97f4c2e11e8d5a1fd03dc3608ee34d9..06b50aeff7b90fb78d4320685976f383c3e315e3 100644 (file)
@@ -2,4 +2,4 @@
  * arch/arm/mach-orion5x/include/mach/vmalloc.h
  */
 
-#define VMALLOC_END       0xfd800000
+#define VMALLOC_END       0xfd800000UL
index 898c0e88acbc30ade69d561e5493e936e23bebdb..9d1975fa4d9f2c2e71e3782c7716bd66c5c67dff 100644 (file)
@@ -22,8 +22,9 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 
-#include <mach/hardware.h>
+#include <asm/clkdev.h>
 
+#include <mach/hardware.h>
 #include <mach/clock.h>
 #include "clock.h"
 
@@ -56,18 +57,19 @@ static void propagate_rate(struct clk *clk)
        }
 }
 
-static inline void clk_reg_disable(struct clk *clk)
+static void clk_reg_disable(struct clk *clk)
 {
        if (clk->enable_reg)
                __raw_writel(__raw_readl(clk->enable_reg) &
                             ~(1 << clk->enable_shift), clk->enable_reg);
 }
 
-static inline void clk_reg_enable(struct clk *clk)
+static int clk_reg_enable(struct clk *clk)
 {
        if (clk->enable_reg)
                __raw_writel(__raw_readl(clk->enable_reg) |
                             (1 << clk->enable_shift), clk->enable_reg);
+       return 0;
 }
 
 static inline void clk_reg_disable1(struct clk *clk)
@@ -636,31 +638,34 @@ static struct clk flash_ck = {
 static struct clk i2c0_ck = {
        .name = "i2c0_ck",
        .parent = &per_ck,
-       .flags = NEEDS_INITIALIZATION,
-       .round_rate = &on_off_round_rate,
-       .set_rate = &on_off_set_rate,
+       .flags = NEEDS_INITIALIZATION | FIXED_RATE,
        .enable_shift = 0,
        .enable_reg = I2CCLKCTRL_REG,
+       .rate = 13000000,
+       .enable = clk_reg_enable,
+       .disable = clk_reg_disable,
 };
 
 static struct clk i2c1_ck = {
        .name = "i2c1_ck",
        .parent = &per_ck,
-       .flags = NEEDS_INITIALIZATION,
-       .round_rate = &on_off_round_rate,
-       .set_rate = &on_off_set_rate,
+       .flags = NEEDS_INITIALIZATION | FIXED_RATE,
        .enable_shift = 1,
        .enable_reg = I2CCLKCTRL_REG,
+       .rate = 13000000,
+       .enable = clk_reg_enable,
+       .disable = clk_reg_disable,
 };
 
 static struct clk i2c2_ck = {
        .name = "i2c2_ck",
        .parent = &per_ck,
-       .flags = NEEDS_INITIALIZATION,
-       .round_rate = &on_off_round_rate,
-       .set_rate = &on_off_set_rate,
+       .flags = NEEDS_INITIALIZATION | FIXED_RATE,
        .enable_shift = 2,
        .enable_reg = USB_OTG_CLKCTRL_REG,
+       .rate = 13000000,
+       .enable = clk_reg_enable,
+       .disable = clk_reg_disable,
 };
 
 static struct clk spi0_ck = {
@@ -738,16 +743,16 @@ static struct clk wdt_ck = {
        .name = "wdt_ck",
        .parent = &per_ck,
        .flags = NEEDS_INITIALIZATION,
-       .round_rate = &on_off_round_rate,
-       .set_rate = &on_off_set_rate,
        .enable_shift = 0,
        .enable_reg = TIMCLKCTRL_REG,
+       .enable = clk_reg_enable,
+       .disable = clk_reg_disable,
 };
 
 /* These clocks are visible outside this module
  * and can be initialized
  */
-static struct clk *onchip_clks[] = {
+static struct clk *onchip_clks[] __initdata = {
        &ck_13MHz,
        &ck_pll1,
        &ck_pll4,
@@ -777,49 +782,74 @@ static struct clk *onchip_clks[] = {
        &wdt_ck,
 };
 
-static int local_clk_enable(struct clk *clk)
-{
-       int ret = 0;
-
-       if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
-           && clk->user_rate)
-               ret = clk->set_rate(clk, clk->user_rate);
-       return ret;
-}
+static struct clk_lookup onchip_clkreg[] = {
+       { .clk = &ck_13MHz,     .con_id = "ck_13MHz"    },
+       { .clk = &ck_pll1,      .con_id = "ck_pll1"     },
+       { .clk = &ck_pll4,      .con_id = "ck_pll4"     },
+       { .clk = &ck_pll5,      .con_id = "ck_pll5"     },
+       { .clk = &ck_pll3,      .con_id = "ck_pll3"     },
+       { .clk = &vfp9_ck,      .con_id = "vfp9_ck"     },
+       { .clk = &m2hclk_ck,    .con_id = "m2hclk_ck"   },
+       { .clk = &hclk_ck,      .con_id = "hclk_ck"     },
+       { .clk = &dma_ck,       .con_id = "dma_ck"      },
+       { .clk = &flash_ck,     .con_id = "flash_ck"    },
+       { .clk = &dum_ck,       .con_id = "dum_ck"      },
+       { .clk = &keyscan_ck,   .con_id = "keyscan_ck"  },
+       { .clk = &pwm1_ck,      .con_id = "pwm1_ck"     },
+       { .clk = &pwm2_ck,      .con_id = "pwm2_ck"     },
+       { .clk = &jpeg_ck,      .con_id = "jpeg_ck"     },
+       { .clk = &ms_ck,        .con_id = "ms_ck"       },
+       { .clk = &touch_ck,     .con_id = "touch_ck"    },
+       { .clk = &i2c0_ck,      .dev_id = "pnx-i2c.0"   },
+       { .clk = &i2c1_ck,      .dev_id = "pnx-i2c.1"   },
+       { .clk = &i2c2_ck,      .dev_id = "pnx-i2c.2"   },
+       { .clk = &spi0_ck,      .con_id = "spi0_ck"     },
+       { .clk = &spi1_ck,      .con_id = "spi1_ck"     },
+       { .clk = &uart3_ck,     .con_id = "uart3_ck"    },
+       { .clk = &uart4_ck,     .con_id = "uart4_ck"    },
+       { .clk = &uart5_ck,     .con_id = "uart5_ck"    },
+       { .clk = &uart6_ck,     .con_id = "uart6_ck"    },
+       { .clk = &wdt_ck,       .dev_id = "pnx4008-watchdog" },
+};
 
 static void local_clk_disable(struct clk *clk)
 {
-       if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
-               clk->set_rate(clk, 0);
-}
+       if (WARN_ON(clk->usecount == 0))
+               return;
 
-static void local_clk_unuse(struct clk *clk)
-{
-       if (clk->usecount > 0 && !(--clk->usecount)) {
-               local_clk_disable(clk);
+       if (!(--clk->usecount)) {
+               if (clk->disable)
+                       clk->disable(clk);
+               else if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
+                       clk->set_rate(clk, 0);
                if (clk->parent)
-                       local_clk_unuse(clk->parent);
+                       local_clk_disable(clk->parent);
        }
 }
 
-static int local_clk_use(struct clk *clk)
+static int local_clk_enable(struct clk *clk)
 {
        int ret = 0;
-       if (clk->usecount++ == 0) {
-               if (clk->parent)
-                       ret = local_clk_use(clk->parent);
 
-               if (ret != 0) {
-                       clk->usecount--;
-                       goto out;
+       if (clk->usecount == 0) {
+               if (clk->parent) {
+                       ret = local_clk_enable(clk->parent);
+                       if (ret != 0)
+                               goto out;
                }
 
-               ret = local_clk_enable(clk);
+               if (clk->enable)
+                       ret = clk->enable(clk);
+               else if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
+                           && clk->user_rate)
+                       ret = clk->set_rate(clk, clk->user_rate);
 
                if (ret != 0 && clk->parent) {
-                       local_clk_unuse(clk->parent);
-                       clk->usecount--;
+                       local_clk_disable(clk->parent);
+                       goto out;
                }
+
+               clk->usecount++;
        }
 out:
        return ret;
@@ -866,35 +896,6 @@ out:
 
 EXPORT_SYMBOL(clk_set_rate);
 
-struct clk *clk_get(struct device *dev, const char *id)
-{
-       struct clk *clk = ERR_PTR(-ENOENT);
-       struct clk **clkp;
-
-       clock_lock();
-       for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
-            clkp++) {
-               if (strcmp(id, (*clkp)->name) == 0
-                   && try_module_get((*clkp)->owner)) {
-                       clk = (*clkp);
-                       break;
-               }
-       }
-       clock_unlock();
-
-       return clk;
-}
-EXPORT_SYMBOL(clk_get);
-
-void clk_put(struct clk *clk)
-{
-       clock_lock();
-       if (clk && !IS_ERR(clk))
-               module_put(clk->owner);
-       clock_unlock();
-}
-EXPORT_SYMBOL(clk_put);
-
 unsigned long clk_get_rate(struct clk *clk)
 {
        unsigned long ret;
@@ -907,10 +908,10 @@ EXPORT_SYMBOL(clk_get_rate);
 
 int clk_enable(struct clk *clk)
 {
-       int ret = 0;
+       int ret;
 
        clock_lock();
-       ret = local_clk_use(clk);
+       ret = local_clk_enable(clk);
        clock_unlock();
        return ret;
 }
@@ -920,7 +921,7 @@ EXPORT_SYMBOL(clk_enable);
 void clk_disable(struct clk *clk)
 {
        clock_lock();
-       local_clk_unuse(clk);
+       local_clk_disable(clk);
        clock_unlock();
 }
 
@@ -967,18 +968,24 @@ static int __init clk_init(void)
 
        for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
             clkp++) {
-               if (((*clkp)->flags & NEEDS_INITIALIZATION)
-                   && ((*clkp)->set_rate)) {
-                       (*clkp)->user_rate = (*clkp)->rate;
-                       local_set_rate((*clkp), (*clkp)->user_rate);
-                       if ((*clkp)->set_parent)
-                               (*clkp)->set_parent((*clkp), (*clkp)->parent);
+               struct clk *clk = *clkp;
+               if (clk->flags & NEEDS_INITIALIZATION) {
+                       if (clk->set_rate) {
+                               clk->user_rate = clk->rate;
+                               local_set_rate(clk, clk->user_rate);
+                               if (clk->set_parent)
+                                       clk->set_parent(clk, clk->parent);
+                       }
+                       if (clk->enable && clk->usecount)
+                               clk->enable(clk);
+                       if (clk->disable && !clk->usecount)
+                               clk->disable(clk);
                }
                pr_debug("%s: clock %s, rate %ld\n",
-                       __func__, (*clkp)->name, (*clkp)->rate);
+                       __func__, clk->name, clk->rate);
        }
 
-       local_clk_use(&ck_pll4);
+       local_clk_enable(&ck_pll4);
 
        /* if ck_13MHz is not used, disable it. */
        if (ck_13MHz.usecount == 0)
@@ -987,6 +994,8 @@ static int __init clk_init(void)
        /* Disable autoclocking */
        __raw_writeb(0xff, AUTOCLK_CTRL);
 
+       clkdev_add_table(onchip_clkreg, ARRAY_SIZE(onchip_clkreg));
+
        return 0;
 }
 
index cd58f372cfd0aa68eae44d810a7a054efd0057ed..39720d6c0d014e370d5804918e263c05a11a6946 100644 (file)
@@ -14,8 +14,6 @@
 #define __ARCH_ARM_PNX4008_CLOCK_H__
 
 struct clk {
-       struct list_head node;
-       struct module *owner;
        const char *name;
        struct clk *parent;
        struct clk *propagate_next;
@@ -29,9 +27,11 @@ struct clk {
        u8 enable_shift1;
        u32 enable_reg1;
        u32 parent_switch_reg;
-        u32(*round_rate) (struct clk *, u32);
+       u32(*round_rate) (struct clk *, u32);
        int (*set_rate) (struct clk *, u32);
        int (*set_parent) (struct clk * clk, struct clk * parent);
+       int (*enable)(struct clk *);
+       void (*disable)(struct clk *);
 };
 
 /* Flags */
index f3fea29c00d3b3072008bf52f2c224370f544357..8103f9644e2d0af099ccadb0b80b29440574119c 100644 (file)
 #include <mach/irqs.h>
 #include <mach/i2c.h>
 
-static int set_clock_run(struct platform_device *pdev)
-{
-       struct clk *clk;
-       char name[10];
-       int retval = 0;
-
-       snprintf(name, 10, "i2c%d_ck", pdev->id);
-       clk = clk_get(&pdev->dev, name);
-       if (!IS_ERR(clk)) {
-               clk_set_rate(clk, 1);
-               clk_put(clk);
-       } else
-               retval = -ENOENT;
-
-       return retval;
-}
-
-static int set_clock_stop(struct platform_device *pdev)
-{
-       struct clk *clk;
-       char name[10];
-       int retval = 0;
-
-       snprintf(name, 10, "i2c%d_ck", pdev->id);
-       clk = clk_get(&pdev->dev, name);
-       if (!IS_ERR(clk)) {
-               clk_set_rate(clk, 0);
-               clk_put(clk);
-       } else
-               retval = -ENOENT;
-
-       return retval;
-}
-
-static int i2c_pnx_suspend(struct platform_device *pdev, pm_message_t state)
-{
-       int retval = 0;
-#ifdef CONFIG_PM
-       retval = set_clock_run(pdev);
-#endif
-       return retval;
-}
-
-static int i2c_pnx_resume(struct platform_device *pdev)
-{
-       int retval = 0;
-#ifdef CONFIG_PM
-       retval = set_clock_run(pdev);
-#endif
-       return retval;
-}
-
-static u32 calculate_input_freq(struct platform_device *pdev)
-{
-       return HCLK_MHZ;
-}
-
-
-static struct i2c_pnx_algo_data pnx_algo_data0 = {
+static struct i2c_pnx_data i2c0_data = {
+       .name = I2C_CHIP_NAME "0",
        .base = PNX4008_I2C1_BASE,
        .irq = I2C_1_INT,
 };
 
-static struct i2c_pnx_algo_data pnx_algo_data1 = {
+static struct i2c_pnx_data i2c1_data = {
+       .name = I2C_CHIP_NAME "1",
        .base = PNX4008_I2C2_BASE,
        .irq = I2C_2_INT,
 };
 
-static struct i2c_pnx_algo_data pnx_algo_data2 = {
+static struct i2c_pnx_data i2c2_data = {
+       .name = "USB-I2C",
        .base = (PNX4008_USB_CONFIG_BASE + 0x300),
        .irq = USB_I2C_INT,
 };
 
-static struct i2c_adapter pnx_adapter0 = {
-       .name = I2C_CHIP_NAME "0",
-       .algo_data = &pnx_algo_data0,
-};
-static struct i2c_adapter pnx_adapter1 = {
-       .name = I2C_CHIP_NAME "1",
-       .algo_data = &pnx_algo_data1,
-};
-
-static struct i2c_adapter pnx_adapter2 = {
-       .name = "USB-I2C",
-       .algo_data = &pnx_algo_data2,
-};
-
-static struct i2c_pnx_data i2c0_data = {
-       .suspend = i2c_pnx_suspend,
-       .resume = i2c_pnx_resume,
-       .calculate_input_freq = calculate_input_freq,
-       .set_clock_run = set_clock_run,
-       .set_clock_stop = set_clock_stop,
-       .adapter = &pnx_adapter0,
-};
-
-static struct i2c_pnx_data i2c1_data = {
-       .suspend = i2c_pnx_suspend,
-       .resume = i2c_pnx_resume,
-       .calculate_input_freq = calculate_input_freq,
-       .set_clock_run = set_clock_run,
-       .set_clock_stop = set_clock_stop,
-       .adapter = &pnx_adapter1,
-};
-
-static struct i2c_pnx_data i2c2_data = {
-       .suspend = i2c_pnx_suspend,
-       .resume = i2c_pnx_resume,
-       .calculate_input_freq = calculate_input_freq,
-       .set_clock_run = set_clock_run,
-       .set_clock_stop = set_clock_stop,
-       .adapter = &pnx_adapter2,
-};
-
 static struct platform_device i2c0_device = {
        .name = "pnx-i2c",
        .id = 0,
diff --git a/arch/arm/mach-pnx4008/include/mach/clkdev.h b/arch/arm/mach-pnx4008/include/mach/clkdev.h
new file mode 100644 (file)
index 0000000..04b37a8
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
index 6d1407f319f8281fc780f34e64037e42cb5ea09c..6ca8bd30bf46f32dd0e55c9284b0962242596dff 100644 (file)
@@ -11,7 +11,7 @@
  *
 */
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                mov     \rx, #0x00090000
index 5ff0196c0f167dd8a72c9443b0353e926123ed83..b383c7de7ab44e811e8b85ae2cf0270a2a7edcf3 100644 (file)
 #ifndef __PNX4008_TIMEX_H
 #define __PNX4008_TIMEX_H
 
-#include <linux/io.h>
-#include <mach/hardware.h>
-
 #define CLOCK_TICK_RATE                1000000
 
-#define TICKS2USECS(x) (x)
-
-/* MilliSecond Timer - Chapter 21 Page 202 */
-
-#define MSTIM_INT     IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x0))
-#define MSTIM_CTRL    IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x4))
-#define MSTIM_COUNTER IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x8))
-#define MSTIM_MCTRL   IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x14))
-#define MSTIM_MATCH0  IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x18))
-#define MSTIM_MATCH1  IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x1c))
-
-/* High Speed Timer - Chpater 22, Page 205 */
-
-#define HSTIM_INT     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x0))
-#define HSTIM_CTRL    IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x4))
-#define HSTIM_COUNTER IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x8))
-#define HSTIM_PMATCH  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0xC))
-#define HSTIM_PCOUNT  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x10))
-#define HSTIM_MCTRL   IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x14))
-#define HSTIM_MATCH0  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x18))
-#define HSTIM_MATCH1  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x1c))
-#define HSTIM_MATCH2  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x20))
-#define HSTIM_CCR     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x28))
-#define HSTIM_CR0     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x2C))
-#define HSTIM_CR1     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x30))
-
-/* IMPORTANT: both timers are UPCOUNTING */
-
-/* xSTIM_MCTRL bit definitions */
-#define MR0_INT        1
-#define RESET_COUNT0   (1<<1)
-#define STOP_COUNT0    (1<<2)
-#define MR1_INT        (1<<3)
-#define RESET_COUNT1   (1<<4)
-#define STOP_COUNT1    (1<<5)
-#define MR2_INT        (1<<6)
-#define RESET_COUNT2   (1<<7)
-#define STOP_COUNT2    (1<<8)
-
-/* xSTIM_CTRL bit definitions */
-#define COUNT_ENAB     1
-#define RESET_COUNT    (1<<1)
-#define DEBUG_EN       (1<<2)
-
-/* xSTIM_INT bit definitions */
-#define MATCH0_INT     1
-#define MATCH1_INT     (1<<1)
-#define MATCH2_INT     (1<<2)
-#define RTC_TICK0      (1<<4)
-#define RTC_TICK1      (1<<5)
-
 #endif
index b3d8d53e32ef8cd5733d0de3dac98bfffe9a9aef..1f0585329be48a3e651a365a9bc05b42c60b532b 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/io.h>
 
 #include <asm/cacheflush.h>
+
+#include <mach/hardware.h>
 #include <mach/pm.h>
 #include <mach/clock.h>
 
index fc0ba183fe1233dcd9165502281928e98b56775e..0c8aad4bb0dc877d0372f5ac7044597d41956f45 100644 (file)
@@ -30,6 +30,8 @@
 #include <asm/mach/time.h>
 #include <asm/errno.h>
 
+#include "time.h"
+
 /*! Note: all timers are UPCOUNTING */
 
 /*!
diff --git a/arch/arm/mach-pnx4008/time.h b/arch/arm/mach-pnx4008/time.h
new file mode 100644 (file)
index 0000000..75e88c5
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/timex.h
+ *
+ * PNX4008 timers header file
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. 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.
+ */
+#ifndef PNX_TIME_H
+#define PNX_TIME_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+
+#define TICKS2USECS(x) (x)
+
+/* MilliSecond Timer - Chapter 21 Page 202 */
+
+#define MSTIM_INT     IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x0))
+#define MSTIM_CTRL    IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x4))
+#define MSTIM_COUNTER IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x8))
+#define MSTIM_MCTRL   IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x14))
+#define MSTIM_MATCH0  IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x18))
+#define MSTIM_MATCH1  IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x1c))
+
+/* High Speed Timer - Chpater 22, Page 205 */
+
+#define HSTIM_INT     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x0))
+#define HSTIM_CTRL    IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x4))
+#define HSTIM_COUNTER IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x8))
+#define HSTIM_PMATCH  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0xC))
+#define HSTIM_PCOUNT  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x10))
+#define HSTIM_MCTRL   IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x14))
+#define HSTIM_MATCH0  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x18))
+#define HSTIM_MATCH1  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x1c))
+#define HSTIM_MATCH2  IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x20))
+#define HSTIM_CCR     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x28))
+#define HSTIM_CR0     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x2C))
+#define HSTIM_CR1     IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x30))
+
+/* IMPORTANT: both timers are UPCOUNTING */
+
+/* xSTIM_MCTRL bit definitions */
+#define MR0_INT        1
+#define RESET_COUNT0   (1<<1)
+#define STOP_COUNT0    (1<<2)
+#define MR1_INT        (1<<3)
+#define RESET_COUNT1   (1<<4)
+#define STOP_COUNT1    (1<<5)
+#define MR2_INT        (1<<6)
+#define RESET_COUNT2   (1<<7)
+#define STOP_COUNT2    (1<<8)
+
+/* xSTIM_CTRL bit definitions */
+#define COUNT_ENAB     1
+#define RESET_COUNT    (1<<1)
+#define DEBUG_EN       (1<<2)
+
+/* xSTIM_INT bit definitions */
+#define MATCH0_INT     1
+#define MATCH1_INT     (1<<1)
+#define MATCH2_INT     (1<<2)
+#define RTC_TICK0      (1<<4)
+#define RTC_TICK1      (1<<5)
+
+#endif
index 49ae38292310c2b1058c433f7e2a16fbe378756f..abba0089a2ae0d6af3ca35a9bf961d9a5a65406e 100644 (file)
@@ -78,11 +78,3 @@ const struct clkops clk_cken_ops = {
        .enable         = clk_cken_enable,
        .disable        = clk_cken_disable,
 };
-
-void clks_register(struct clk_lookup *clks, size_t num)
-{
-       int i;
-
-       for (i = 0; i < num; i++)
-               clkdev_add(&clks[i]);
-}
index 978a3667e90dcd3548c2fc01fcbc82484c724686..d8488742b8075179fd4d66026d79730e00505a21 100644 (file)
@@ -67,7 +67,3 @@ extern void clk_pxa3xx_cken_enable(struct clk *);
 extern void clk_pxa3xx_cken_disable(struct clk *);
 #endif
 
-void clks_register(struct clk_lookup *clks, size_t num);
-int clk_add_alias(const char *alias, const char *alias_name, char *id,
-       struct device *dev);
-
index 91417f035069a0ce40efd7cc9c60d2542962bdd9..96ed13081639598335309b23b992751d27102ea5 100644 (file)
@@ -128,6 +128,6 @@ static struct clk_lookup eseries_clkregs[] = {
 
 void eseries_register_clks(void)
 {
-       clks_register(eseries_clkregs, ARRAY_SIZE(eseries_clkregs));
+       clkdev_add_table(eseries_clkregs, ARRAY_SIZE(eseries_clkregs));
 }
 
index 55d6a175ab19074a2851e57ceeb958dd5c08eda0..01cf81393fe2d5e25787ea87b375aa510e754f2c 100644 (file)
@@ -13,7 +13,7 @@
 
 #include "hardware.h"
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0x40000000                @ physical
index e90c5eeb81dde9b94304e2eae66ab7b10ea0337e..bfecfbf5f460a4fcfdeca64cd54d1cc6d644f635 100644 (file)
@@ -8,4 +8,4 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define VMALLOC_END       (0xe8000000)
+#define VMALLOC_END       (0xe8000000UL)
index 2c1b0b70d01d0520b6b8facecd88c05884c319d6..0b9ad30bfd51cd659359dfbf2ded2412095033ad 100644 (file)
@@ -349,7 +349,7 @@ static int __init pxa25x_init(void)
 
                reset_status = RCSR;
 
-               clks_register(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs));
+               clkdev_add_table(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs));
 
                if ((ret = pxa_init_dma(IRQ_DMA, 16)))
                        return ret;
@@ -370,7 +370,7 @@ static int __init pxa25x_init(void)
 
        /* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */
        if (cpu_is_pxa255())
-               clks_register(&pxa25x_hwuart_clkreg, 1);
+               clkdev_add(&pxa25x_hwuart_clkreg);
 
        return ret;
 }
index 6a0b73167e03b9bc4529c8e73060117f7fc02190..d783123e2d48e483917f88614dea852d74040504 100644 (file)
@@ -392,7 +392,7 @@ static int __init pxa27x_init(void)
 
                reset_status = RCSR;
 
-               clks_register(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs));
+               clkdev_add_table(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs));
 
                if ((ret = pxa_init_dma(IRQ_DMA, 32)))
                        return ret;
index f4af6e2bef892700b273db56e1b13605a1c22d56..40bb16501d8601789875c03bbef88dd87519c925 100644 (file)
@@ -102,12 +102,12 @@ static int __init pxa300_init(void)
        if (cpu_is_pxa300() || cpu_is_pxa310()) {
                mfp_init_base(io_p2v(MFPR_BASE));
                mfp_init_addr(pxa300_mfp_addr_map);
-               clks_register(ARRAY_AND_SIZE(common_clkregs));
+               clkdev_add_table(ARRAY_AND_SIZE(common_clkregs));
        }
 
        if (cpu_is_pxa310()) {
                mfp_init_addr(pxa310_mfp_addr_map);
-               clks_register(ARRAY_AND_SIZE(pxa310_clkregs));
+               clkdev_add_table(ARRAY_AND_SIZE(pxa310_clkregs));
        }
 
        return 0;
index c7373e74a109dffe6ad923e18c7c7ef951a121e4..8d614ecd8e998d3d663187656dd108ca29405e62 100644 (file)
@@ -90,7 +90,7 @@ static int __init pxa320_init(void)
        if (cpu_is_pxa320()) {
                mfp_init_base(io_p2v(MFPR_BASE));
                mfp_init_addr(pxa320_mfp_addr_map);
-               clks_register(ARRAY_AND_SIZE(pxa320_clkregs));
+               clkdev_add_table(ARRAY_AND_SIZE(pxa320_clkregs));
        }
 
        return 0;
index fcb0721f466947f221c447f235846841204f8bf8..4d7c03e725042e4d735c7b0055df65ce26214bda 100644 (file)
@@ -634,7 +634,7 @@ static int __init pxa3xx_init(void)
                 */
                ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
 
-               clks_register(pxa3xx_clkregs, ARRAY_SIZE(pxa3xx_clkregs));
+               clkdev_add_table(pxa3xx_clkregs, ARRAY_SIZE(pxa3xx_clkregs));
 
                if ((ret = pxa_init_dma(IRQ_DMA, 32)))
                        return ret;
index 9f293438e020cb124e36cf4b370a5c43b0379c19..90bd4ef71b2cae9b426d0bf5e707c2a441a35e1c 100644 (file)
@@ -346,10 +346,7 @@ static struct clk_lookup lookups[] = {
 
 static int __init clk_init(void)
 {
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(lookups); i++)
-               clkdev_add(&lookups[i]);
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
        return 0;
 }
 arch_initcall(clk_init);
index 932d8af180624a7415bdb5a09aafcb4b3235adb0..86622289b74e97950cabe4817bfaa5fc1f378e12 100644 (file)
@@ -33,7 +33,7 @@
 #error "Unknown RealView platform"
 #endif
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx,      #0x10000000
index fe0de1b507ac20b6305b49ff341e8a0b575251ab..a2a4c68614073f37d0ec8ac0e47a40556571fffb 100644 (file)
@@ -18,4 +18,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#define VMALLOC_END            0xf8000000
+#define VMALLOC_END            0xf8000000UL
index b2a939ffdcdeed21a9f63e5199eade9e15d7f351..6fc8d66395dc373d48935ec26c7364da1561ca90 100644 (file)
@@ -11,7 +11,7 @@
  *
 */
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0x03000000
index 4c29a89ad0770566b4969a84354af3d2e4f76b14..0eef78b4a6ed6fa24cddf346dfe55afeaf28a2e8 100644 (file)
@@ -19,7 +19,7 @@
 #define S3C2410_UART1_OFF (0x4000)
 #define SHIFT_2440TXF (14-9)
 
-       .macro addruart, rx
+       .macro addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1
                ldreq   \rx, = S3C24XX_PA_UART
index f0ef0ab475f68bb9c7e6f5c8aea515e1001cf196..239476b81f3b4fd643410401fad18c1b646739ef 100644 (file)
@@ -10,7 +10,7 @@
 #include <mach/map.h>
 #include <plat/regs-serial.h>
 
-       .macro addruart, rx
+       .macro addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1
                ldreq   \rx, = S3C24XX_PA_UART
index 4d4fe48495898fd20d284e5e23da2ca6fd0f738f..914656820794062b578b4cde002a9a2ecd0ed378 100644 (file)
@@ -12,6 +12,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END      (0xE0000000)
+#define VMALLOC_END      (0xe0000000UL)
 
 #endif /* __ASM_ARCH_VMALLOC_H */
index b18ac5266dfc333d9196a564a565341bb4168cb9..5c88875d6a3f57054f29ec6a91e4f9ade5d8e385 100644 (file)
@@ -21,7 +21,7 @@
         * aligned and add in the offset when we load the value here.
         */
 
-       .macro addruart, rx
+       .macro addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1
                ldreq   \rx, = S3C_PA_UART
index 9d142ccf654bbab3fa046b0d9576b4982025eb78..e181f5789482fcd7943777b1343d99eb86654ff1 100644 (file)
@@ -22,7 +22,7 @@
         * aligned and add in the offset when we load the value here.
         */
 
-       .macro addruart, rx
+       .macro addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1
                ldreq   \rx, = S3C_PA_UART
index 1f0634d92702a29c3540d59356d5cc5afd841e85..336adccea54232ef50f7b43367f824c26bc20163 100644 (file)
@@ -12,7 +12,7 @@
 */
 #include <mach/hardware.h>
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0x80000000        @ physical base address
index ec8fdc5a3606bb80be5b32e7f990c44a47e89b4d..b3d0023984803dc17f7716427318ee0626844688 100644 (file)
@@ -1,4 +1,4 @@
 /*
  * arch/arm/mach-sa1100/include/mach/vmalloc.h
  */
-#define VMALLOC_END       (0xe8000000)
+#define VMALLOC_END       (0xe8000000UL)
index f97a7626bd587d39884e160e0877be571382e5f2..50f071c5bf4d603656a01a9c8c2865bf07ee2eb9 100644 (file)
@@ -11,7 +11,7 @@
  *
 */
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mov     \rx, #0xe0000000
                orr     \rx, \rx, #0x000003f8
                .endm
index 111f7ea32b384bd6e492d1cb1c0cf9635632c035..5af71d5ba6656c648fc724a36b66e6d419389a1d 100644 (file)
@@ -610,34 +610,34 @@ EXPORT_SYMBOL(clk_get_rate);
 
 static unsigned long clk_round_rate_mclk(struct clk *clk, unsigned long rate)
 {
-       if (rate >= 18900000)
+       if (rate <= 18900000)
                return 18900000;
-       if (rate >= 20800000)
+       if (rate <= 20800000)
                return 20800000;
-       if (rate >= 23100000)
+       if (rate <= 23100000)
                return 23100000;
-       if (rate >= 26000000)
+       if (rate <= 26000000)
                return 26000000;
-       if (rate >= 29700000)
+       if (rate <= 29700000)
                return 29700000;
-       if (rate >= 34700000)
+       if (rate <= 34700000)
                return 34700000;
-       if (rate >= 41600000)
+       if (rate <= 41600000)
                return 41600000;
-       if (rate >= 52000000)
+       if (rate <= 52000000)
                return 52000000;
        return -EINVAL;
 }
 
 static unsigned long clk_round_rate_cpuclk(struct clk *clk, unsigned long rate)
 {
-       if (rate >= 13000000)
+       if (rate <= 13000000)
                return 13000000;
-       if (rate >= 52000000)
+       if (rate <= 52000000)
                return 52000000;
-       if (rate >= 104000000)
+       if (rate <= 104000000)
                return 104000000;
-       if (rate >= 208000000)
+       if (rate <= 208000000)
                return 208000000;
        return -EINVAL;
 }
@@ -1276,11 +1276,8 @@ static struct clk_lookup lookups[] = {
 
 static void __init clk_register(void)
 {
-       int i;
-
        /* Register the lookups */
-       for (i = 0; i < ARRAY_SIZE(lookups); i++)
-               clkdev_add(&lookups[i]);
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 }
 
 /*
index 653e25be3dd82df532b4b3a508fb45e393b00876..01b50313914cf99fd8738d288495eb18bc2919c9 100644 (file)
@@ -3,7 +3,7 @@
  * arch/arm/mach-u300/core.c
  *
  *
- * Copyright (C) 2007-2009 ST-Ericsson AB
+ * Copyright (C) 2007-2010 ST-Ericsson AB
  * License terms: GNU General Public License (GPL) version 2
  * Core platform support, IRQ handling and device definitions.
  * Author: Linus Walleij <linus.walleij@stericsson.com>
@@ -19,6 +19,7 @@
 #include <linux/amba/bus.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <mach/coh901318.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -29,6 +30,7 @@
 
 #include <mach/hardware.h>
 #include <mach/syscon.h>
+#include <mach/dma_channels.h>
 
 #include "clock.h"
 #include "mmc.h"
@@ -372,8 +374,1019 @@ static struct resource ave_resources[] = {
        },
 };
 
+static struct resource dma_resource[] = {
+       {
+               .start = U300_DMAC_BASE,
+               .end = U300_DMAC_BASE + PAGE_SIZE - 1,
+               .flags =  IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_U300_DMA,
+               .end = IRQ_U300_DMA,
+               .flags =  IORESOURCE_IRQ,
+       }
+};
+
+#ifdef CONFIG_MACH_U300_BS335
+/* points out all dma slave channels.
+ * Syntax is [A1, B1, A2, B2, .... ,-1,-1]
+ * Select all channels from A to B, end of list is marked with -1,-1
+ */
+static int dma_slave_channels[] = {
+       U300_DMA_MSL_TX_0, U300_DMA_SPI_RX,
+       U300_DMA_UART1_TX, U300_DMA_UART1_RX, -1, -1};
+
+/* points out all dma memcpy channels. */
+static int dma_memcpy_channels[] = {
+       U300_DMA_GENERAL_PURPOSE_0, U300_DMA_GENERAL_PURPOSE_8, -1, -1};
+
+#else /* CONFIG_MACH_U300_BS335 */
+
+static int dma_slave_channels[] = {U300_DMA_MSL_TX_0, U300_DMA_SPI_RX, -1, -1};
+static int dma_memcpy_channels[] = {
+       U300_DMA_GENERAL_PURPOSE_0, U300_DMA_GENERAL_PURPOSE_10, -1, -1};
+
+#endif
+
+/** register dma for memory access
+ *
+ * active  1 means dma intends to access memory
+ *         0 means dma wont access memory
+ */
+static void coh901318_access_memory_state(struct device *dev, bool active)
+{
+}
+
+#define flags_memcpy_config (COH901318_CX_CFG_CH_DISABLE | \
+                       COH901318_CX_CFG_RM_MEMORY_TO_MEMORY | \
+                       COH901318_CX_CFG_LCR_DISABLE | \
+                       COH901318_CX_CFG_TC_IRQ_ENABLE | \
+                       COH901318_CX_CFG_BE_IRQ_ENABLE)
+#define flags_memcpy_lli_chained (COH901318_CX_CTRL_TC_ENABLE | \
+                       COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \
+                       COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \
+                       COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \
+                       COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \
+                       COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \
+                       COH901318_CX_CTRL_MASTER_MODE_M1RW | \
+                       COH901318_CX_CTRL_TCP_DISABLE | \
+                       COH901318_CX_CTRL_TC_IRQ_DISABLE | \
+                       COH901318_CX_CTRL_HSP_DISABLE | \
+                       COH901318_CX_CTRL_HSS_DISABLE | \
+                       COH901318_CX_CTRL_DDMA_LEGACY | \
+                       COH901318_CX_CTRL_PRDD_SOURCE)
+#define flags_memcpy_lli (COH901318_CX_CTRL_TC_ENABLE | \
+                       COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \
+                       COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \
+                       COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \
+                       COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \
+                       COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \
+                       COH901318_CX_CTRL_MASTER_MODE_M1RW | \
+                       COH901318_CX_CTRL_TCP_DISABLE | \
+                       COH901318_CX_CTRL_TC_IRQ_DISABLE | \
+                       COH901318_CX_CTRL_HSP_DISABLE | \
+                       COH901318_CX_CTRL_HSS_DISABLE | \
+                       COH901318_CX_CTRL_DDMA_LEGACY | \
+                       COH901318_CX_CTRL_PRDD_SOURCE)
+#define flags_memcpy_lli_last (COH901318_CX_CTRL_TC_ENABLE | \
+                       COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \
+                       COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \
+                       COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \
+                       COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \
+                       COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \
+                       COH901318_CX_CTRL_MASTER_MODE_M1RW | \
+                       COH901318_CX_CTRL_TCP_DISABLE | \
+                       COH901318_CX_CTRL_TC_IRQ_ENABLE | \
+                       COH901318_CX_CTRL_HSP_DISABLE | \
+                       COH901318_CX_CTRL_HSS_DISABLE | \
+                       COH901318_CX_CTRL_DDMA_LEGACY | \
+                       COH901318_CX_CTRL_PRDD_SOURCE)
+
+const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = {
+       {
+               .number = U300_DMA_MSL_TX_0,
+               .name = "MSL TX 0",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 0 * 0x40 + 0x20,
+       },
+       {
+               .number = U300_DMA_MSL_TX_1,
+               .name = "MSL TX 1",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 1 * 0x40 + 0x20,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+               .param.ctrl_lli = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+       },
+       {
+               .number = U300_DMA_MSL_TX_2,
+               .name = "MSL TX 2",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 2 * 0x40 + 0x20,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+               .param.ctrl_lli = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+               .desc_nbr_max = 10,
+       },
+       {
+               .number = U300_DMA_MSL_TX_3,
+               .name = "MSL TX 3",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 3 * 0x40 + 0x20,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+               .param.ctrl_lli = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+       },
+       {
+               .number = U300_DMA_MSL_TX_4,
+               .name = "MSL TX 4",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 4 * 0x40 + 0x20,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+               .param.ctrl_lli = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+       },
+       {
+               .number = U300_DMA_MSL_TX_5,
+               .name = "MSL TX 5",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 5 * 0x40 + 0x20,
+       },
+       {
+               .number = U300_DMA_MSL_TX_6,
+               .name = "MSL TX 6",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 6 * 0x40 + 0x20,
+       },
+       {
+               .number = U300_DMA_MSL_RX_0,
+               .name = "MSL RX 0",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 0 * 0x40 + 0x220,
+       },
+       {
+               .number = U300_DMA_MSL_RX_1,
+               .name = "MSL RX 1",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 1 * 0x40 + 0x220,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+               .param.ctrl_lli = 0,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+       },
+       {
+               .number = U300_DMA_MSL_RX_2,
+               .name = "MSL RX 2",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 2 * 0x40 + 0x220,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+               .param.ctrl_lli = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+       },
+       {
+               .number = U300_DMA_MSL_RX_3,
+               .name = "MSL RX 3",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 3 * 0x40 + 0x220,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+               .param.ctrl_lli = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+       },
+       {
+               .number = U300_DMA_MSL_RX_4,
+               .name = "MSL RX 4",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 4 * 0x40 + 0x220,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+               .param.ctrl_lli = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+       },
+       {
+               .number = U300_DMA_MSL_RX_5,
+               .name = "MSL RX 5",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 5 * 0x40 + 0x220,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+               .param.ctrl_lli = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+                               COH901318_CX_CTRL_PRDD_DEST,
+       },
+       {
+               .number = U300_DMA_MSL_RX_6,
+               .name = "MSL RX 6",
+               .priority_high = 0,
+               .dev_addr = U300_MSL_BASE + 6 * 0x40 + 0x220,
+       },
+       {
+               .number = U300_DMA_MMCSD_RX_TX,
+               .name = "MMCSD RX TX",
+               .priority_high = 0,
+               .dev_addr =  U300_MMCSD_BASE + 0x080,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY,
+               .param.ctrl_lli = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY,
+
+       },
+       {
+               .number = U300_DMA_MSPRO_TX,
+               .name = "MSPRO TX",
+               .priority_high = 0,
+       },
+       {
+               .number = U300_DMA_MSPRO_RX,
+               .name = "MSPRO RX",
+               .priority_high = 0,
+       },
+       {
+               .number = U300_DMA_UART0_TX,
+               .name = "UART0 TX",
+               .priority_high = 0,
+       },
+       {
+               .number = U300_DMA_UART0_RX,
+               .name = "UART0 RX",
+               .priority_high = 0,
+       },
+       {
+               .number = U300_DMA_APEX_TX,
+               .name = "APEX TX",
+               .priority_high = 0,
+       },
+       {
+               .number = U300_DMA_APEX_RX,
+               .name = "APEX RX",
+               .priority_high = 0,
+       },
+       {
+               .number = U300_DMA_PCM_I2S0_TX,
+               .name = "PCM I2S0 TX",
+               .priority_high = 1,
+               .dev_addr = U300_PCM_I2S0_BASE + 0x14,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+               .param.ctrl_lli = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+       },
+       {
+               .number = U300_DMA_PCM_I2S0_RX,
+               .name = "PCM I2S0 RX",
+               .priority_high = 1,
+               .dev_addr = U300_PCM_I2S0_BASE + 0x10,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_DEST,
+               .param.ctrl_lli = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_DEST,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_DEST,
+       },
+       {
+               .number = U300_DMA_PCM_I2S1_TX,
+               .name = "PCM I2S1 TX",
+               .priority_high = 1,
+               .dev_addr =  U300_PCM_I2S1_BASE + 0x14,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+               .param.ctrl_lli = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_SOURCE,
+       },
+       {
+               .number = U300_DMA_PCM_I2S1_RX,
+               .name = "PCM I2S1 RX",
+               .priority_high = 1,
+               .dev_addr = U300_PCM_I2S1_BASE + 0x10,
+               .param.config = COH901318_CX_CFG_CH_DISABLE |
+                               COH901318_CX_CFG_LCR_DISABLE |
+                               COH901318_CX_CFG_TC_IRQ_ENABLE |
+                               COH901318_CX_CFG_BE_IRQ_ENABLE,
+               .param.ctrl_lli_chained = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_DISABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_DEST,
+               .param.ctrl_lli = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_DISABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_DEST,
+               .param.ctrl_lli_last = 0 |
+                               COH901318_CX_CTRL_TC_ENABLE |
+                               COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+                               COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+                               COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+                               COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+                               COH901318_CX_CTRL_MASTER_MODE_M1RW |
+                               COH901318_CX_CTRL_TCP_ENABLE |
+                               COH901318_CX_CTRL_TC_IRQ_ENABLE |
+                               COH901318_CX_CTRL_HSP_ENABLE |
+                               COH901318_CX_CTRL_HSS_DISABLE |
+                               COH901318_CX_CTRL_DDMA_LEGACY |
+                               COH901318_CX_CTRL_PRDD_DEST,
+       },
+       {
+               .number = U300_DMA_XGAM_CDI,
+               .name = "XGAM CDI",
+               .priority_high = 0,
+       },
+       {
+               .number = U300_DMA_XGAM_PDI,
+               .name = "XGAM PDI",
+               .priority_high = 0,
+       },
+       {
+               .number = U300_DMA_SPI_TX,
+               .name = "SPI TX",
+               .priority_high = 0,
+       },
+       {
+               .number = U300_DMA_SPI_RX,
+               .name = "SPI RX",
+               .priority_high = 0,
+       },
+       {
+               .number = U300_DMA_GENERAL_PURPOSE_0,
+               .name = "GENERAL 00",
+               .priority_high = 0,
+
+               .param.config = flags_memcpy_config,
+               .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+               .param.ctrl_lli = flags_memcpy_lli,
+               .param.ctrl_lli_last = flags_memcpy_lli_last,
+       },
+       {
+               .number = U300_DMA_GENERAL_PURPOSE_1,
+               .name = "GENERAL 01",
+               .priority_high = 0,
+
+               .param.config = flags_memcpy_config,
+               .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+               .param.ctrl_lli = flags_memcpy_lli,
+               .param.ctrl_lli_last = flags_memcpy_lli_last,
+       },
+       {
+               .number = U300_DMA_GENERAL_PURPOSE_2,
+               .name = "GENERAL 02",
+               .priority_high = 0,
+
+               .param.config = flags_memcpy_config,
+               .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+               .param.ctrl_lli = flags_memcpy_lli,
+               .param.ctrl_lli_last = flags_memcpy_lli_last,
+       },
+       {
+               .number = U300_DMA_GENERAL_PURPOSE_3,
+               .name = "GENERAL 03",
+               .priority_high = 0,
+
+               .param.config = flags_memcpy_config,
+               .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+               .param.ctrl_lli = flags_memcpy_lli,
+               .param.ctrl_lli_last = flags_memcpy_lli_last,
+       },
+       {
+               .number = U300_DMA_GENERAL_PURPOSE_4,
+               .name = "GENERAL 04",
+               .priority_high = 0,
+
+               .param.config = flags_memcpy_config,
+               .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+               .param.ctrl_lli = flags_memcpy_lli,
+               .param.ctrl_lli_last = flags_memcpy_lli_last,
+       },
+       {
+               .number = U300_DMA_GENERAL_PURPOSE_5,
+               .name = "GENERAL 05",
+               .priority_high = 0,
+
+               .param.config = flags_memcpy_config,
+               .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+               .param.ctrl_lli = flags_memcpy_lli,
+               .param.ctrl_lli_last = flags_memcpy_lli_last,
+       },
+       {
+               .number = U300_DMA_GENERAL_PURPOSE_6,
+               .name = "GENERAL 06",
+               .priority_high = 0,
+
+               .param.config = flags_memcpy_config,
+               .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+               .param.ctrl_lli = flags_memcpy_lli,
+               .param.ctrl_lli_last = flags_memcpy_lli_last,
+       },
+       {
+               .number = U300_DMA_GENERAL_PURPOSE_7,
+               .name = "GENERAL 07",
+               .priority_high = 0,
+
+               .param.config = flags_memcpy_config,
+               .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+               .param.ctrl_lli = flags_memcpy_lli,
+               .param.ctrl_lli_last = flags_memcpy_lli_last,
+       },
+       {
+               .number = U300_DMA_GENERAL_PURPOSE_8,
+               .name = "GENERAL 08",
+               .priority_high = 0,
+
+               .param.config = flags_memcpy_config,
+               .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+               .param.ctrl_lli = flags_memcpy_lli,
+               .param.ctrl_lli_last = flags_memcpy_lli_last,
+       },
+#ifdef CONFIG_MACH_U300_BS335
+       {
+               .number = U300_DMA_UART1_TX,
+               .name = "UART1 TX",
+               .priority_high = 0,
+       },
+       {
+               .number = U300_DMA_UART1_RX,
+               .name = "UART1 RX",
+               .priority_high = 0,
+       }
+#else
+       {
+               .number = U300_DMA_GENERAL_PURPOSE_9,
+               .name = "GENERAL 09",
+               .priority_high = 0,
+
+               .param.config = flags_memcpy_config,
+               .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+               .param.ctrl_lli = flags_memcpy_lli,
+               .param.ctrl_lli_last = flags_memcpy_lli_last,
+       },
+       {
+               .number = U300_DMA_GENERAL_PURPOSE_10,
+               .name = "GENERAL 10",
+               .priority_high = 0,
+
+               .param.config = flags_memcpy_config,
+               .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+               .param.ctrl_lli = flags_memcpy_lli,
+               .param.ctrl_lli_last = flags_memcpy_lli_last,
+       }
+#endif
+};
+
+
+static struct coh901318_platform coh901318_platform = {
+       .chans_slave = dma_slave_channels,
+       .chans_memcpy = dma_memcpy_channels,
+       .access_memory_state = coh901318_access_memory_state,
+       .chan_conf = chan_config,
+       .max_channels = U300_DMA_CHANNELS,
+};
+
 static struct platform_device wdog_device = {
-       .name = "wdog",
+       .name = "coh901327_wdog",
        .id = -1,
        .num_resources = ARRAY_SIZE(wdog_resources),
        .resource = wdog_resources,
@@ -428,11 +1441,23 @@ static struct platform_device ave_device = {
        .resource = ave_resources,
 };
 
+static struct platform_device dma_device = {
+       .name           = "coh901318",
+       .id             = -1,
+       .resource       = dma_resource,
+       .num_resources  = ARRAY_SIZE(dma_resource),
+       .dev = {
+               .platform_data = &coh901318_platform,
+               .coherent_dma_mask = ~0,
+       },
+};
+
 /*
  * Notice that AMBA devices are initialized before platform devices.
  *
  */
 static struct platform_device *platform_devs[] __initdata = {
+       &dma_device,
        &i2c0_device,
        &i2c1_device,
        &keypad_device,
index 0b35826b7d1d419a5daf875cdf1cfc215fac726c..5f61fd45a0c8a1dee47baa305ca3aa49d07fac01 100644 (file)
@@ -546,7 +546,7 @@ static void gpio_set_initial_values(void)
        for (i = 0; i < U300_GPIO_MAX; i++) {
                val = 0;
                for (j = 0; j < 8; j++)
-                       val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP)) << j;
+                       val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP) << j);
                local_irq_save(flags);
                writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING);
                local_irq_restore(flags);
index f3a1cbbeeab3876a91ec8da8411bcb09d2d78901..ca4a028c26613097811977bf2f2d14be592aee18 100644 (file)
@@ -10,7 +10,7 @@
  */
 #include <mach/hardware.h>
 
-       .macro  addruart,rx
+       .macro  addruart, rx, tmp
        /* If we move the adress using MMU, use this. */
        mrc     p15, 0, \rx, c1, c0
        tst     \rx, #1                 @ MMU enabled?
diff --git a/arch/arm/mach-u300/include/mach/dma_channels.h b/arch/arm/mach-u300/include/mach/dma_channels.h
new file mode 100644 (file)
index 0000000..b239149
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/dma_channels.h
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ * Map file for the U300 dma driver.
+ * Author: Per Friden <per.friden@stericsson.com>
+ */
+
+#ifndef DMA_CHANNELS_H
+#define DMA_CHANNELS_H
+
+#define U300_DMA_MSL_TX_0             0
+#define U300_DMA_MSL_TX_1             1
+#define U300_DMA_MSL_TX_2             2
+#define U300_DMA_MSL_TX_3             3
+#define U300_DMA_MSL_TX_4             4
+#define U300_DMA_MSL_TX_5             5
+#define U300_DMA_MSL_TX_6             6
+#define U300_DMA_MSL_RX_0             7
+#define U300_DMA_MSL_RX_1             8
+#define U300_DMA_MSL_RX_2             9
+#define U300_DMA_MSL_RX_3             10
+#define U300_DMA_MSL_RX_4             11
+#define U300_DMA_MSL_RX_5             12
+#define U300_DMA_MSL_RX_6             13
+#define U300_DMA_MMCSD_RX_TX          14
+#define U300_DMA_MSPRO_TX             15
+#define U300_DMA_MSPRO_RX             16
+#define U300_DMA_UART0_TX             17
+#define U300_DMA_UART0_RX             18
+#define U300_DMA_APEX_TX              19
+#define U300_DMA_APEX_RX              20
+#define U300_DMA_PCM_I2S0_TX          21
+#define U300_DMA_PCM_I2S0_RX          22
+#define U300_DMA_PCM_I2S1_TX          23
+#define U300_DMA_PCM_I2S1_RX          24
+#define U300_DMA_XGAM_CDI             25
+#define U300_DMA_XGAM_PDI             26
+#define U300_DMA_SPI_TX               27
+#define U300_DMA_SPI_RX               28
+#define U300_DMA_GENERAL_PURPOSE_0    29
+#define U300_DMA_GENERAL_PURPOSE_1    30
+#define U300_DMA_GENERAL_PURPOSE_2    31
+#define U300_DMA_GENERAL_PURPOSE_3    32
+#define U300_DMA_GENERAL_PURPOSE_4    33
+#define U300_DMA_GENERAL_PURPOSE_5    34
+#define U300_DMA_GENERAL_PURPOSE_6    35
+#define U300_DMA_GENERAL_PURPOSE_7    36
+#define U300_DMA_GENERAL_PURPOSE_8    37
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_DMA_UART1_TX             38
+#define U300_DMA_UART1_RX             39
+#else
+#define U300_DMA_GENERAL_PURPOSE_9    38
+#define U300_DMA_GENERAL_PURPOSE_10   39
+#endif
+
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_DMA_DEVICE_CHANNELS      32
+#else
+#define U300_DMA_DEVICE_CHANNELS      30
+#endif
+#define U300_DMA_CHANNELS             40
+
+
+#endif /* DMA_CHANNELS_H */
index b00c51a66fbe59cf948d14fc8582ded0a3374eca..ec423b92b81dd25ffd69f623bb190c6114108653 100644 (file)
@@ -9,4 +9,4 @@
  * End must be above the I/O registers and on an even 2MiB boundary.
  * Author: Linus Walleij <linus.walleij@stericsson.com>
  */
-#define VMALLOC_END    0xfe800000
+#define VMALLOC_END    0xfe800000UL
index aa5afbcc90f9a752dcc49f18010efe2e9315d0b6..803aec1d672823e44854be50a29a931e1914e409 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/mach/arch.h>
 
 #include <plat/mtu.h>
+#include <plat/i2c.h>
 
 #include <mach/hardware.h>
 #include <mach/setup.h>
@@ -108,11 +109,96 @@ static struct amba_device pl022_device = {
        .periphid = SSP_PER_ID,
 };
 
+static struct amba_device pl031_device = {
+       .dev = {
+               .init_name = "pl031",
+       },
+       .res = {
+               .start = U8500_RTC_BASE,
+               .end = U8500_RTC_BASE + SZ_4K - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       .irq = {IRQ_RTC_RTT, NO_IRQ},
+};
+
+#define U8500_I2C_RESOURCES(id, size)          \
+static struct resource u8500_i2c_resources_##id[] = {  \
+       [0] = {                                 \
+               .start  = U8500_I2C##id##_BASE, \
+               .end    = U8500_I2C##id##_BASE + size - 1, \
+               .flags  = IORESOURCE_MEM,       \
+       },                                      \
+       [1] = {                                 \
+               .start  = IRQ_I2C##id,          \
+               .end    = IRQ_I2C##id,          \
+               .flags  = IORESOURCE_IRQ        \
+       }                                       \
+}
+
+U8500_I2C_RESOURCES(0, SZ_4K);
+U8500_I2C_RESOURCES(1, SZ_4K);
+U8500_I2C_RESOURCES(2, SZ_4K);
+U8500_I2C_RESOURCES(3, SZ_4K);
+
+#define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \
+static struct nmk_i2c_controller u8500_i2c_##id = { \
+       /*                              \
+        * slave data setup time, which is      \
+        * 250 ns,100ns,10ns which is 14,6,2    \
+        * respectively for a 48 Mhz    \
+        * i2c clock                    \
+        */                             \
+       .slsu           = _slsu,        \
+       /* Tx FIFO threshold */         \
+       .tft            = _tft,         \
+       /* Rx FIFO threshold */         \
+       .rft            = _rft,         \
+       /* std. mode operation */       \
+       .clk_freq       = clk,          \
+       .sm             = _sm,          \
+}
+
+/*
+ * The board uses 4 i2c controllers, initialize all of
+ * them with slave data setup time of 250 ns,
+ * Tx & Rx FIFO threshold values as 1 and standard
+ * mode of operation
+ */
+U8500_I2C_CONTROLLER(0, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
+U8500_I2C_CONTROLLER(1, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
+U8500_I2C_CONTROLLER(2,        0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
+U8500_I2C_CONTROLLER(3,        0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
+
+#define U8500_I2C_PDEVICE(cid)         \
+static struct platform_device i2c_controller##cid = { \
+       .name = "nmk-i2c",              \
+       .id      = cid,                 \
+       .num_resources = 2,             \
+       .resource = u8500_i2c_resources_##cid,  \
+       .dev = {                        \
+               .platform_data = &u8500_i2c_##cid \
+       }                               \
+}
+
+U8500_I2C_PDEVICE(0);
+U8500_I2C_PDEVICE(1);
+U8500_I2C_PDEVICE(2);
+U8500_I2C_PDEVICE(3);
+
 static struct amba_device *amba_devs[] __initdata = {
        &uart0_device,
        &uart1_device,
        &uart2_device,
        &pl022_device,
+       &pl031_device,
+};
+
+/* add any platform devices here - TODO */
+static struct platform_device *platform_devs[] __initdata = {
+       &i2c_controller0,
+       &i2c_controller1,
+       &i2c_controller2,
+       &i2c_controller3,
 };
 
 static void __init u8500_timer_init(void)
@@ -139,6 +225,8 @@ static void __init u8500_init_machine(void)
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
                amba_device_register(amba_devs[i], &iomem_resource);
 
+       platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
+
        spi_register_board_info(u8500_spi_devices,
                        ARRAY_SIZE(u8500_spi_devices));
 
index 20b6ebb6783aa7bb8f3a60356b780b66ff784a95..8359a73d0041c0b988cd4ecea50a77ac92f71093 100644 (file)
@@ -85,11 +85,8 @@ static struct clk_lookup lookups[] = {
 
 static int __init clk_init(void)
 {
-       int i;
-
        /* register the clock lookups */
-       for (i = 0; i < ARRAY_SIZE(lookups); i++)
-               clkdev_add(&lookups[i]);
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
        return 0;
 }
 arch_initcall(clk_init);
index 5f05e5850f7162de73125305c7c124140cf93d1e..397bc1f9ed94aed1b56abfd669b55b0fa5976ae8 100644 (file)
@@ -33,6 +33,7 @@ static struct platform_device *platform_devs[] __initdata = {
 
 /* minimum static i/o mapping required to boot U8500 platforms */
 static struct map_desc u8500_io_desc[] __initdata = {
+       __IO_DEV_DESC(U8500_UART2_BASE, SZ_4K),
        __IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K),
        __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K),
        __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
index 8f21b6a95dce5b13f6fc9becfe4c4606145366ee..09cbfda8aee5af8d6359fb25a0a525d99f11414f 100644 (file)
@@ -8,12 +8,13 @@
  * published by the Free Software Foundation.
  *
  */
-       .macro  addruart,rx
+#include <mach/hardware.h>
+
+       .macro  addruart, rx, tmp
        mrc     p15, 0, \rx, c1, c0
-       tst     \rx, #1                 @MMU enabled?
-       moveq   \rx, #0x80000000        @MMU off, Physical address
-       movne   \rx, #0xF0000000        @MMU on, Virtual address
-       orr     \rx, \rx, #0x7000
+       tst     \rx, #1                                 @ MMU enabled?
+       ldreq   \rx, =U8500_UART2_BASE                  @ no, physical address
+       ldrne   \rx, =IO_ADDRESS(U8500_UART2_BASE)      @ yes, virtual address
        .endm
 
 #include <asm/hardware/debug-pl01x.S>
index 86cdbbce1842f8b8bd089261fb0a444eaeb5564c..a4945cb41172c09e80620f19fad10bfe499fcb55 100644 (file)
@@ -15,4 +15,4 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#define VMALLOC_END    0xf0000000
+#define VMALLOC_END    0xf0000000UL
index e13be7c444ca83acb774b3865b4055b81f908b0f..9ddb49b1cb719119c2df40c3e807a4c90b36e712 100644 (file)
@@ -851,8 +851,7 @@ void __init versatile_init(void)
 {
        int i;
 
-       for (i = 0; i < ARRAY_SIZE(lookups); i++)
-               clkdev_add(&lookups[i]);
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        platform_device_register(&versatile_flash_device);
        platform_device_register(&versatile_i2c_device);
index b4ac00eacf6876fa69719f47537f9a1899b8ff93..6fea7199c626742d4e39afcaadecd5e32ad39e99 100644 (file)
@@ -11,7 +11,7 @@
  *
 */
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx,      #0x10000000
index b785994bab0a64fbe2bf5cf6f2cdd8e67f10306c..2c371ff22e517ad17776902f5af31e8e198d1a66 100644 (file)
@@ -90,12 +90,3 @@ void nuc900_subclk_enable(struct clk *clk, int enable)
 
        __raw_writel(clken, W90X900_VA_CLKPWR + SUBCLK);
 }
-
-
-void clks_register(struct clk_lookup *clks, size_t num)
-{
-       int i;
-
-       for (i = 0; i < num; i++)
-               clkdev_add(&clks[i]);
-}
index f5816a06eed6aa415bffd21b5dbd708266d404dc..c56ddab3d9128acce33ba0d293a3dcfa29bcd08c 100644 (file)
@@ -14,7 +14,6 @@
 
 void nuc900_clk_enable(struct clk *clk, int enable);
 void nuc900_subclk_enable(struct clk *clk, int enable);
-void clks_register(struct clk_lookup *clks, size_t num);
 
 struct clk {
        unsigned long           cken;
index 20dc0c96214dcae4e93bb67910e5c0027eb6cf8f..642207e18198db20777ef475a27ada0bd2ae0c3d 100644 (file)
@@ -45,6 +45,7 @@ static struct map_desc nuc900_iodesc[] __initdata = {
        IODESC_ENT(UART),
        IODESC_ENT(TIMER),
        IODESC_ENT(EBI),
+       IODESC_ENT(GPIO),
 };
 
 /* Initial clock declarations. */
@@ -68,6 +69,11 @@ static DEFINE_CLK(gdma, 27);
 static DEFINE_CLK(adc, 28);
 static DEFINE_CLK(usi, 29);
 static DEFINE_CLK(ext, 0);
+static DEFINE_CLK(timer0, 19);
+static DEFINE_CLK(timer1, 20);
+static DEFINE_CLK(timer2, 21);
+static DEFINE_CLK(timer3, 22);
+static DEFINE_CLK(timer4, 23);
 
 static struct clk_lookup nuc900_clkregs[] = {
        DEF_CLKLOOK(&clk_lcd, "nuc900-lcd", NULL),
@@ -90,6 +96,11 @@ static struct clk_lookup nuc900_clkregs[] = {
        DEF_CLKLOOK(&clk_adc, "nuc900-adc", NULL),
        DEF_CLKLOOK(&clk_usi, "nuc900-spi", NULL),
        DEF_CLKLOOK(&clk_ext, NULL, "ext"),
+       DEF_CLKLOOK(&clk_timer0, NULL, "timer0"),
+       DEF_CLKLOOK(&clk_timer1, NULL, "timer1"),
+       DEF_CLKLOOK(&clk_timer2, NULL, "timer2"),
+       DEF_CLKLOOK(&clk_timer3, NULL, "timer3"),
+       DEF_CLKLOOK(&clk_timer4, NULL, "timer4"),
 };
 
 /* Initial serial platform data */
@@ -208,6 +219,6 @@ void __init nuc900_map_io(struct map_desc *mach_desc, int mach_size)
 
 void __init nuc900_init_clocks(void)
 {
-       clks_register(nuc900_clkregs, ARRAY_SIZE(nuc900_clkregs));
+       clkdev_add_table(nuc900_clkregs, ARRAY_SIZE(nuc900_clkregs));
 }
 
index 2f9dfb928533391e292feb51cd45aaec5543a3a3..b067e44500a48b84796fbfae6db045ac69b21265 100644 (file)
@@ -18,6 +18,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END      (0xE0000000)
+#define VMALLOC_END      (0xe0000000UL)
 
 #endif /* __ASM_ARCH_VMALLOC_H */
index baf638487a2d530acaf30c7cab9581b3ec5b6f47..c4ed9f93f646be93fbdcc048a326c5d7db995bcd 100644 (file)
@@ -399,7 +399,7 @@ config CPU_V6
 config CPU_32v6K
        bool "Support ARM V6K processor extensions" if !SMP
        depends on CPU_V6
-       default y if SMP && !ARCH_MX3
+       default y if SMP && !(ARCH_MX3 || ARCH_OMAP2)
        help
          Say Y here if your ARMv6 processor supports the 'K' extension.
          This enables the kernel to use some instructions not present
@@ -410,7 +410,7 @@ config CPU_32v6K
 # ARMv7
 config CPU_V7
        bool "Support ARM V7 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
-       select CPU_32v6K
+       select CPU_32v6K if !ARCH_OMAP2
        select CPU_32v7
        select CPU_ABRT_EV7
        select CPU_PABRT_V7
@@ -754,7 +754,7 @@ config CACHE_FEROCEON_L2_WRITETHROUGH
 config CACHE_L2X0
        bool "Enable the L2x0 outer cache controller"
        depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
-                  REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK
+                  REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4
        default y
        select OUTER_CACHE
        help
@@ -779,5 +779,5 @@ config CACHE_XSC3L2
 
 config ARM_L1_CACHE_SHIFT
        int
-       default 6 if ARCH_OMAP3 || ARCH_S5PC1XX
+       default 6 if ARM_L1_CACHE_SHIFT_6
        default 5
index 62820eda84d9ea89bb1ec729b8934c626a74c20a..edddd66faac6bb9a1f08e8ca144b3677cb9fac3c 100644 (file)
@@ -901,11 +901,7 @@ static int __init alignment_init(void)
 #ifdef CONFIG_PROC_FS
        struct proc_dir_entry *res;
 
-       res = proc_mkdir("cpu", NULL);
-       if (!res)
-               return -ENOMEM;
-
-       res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, res);
+       res = create_proc_entry("cpu/alignment", S_IWUSR | S_IRUGO, NULL);
        if (!res)
                return -ENOMEM;
 
index a89444a3c016f0c2ecee35d38655b109664bc91b..7148e53e6078fff5b32a5d8d87a5ce1658095ae3 100644 (file)
@@ -157,7 +157,7 @@ ENTRY(fa_flush_kern_dcache_area)
  *     - start  - virtual start address
  *     - end    - virtual end address
  */
-ENTRY(fa_dma_inv_range)
+fa_dma_inv_range:
        tst     r0, #CACHE_DLINESIZE - 1
        bic     r0, r0, #CACHE_DLINESIZE - 1
        mcrne   p15, 0, r0, c7, c14, 1          @ clean & invalidate D entry
@@ -180,7 +180,7 @@ ENTRY(fa_dma_inv_range)
  *     - start  - virtual start address
  *     - end    - virtual end address
  */
-ENTRY(fa_dma_clean_range)
+fa_dma_clean_range:
        bic     r0, r0, #CACHE_DLINESIZE - 1
 1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
        add     r0, r0, #CACHE_DLINESIZE
@@ -205,6 +205,30 @@ ENTRY(fa_dma_flush_range)
        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(fa_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     fa_dma_clean_range
+       bcs     fa_dma_inv_range
+       b       fa_dma_flush_range
+ENDPROC(fa_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(fa_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(fa_dma_unmap_area)
+
        __INITDATA
 
        .type   fa_cache_fns, #object
@@ -215,7 +239,7 @@ ENTRY(fa_cache_fns)
        .long   fa_coherent_kern_range
        .long   fa_coherent_user_range
        .long   fa_flush_kern_dcache_area
-       .long   fa_dma_inv_range
-       .long   fa_dma_clean_range
+       .long   fa_dma_map_area
+       .long   fa_dma_unmap_area
        .long   fa_dma_flush_range
        .size   fa_cache_fns, . - fa_cache_fns
index cb8fc6573b1b2c9dedbeeec0f9a87c491a78ba85..07334632d3e2761293e1880b2486a2e85c3437e4 100644 (file)
@@ -42,6 +42,57 @@ static inline void cache_sync(void)
        cache_wait(base + L2X0_CACHE_SYNC, 1);
 }
 
+static inline void l2x0_clean_line(unsigned long addr)
+{
+       void __iomem *base = l2x0_base;
+       cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
+       writel(addr, base + L2X0_CLEAN_LINE_PA);
+}
+
+static inline void l2x0_inv_line(unsigned long addr)
+{
+       void __iomem *base = l2x0_base;
+       cache_wait(base + L2X0_INV_LINE_PA, 1);
+       writel(addr, base + L2X0_INV_LINE_PA);
+}
+
+#ifdef CONFIG_PL310_ERRATA_588369
+static void debug_writel(unsigned long val)
+{
+       extern void omap_smc1(u32 fn, u32 arg);
+
+       /*
+        * Texas Instrument secure monitor api to modify the
+        * PL310 Debug Control Register.
+        */
+       omap_smc1(0x100, val);
+}
+
+static inline void l2x0_flush_line(unsigned long addr)
+{
+       void __iomem *base = l2x0_base;
+
+       /* Clean by PA followed by Invalidate by PA */
+       cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
+       writel(addr, base + L2X0_CLEAN_LINE_PA);
+       cache_wait(base + L2X0_INV_LINE_PA, 1);
+       writel(addr, base + L2X0_INV_LINE_PA);
+}
+#else
+
+/* Optimised out for non-errata case */
+static inline void debug_writel(unsigned long val)
+{
+}
+
+static inline void l2x0_flush_line(unsigned long addr)
+{
+       void __iomem *base = l2x0_base;
+       cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
+       writel(addr, base + L2X0_CLEAN_INV_LINE_PA);
+}
+#endif
+
 static inline void l2x0_inv_all(void)
 {
        unsigned long flags;
@@ -62,23 +113,24 @@ static void l2x0_inv_range(unsigned long start, unsigned long end)
        spin_lock_irqsave(&l2x0_lock, flags);
        if (start & (CACHE_LINE_SIZE - 1)) {
                start &= ~(CACHE_LINE_SIZE - 1);
-               cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
-               writel(start, base + L2X0_CLEAN_INV_LINE_PA);
+               debug_writel(0x03);
+               l2x0_flush_line(start);
+               debug_writel(0x00);
                start += CACHE_LINE_SIZE;
        }
 
        if (end & (CACHE_LINE_SIZE - 1)) {
                end &= ~(CACHE_LINE_SIZE - 1);
-               cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
-               writel(end, base + L2X0_CLEAN_INV_LINE_PA);
+               debug_writel(0x03);
+               l2x0_flush_line(end);
+               debug_writel(0x00);
        }
 
        while (start < end) {
                unsigned long blk_end = start + min(end - start, 4096UL);
 
                while (start < blk_end) {
-                       cache_wait(base + L2X0_INV_LINE_PA, 1);
-                       writel(start, base + L2X0_INV_LINE_PA);
+                       l2x0_inv_line(start);
                        start += CACHE_LINE_SIZE;
                }
 
@@ -103,8 +155,7 @@ static void l2x0_clean_range(unsigned long start, unsigned long end)
                unsigned long blk_end = start + min(end - start, 4096UL);
 
                while (start < blk_end) {
-                       cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
-                       writel(start, base + L2X0_CLEAN_LINE_PA);
+                       l2x0_clean_line(start);
                        start += CACHE_LINE_SIZE;
                }
 
@@ -128,11 +179,12 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
        while (start < end) {
                unsigned long blk_end = start + min(end - start, 4096UL);
 
+               debug_writel(0x03);
                while (start < blk_end) {
-                       cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
-                       writel(start, base + L2X0_CLEAN_INV_LINE_PA);
+                       l2x0_flush_line(start);
                        start += CACHE_LINE_SIZE;
                }
+               debug_writel(0x00);
 
                if (blk_end < end) {
                        spin_unlock_irqrestore(&l2x0_lock, flags);
index 2a482731ea36914f2f6ca2b6bb4299e7dee84742..c2ff3c599feed47eb77d92190d29958fb95e8315 100644 (file)
@@ -83,20 +83,6 @@ ENTRY(v3_coherent_user_range)
 ENTRY(v3_flush_kern_dcache_area)
        /* FALLTHROUGH */
 
-/*
- *     dma_inv_range(start, end)
- *
- *     Invalidate (discard) the specified virtual address range.
- *     May not write back any entries.  If 'start' or 'end'
- *     are not cache line aligned, those lines must be written
- *     back.
- *
- *     - start  - virtual start address
- *     - end    - virtual end address
- */
-ENTRY(v3_dma_inv_range)
-       /* FALLTHROUGH */
-
 /*
  *     dma_flush_range(start, end)
  *
@@ -108,18 +94,29 @@ ENTRY(v3_dma_inv_range)
 ENTRY(v3_dma_flush_range)
        mov     r0, #0
        mcr     p15, 0, r0, c7, c0, 0           @ flush ID cache
+       mov     pc, lr
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(v3_dma_unmap_area)
+       teq     r2, #DMA_TO_DEVICE
+       bne     v3_dma_flush_range
        /* FALLTHROUGH */
 
 /*
- *     dma_clean_range(start, end)
- *
- *     Clean (write back) the specified virtual address range.
- *
- *     - start  - virtual start address
- *     - end    - virtual end address
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
  */
-ENTRY(v3_dma_clean_range)
+ENTRY(v3_dma_map_area)
        mov     pc, lr
+ENDPROC(v3_dma_unmap_area)
+ENDPROC(v3_dma_map_area)
 
        __INITDATA
 
@@ -131,7 +128,7 @@ ENTRY(v3_cache_fns)
        .long   v3_coherent_kern_range
        .long   v3_coherent_user_range
        .long   v3_flush_kern_dcache_area
-       .long   v3_dma_inv_range
-       .long   v3_dma_clean_range
+       .long   v3_dma_map_area
+       .long   v3_dma_unmap_area
        .long   v3_dma_flush_range
        .size   v3_cache_fns, . - v3_cache_fns
index 5c7da3e372e94faa6f85a07b2c154730140f44b6..4810f7e3e8139ea8bed712cc4b9cea792660d99a 100644 (file)
@@ -93,20 +93,6 @@ ENTRY(v4_coherent_user_range)
 ENTRY(v4_flush_kern_dcache_area)
        /* FALLTHROUGH */
 
-/*
- *     dma_inv_range(start, end)
- *
- *     Invalidate (discard) the specified virtual address range.
- *     May not write back any entries.  If 'start' or 'end'
- *     are not cache line aligned, those lines must be written
- *     back.
- *
- *     - start  - virtual start address
- *     - end    - virtual end address
- */
-ENTRY(v4_dma_inv_range)
-       /* FALLTHROUGH */
-
 /*
  *     dma_flush_range(start, end)
  *
@@ -120,18 +106,29 @@ ENTRY(v4_dma_flush_range)
        mov     r0, #0
        mcr     p15, 0, r0, c7, c7, 0           @ flush ID cache
 #endif
+       mov     pc, lr
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(v4_dma_unmap_area)
+       teq     r2, #DMA_TO_DEVICE
+       bne     v4_dma_flush_range
        /* FALLTHROUGH */
 
 /*
- *     dma_clean_range(start, end)
- *
- *     Clean (write back) the specified virtual address range.
- *
- *     - start  - virtual start address
- *     - end    - virtual end address
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
  */
-ENTRY(v4_dma_clean_range)
+ENTRY(v4_dma_map_area)
        mov     pc, lr
+ENDPROC(v4_dma_unmap_area)
+ENDPROC(v4_dma_map_area)
 
        __INITDATA
 
@@ -143,7 +140,7 @@ ENTRY(v4_cache_fns)
        .long   v4_coherent_kern_range
        .long   v4_coherent_user_range
        .long   v4_flush_kern_dcache_area
-       .long   v4_dma_inv_range
-       .long   v4_dma_clean_range
+       .long   v4_dma_map_area
+       .long   v4_dma_unmap_area
        .long   v4_dma_flush_range
        .size   v4_cache_fns, . - v4_cache_fns
index 3dbedf1ec0e7790612385b34def041378af5f0d9..df8368afa102771bb99c19045abac26abb42e656 100644 (file)
@@ -173,7 +173,7 @@ ENTRY(v4wb_coherent_user_range)
  *     - start  - virtual start address
  *     - end    - virtual end address
  */
-ENTRY(v4wb_dma_inv_range)
+v4wb_dma_inv_range:
        tst     r0, #CACHE_DLINESIZE - 1
        bic     r0, r0, #CACHE_DLINESIZE - 1
        mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
@@ -194,7 +194,7 @@ ENTRY(v4wb_dma_inv_range)
  *     - start  - virtual start address
  *     - end    - virtual end address
  */
-ENTRY(v4wb_dma_clean_range)
+v4wb_dma_clean_range:
        bic     r0, r0, #CACHE_DLINESIZE - 1
 1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
        add     r0, r0, #CACHE_DLINESIZE
@@ -216,6 +216,30 @@ ENTRY(v4wb_dma_clean_range)
        .globl  v4wb_dma_flush_range
        .set    v4wb_dma_flush_range, v4wb_coherent_kern_range
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(v4wb_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     v4wb_dma_clean_range
+       bcs     v4wb_dma_inv_range
+       b       v4wb_dma_flush_range
+ENDPROC(v4wb_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(v4wb_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(v4wb_dma_unmap_area)
+
        __INITDATA
 
        .type   v4wb_cache_fns, #object
@@ -226,7 +250,7 @@ ENTRY(v4wb_cache_fns)
        .long   v4wb_coherent_kern_range
        .long   v4wb_coherent_user_range
        .long   v4wb_flush_kern_dcache_area
-       .long   v4wb_dma_inv_range
-       .long   v4wb_dma_clean_range
+       .long   v4wb_dma_map_area
+       .long   v4wb_dma_unmap_area
        .long   v4wb_dma_flush_range
        .size   v4wb_cache_fns, . - v4wb_cache_fns
index b3b7410270b48e6bf3414de930e2eff0010cf6b3..45c70312f43bb1db9f49ae9591283d243b072ae8 100644 (file)
@@ -142,23 +142,12 @@ ENTRY(v4wt_flush_kern_dcache_area)
  *     - start  - virtual start address
  *     - end    - virtual end address
  */
-ENTRY(v4wt_dma_inv_range)
+v4wt_dma_inv_range:
        bic     r0, r0, #CACHE_DLINESIZE - 1
 1:     mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
        add     r0, r0, #CACHE_DLINESIZE
        cmp     r0, r1
        blo     1b
-       /* FALLTHROUGH */
-
-/*
- *     dma_clean_range(start, end)
- *
- *     Clean the specified virtual address range.
- *
- *     - start  - virtual start address
- *     - end    - virtual end address
- */
-ENTRY(v4wt_dma_clean_range)
        mov     pc, lr
 
 /*
@@ -172,6 +161,29 @@ ENTRY(v4wt_dma_clean_range)
        .globl  v4wt_dma_flush_range
        .equ    v4wt_dma_flush_range, v4wt_dma_inv_range
 
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(v4wt_dma_unmap_area)
+       add     r1, r1, r0
+       teq     r2, #DMA_TO_DEVICE
+       bne     v4wt_dma_inv_range
+       /* FALLTHROUGH */
+
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(v4wt_dma_map_area)
+       mov     pc, lr
+ENDPROC(v4wt_dma_unmap_area)
+ENDPROC(v4wt_dma_map_area)
+
        __INITDATA
 
        .type   v4wt_cache_fns, #object
@@ -182,7 +194,7 @@ ENTRY(v4wt_cache_fns)
        .long   v4wt_coherent_kern_range
        .long   v4wt_coherent_user_range
        .long   v4wt_flush_kern_dcache_area
-       .long   v4wt_dma_inv_range
-       .long   v4wt_dma_clean_range
+       .long   v4wt_dma_map_area
+       .long   v4wt_dma_unmap_area
        .long   v4wt_dma_flush_range
        .size   v4wt_cache_fns, . - v4wt_cache_fns
index 4ba0a24ce6f58341bcf0a78aef56531709e7b774..9d89c67a1cc3902c32b5aed501d27f28b091695c 100644 (file)
@@ -195,7 +195,7 @@ ENTRY(v6_flush_kern_dcache_area)
  *     - start   - virtual start address of region
  *     - end     - virtual end address of region
  */
-ENTRY(v6_dma_inv_range)
+v6_dma_inv_range:
        tst     r0, #D_CACHE_LINE_SIZE - 1
        bic     r0, r0, #D_CACHE_LINE_SIZE - 1
 #ifdef HARVARD_CACHE
@@ -228,7 +228,7 @@ ENTRY(v6_dma_inv_range)
  *     - start   - virtual start address of region
  *     - end     - virtual end address of region
  */
-ENTRY(v6_dma_clean_range)
+v6_dma_clean_range:
        bic     r0, r0, #D_CACHE_LINE_SIZE - 1
 1:
 #ifdef HARVARD_CACHE
@@ -263,6 +263,32 @@ ENTRY(v6_dma_flush_range)
        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(v6_dma_map_area)
+       add     r1, r1, r0
+       teq     r2, #DMA_FROM_DEVICE
+       beq     v6_dma_inv_range
+       b       v6_dma_clean_range
+ENDPROC(v6_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(v6_dma_unmap_area)
+       add     r1, r1, r0
+       teq     r2, #DMA_TO_DEVICE
+       bne     v6_dma_inv_range
+       mov     pc, lr
+ENDPROC(v6_dma_unmap_area)
+
        __INITDATA
 
        .type   v6_cache_fns, #object
@@ -273,7 +299,7 @@ ENTRY(v6_cache_fns)
        .long   v6_coherent_kern_range
        .long   v6_coherent_user_range
        .long   v6_flush_kern_dcache_area
-       .long   v6_dma_inv_range
-       .long   v6_dma_clean_range
+       .long   v6_dma_map_area
+       .long   v6_dma_unmap_area
        .long   v6_dma_flush_range
        .size   v6_cache_fns, . - v6_cache_fns
index 9073db849fb46a75f08c18c1ae9790614696e377..bcd64f265870804532dc6012274bca6e398a0622 100644 (file)
@@ -216,7 +216,7 @@ ENDPROC(v7_flush_kern_dcache_area)
  *     - start   - virtual start address of region
  *     - end     - virtual end address of region
  */
-ENTRY(v7_dma_inv_range)
+v7_dma_inv_range:
        dcache_line_size r2, r3
        sub     r3, r2, #1
        tst     r0, r3
@@ -240,7 +240,7 @@ ENDPROC(v7_dma_inv_range)
  *     - start   - virtual start address of region
  *     - end     - virtual end address of region
  */
-ENTRY(v7_dma_clean_range)
+v7_dma_clean_range:
        dcache_line_size r2, r3
        sub     r3, r2, #1
        bic     r0, r0, r3
@@ -271,6 +271,32 @@ ENTRY(v7_dma_flush_range)
        mov     pc, lr
 ENDPROC(v7_dma_flush_range)
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(v7_dma_map_area)
+       add     r1, r1, r0
+       teq     r2, #DMA_FROM_DEVICE
+       beq     v7_dma_inv_range
+       b       v7_dma_clean_range
+ENDPROC(v7_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(v7_dma_unmap_area)
+       add     r1, r1, r0
+       teq     r2, #DMA_TO_DEVICE
+       bne     v7_dma_inv_range
+       mov     pc, lr
+ENDPROC(v7_dma_unmap_area)
+
        __INITDATA
 
        .type   v7_cache_fns, #object
@@ -281,7 +307,7 @@ ENTRY(v7_cache_fns)
        .long   v7_coherent_kern_range
        .long   v7_coherent_user_range
        .long   v7_flush_kern_dcache_area
-       .long   v7_dma_inv_range
-       .long   v7_dma_clean_range
+       .long   v7_dma_map_area
+       .long   v7_dma_unmap_area
        .long   v7_dma_flush_range
        .size   v7_cache_fns, . - v7_cache_fns
index a9e22e31eaa1135ca9997840266f3144dd587735..b0ee9ba3cfab41a52853eca727466abff88ddf27 100644 (file)
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/percpu.h>
 
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
 
 static DEFINE_SPINLOCK(cpu_asid_lock);
 unsigned int cpu_last_asid = ASID_FIRST_VERSION;
+#ifdef CONFIG_SMP
+DEFINE_PER_CPU(struct mm_struct *, current_mm);
+#endif
 
 /*
  * We fork()ed a process, and we need a new context for the child
@@ -26,13 +31,109 @@ unsigned int cpu_last_asid = ASID_FIRST_VERSION;
 void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 {
        mm->context.id = 0;
+       spin_lock_init(&mm->context.id_lock);
 }
 
+static void flush_context(void)
+{
+       /* set the reserved ASID before flushing the TLB */
+       asm("mcr        p15, 0, %0, c13, c0, 1\n" : : "r" (0));
+       isb();
+       local_flush_tlb_all();
+       if (icache_is_vivt_asid_tagged()) {
+               __flush_icache_all();
+               dsb();
+       }
+}
+
+#ifdef CONFIG_SMP
+
+static void set_mm_context(struct mm_struct *mm, unsigned int asid)
+{
+       unsigned long flags;
+
+       /*
+        * Locking needed for multi-threaded applications where the
+        * same mm->context.id could be set from different CPUs during
+        * the broadcast. This function is also called via IPI so the
+        * mm->context.id_lock has to be IRQ-safe.
+        */
+       spin_lock_irqsave(&mm->context.id_lock, flags);
+       if (likely((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) {
+               /*
+                * Old version of ASID found. Set the new one and
+                * reset mm_cpumask(mm).
+                */
+               mm->context.id = asid;
+               cpumask_clear(mm_cpumask(mm));
+       }
+       spin_unlock_irqrestore(&mm->context.id_lock, flags);
+
+       /*
+        * Set the mm_cpumask(mm) bit for the current CPU.
+        */
+       cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
+}
+
+/*
+ * Reset the ASID on the current CPU. This function call is broadcast
+ * from the CPU handling the ASID rollover and holding cpu_asid_lock.
+ */
+static void reset_context(void *info)
+{
+       unsigned int asid;
+       unsigned int cpu = smp_processor_id();
+       struct mm_struct *mm = per_cpu(current_mm, cpu);
+
+       /*
+        * Check if a current_mm was set on this CPU as it might still
+        * be in the early booting stages and using the reserved ASID.
+        */
+       if (!mm)
+               return;
+
+       smp_rmb();
+       asid = cpu_last_asid + cpu + 1;
+
+       flush_context();
+       set_mm_context(mm, asid);
+
+       /* set the new ASID */
+       asm("mcr        p15, 0, %0, c13, c0, 1\n" : : "r" (mm->context.id));
+       isb();
+}
+
+#else
+
+static inline void set_mm_context(struct mm_struct *mm, unsigned int asid)
+{
+       mm->context.id = asid;
+       cpumask_copy(mm_cpumask(mm), cpumask_of(smp_processor_id()));
+}
+
+#endif
+
 void __new_context(struct mm_struct *mm)
 {
        unsigned int asid;
 
        spin_lock(&cpu_asid_lock);
+#ifdef CONFIG_SMP
+       /*
+        * Check the ASID again, in case the change was broadcast from
+        * another CPU before we acquired the lock.
+        */
+       if (unlikely(((mm->context.id ^ cpu_last_asid) >> ASID_BITS) == 0)) {
+               cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
+               spin_unlock(&cpu_asid_lock);
+               return;
+       }
+#endif
+       /*
+        * At this point, it is guaranteed that the current mm (with
+        * an old ASID) isn't active on any other CPU since the ASIDs
+        * are changed simultaneously via IPI.
+        */
        asid = ++cpu_last_asid;
        if (asid == 0)
                asid = cpu_last_asid = ASID_FIRST_VERSION;
@@ -42,20 +143,15 @@ void __new_context(struct mm_struct *mm)
         * to start a new version and flush the TLB.
         */
        if (unlikely((asid & ~ASID_MASK) == 0)) {
-               asid = ++cpu_last_asid;
-               /* set the reserved ASID before flushing the TLB */
-               asm("mcr        p15, 0, %0, c13, c0, 1  @ set reserved context ID\n"
-                   :
-                   : "r" (0));
-               isb();
-               flush_tlb_all();
-               if (icache_is_vivt_asid_tagged()) {
-                       __flush_icache_all();
-                       dsb();
-               }
+               asid = cpu_last_asid + smp_processor_id() + 1;
+               flush_context();
+#ifdef CONFIG_SMP
+               smp_wmb();
+               smp_call_function(reset_context, NULL, 1);
+#endif
+               cpu_last_asid += NR_CPUS;
        }
-       spin_unlock(&cpu_asid_lock);
 
-       cpumask_copy(mm_cpumask(mm), cpumask_of(smp_processor_id()));
-       mm->context.id = asid;
+       set_mm_context(mm, asid);
+       spin_unlock(&cpu_asid_lock);
 }
index 70997d5bee2d76d1d617a5ce5453437e51e4c009..5eb4fd93893dfa113cddf7944eeb063d968965a2 100644 (file)
@@ -68,12 +68,13 @@ feroceon_copy_user_page(void *kto, const void *kfrom)
 }
 
 void feroceon_copy_user_highpage(struct page *to, struct page *from,
-       unsigned long vaddr)
+       unsigned long vaddr, struct vm_area_struct *vma)
 {
        void *kto, *kfrom;
 
        kto = kmap_atomic(to, KM_USER0);
        kfrom = kmap_atomic(from, KM_USER1);
+       flush_cache_page(vma, vaddr, page_to_pfn(from));
        feroceon_copy_user_page(kto, kfrom);
        kunmap_atomic(kfrom, KM_USER1);
        kunmap_atomic(kto, KM_USER0);
index de9c06854ad724547b36937fcc57fa2f1905f1e0..f72303e1d804e08d7cecf2c82760a2c7a6355318 100644 (file)
@@ -38,7 +38,7 @@ v3_copy_user_page(void *kto, const void *kfrom)
 }
 
 void v3_copy_user_highpage(struct page *to, struct page *from,
-       unsigned long vaddr)
+       unsigned long vaddr, struct vm_area_struct *vma)
 {
        void *kto, *kfrom;
 
index 7370a7142b0424eba7f356151048db8cff66a38f..598c51ad50717f28d00202a9f8fd185b6a58b6a8 100644 (file)
@@ -69,7 +69,7 @@ mc_copy_user_page(void *from, void *to)
 }
 
 void v4_mc_copy_user_highpage(struct page *to, struct page *from,
-       unsigned long vaddr)
+       unsigned long vaddr, struct vm_area_struct *vma)
 {
        void *kto = kmap_atomic(to, KM_USER1);
 
index 9ab098414227e928007212f6159d8fcba88fc763..7c2eb55cd4a9263c9d3eb3e17d590cac0cc5d9b3 100644 (file)
@@ -48,12 +48,13 @@ v4wb_copy_user_page(void *kto, const void *kfrom)
 }
 
 void v4wb_copy_user_highpage(struct page *to, struct page *from,
-       unsigned long vaddr)
+       unsigned long vaddr, struct vm_area_struct *vma)
 {
        void *kto, *kfrom;
 
        kto = kmap_atomic(to, KM_USER0);
        kfrom = kmap_atomic(from, KM_USER1);
+       flush_cache_page(vma, vaddr, page_to_pfn(from));
        v4wb_copy_user_page(kto, kfrom);
        kunmap_atomic(kfrom, KM_USER1);
        kunmap_atomic(kto, KM_USER0);
index 300efafd66431ae02b042df0e065efca88424bf3..172e6a55458eb321dbf0708be20433a4daa7909f 100644 (file)
@@ -44,7 +44,7 @@ v4wt_copy_user_page(void *kto, const void *kfrom)
 }
 
 void v4wt_copy_user_highpage(struct page *to, struct page *from,
-       unsigned long vaddr)
+       unsigned long vaddr, struct vm_area_struct *vma)
 {
        void *kto, *kfrom;
 
index 0fa1319273dead26070b178751828f025d661561..8bca4dea6dfa234bbcf0c343a70f87f751de3b66 100644 (file)
@@ -34,7 +34,7 @@ static DEFINE_SPINLOCK(v6_lock);
  * attack the kernel's existing mapping of these pages.
  */
 static void v6_copy_user_highpage_nonaliasing(struct page *to,
-       struct page *from, unsigned long vaddr)
+       struct page *from, unsigned long vaddr, struct vm_area_struct *vma)
 {
        void *kto, *kfrom;
 
@@ -81,7 +81,7 @@ static void discard_old_kernel_data(void *kto)
  * Copy the page, taking account of the cache colour.
  */
 static void v6_copy_user_highpage_aliasing(struct page *to,
-       struct page *from, unsigned long vaddr)
+       struct page *from, unsigned long vaddr, struct vm_area_struct *vma)
 {
        unsigned int offset = CACHE_COLOUR(vaddr);
        unsigned long kfrom, kto;
index bc4525f5ab2326d266c828dac8c21f81a7655854..747ad4140fc75527d9c7b7409caf98e59504894d 100644 (file)
@@ -71,12 +71,13 @@ xsc3_mc_copy_user_page(void *kto, const void *kfrom)
 }
 
 void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
-       unsigned long vaddr)
+       unsigned long vaddr, struct vm_area_struct *vma)
 {
        void *kto, *kfrom;
 
        kto = kmap_atomic(to, KM_USER0);
        kfrom = kmap_atomic(from, KM_USER1);
+       flush_cache_page(vma, vaddr, page_to_pfn(from));
        xsc3_mc_copy_user_page(kto, kfrom);
        kunmap_atomic(kfrom, KM_USER1);
        kunmap_atomic(kto, KM_USER0);
index 76824d3e966a5a1b34105775aeb96b8acb086f4d..9920c0ae2096cc2c6b8c9e535dc63ab5d400afb0 100644 (file)
@@ -91,7 +91,7 @@ mc_copy_user_page(void *from, void *to)
 }
 
 void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
-       unsigned long vaddr)
+       unsigned long vaddr, struct vm_area_struct *vma)
 {
        void *kto = kmap_atomic(to, KM_USER1);
 
index 26325cb5d368e504e6eb7c669b28ac3ed023e3c6..0da7eccf7749103d26e9545560256f0a8b47dce4 100644 (file)
@@ -29,9 +29,6 @@
 #error "CONSISTENT_DMA_SIZE must be multiple of 2MiB"
 #endif
 
-#define CONSISTENT_END (0xffe00000)
-#define CONSISTENT_BASE        (CONSISTENT_END - CONSISTENT_DMA_SIZE)
-
 #define CONSISTENT_OFFSET(x)   (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
 #define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
 #define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
@@ -404,78 +401,44 @@ EXPORT_SYMBOL(dma_free_coherent);
  * platforms with CONFIG_DMABOUNCE.
  * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
  */
-void dma_cache_maint(const void *start, size_t size, int direction)
+void ___dma_single_cpu_to_dev(const void *kaddr, size_t size,
+       enum dma_data_direction dir)
 {
-       void (*inner_op)(const void *, const void *);
-       void (*outer_op)(unsigned long, unsigned long);
-
-       BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(start + size - 1));
-
-       switch (direction) {
-       case DMA_FROM_DEVICE:           /* invalidate only */
-               inner_op = dmac_inv_range;
-               outer_op = outer_inv_range;
-               break;
-       case DMA_TO_DEVICE:             /* writeback only */
-               inner_op = dmac_clean_range;
-               outer_op = outer_clean_range;
-               break;
-       case DMA_BIDIRECTIONAL:         /* writeback and invalidate */
-               inner_op = dmac_flush_range;
-               outer_op = outer_flush_range;
-               break;
-       default:
-               BUG();
-       }
+       unsigned long paddr;
+
+       BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
 
-       inner_op(start, start + size);
-       outer_op(__pa(start), __pa(start) + size);
+       dmac_map_area(kaddr, size, dir);
+
+       paddr = __pa(kaddr);
+       if (dir == DMA_FROM_DEVICE) {
+               outer_inv_range(paddr, paddr + size);
+       } else {
+               outer_clean_range(paddr, paddr + size);
+       }
+       /* FIXME: non-speculating: flush on bidirectional mappings? */
 }
-EXPORT_SYMBOL(dma_cache_maint);
+EXPORT_SYMBOL(___dma_single_cpu_to_dev);
 
-static void dma_cache_maint_contiguous(struct page *page, unsigned long offset,
-                                      size_t size, int direction)
+void ___dma_single_dev_to_cpu(const void *kaddr, size_t size,
+       enum dma_data_direction dir)
 {
-       void *vaddr;
-       unsigned long paddr;
-       void (*inner_op)(const void *, const void *);
-       void (*outer_op)(unsigned long, unsigned long);
-
-       switch (direction) {
-       case DMA_FROM_DEVICE:           /* invalidate only */
-               inner_op = dmac_inv_range;
-               outer_op = outer_inv_range;
-               break;
-       case DMA_TO_DEVICE:             /* writeback only */
-               inner_op = dmac_clean_range;
-               outer_op = outer_clean_range;
-               break;
-       case DMA_BIDIRECTIONAL:         /* writeback and invalidate */
-               inner_op = dmac_flush_range;
-               outer_op = outer_flush_range;
-               break;
-       default:
-               BUG();
-       }
+       BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
 
-       if (!PageHighMem(page)) {
-               vaddr = page_address(page) + offset;
-               inner_op(vaddr, vaddr + size);
-       } else {
-               vaddr = kmap_high_get(page);
-               if (vaddr) {
-                       vaddr += offset;
-                       inner_op(vaddr, vaddr + size);
-                       kunmap_high(page);
-               }
+       /* FIXME: non-speculating: not required */
+       /* don't bother invalidating if DMA to device */
+       if (dir != DMA_TO_DEVICE) {
+               unsigned long paddr = __pa(kaddr);
+               outer_inv_range(paddr, paddr + size);
        }
 
-       paddr = page_to_phys(page) + offset;
-       outer_op(paddr, paddr + size);
+       dmac_unmap_area(kaddr, size, dir);
 }
+EXPORT_SYMBOL(___dma_single_dev_to_cpu);
 
-void dma_cache_maint_page(struct page *page, unsigned long offset,
-                         size_t size, int dir)
+static void dma_cache_maint_page(struct page *page, unsigned long offset,
+       size_t size, enum dma_data_direction dir,
+       void (*op)(const void *, size_t, int))
 {
        /*
         * A single sg entry may refer to multiple physically contiguous
@@ -486,20 +449,62 @@ void dma_cache_maint_page(struct page *page, unsigned long offset,
        size_t left = size;
        do {
                size_t len = left;
-               if (PageHighMem(page) && len + offset > PAGE_SIZE) {
-                       if (offset >= PAGE_SIZE) {
-                               page += offset / PAGE_SIZE;
-                               offset %= PAGE_SIZE;
+               void *vaddr;
+
+               if (PageHighMem(page)) {
+                       if (len + offset > PAGE_SIZE) {
+                               if (offset >= PAGE_SIZE) {
+                                       page += offset / PAGE_SIZE;
+                                       offset %= PAGE_SIZE;
+                               }
+                               len = PAGE_SIZE - offset;
                        }
-                       len = PAGE_SIZE - offset;
+                       vaddr = kmap_high_get(page);
+                       if (vaddr) {
+                               vaddr += offset;
+                               op(vaddr, len, dir);
+                               kunmap_high(page);
+                       }
+               } else {
+                       vaddr = page_address(page) + offset;
+                       op(vaddr, len, dir);
                }
-               dma_cache_maint_contiguous(page, offset, len, dir);
                offset = 0;
                page++;
                left -= len;
        } while (left);
 }
-EXPORT_SYMBOL(dma_cache_maint_page);
+
+void ___dma_page_cpu_to_dev(struct page *page, unsigned long off,
+       size_t size, enum dma_data_direction dir)
+{
+       unsigned long paddr;
+
+       dma_cache_maint_page(page, off, size, dir, dmac_map_area);
+
+       paddr = page_to_phys(page) + off;
+       if (dir == DMA_FROM_DEVICE) {
+               outer_inv_range(paddr, paddr + size);
+       } else {
+               outer_clean_range(paddr, paddr + size);
+       }
+       /* FIXME: non-speculating: flush on bidirectional mappings? */
+}
+EXPORT_SYMBOL(___dma_page_cpu_to_dev);
+
+void ___dma_page_dev_to_cpu(struct page *page, unsigned long off,
+       size_t size, enum dma_data_direction dir)
+{
+       unsigned long paddr = page_to_phys(page) + off;
+
+       /* FIXME: non-speculating: not required */
+       /* don't bother invalidating if DMA to device */
+       if (dir != DMA_TO_DEVICE)
+               outer_inv_range(paddr, paddr + size);
+
+       dma_cache_maint_page(page, off, size, dir, dmac_unmap_area);
+}
+EXPORT_SYMBOL(___dma_page_dev_to_cpu);
 
 /**
  * dma_map_sg - map a set of SG buffers for streaming mode DMA
@@ -573,8 +578,12 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
        int i;
 
        for_each_sg(sg, s, nents, i) {
-               dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0,
-                                       sg_dma_len(s), dir);
+               if (!dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0,
+                                           sg_dma_len(s), dir))
+                       continue;
+
+               __dma_page_dev_to_cpu(sg_page(s), s->offset,
+                                     s->length, dir);
        }
 }
 EXPORT_SYMBOL(dma_sync_sg_for_cpu);
@@ -597,9 +606,8 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
                                        sg_dma_len(s), dir))
                        continue;
 
-               if (!arch_is_coherent())
-                       dma_cache_maint_page(sg_page(s), s->offset,
-                                            s->length, dir);
+               __dma_page_cpu_to_dev(sg_page(s), s->offset,
+                                     s->length, dir);
        }
 }
 EXPORT_SYMBOL(dma_sync_sg_for_device);
index 56ee15321b005f0ae9a6cc62dfaaa5bd8ad5cf73..c9b97e9836a201ba752c069731afdf1a10b7cea1 100644 (file)
@@ -36,28 +36,12 @@ static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE;
  * Therefore those configurations which might call adjust_pte (those
  * without CONFIG_CPU_CACHE_VIPT) cannot support split page_table_lock.
  */
-static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
+static int do_adjust_pte(struct vm_area_struct *vma, unsigned long address,
+       unsigned long pfn, pte_t *ptep)
 {
-       pgd_t *pgd;
-       pmd_t *pmd;
-       pte_t *pte, entry;
+       pte_t entry = *ptep;
        int ret;
 
-       pgd = pgd_offset(vma->vm_mm, address);
-       if (pgd_none(*pgd))
-               goto no_pgd;
-       if (pgd_bad(*pgd))
-               goto bad_pgd;
-
-       pmd = pmd_offset(pgd, address);
-       if (pmd_none(*pmd))
-               goto no_pmd;
-       if (pmd_bad(*pmd))
-               goto bad_pmd;
-
-       pte = pte_offset_map(pmd, address);
-       entry = *pte;
-
        /*
         * If this page is present, it's actually being shared.
         */
@@ -68,33 +52,55 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
         * fault (ie, is old), we can safely ignore any issues.
         */
        if (ret && (pte_val(entry) & L_PTE_MT_MASK) != shared_pte_mask) {
-               unsigned long pfn = pte_pfn(entry);
                flush_cache_page(vma, address, pfn);
                outer_flush_range((pfn << PAGE_SHIFT),
                                  (pfn << PAGE_SHIFT) + PAGE_SIZE);
                pte_val(entry) &= ~L_PTE_MT_MASK;
                pte_val(entry) |= shared_pte_mask;
-               set_pte_at(vma->vm_mm, address, pte, entry);
+               set_pte_at(vma->vm_mm, address, ptep, entry);
                flush_tlb_page(vma, address);
        }
-       pte_unmap(pte);
+
        return ret;
+}
+
+static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
+       unsigned long pfn)
+{
+       spinlock_t *ptl;
+       pgd_t *pgd;
+       pmd_t *pmd;
+       pte_t *pte;
+       int ret;
+
+       pgd = pgd_offset(vma->vm_mm, address);
+       if (pgd_none_or_clear_bad(pgd))
+               return 0;
+
+       pmd = pmd_offset(pgd, address);
+       if (pmd_none_or_clear_bad(pmd))
+               return 0;
 
-bad_pgd:
-       pgd_ERROR(*pgd);
-       pgd_clear(pgd);
-no_pgd:
-       return 0;
-
-bad_pmd:
-       pmd_ERROR(*pmd);
-       pmd_clear(pmd);
-no_pmd:
-       return 0;
+       /*
+        * This is called while another page table is mapped, so we
+        * must use the nested version.  This also means we need to
+        * open-code the spin-locking.
+        */
+       ptl = pte_lockptr(vma->vm_mm, pmd);
+       pte = pte_offset_map_nested(pmd, address);
+       spin_lock(ptl);
+
+       ret = do_adjust_pte(vma, address, pfn, pte);
+
+       spin_unlock(ptl);
+       pte_unmap_nested(pte);
+
+       return ret;
 }
 
 static void
-make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
+make_coherent(struct address_space *mapping, struct vm_area_struct *vma,
+       unsigned long addr, pte_t *ptep, unsigned long pfn)
 {
        struct mm_struct *mm = vma->vm_mm;
        struct vm_area_struct *mpnt;
@@ -122,11 +128,11 @@ make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigne
                if (!(mpnt->vm_flags & VM_MAYSHARE))
                        continue;
                offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
-               aliases += adjust_pte(mpnt, mpnt->vm_start + offset);
+               aliases += adjust_pte(mpnt, mpnt->vm_start + offset, pfn);
        }
        flush_dcache_mmap_unlock(mapping);
        if (aliases)
-               adjust_pte(vma, addr);
+               do_adjust_pte(vma, addr, pfn, ptep);
        else
                flush_cache_page(vma, addr, pfn);
 }
@@ -144,9 +150,10 @@ make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigne
  *
  * Note that the pte lock will be held.
  */
-void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
+       pte_t *ptep)
 {
-       unsigned long pfn = pte_pfn(pte);
+       unsigned long pfn = pte_pfn(*ptep);
        struct address_space *mapping;
        struct page *page;
 
@@ -168,7 +175,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
 #endif
        if (mapping) {
                if (cache_is_vivt())
-                       make_coherent(mapping, vma, addr, pfn);
+                       make_coherent(mapping, vma, addr, ptep, pfn);
                else if (vma->vm_flags & VM_EXEC)
                        __flush_icache_all();
        }
index 10e06801afb38e9d0a60cdb8b8cd94d43bc9e139..9d40c341e07e5846e270934c2b942035cae19f44 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/page-flags.h>
 #include <linux/sched.h>
 #include <linux/highmem.h>
+#include <linux/perf_event.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -302,6 +303,12 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
        fault = __do_page_fault(mm, addr, fsr, tsk);
        up_read(&mm->mmap_sem);
 
+       perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, addr);
+       if (fault & VM_FAULT_MAJOR)
+               perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, regs, addr);
+       else if (fault & VM_FAULT_MINOR)
+               perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, regs, addr);
+
        /*
         * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR
         */
index 6f3a4b7a3b8276e5c442e4bbfc8273c8e9745f54..e34f095e2090517b8f968f4af6703e60dd371c8b 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/cachetype.h>
+#include <asm/smp_plat.h>
 #include <asm/system.h>
 #include <asm/tlbflush.h>
 
@@ -87,13 +88,26 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsig
        if (vma->vm_flags & VM_EXEC && icache_is_vivt_asid_tagged())
                __flush_icache_all();
 }
+#else
+#define flush_pfn_alias(pfn,vaddr)     do { } while (0)
+#endif
 
+#ifdef CONFIG_SMP
+static void flush_ptrace_access_other(void *args)
+{
+       __flush_icache_all();
+}
+#endif
+
+static
 void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
-                        unsigned long uaddr, void *kaddr,
-                        unsigned long len, int write)
+                        unsigned long uaddr, void *kaddr, unsigned long len)
 {
        if (cache_is_vivt()) {
-               vivt_flush_ptrace_access(vma, page, uaddr, kaddr, len, write);
+               if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
+                       unsigned long addr = (unsigned long)kaddr;
+                       __cpuc_coherent_kern_range(addr, addr + len);
+               }
                return;
        }
 
@@ -104,16 +118,37 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
        }
 
        /* VIPT non-aliasing cache */
-       if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm)) &&
-           vma->vm_flags & VM_EXEC) {
+       if (vma->vm_flags & VM_EXEC) {
                unsigned long addr = (unsigned long)kaddr;
-               /* only flushing the kernel mapping on non-aliasing VIPT */
                __cpuc_coherent_kern_range(addr, addr + len);
+#ifdef CONFIG_SMP
+               if (cache_ops_need_broadcast())
+                       smp_call_function(flush_ptrace_access_other,
+                                         NULL, 1);
+#endif
        }
 }
-#else
-#define flush_pfn_alias(pfn,vaddr)     do { } while (0)
+
+/*
+ * Copy user data from/to a page which is mapped into a different
+ * processes address space.  Really, we want to allow our "user
+ * space" model to handle this.
+ *
+ * Note that this code needs to run on the current CPU.
+ */
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+                      unsigned long uaddr, void *dst, const void *src,
+                      unsigned long len)
+{
+#ifdef CONFIG_SMP
+       preempt_disable();
 #endif
+       memcpy(dst, src, len);
+       flush_ptrace_access(vma, page, uaddr, dst, len);
+#ifdef CONFIG_SMP
+       preempt_enable();
+#endif
+}
 
 void __flush_dcache_page(struct address_space *mapping, struct page *page)
 {
index a04ffbbbe2536309ee73442db96fd271a46561a4..7829cb5425f56e460a62390158114db98f4acc10 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/setup.h>
 #include <asm/sizes.h>
 #include <asm/tlb.h>
+#include <asm/fixmap.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 static unsigned long phys_initrd_start __initdata = 0;
 static unsigned long phys_initrd_size __initdata = 0;
 
-static void __init early_initrd(char **p)
+static int __init early_initrd(char *p)
 {
        unsigned long start, size;
+       char *endp;
 
-       start = memparse(*p, p);
-       if (**p == ',') {
-               size = memparse((*p) + 1, p);
+       start = memparse(p, &endp);
+       if (*endp == ',') {
+               size = memparse(endp + 1, NULL);
 
                phys_initrd_start = start;
                phys_initrd_size = size;
        }
+       return 0;
 }
-__early_param("initrd=", early_initrd);
+early_param("initrd", early_initrd);
 
 static int __init parse_tag_initrd(const struct tag *tag)
 {
@@ -560,7 +563,7 @@ static void __init free_unused_memmap_node(int node, struct meminfo *mi)
  */
 void __init mem_init(void)
 {
-       unsigned int codesize, datasize, initsize;
+       unsigned long reserved_pages, free_pages;
        int i, node;
 
 #ifndef CONFIG_DISCONTIGMEM
@@ -596,6 +599,33 @@ void __init mem_init(void)
        totalram_pages += totalhigh_pages;
 #endif
 
+       reserved_pages = free_pages = 0;
+
+       for_each_online_node(node) {
+               pg_data_t *n = NODE_DATA(node);
+               struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn;
+
+               for_each_nodebank(i, &meminfo, node) {
+                       struct membank *bank = &meminfo.bank[i];
+                       unsigned int pfn1, pfn2;
+                       struct page *page, *end;
+
+                       pfn1 = bank_pfn_start(bank);
+                       pfn2 = bank_pfn_end(bank);
+
+                       page = map + pfn1;
+                       end  = map + pfn2;
+
+                       do {
+                               if (PageReserved(page))
+                                       reserved_pages++;
+                               else if (!page_count(page))
+                                       free_pages++;
+                               page++;
+                       } while (page < end);
+               }
+       }
+
        /*
         * Since our memory may not be contiguous, calculate the
         * real number of pages we have in this system
@@ -608,16 +638,71 @@ void __init mem_init(void)
        }
        printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
 
-       codesize = _etext - _text;
-       datasize = _end - _data;
-       initsize = __init_end - __init_begin;
-
-       printk(KERN_NOTICE "Memory: %luKB available (%dK code, "
-               "%dK data, %dK init, %luK highmem)\n",
-               nr_free_pages() << (PAGE_SHIFT-10), codesize >> 10,
-               datasize >> 10, initsize >> 10,
+       printk(KERN_NOTICE "Memory: %luk/%luk available, %luk reserved, %luK highmem\n",
+               nr_free_pages() << (PAGE_SHIFT-10),
+               free_pages << (PAGE_SHIFT-10),
+               reserved_pages << (PAGE_SHIFT-10),
                totalhigh_pages << (PAGE_SHIFT-10));
 
+#define MLK(b, t) b, t, ((t) - (b)) >> 10
+#define MLM(b, t) b, t, ((t) - (b)) >> 20
+#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
+
+       printk(KERN_NOTICE "Virtual kernel memory layout:\n"
+                       "    vector  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+                       "    fixmap  : 0x%08lx - 0x%08lx   (%4ld kB)\n"
+#ifdef CONFIG_MMU
+                       "    DMA     : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+#endif
+                       "    vmalloc : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+                       "    lowmem  : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+#ifdef CONFIG_HIGHMEM
+                       "    pkmap   : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+#endif
+                       "    modules : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+                       "      .init : 0x%p" " - 0x%p" "   (%4d kB)\n"
+                       "      .text : 0x%p" " - 0x%p" "   (%4d kB)\n"
+                       "      .data : 0x%p" " - 0x%p" "   (%4d kB)\n",
+
+                       MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) +
+                               (PAGE_SIZE)),
+                       MLK(FIXADDR_START, FIXADDR_TOP),
+#ifdef CONFIG_MMU
+                       MLM(CONSISTENT_BASE, CONSISTENT_END),
+#endif
+                       MLM(VMALLOC_START, VMALLOC_END),
+                       MLM(PAGE_OFFSET, (unsigned long)high_memory),
+#ifdef CONFIG_HIGHMEM
+                       MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) *
+                               (PAGE_SIZE)),
+#endif
+                       MLM(MODULES_VADDR, MODULES_END),
+
+                       MLK_ROUNDUP(__init_begin, __init_end),
+                       MLK_ROUNDUP(_text, _etext),
+                       MLK_ROUNDUP(_data, _edata));
+
+#undef MLK
+#undef MLM
+#undef MLK_ROUNDUP
+
+       /*
+        * Check boundaries twice: Some fundamental inconsistencies can
+        * be detected at build time already.
+        */
+#ifdef CONFIG_MMU
+       BUILD_BUG_ON(VMALLOC_END                        > CONSISTENT_BASE);
+       BUG_ON(VMALLOC_END                              > CONSISTENT_BASE);
+
+       BUILD_BUG_ON(TASK_SIZE                          > MODULES_VADDR);
+       BUG_ON(TASK_SIZE                                > MODULES_VADDR);
+#endif
+
+#ifdef CONFIG_HIGHMEM
+       BUILD_BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > PAGE_OFFSET);
+       BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE      > PAGE_OFFSET);
+#endif
+
        if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
                extern int sysctl_overcommit_memory;
                /*
index 0ab75c60f7cfdf4745cc1f9c48d87db61cb93918..28c8b950ef04e84f6d0893712fb22c5394808ee6 100644 (file)
@@ -139,8 +139,8 @@ void __check_kvm_seq(struct mm_struct *mm)
  * which requires the new ioremap'd region to be referenced, the CPU will
  * reference the _old_ region.
  *
- * Note that get_vm_area() allocates a guard 4K page, so we need to mask
- * the size back to 1MB aligned or we will overflow in the loop below.
+ * Note that get_vm_area_caller() allocates a guard 4K page, so we need to
+ * mask the size back to 1MB aligned or we will overflow in the loop below.
  */
 static void unmap_area_sections(unsigned long virt, unsigned long size)
 {
@@ -254,22 +254,8 @@ remap_area_supersections(unsigned long virt, unsigned long pfn,
 }
 #endif
 
-
-/*
- * Remap an arbitrary physical address space into the kernel virtual
- * address space. Needed when the kernel wants to access high addresses
- * directly.
- *
- * NOTE! We need to allow non-page-aligned mappings too: we will obviously
- * have to convert them into an offset in a page-aligned mapping, but the
- * caller shouldn't need to know that small detail.
- *
- * 'flags' are the extra L_PTE_ flags that you want to specify for this
- * mapping.  See <asm/pgtable.h> for more information.
- */
-void __iomem *
-__arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
-                 unsigned int mtype)
+void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
+       unsigned long offset, size_t size, unsigned int mtype, void *caller)
 {
        const struct mem_type *type;
        int err;
@@ -291,7 +277,7 @@ __arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
         */
        size = PAGE_ALIGN(offset + size);
 
-       area = get_vm_area(size, VM_IOREMAP);
+       area = get_vm_area_caller(size, VM_IOREMAP, caller);
        if (!area)
                return NULL;
        addr = (unsigned long)area->addr;
@@ -318,10 +304,9 @@ __arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
        flush_cache_vmap(addr, addr + size);
        return (void __iomem *) (offset + addr);
 }
-EXPORT_SYMBOL(__arm_ioremap_pfn);
 
-void __iomem *
-__arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
+void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size,
+       unsigned int mtype, void *caller)
 {
        unsigned long last_addr;
        unsigned long offset = phys_addr & ~PAGE_MASK;
@@ -334,7 +319,33 @@ __arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
        if (!size || last_addr < phys_addr)
                return NULL;
 
-       return __arm_ioremap_pfn(pfn, offset, size, mtype);
+       return __arm_ioremap_pfn_caller(pfn, offset, size, mtype,
+                       caller);
+}
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space. Needed when the kernel wants to access high addresses
+ * directly.
+ *
+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+ * have to convert them into an offset in a page-aligned mapping, but the
+ * caller shouldn't need to know that small detail.
+ */
+void __iomem *
+__arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
+                 unsigned int mtype)
+{
+       return __arm_ioremap_pfn_caller(pfn, offset, size, mtype,
+                       __builtin_return_address(0));
+}
+EXPORT_SYMBOL(__arm_ioremap_pfn);
+
+void __iomem *
+__arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
+{
+       return __arm_ioremap_caller(phys_addr, size, mtype,
+                       __builtin_return_address(0));
 }
 EXPORT_SYMBOL(__arm_ioremap);
 
index 761ffede6a23a9027bd6d805a7fdb8d5e674c7ec..9d4da6ac28ebf9fae8718de70af211beede72156 100644 (file)
@@ -100,18 +100,17 @@ static struct cachepolicy cache_policies[] __initdata = {
  * writebuffer to be turned off.  (Note: the write
  * buffer should not be on and the cache off).
  */
-static void __init early_cachepolicy(char **p)
+static int __init early_cachepolicy(char *p)
 {
        int i;
 
        for (i = 0; i < ARRAY_SIZE(cache_policies); i++) {
                int len = strlen(cache_policies[i].policy);
 
-               if (memcmp(*p, cache_policies[i].policy, len) == 0) {
+               if (memcmp(p, cache_policies[i].policy, len) == 0) {
                        cachepolicy = i;
                        cr_alignment &= ~cache_policies[i].cr_mask;
                        cr_no_alignment &= ~cache_policies[i].cr_mask;
-                       *p += len;
                        break;
                }
        }
@@ -130,36 +129,37 @@ static void __init early_cachepolicy(char **p)
        }
        flush_cache_all();
        set_cr(cr_alignment);
+       return 0;
 }
-__early_param("cachepolicy=", early_cachepolicy);
+early_param("cachepolicy", early_cachepolicy);
 
-static void __init early_nocache(char **__unused)
+static int __init early_nocache(char *__unused)
 {
        char *p = "buffered";
        printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p);
-       early_cachepolicy(&p);
+       early_cachepolicy(p);
+       return 0;
 }
-__early_param("nocache", early_nocache);
+early_param("nocache", early_nocache);
 
-static void __init early_nowrite(char **__unused)
+static int __init early_nowrite(char *__unused)
 {
        char *p = "uncached";
        printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p);
-       early_cachepolicy(&p);
+       early_cachepolicy(p);
+       return 0;
 }
-__early_param("nowb", early_nowrite);
+early_param("nowb", early_nowrite);
 
-static void __init early_ecc(char **p)
+static int __init early_ecc(char *p)
 {
-       if (memcmp(*p, "on", 2) == 0) {
+       if (memcmp(p, "on", 2) == 0)
                ecc_mask = PMD_PROTECTION;
-               *p += 2;
-       } else if (memcmp(*p, "off", 3) == 0) {
+       else if (memcmp(p, "off", 3) == 0)
                ecc_mask = 0;
-               *p += 3;
-       }
+       return 0;
 }
-__early_param("ecc=", early_ecc);
+early_param("ecc", early_ecc);
 
 static int __init noalign_setup(char *__unused)
 {
@@ -670,9 +670,9 @@ static unsigned long __initdata vmalloc_reserve = SZ_128M;
  * bytes. This can be used to increase (or decrease) the vmalloc
  * area - the default is 128m.
  */
-static void __init early_vmalloc(char **arg)
+static int __init early_vmalloc(char *arg)
 {
-       vmalloc_reserve = memparse(*arg, arg);
+       vmalloc_reserve = memparse(arg, NULL);
 
        if (vmalloc_reserve < SZ_16M) {
                vmalloc_reserve = SZ_16M;
@@ -687,8 +687,9 @@ static void __init early_vmalloc(char **arg)
                        "vmalloc area is too big, limiting to %luMB\n",
                        vmalloc_reserve >> 20);
        }
+       return 0;
 }
-__early_param("vmalloc=", early_vmalloc);
+early_param("vmalloc", early_vmalloc);
 
 #define VMALLOC_MIN    (void *)(VMALLOC_END - vmalloc_reserve)
 
index 374a8311bc84b0eeadaa37a14004ee53f499ab67..9bfeb6b9509ad3480bd33a664e51b4f94311bfbb 100644 (file)
@@ -74,6 +74,12 @@ void __iomem *__arm_ioremap_pfn(unsigned long pfn, unsigned long offset,
 }
 EXPORT_SYMBOL(__arm_ioremap_pfn);
 
+void __iomem *__arm_ioremap_pfn_caller(unsigned long pfn, unsigned long offset,
+                          size_t size, unsigned int mtype, void *caller)
+{
+       return __arm_ioremap_pfn(pfn, offset, size, mtype);
+}
+
 void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
                            unsigned int mtype)
 {
@@ -81,6 +87,12 @@ void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
 }
 EXPORT_SYMBOL(__arm_ioremap);
 
+void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
+                           unsigned int mtype, void *caller)
+{
+       return __arm_ioremap(phys_addr, size, mtype);
+}
+
 void __iounmap(volatile void __iomem *addr)
 {
 }
index 8012e24282b2d0ffbbab5a38cd963c6cb9acf6e5..72507c630ceb563e9242145722b542b52731a7b3 100644 (file)
@@ -265,7 +265,7 @@ ENTRY(arm1020_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm1020_dma_inv_range)
+arm1020_dma_inv_range:
        mov     ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
        tst     r0, #CACHE_DLINESIZE - 1
@@ -295,7 +295,7 @@ ENTRY(arm1020_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm1020_dma_clean_range)
+arm1020_dma_clean_range:
        mov     ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
        bic     r0, r0, #CACHE_DLINESIZE - 1
@@ -330,6 +330,30 @@ ENTRY(arm1020_dma_flush_range)
        mcr     p15, 0, ip, c7, c10, 4          @ drain WB
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm1020_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     arm1020_dma_clean_range
+       bcs     arm1020_dma_inv_range
+       b       arm1020_dma_flush_range
+ENDPROC(arm1020_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm1020_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(arm1020_dma_unmap_area)
+
 ENTRY(arm1020_cache_fns)
        .long   arm1020_flush_kern_cache_all
        .long   arm1020_flush_user_cache_all
@@ -337,8 +361,8 @@ ENTRY(arm1020_cache_fns)
        .long   arm1020_coherent_kern_range
        .long   arm1020_coherent_user_range
        .long   arm1020_flush_kern_dcache_area
-       .long   arm1020_dma_inv_range
-       .long   arm1020_dma_clean_range
+       .long   arm1020_dma_map_area
+       .long   arm1020_dma_unmap_area
        .long   arm1020_dma_flush_range
 
        .align  5
index 41fe25d234f50b76b563c6b5516a258d45c014fe..d27829805609f5793e23bb2fd0c67ac85993e955 100644 (file)
@@ -258,7 +258,7 @@ ENTRY(arm1020e_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm1020e_dma_inv_range)
+arm1020e_dma_inv_range:
        mov     ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
        tst     r0, #CACHE_DLINESIZE - 1
@@ -284,7 +284,7 @@ ENTRY(arm1020e_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm1020e_dma_clean_range)
+arm1020e_dma_clean_range:
        mov     ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
        bic     r0, r0, #CACHE_DLINESIZE - 1
@@ -316,6 +316,30 @@ ENTRY(arm1020e_dma_flush_range)
        mcr     p15, 0, ip, c7, c10, 4          @ drain WB
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm1020e_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     arm1020e_dma_clean_range
+       bcs     arm1020e_dma_inv_range
+       b       arm1020e_dma_flush_range
+ENDPROC(arm1020e_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm1020e_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(arm1020e_dma_unmap_area)
+
 ENTRY(arm1020e_cache_fns)
        .long   arm1020e_flush_kern_cache_all
        .long   arm1020e_flush_user_cache_all
@@ -323,8 +347,8 @@ ENTRY(arm1020e_cache_fns)
        .long   arm1020e_coherent_kern_range
        .long   arm1020e_coherent_user_range
        .long   arm1020e_flush_kern_dcache_area
-       .long   arm1020e_dma_inv_range
-       .long   arm1020e_dma_clean_range
+       .long   arm1020e_dma_map_area
+       .long   arm1020e_dma_unmap_area
        .long   arm1020e_dma_flush_range
 
        .align  5
index 20a5b1b31a706051ac2c1b6cb58b293b3b2794a2..ce13e4a827de8ed9e787b11bf3a784b0bf803dab 100644 (file)
@@ -247,7 +247,7 @@ ENTRY(arm1022_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm1022_dma_inv_range)
+arm1022_dma_inv_range:
        mov     ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
        tst     r0, #CACHE_DLINESIZE - 1
@@ -273,7 +273,7 @@ ENTRY(arm1022_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm1022_dma_clean_range)
+arm1022_dma_clean_range:
        mov     ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
        bic     r0, r0, #CACHE_DLINESIZE - 1
@@ -305,6 +305,30 @@ ENTRY(arm1022_dma_flush_range)
        mcr     p15, 0, ip, c7, c10, 4          @ drain WB
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm1022_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     arm1022_dma_clean_range
+       bcs     arm1022_dma_inv_range
+       b       arm1022_dma_flush_range
+ENDPROC(arm1022_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm1022_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(arm1022_dma_unmap_area)
+
 ENTRY(arm1022_cache_fns)
        .long   arm1022_flush_kern_cache_all
        .long   arm1022_flush_user_cache_all
@@ -312,8 +336,8 @@ ENTRY(arm1022_cache_fns)
        .long   arm1022_coherent_kern_range
        .long   arm1022_coherent_user_range
        .long   arm1022_flush_kern_dcache_area
-       .long   arm1022_dma_inv_range
-       .long   arm1022_dma_clean_range
+       .long   arm1022_dma_map_area
+       .long   arm1022_dma_unmap_area
        .long   arm1022_dma_flush_range
 
        .align  5
index 96aedb10fcc418c528f536fb9a06f77185a3fa9c..636672a29c6d1e58ad905850cba7374ba09d8f45 100644 (file)
@@ -241,7 +241,7 @@ ENTRY(arm1026_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm1026_dma_inv_range)
+arm1026_dma_inv_range:
        mov     ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
        tst     r0, #CACHE_DLINESIZE - 1
@@ -267,7 +267,7 @@ ENTRY(arm1026_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm1026_dma_clean_range)
+arm1026_dma_clean_range:
        mov     ip, #0
 #ifndef CONFIG_CPU_DCACHE_DISABLE
        bic     r0, r0, #CACHE_DLINESIZE - 1
@@ -299,6 +299,30 @@ ENTRY(arm1026_dma_flush_range)
        mcr     p15, 0, ip, c7, c10, 4          @ drain WB
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm1026_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     arm1026_dma_clean_range
+       bcs     arm1026_dma_inv_range
+       b       arm1026_dma_flush_range
+ENDPROC(arm1026_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm1026_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(arm1026_dma_unmap_area)
+
 ENTRY(arm1026_cache_fns)
        .long   arm1026_flush_kern_cache_all
        .long   arm1026_flush_user_cache_all
@@ -306,8 +330,8 @@ ENTRY(arm1026_cache_fns)
        .long   arm1026_coherent_kern_range
        .long   arm1026_coherent_user_range
        .long   arm1026_flush_kern_dcache_area
-       .long   arm1026_dma_inv_range
-       .long   arm1026_dma_clean_range
+       .long   arm1026_dma_map_area
+       .long   arm1026_dma_unmap_area
        .long   arm1026_dma_flush_range
 
        .align  5
index 471669e2d7cb458567d9233a805dd8ce772bf719..8be81992645d8d814517510ea473d85c604888bd 100644 (file)
@@ -239,7 +239,7 @@ ENTRY(arm920_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm920_dma_inv_range)
+arm920_dma_inv_range:
        tst     r0, #CACHE_DLINESIZE - 1
        bic     r0, r0, #CACHE_DLINESIZE - 1
        mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
@@ -262,7 +262,7 @@ ENTRY(arm920_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm920_dma_clean_range)
+arm920_dma_clean_range:
        bic     r0, r0, #CACHE_DLINESIZE - 1
 1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
        add     r0, r0, #CACHE_DLINESIZE
@@ -288,6 +288,30 @@ ENTRY(arm920_dma_flush_range)
        mcr     p15, 0, r0, c7, c10, 4          @ drain WB
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm920_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     arm920_dma_clean_range
+       bcs     arm920_dma_inv_range
+       b       arm920_dma_flush_range
+ENDPROC(arm920_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm920_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(arm920_dma_unmap_area)
+
 ENTRY(arm920_cache_fns)
        .long   arm920_flush_kern_cache_all
        .long   arm920_flush_user_cache_all
@@ -295,8 +319,8 @@ ENTRY(arm920_cache_fns)
        .long   arm920_coherent_kern_range
        .long   arm920_coherent_user_range
        .long   arm920_flush_kern_dcache_area
-       .long   arm920_dma_inv_range
-       .long   arm920_dma_clean_range
+       .long   arm920_dma_map_area
+       .long   arm920_dma_unmap_area
        .long   arm920_dma_flush_range
 
 #endif
index ee111b00fa41951619593c758fe22eb06a4e4ee4..c0ff8e4b1074bac560f318a25c2715b89976c603 100644 (file)
@@ -241,7 +241,7 @@ ENTRY(arm922_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm922_dma_inv_range)
+arm922_dma_inv_range:
        tst     r0, #CACHE_DLINESIZE - 1
        bic     r0, r0, #CACHE_DLINESIZE - 1
        mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
@@ -264,7 +264,7 @@ ENTRY(arm922_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm922_dma_clean_range)
+arm922_dma_clean_range:
        bic     r0, r0, #CACHE_DLINESIZE - 1
 1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
        add     r0, r0, #CACHE_DLINESIZE
@@ -290,6 +290,30 @@ ENTRY(arm922_dma_flush_range)
        mcr     p15, 0, r0, c7, c10, 4          @ drain WB
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm922_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     arm922_dma_clean_range
+       bcs     arm922_dma_inv_range
+       b       arm922_dma_flush_range
+ENDPROC(arm922_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm922_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(arm922_dma_unmap_area)
+
 ENTRY(arm922_cache_fns)
        .long   arm922_flush_kern_cache_all
        .long   arm922_flush_user_cache_all
@@ -297,8 +321,8 @@ ENTRY(arm922_cache_fns)
        .long   arm922_coherent_kern_range
        .long   arm922_coherent_user_range
        .long   arm922_flush_kern_dcache_area
-       .long   arm922_dma_inv_range
-       .long   arm922_dma_clean_range
+       .long   arm922_dma_map_area
+       .long   arm922_dma_unmap_area
        .long   arm922_dma_flush_range
 
 #endif
index 8deb5bde58e4883765e1d7bb6b81b10e0388911b..3c6cffe400f685f4dc3e32ccf078ef726d88d625 100644 (file)
@@ -283,7 +283,7 @@ ENTRY(arm925_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm925_dma_inv_range)
+arm925_dma_inv_range:
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
        tst     r0, #CACHE_DLINESIZE - 1
        mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
@@ -308,7 +308,7 @@ ENTRY(arm925_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm925_dma_clean_range)
+arm925_dma_clean_range:
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
        bic     r0, r0, #CACHE_DLINESIZE - 1
 1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
@@ -341,6 +341,30 @@ ENTRY(arm925_dma_flush_range)
        mcr     p15, 0, r0, c7, c10, 4          @ drain WB
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm925_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     arm925_dma_clean_range
+       bcs     arm925_dma_inv_range
+       b       arm925_dma_flush_range
+ENDPROC(arm925_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm925_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(arm925_dma_unmap_area)
+
 ENTRY(arm925_cache_fns)
        .long   arm925_flush_kern_cache_all
        .long   arm925_flush_user_cache_all
@@ -348,8 +372,8 @@ ENTRY(arm925_cache_fns)
        .long   arm925_coherent_kern_range
        .long   arm925_coherent_user_range
        .long   arm925_flush_kern_dcache_area
-       .long   arm925_dma_inv_range
-       .long   arm925_dma_clean_range
+       .long   arm925_dma_map_area
+       .long   arm925_dma_unmap_area
        .long   arm925_dma_flush_range
 
 ENTRY(cpu_arm925_dcache_clean_area)
index 64db6e275a442f610239fe9b692753c4d88d14f9..75b707c9cce1ad31c2adf960d99e99cb5a266f8d 100644 (file)
@@ -246,7 +246,7 @@ ENTRY(arm926_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(arm926_dma_inv_range)
+arm926_dma_inv_range:
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
        tst     r0, #CACHE_DLINESIZE - 1
        mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
@@ -271,7 +271,7 @@ ENTRY(arm926_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(arm926_dma_clean_range)
+arm926_dma_clean_range:
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
        bic     r0, r0, #CACHE_DLINESIZE - 1
 1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
@@ -304,6 +304,30 @@ ENTRY(arm926_dma_flush_range)
        mcr     p15, 0, r0, c7, c10, 4          @ drain WB
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm926_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     arm926_dma_clean_range
+       bcs     arm926_dma_inv_range
+       b       arm926_dma_flush_range
+ENDPROC(arm926_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm926_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(arm926_dma_unmap_area)
+
 ENTRY(arm926_cache_fns)
        .long   arm926_flush_kern_cache_all
        .long   arm926_flush_user_cache_all
@@ -311,8 +335,8 @@ ENTRY(arm926_cache_fns)
        .long   arm926_coherent_kern_range
        .long   arm926_coherent_user_range
        .long   arm926_flush_kern_dcache_area
-       .long   arm926_dma_inv_range
-       .long   arm926_dma_clean_range
+       .long   arm926_dma_map_area
+       .long   arm926_dma_unmap_area
        .long   arm926_dma_flush_range
 
 ENTRY(cpu_arm926_dcache_clean_area)
index 8196b9f401fb53f17cd0a215c384a872330e054d..1af1657819eb8e32caf40dbbc148ca2c0259144f 100644 (file)
@@ -171,7 +171,7 @@ ENTRY(arm940_flush_kern_dcache_area)
  *     - start - virtual start address
  *     - end   - virtual end address
  */
-ENTRY(arm940_dma_inv_range)
+arm940_dma_inv_range:
        mov     ip, #0
        mov     r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
 1:     orr     r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
@@ -192,7 +192,7 @@ ENTRY(arm940_dma_inv_range)
  *     - start - virtual start address
  *     - end   - virtual end address
  */
-ENTRY(arm940_dma_clean_range)
+arm940_dma_clean_range:
 ENTRY(cpu_arm940_dcache_clean_area)
        mov     ip, #0
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
@@ -233,6 +233,30 @@ ENTRY(arm940_dma_flush_range)
        mcr     p15, 0, ip, c7, c10, 4          @ drain WB
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm940_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     arm940_dma_clean_range
+       bcs     arm940_dma_inv_range
+       b       arm940_dma_flush_range
+ENDPROC(arm940_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm940_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(arm940_dma_unmap_area)
+
 ENTRY(arm940_cache_fns)
        .long   arm940_flush_kern_cache_all
        .long   arm940_flush_user_cache_all
@@ -240,8 +264,8 @@ ENTRY(arm940_cache_fns)
        .long   arm940_coherent_kern_range
        .long   arm940_coherent_user_range
        .long   arm940_flush_kern_dcache_area
-       .long   arm940_dma_inv_range
-       .long   arm940_dma_clean_range
+       .long   arm940_dma_map_area
+       .long   arm940_dma_unmap_area
        .long   arm940_dma_flush_range
 
        __INIT
index 9a951239c86c0a1b93dcefdf6687312b6c3c51c7..1664b6aaff794957723cfac21696e8a2af030f3b 100644 (file)
@@ -215,7 +215,7 @@ ENTRY(arm946_flush_kern_dcache_area)
  *     - end   - virtual end address
  * (same as arm926)
  */
-ENTRY(arm946_dma_inv_range)
+arm946_dma_inv_range:
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
        tst     r0, #CACHE_DLINESIZE - 1
        mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
@@ -240,7 +240,7 @@ ENTRY(arm946_dma_inv_range)
  *
  * (same as arm926)
  */
-ENTRY(arm946_dma_clean_range)
+arm946_dma_clean_range:
 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
        bic     r0, r0, #CACHE_DLINESIZE - 1
 1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
@@ -275,6 +275,30 @@ ENTRY(arm946_dma_flush_range)
        mcr     p15, 0, r0, c7, c10, 4          @ drain WB
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm946_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     arm946_dma_clean_range
+       bcs     arm946_dma_inv_range
+       b       arm946_dma_flush_range
+ENDPROC(arm946_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(arm946_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(arm946_dma_unmap_area)
+
 ENTRY(arm946_cache_fns)
        .long   arm946_flush_kern_cache_all
        .long   arm946_flush_user_cache_all
@@ -282,8 +306,8 @@ ENTRY(arm946_cache_fns)
        .long   arm946_coherent_kern_range
        .long   arm946_coherent_user_range
        .long   arm946_flush_kern_dcache_area
-       .long   arm946_dma_inv_range
-       .long   arm946_dma_clean_range
+       .long   arm946_dma_map_area
+       .long   arm946_dma_unmap_area
        .long   arm946_dma_flush_range
 
 
index dbc39383e66aaf0d2ec0e5865f15e21dafb02ec7..53e63234384992ed07daf2eb48da91eaa5fa4a7d 100644 (file)
@@ -274,7 +274,7 @@ ENTRY(feroceon_range_flush_kern_dcache_area)
  * (same as v4wb)
  */
        .align  5
-ENTRY(feroceon_dma_inv_range)
+feroceon_dma_inv_range:
        tst     r0, #CACHE_DLINESIZE - 1
        bic     r0, r0, #CACHE_DLINESIZE - 1
        mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
@@ -288,7 +288,7 @@ ENTRY(feroceon_dma_inv_range)
        mov     pc, lr
 
        .align  5
-ENTRY(feroceon_range_dma_inv_range)
+feroceon_range_dma_inv_range:
        mrs     r2, cpsr
        tst     r0, #CACHE_DLINESIZE - 1
        mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
@@ -314,7 +314,7 @@ ENTRY(feroceon_range_dma_inv_range)
  * (same as v4wb)
  */
        .align  5
-ENTRY(feroceon_dma_clean_range)
+feroceon_dma_clean_range:
        bic     r0, r0, #CACHE_DLINESIZE - 1
 1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
        add     r0, r0, #CACHE_DLINESIZE
@@ -324,7 +324,7 @@ ENTRY(feroceon_dma_clean_range)
        mov     pc, lr
 
        .align  5
-ENTRY(feroceon_range_dma_clean_range)
+feroceon_range_dma_clean_range:
        mrs     r2, cpsr
        cmp     r1, r0
        subne   r1, r1, #1                      @ top address is inclusive
@@ -367,6 +367,44 @@ ENTRY(feroceon_range_dma_flush_range)
        mcr     p15, 0, r0, c7, c10, 4          @ drain WB
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(feroceon_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     feroceon_dma_clean_range
+       bcs     feroceon_dma_inv_range
+       b       feroceon_dma_flush_range
+ENDPROC(feroceon_dma_map_area)
+
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(feroceon_range_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     feroceon_range_dma_clean_range
+       bcs     feroceon_range_dma_inv_range
+       b       feroceon_range_dma_flush_range
+ENDPROC(feroceon_range_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(feroceon_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(feroceon_dma_unmap_area)
+
 ENTRY(feroceon_cache_fns)
        .long   feroceon_flush_kern_cache_all
        .long   feroceon_flush_user_cache_all
@@ -374,8 +412,8 @@ ENTRY(feroceon_cache_fns)
        .long   feroceon_coherent_kern_range
        .long   feroceon_coherent_user_range
        .long   feroceon_flush_kern_dcache_area
-       .long   feroceon_dma_inv_range
-       .long   feroceon_dma_clean_range
+       .long   feroceon_dma_map_area
+       .long   feroceon_dma_unmap_area
        .long   feroceon_dma_flush_range
 
 ENTRY(feroceon_range_cache_fns)
@@ -385,8 +423,8 @@ ENTRY(feroceon_range_cache_fns)
        .long   feroceon_coherent_kern_range
        .long   feroceon_coherent_user_range
        .long   feroceon_range_flush_kern_dcache_area
-       .long   feroceon_range_dma_inv_range
-       .long   feroceon_range_dma_clean_range
+       .long   feroceon_range_dma_map_area
+       .long   feroceon_dma_unmap_area
        .long   feroceon_range_dma_flush_range
 
        .align  5
index 9674d36cc97d4c1a6489599d2047b3c29ef58110..caa31154e7dbf71417beebc71128e0d061fb17ce 100644 (file)
@@ -218,7 +218,7 @@ ENTRY(mohawk_flush_kern_dcache_area)
  *
  * (same as v4wb)
  */
-ENTRY(mohawk_dma_inv_range)
+mohawk_dma_inv_range:
        tst     r0, #CACHE_DLINESIZE - 1
        mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
        tst     r1, #CACHE_DLINESIZE - 1
@@ -241,7 +241,7 @@ ENTRY(mohawk_dma_inv_range)
  *
  * (same as v4wb)
  */
-ENTRY(mohawk_dma_clean_range)
+mohawk_dma_clean_range:
        bic     r0, r0, #CACHE_DLINESIZE - 1
 1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
        add     r0, r0, #CACHE_DLINESIZE
@@ -268,6 +268,30 @@ ENTRY(mohawk_dma_flush_range)
        mcr     p15, 0, r0, c7, c10, 4          @ drain WB
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(mohawk_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     mohawk_dma_clean_range
+       bcs     mohawk_dma_inv_range
+       b       mohawk_dma_flush_range
+ENDPROC(mohawk_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(mohawk_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(mohawk_dma_unmap_area)
+
 ENTRY(mohawk_cache_fns)
        .long   mohawk_flush_kern_cache_all
        .long   mohawk_flush_user_cache_all
@@ -275,8 +299,8 @@ ENTRY(mohawk_cache_fns)
        .long   mohawk_coherent_kern_range
        .long   mohawk_coherent_user_range
        .long   mohawk_flush_kern_dcache_area
-       .long   mohawk_dma_inv_range
-       .long   mohawk_dma_clean_range
+       .long   mohawk_dma_map_area
+       .long   mohawk_dma_unmap_area
        .long   mohawk_dma_flush_range
 
 ENTRY(cpu_mohawk_dcache_clean_area)
index 8e4f6dca89976c8809933a96fe76600720d133bf..e5797f1c1db7d0dd4ccf06ff308655be1d2aa2a9 100644 (file)
@@ -257,7 +257,7 @@ ENTRY(xsc3_flush_kern_dcache_area)
  *     - start  - virtual start address
  *     - end    - virtual end address
  */
-ENTRY(xsc3_dma_inv_range)
+xsc3_dma_inv_range:
        tst     r0, #CACHELINESIZE - 1
        bic     r0, r0, #CACHELINESIZE - 1
        mcrne   p15, 0, r0, c7, c10, 1          @ clean L1 D line
@@ -278,7 +278,7 @@ ENTRY(xsc3_dma_inv_range)
  *     - start  - virtual start address
  *     - end    - virtual end address
  */
-ENTRY(xsc3_dma_clean_range)
+xsc3_dma_clean_range:
        bic     r0, r0, #CACHELINESIZE - 1
 1:     mcr     p15, 0, r0, c7, c10, 1          @ clean L1 D line
        add     r0, r0, #CACHELINESIZE
@@ -304,6 +304,30 @@ ENTRY(xsc3_dma_flush_range)
        mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(xsc3_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     xsc3_dma_clean_range
+       bcs     xsc3_dma_inv_range
+       b       xsc3_dma_flush_range
+ENDPROC(xsc3_dma_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(xsc3_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(xsc3_dma_unmap_area)
+
 ENTRY(xsc3_cache_fns)
        .long   xsc3_flush_kern_cache_all
        .long   xsc3_flush_user_cache_all
@@ -311,8 +335,8 @@ ENTRY(xsc3_cache_fns)
        .long   xsc3_coherent_kern_range
        .long   xsc3_coherent_user_range
        .long   xsc3_flush_kern_dcache_area
-       .long   xsc3_dma_inv_range
-       .long   xsc3_dma_clean_range
+       .long   xsc3_dma_map_area
+       .long   xsc3_dma_unmap_area
        .long   xsc3_dma_flush_range
 
 ENTRY(cpu_xsc3_dcache_clean_area)
index 93df47265f2dfda487fcb7c11425d14b0a9ea02f..63037e2162f201ba76ad34604c2cd09ab450d71b 100644 (file)
@@ -315,7 +315,7 @@ ENTRY(xscale_flush_kern_dcache_area)
  *     - start  - virtual start address
  *     - end    - virtual end address
  */
-ENTRY(xscale_dma_inv_range)
+xscale_dma_inv_range:
        tst     r0, #CACHELINESIZE - 1
        bic     r0, r0, #CACHELINESIZE - 1
        mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
@@ -336,7 +336,7 @@ ENTRY(xscale_dma_inv_range)
  *     - start  - virtual start address
  *     - end    - virtual end address
  */
-ENTRY(xscale_dma_clean_range)
+xscale_dma_clean_range:
        bic     r0, r0, #CACHELINESIZE - 1
 1:     mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
        add     r0, r0, #CACHELINESIZE
@@ -363,6 +363,43 @@ ENTRY(xscale_dma_flush_range)
        mcr     p15, 0, r0, c7, c10, 4          @ Drain Write (& Fill) Buffer
        mov     pc, lr
 
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(xscale_dma_map_area)
+       add     r1, r1, r0
+       cmp     r2, #DMA_TO_DEVICE
+       beq     xscale_dma_clean_range
+       bcs     xscale_dma_inv_range
+       b       xscale_dma_flush_range
+ENDPROC(xscale_dma_map_area)
+
+/*
+ *     dma_map_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(xscale_dma_a0_map_area)
+       add     r1, r1, r0
+       teq     r2, #DMA_TO_DEVICE
+       beq     xscale_dma_clean_range
+       b       xscale_dma_flush_range
+ENDPROC(xscsale_dma_a0_map_area)
+
+/*
+ *     dma_unmap_area(start, size, dir)
+ *     - start - kernel virtual start address
+ *     - size  - size of region
+ *     - dir   - DMA direction
+ */
+ENTRY(xscale_dma_unmap_area)
+       mov     pc, lr
+ENDPROC(xscale_dma_unmap_area)
+
 ENTRY(xscale_cache_fns)
        .long   xscale_flush_kern_cache_all
        .long   xscale_flush_user_cache_all
@@ -370,8 +407,8 @@ ENTRY(xscale_cache_fns)
        .long   xscale_coherent_kern_range
        .long   xscale_coherent_user_range
        .long   xscale_flush_kern_dcache_area
-       .long   xscale_dma_inv_range
-       .long   xscale_dma_clean_range
+       .long   xscale_dma_map_area
+       .long   xscale_dma_unmap_area
        .long   xscale_dma_flush_range
 
 /*
@@ -394,8 +431,8 @@ ENTRY(xscale_80200_A0_A1_cache_fns)
        .long   xscale_coherent_kern_range
        .long   xscale_coherent_user_range
        .long   xscale_flush_kern_dcache_area
-       .long   xscale_dma_flush_range
-       .long   xscale_dma_clean_range
+       .long   xscale_dma_a0_map_area
+       .long   xscale_dma_unmap_area
        .long   xscale_dma_flush_range
 
 ENTRY(cpu_xscale_dcache_clean_area)
index ad80752cb9fb2d721479904fd58a7b94950ca142..ef3e2653b90ceb1966bb64e1bb14ad087c966895 100644 (file)
@@ -132,7 +132,7 @@ static irqreturn_t arm11_pmu_interrupt(int irq, void *arg)
        return IRQ_HANDLED;
 }
 
-int arm11_request_interrupts(int *irqs, int nr)
+int arm11_request_interrupts(const int *irqs, int nr)
 {
        unsigned int i;
        int ret = 0;
@@ -153,7 +153,7 @@ int arm11_request_interrupts(int *irqs, int nr)
        return ret;
 }
 
-void arm11_release_interrupts(int *irqs, int nr)
+void arm11_release_interrupts(const int *irqs, int nr)
 {
        unsigned int i;
 
index 6f8538e5a96078a05d0a751e8cbf61ad78e4ceb6..1902b99d9dfdd23b67e98915864c602c0892bf4e 100644 (file)
@@ -39,7 +39,7 @@
 int arm11_setup_pmu(void);
 int arm11_start_pmu(void);
 int arm11_stop_pmu(void);
-int arm11_request_interrupts(int *, int);
-void arm11_release_interrupts(int *, int);
+int arm11_request_interrupts(const int *, int);
+void arm11_release_interrupts(const int *, int);
 
 #endif
index 4ce0f9801e2ef2c5ea9d92e29ec1c680b8335aec..f73ce875a395012c7f7b9500a5af1abbecafc438 100644 (file)
@@ -32,6 +32,7 @@
 /* #define DEBUG */
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/sched.h>
 #include <linux/oprofile.h>
 #include <linux/interrupt.h>
@@ -43,6 +44,7 @@
 #include <mach/hardware.h>
 #include <mach/board-eb.h>
 #include <asm/system.h>
+#include <asm/pmu.h>
 
 #include "op_counter.h"
 #include "op_arm_model.h"
@@ -58,6 +60,7 @@
  * Bitmask of used SCU counters
  */
 static unsigned int scu_em_used;
+static const struct pmu_irqs *pmu_irqs;
 
 /*
  * 2 helper fns take a counter number from 0-7 (not the userspace-visible counter number)
@@ -225,33 +228,40 @@ static int em_setup_ctrs(void)
        return 0;
 }
 
-static int arm11_irqs[] = {
-       [0]     = IRQ_EB11MP_PMU_CPU0,
-       [1]     = IRQ_EB11MP_PMU_CPU1,
-       [2]     = IRQ_EB11MP_PMU_CPU2,
-       [3]     = IRQ_EB11MP_PMU_CPU3
-};
-
 static int em_start(void)
 {
        int ret;
 
-       ret = arm11_request_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
+       pmu_irqs = reserve_pmu();
+       if (IS_ERR(pmu_irqs)) {
+               ret = PTR_ERR(pmu_irqs);
+               goto out;
+       }
+
+       ret = arm11_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
        if (ret == 0) {
                em_call_function(arm11_start_pmu);
 
                ret = scu_start();
-               if (ret)
-                       arm11_release_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
+               if (ret) {
+                       arm11_release_interrupts(pmu_irqs->irqs,
+                                                pmu_irqs->num_irqs);
+               } else {
+                       release_pmu(pmu_irqs);
+                       pmu_irqs = NULL;
+               }
        }
+
+out:
        return ret;
 }
 
 static void em_stop(void)
 {
        em_call_function(arm11_stop_pmu);
-       arm11_release_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
+       arm11_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
        scu_stop();
+       release_pmu(pmu_irqs);
 }
 
 /*
@@ -283,15 +293,7 @@ static int em_setup(void)
        em_route_irq(IRQ_EB11MP_PMU_SCU6, 3);
        em_route_irq(IRQ_EB11MP_PMU_SCU7, 3);
 
-       /*
-        * Send CP15 PMU interrupts to the owner CPU.
-        */
-       em_route_irq(IRQ_EB11MP_PMU_CPU0, 0);
-       em_route_irq(IRQ_EB11MP_PMU_CPU1, 1);
-       em_route_irq(IRQ_EB11MP_PMU_CPU2, 2);
-       em_route_irq(IRQ_EB11MP_PMU_CPU3, 3);
-
-       return 0;
+       return init_pmu();
 }
 
 struct op_arm_model_spec op_mpcore_spec = {
index f7d2ec5ee9a1282be6f6089625b97906fbe9df0d..a22357a2fd08270ce4f369443ec966b1f317ee6c 100644 (file)
 /* #define DEBUG */
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/sched.h>
 #include <linux/oprofile.h>
 #include <linux/interrupt.h>
 #include <asm/irq.h>
 #include <asm/system.h>
+#include <asm/pmu.h>
 
 #include "op_counter.h"
 #include "op_arm_model.h"
 #include "op_model_arm11_core.h"
 
-static int irqs[] = {
-#ifdef CONFIG_ARCH_OMAP2
-       3,
-#endif
-#ifdef CONFIG_ARCH_BCMRING
-       IRQ_PMUIRQ, /* for BCMRING, ARM PMU interrupt is 43 */
-#endif
-};
+static const struct pmu_irqs *pmu_irqs;
 
 static void armv6_pmu_stop(void)
 {
        arm11_stop_pmu();
-       arm11_release_interrupts(irqs, ARRAY_SIZE(irqs));
+       arm11_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
+       release_pmu(pmu_irqs);
+       pmu_irqs = NULL;
 }
 
 static int armv6_pmu_start(void)
 {
        int ret;
 
-       ret = arm11_request_interrupts(irqs, ARRAY_SIZE(irqs));
-       if (ret >= 0)
+       pmu_irqs = reserve_pmu();
+       if (IS_ERR(pmu_irqs)) {
+               ret = PTR_ERR(pmu_irqs);
+               goto out;
+       }
+
+       ret = arm11_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
+       if (ret >= 0) {
                ret = arm11_start_pmu();
+       } else {
+               release_pmu(pmu_irqs);
+               pmu_irqs = NULL;
+       }
 
+out:
        return ret;
 }
 
index 2088a6c0cc0e36f3e8ba23239f1a62fbb80e4858..8642d0891ae15eac8f2de05e6b02a381ba7cf131 100644 (file)
  */
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/oprofile.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/smp.h>
 
+#include <asm/pmu.h>
+
 #include "op_counter.h"
 #include "op_arm_model.h"
 #include "op_model_v7.h"
@@ -295,7 +298,7 @@ static irqreturn_t armv7_pmnc_interrupt(int irq, void *arg)
        return IRQ_HANDLED;
 }
 
-int armv7_request_interrupts(int *irqs, int nr)
+int armv7_request_interrupts(const int *irqs, int nr)
 {
        unsigned int i;
        int ret = 0;
@@ -318,7 +321,7 @@ int armv7_request_interrupts(int *irqs, int nr)
        return ret;
 }
 
-void armv7_release_interrupts(int *irqs, int nr)
+void armv7_release_interrupts(const int *irqs, int nr)
 {
        unsigned int i;
 
@@ -362,12 +365,7 @@ static void armv7_pmnc_dump_regs(void)
 }
 #endif
 
-
-static int irqs[] = {
-#ifdef CONFIG_ARCH_OMAP3
-       INT_34XX_BENCH_MPU_EMUL,
-#endif
-};
+static const struct pmu_irqs *pmu_irqs;
 
 static void armv7_pmnc_stop(void)
 {
@@ -375,19 +373,29 @@ static void armv7_pmnc_stop(void)
        armv7_pmnc_dump_regs();
 #endif
        armv7_stop_pmnc();
-       armv7_release_interrupts(irqs, ARRAY_SIZE(irqs));
+       armv7_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
+       release_pmu(pmu_irqs);
+       pmu_irqs = NULL;
 }
 
 static int armv7_pmnc_start(void)
 {
        int ret;
 
+       pmu_irqs = reserve_pmu();
+       if (IS_ERR(pmu_irqs))
+               return PTR_ERR(pmu_irqs);
+
 #ifdef DEBUG
        armv7_pmnc_dump_regs();
 #endif
-       ret = armv7_request_interrupts(irqs, ARRAY_SIZE(irqs));
-       if (ret >= 0)
+       ret = armv7_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
+       if (ret >= 0) {
                armv7_start_pmnc();
+       } else {
+               release_pmu(pmu_irqs);
+               pmu_irqs = NULL;
+       }
 
        return ret;
 }
index 0e19bcc2e1007eb75beb929ab0adc9a920be195d..9ca334b39c75f8fd76b4b365445ef03c24c0127b 100644 (file)
@@ -97,7 +97,7 @@
 int armv7_setup_pmu(void);
 int armv7_start_pmu(void);
 int armv7_stop_pmu(void);
-int armv7_request_interrupts(int *, int);
-void armv7_release_interrupts(int *, int);
+int armv7_request_interrupts(const int *, int);
+void armv7_release_interrupts(const int *, int);
 
 #endif
index 724ab9ce252674ff02d0e319cc25cd2a7b22da01..1d34a02048bd3a8da91ef1c350dc9656fcbedbd9 100644 (file)
 /* #define DEBUG */
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/err.h>
 #include <linux/sched.h>
 #include <linux/oprofile.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 
 #include <asm/cputype.h>
+#include <asm/pmu.h>
 
 #include "op_counter.h"
 #include "op_arm_model.h"
 #define        PMU_RESET       (CCNT_RESET | PMN_RESET)
 #define PMU_CNT64      0x008   /* Make CCNT count every 64th cycle */
 
-/* TODO do runtime detection */
-#ifdef CONFIG_ARCH_IOP32X
-#define XSCALE_PMU_IRQ  IRQ_IOP32X_CORE_PMU
-#endif
-#ifdef CONFIG_ARCH_IOP33X
-#define XSCALE_PMU_IRQ  IRQ_IOP33X_CORE_PMU
-#endif
-#ifdef CONFIG_ARCH_PXA
-#define XSCALE_PMU_IRQ  IRQ_PMU
-#endif
-
 /*
  * Different types of events that can be counted by the XScale PMU
  * as used by Oprofile userspace. Here primarily for documentation
@@ -367,6 +358,8 @@ static irqreturn_t xscale_pmu_interrupt(int irq, void *arg)
        return IRQ_HANDLED;
 }
 
+static const struct pmu_irqs *pmu_irqs;
+
 static void xscale_pmu_stop(void)
 {
        u32 pmnc = read_pmnc();
@@ -374,20 +367,30 @@ static void xscale_pmu_stop(void)
        pmnc &= ~PMU_ENABLE;
        write_pmnc(pmnc);
 
-       free_irq(XSCALE_PMU_IRQ, results);
+       free_irq(pmu_irqs->irqs[0], results);
+       release_pmu(pmu_irqs);
+       pmu_irqs = NULL;
 }
 
 static int xscale_pmu_start(void)
 {
        int ret;
-       u32 pmnc = read_pmnc();
+       u32 pmnc;
+
+       pmu_irqs = reserve_pmu();
+       if (IS_ERR(pmu_irqs))
+               return PTR_ERR(pmu_irqs);
+
+       pmnc = read_pmnc();
 
-       ret = request_irq(XSCALE_PMU_IRQ, xscale_pmu_interrupt, IRQF_DISABLED,
-                       "XScale PMU", (void *)results);
+       ret = request_irq(pmu_irqs->irqs[0], xscale_pmu_interrupt,
+                         IRQF_DISABLED, "XScale PMU", (void *)results);
 
        if (ret < 0) {
                printk(KERN_ERR "oprofile: unable to request IRQ%d for XScale PMU\n",
-                       XSCALE_PMU_IRQ);
+                      pmu_irqs->irqs[0]);
+               release_pmu(pmu_irqs);
+               pmu_irqs = NULL;
                return ret;
        }
 
index ed0bbece0d6164d7613a4908cd0f9972986990c5..e15bc17db90b0fc845cf44c0f27dd9e4cec5e51a 100644 (file)
@@ -34,7 +34,8 @@ void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size,
                retval = (void *) IOP3XX_PMMR_PHYS_TO_VIRT(cookie);
                break;
        default:
-               retval = __arm_ioremap(cookie, size, mtype);
+               retval = __arm_ioremap_caller(cookie, size, mtype,
+                               __builtin_return_address(0));
        }
 
        return retval;
index 15b2b148a105c02fa74ba392c33f4eb0de1fc1a8..5a6ae1b9e1e8abe4533e6d61de682042c33820df 100644 (file)
@@ -52,7 +52,7 @@
 #define UART_PADDR     MXC91231_UART2_BASE_ADDR
 #define UART_VADDR     MXC91231_AIPS1_IO_ADDRESS(MXC91231_UART2_BASE_ADDR)
 #endif
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                ldreq   \rx, =UART_PADDR        @ physical
index 62d97623412f1061cee30d249823c5e98416f37f..44243a278434b027d604ed590e43d9cdb5749653 100644 (file)
@@ -21,6 +21,6 @@
 #define __ASM_ARCH_MXC_VMALLOC_H__
 
 /* vmalloc ending address */
-#define VMALLOC_END       0xF4000000
+#define VMALLOC_END       0xf4000000UL
 
 #endif /* __ASM_ARCH_MXC_VMALLOC_H__ */
diff --git a/arch/arm/plat-nomadik/include/plat/i2c.h b/arch/arm/plat-nomadik/include/plat/i2c.h
new file mode 100644 (file)
index 0000000..1621db6
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson
+ *
+ * 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 __PLAT_I2C_H
+#define __PLAT_I2C_H
+
+enum i2c_freq_mode {
+       I2C_FREQ_MODE_STANDARD,         /* up to 100 Kb/s */
+       I2C_FREQ_MODE_FAST,             /* up to 400 Kb/s */
+       I2C_FREQ_MODE_FAST_PLUS,        /* up to 1 Mb/s */
+       I2C_FREQ_MODE_HIGH_SPEED        /* up to 3.4 Mb/s */
+};
+
+/**
+ * struct nmk_i2c_controller - client specific controller configuration
+ * @clk_freq:  clock frequency for the operation mode
+ * @slsu:      Slave data setup time in ns.
+ *             The needed setup time for three modes of operation
+ *             are 250ns, 100ns and 10ns respectively thus leading
+ *             to the values of 14, 6, 2 for a 48 MHz i2c clk
+ * @tft:       Tx FIFO Threshold in bytes
+ * @rft:       Rx FIFO Threshold in bytes
+ * @sm:                speed mode
+ */
+struct nmk_i2c_controller {
+       unsigned long   clk_freq;
+       unsigned short  slsu;
+       unsigned char   tft;
+       unsigned char   rft;
+       enum i2c_freq_mode      sm;
+};
+
+#endif /* __PLAT_I2C_H */
index e2ea04a4c8a1b06b2c8d477b631fe38251fe9018..2e3eec6608647cafa6d1a435cc3681931b35f970 100644 (file)
@@ -22,6 +22,7 @@ config ARCH_OMAP3
        bool "TI OMAP3"
        select CPU_V7
        select COMMON_CLKDEV
+       select ARM_L1_CACHE_SHIFT_6
 
 config ARCH_OMAP4
        bool "TI OMAP4"
index ef870de43c29b9c12d7491e0262bf1815b7e7865..c7d628ecb467aa57a85090af29a9904488643604 100644 (file)
@@ -40,6 +40,7 @@
 #define OMAP44XX_GIC_CPU_BASE          0x48240100
 #define OMAP44XX_SCU_BASE              0x48240000
 #define OMAP44XX_LOCAL_TWD_BASE                0x48240600
+#define OMAP44XX_L2CACHE_BASE          0x48242000
 #define OMAP44XX_WKUPGEN_BASE          0x48281000
 
 #define OMAP44XX_MAILBOX_BASE          (L4_44XX_BASE + 0xF4000)
index 0cfd54f519c4012eb0eb6fe518bf19ce0d3ebf42..4cbd4fb3232c86bcc50e27f05246e9577f9daa17 100644 (file)
@@ -128,7 +128,7 @@ void __iomem *omap_ioremap(unsigned long p, size_t size, unsigned int type)
                        return XLATE(p, L4_EMU_44XX_PHYS, L4_EMU_44XX_VIRT);
        }
 #endif
-       return __arm_ioremap(p, size, type);
+       return __arm_ioremap_caller(p, size, type, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(omap_ioremap);
 
index bfd2ca6e3074a6d4abd4d5706dcc4bf9d0031099..299d95f365c961dc21aad21cacd88730c183ce84 100644 (file)
@@ -15,6 +15,6 @@
 #ifndef __ASM_ARCH_VMALLOC_H
 #define __ASM_ARCH_VMALLOC_H
 
-#define VMALLOC_END      (0xE0000000)
+#define VMALLOC_END      (0xe0000000UL)
 
 #endif /* __ASM_ARCH_VMALLOC_H */
index 5d2f19a09e44c7bc02b05bfbe16c420769b29104..e593a2a801c63370efea993d529adf8b8960e0f4 100644 (file)
@@ -1126,9 +1126,8 @@ static int __init clk_init(void)
                        if (ops && ops->set_parent)
                                ops->set_parent(cl->clk, cl->clk->parent);
                }
-
-               clkdev_add(cl);
        }
+       clkdev_add_table(onchip_clks, ARRAY_SIZE(onchip_clks));
        return 0;
 }
 
index fb3b969bf0a24fc4de8a9ba87e1936a5fe9c75a5..1b9348bf0e4926b542bea6d1bfcc4a9cd2e29440 100644 (file)
@@ -16,7 +16,7 @@
  * http://www.gnu.org/copyleft/gpl.html
  */
 
-               .macro  addruart,rx
+               .macro  addruart, rx, tmp
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1                 @ MMU enabled?
                moveq   \rx, #0x80000000        @ physical base address
index 541b880c1863627ac36c1e84f36de0221df4d632..943c1a29d641470fa733b7cf7fd3604f15433e8d 100644 (file)
@@ -9,4 +9,4 @@
  * http://www.opensource.org/licenses/gpl-license.html
  * http://www.gnu.org/copyleft/gpl.html
  */
-#define VMALLOC_END       (0xF0000000)
+#define VMALLOC_END       0xf0000000UL
index a63c4be99b36eb576cbf2314aab9725960f2ea1d..7f3f59fcaa2199dda10eebd5b7bfa62348643342 100644 (file)
@@ -433,7 +433,11 @@ static inline void vfp_pm_init(void) { }
  * saved one. This function is used by the ptrace mechanism.
  */
 #ifdef CONFIG_SMP
-void vfp_sync_state(struct thread_info *thread)
+void vfp_sync_hwstate(struct thread_info *thread)
+{
+}
+
+void vfp_flush_hwstate(struct thread_info *thread)
 {
        /*
         * On SMP systems, the VFP state is automatically saved at every
@@ -444,35 +448,48 @@ void vfp_sync_state(struct thread_info *thread)
        thread->vfpstate.hard.cpu = NR_CPUS;
 }
 #else
-void vfp_sync_state(struct thread_info *thread)
+void vfp_sync_hwstate(struct thread_info *thread)
 {
        unsigned int cpu = get_cpu();
-       u32 fpexc = fmrx(FPEXC);
 
        /*
-        * If VFP is enabled, the previous state was already saved and
-        * last_VFP_context updated.
+        * If the thread we're interested in is the current owner of the
+        * hardware VFP state, then we need to save its state.
         */
-       if (fpexc & FPEXC_EN)
-               goto out;
+       if (last_VFP_context[cpu] == &thread->vfpstate) {
+               u32 fpexc = fmrx(FPEXC);
 
-       if (!last_VFP_context[cpu])
-               goto out;
+               /*
+                * Save the last VFP state on this CPU.
+                */
+               fmxr(FPEXC, fpexc | FPEXC_EN);
+               vfp_save_state(&thread->vfpstate, fpexc | FPEXC_EN);
+               fmxr(FPEXC, fpexc);
+       }
 
-       /*
-        * Save the last VFP state on this CPU.
-        */
-       fmxr(FPEXC, fpexc | FPEXC_EN);
-       vfp_save_state(last_VFP_context[cpu], fpexc);
-       fmxr(FPEXC, fpexc);
+       put_cpu();
+}
+
+void vfp_flush_hwstate(struct thread_info *thread)
+{
+       unsigned int cpu = get_cpu();
 
        /*
-        * Set the context to NULL to force a reload the next time the thread
-        * uses the VFP.
+        * If the thread we're interested in is the current owner of the
+        * hardware VFP state, then we need to save its state.
         */
-       last_VFP_context[cpu] = NULL;
+       if (last_VFP_context[cpu] == &thread->vfpstate) {
+               u32 fpexc = fmrx(FPEXC);
+
+               fmxr(FPEXC, fpexc & ~FPEXC_EN);
+
+               /*
+                * Set the context to NULL to force a reload the next time
+                * the thread uses the VFP.
+                */
+               last_VFP_context[cpu] = NULL;
+       }
 
-out:
        put_cpu();
 }
 #endif
index fecdda16f4443a7ed957690eeb5ec57cd5d4f5ae..a9ae30c41e746d53e25281d3c8132c5aeba9f09d 100644 (file)
@@ -325,7 +325,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 
 struct vm_area_struct;
 extern void update_mmu_cache(struct vm_area_struct * vma,
-                            unsigned long address, pte_t pte);
+                            unsigned long address, pte_t *ptep);
 
 /*
  * Encode and decode a swap entry
index 06677be98ffba5fcb0143dac626bf96235fd1e16..0da23109f817ad5cdb14f87e0b5b84bca3da2ff5 100644 (file)
@@ -101,7 +101,7 @@ static void update_dtlb(unsigned long address, pte_t pte)
 }
 
 void update_mmu_cache(struct vm_area_struct *vma,
-                     unsigned long address, pte_t pte)
+                     unsigned long address, pte_t *ptep)
 {
        unsigned long flags;
 
@@ -110,7 +110,7 @@ void update_mmu_cache(struct vm_area_struct *vma,
                return;
 
        local_irq_save(flags);
-       update_dtlb(address, pte);
+       update_dtlb(address, *ptep);
        local_irq_restore(flags);
 }
 
index 1fcce00f01f4f1fc1bab0f0c994bff80251333c5..99ea6cd1b1436f03a171ad9e3c42a0205780734d 100644 (file)
@@ -270,7 +270,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* defined in head.S */
  * Actually I am not sure on what this could be used for.
  */
 static inline void update_mmu_cache(struct vm_area_struct * vma,
-       unsigned long address, pte_t pte)
+       unsigned long address, pte_t *ptep)
 {
 }
 
index 22c60692b5513c7c6f66d49947a16e574ba31835..c18b0d32e63655ed7dc7d26b5ce0c44c5f990c36 100644 (file)
@@ -505,7 +505,7 @@ static inline int pte_file(pte_t pte)
 /*
  * preload information about a newly instantiated PTE into the SCR0/SCR1 PGE cache
  */
-static inline void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+static inline void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
        struct mm_struct *mm;
        unsigned long ampr;
index 69bf13857a9fc8ac9ff07e73a24436c17af19adb..c3286f42e501477722bdec7373112e92efc8a40d 100644 (file)
@@ -462,7 +462,7 @@ pte_same (pte_t a, pte_t b)
        return pte_val(a) == pte_val(b);
 }
 
-#define update_mmu_cache(vma, address, pte) do { } while (0)
+#define update_mmu_cache(vma, address, ptep) do { } while (0)
 
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 extern void paging_init (void);
index 0ef95307784e0d9143cba8d2608d9f6cada5ca11..92614b0ccf1754e2cae1f653b30e797b613792d8 100644 (file)
@@ -92,6 +92,6 @@ static __inline__ void __flush_tlb_all(void)
        );
 }
 
-extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
+extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
 
 #endif /* _ASM_M32R_TLBFLUSH_H */
index 88469178ea6bbfcd690a539c9a51e5ec02878f3f..888aab1157edaf1d13f6f2deee693ece3fb64ef2 100644 (file)
@@ -95,7 +95,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
  * update_mmu_cache()
  *======================================================================*/
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
-       pte_t pte)
+       pte_t *ptep)
 {
        BUG();
 }
index 7274b47f4c229b9d27aae0c6e787468fc07b8fb3..28ee389e5f5a3e43d39f8d5f1cdccf45923785d3 100644 (file)
@@ -336,7 +336,7 @@ vmalloc_fault:
 
                addr = (address & PAGE_MASK);
                set_thread_fault_code(error_code);
-               update_mmu_cache(NULL, addr, *pte_k);
+               update_mmu_cache(NULL, addr, pte_k);
                set_thread_fault_code(0);
                return;
        }
@@ -349,7 +349,7 @@ vmalloc_fault:
 #define ITLB_END       (unsigned long *)(ITLB_BASE + (NR_TLB_ENTRIES * 8))
 #define DTLB_END       (unsigned long *)(DTLB_BASE + (NR_TLB_ENTRIES * 8))
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr,
-       pte_t pte)
+       pte_t *ptep)
 {
        volatile unsigned long *entry1, *entry2;
        unsigned long pte_data, flags;
@@ -365,7 +365,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr,
 
        vaddr = (vaddr & PAGE_MASK) | get_asid();
 
-       pte_data = pte_val(pte);
+       pte_data = pte_val(*ptep);
 
 #ifdef CONFIG_CHIP_OPSP
        entry1 = (unsigned long *)ITLB_BASE;
index aca0e28581c7733febbd2029a5c0a687f41b7485..87174c904d2b2e8eb5adc83a4fc056ac8790a9cc 100644 (file)
@@ -115,7 +115,7 @@ extern void kernel_set_cachemode(void *addr, unsigned long size, int cmode);
  * they are updated on demand.
  */
 static inline void update_mmu_cache(struct vm_area_struct *vma,
-                                   unsigned long address, pte_t pte)
+                                   unsigned long address, pte_t *ptep)
 {
 }
 
index eb31a0e8a7725cc843a3c19a16886fbae8e55ed6..10ec70cd8735446a2c5e0b938487fb6db0f6417a 100644 (file)
@@ -38,7 +38,7 @@ static inline void local_flush_tlb_range(struct vm_area_struct *vma,
 
 #define flush_tlb_kernel_range(start, end)     do { } while (0)
 
-#define update_mmu_cache(vma, addr, pte      do { } while (0)
+#define update_mmu_cache(vma, addr, ptep)      do { } while (0)
 
 #define flush_tlb_all local_flush_tlb_all
 #define flush_tlb_mm local_flush_tlb_mm
index 93598ba013556eaccdf5c37b6551d9111afd1683..7e40f37781790206a1174830f295258d89ec648f 100644 (file)
@@ -368,8 +368,9 @@ extern void __update_cache(struct vm_area_struct *vma, unsigned long address,
        pte_t pte);
 
 static inline void update_mmu_cache(struct vm_area_struct *vma,
-       unsigned long address, pte_t pte)
+       unsigned long address, pte_t *ptep)
 {
+       pte_t pte = *ptep;
        __update_tlb(vma, address, pte);
        __update_cache(vma, address, pte);
 }
index 6dc30fc827c458d5d2c6e67f964a79b720a96bdc..16d88577f3e08510b543452ac322d6cd7e970e77 100644 (file)
@@ -466,7 +466,7 @@ static inline int set_kernel_exec(unsigned long vaddr, int enable)
  * the kernel page tables containing the necessary information by tlb-mn10300.S
  */
 extern void update_mmu_cache(struct vm_area_struct *vma,
-                            unsigned long address, pte_t pte);
+                            unsigned long address, pte_t *ptep);
 
 #endif /* !__ASSEMBLY__ */
 
index 31c9d27a75ae8cab8a0e3daa650ddb8e8659febc..36ba02191d408251f9eaefa366610824e34d3d69 100644 (file)
@@ -51,9 +51,10 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
 /*
  * preemptively set a TLB entry
  */
-void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
 {
        unsigned long pteu, ptel, cnx, flags;
+       pte_t pte = *ptep;
 
        addr &= PAGE_MASK;
        ptel = pte_val(pte) & ~(xPTEL_UNUSED1 | xPTEL_UNUSED2);
index a27d2e200fb2a62519ba1dc281ebf0d3abe8f8be..01c15035e783d47ec944f7d47b30ee90202cd9a2 100644 (file)
@@ -410,7 +410,7 @@ extern void paging_init (void);
 
 #define PG_dcache_dirty         PG_arch_1
 
-extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
+extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
 
 /* Encode and de-code a swap entry */
 
index b6ed34de14e15899cbcfccdbfa25cd80649282a6..1054baa2fc69000a17faa4bca451864cbdac2f0d 100644 (file)
@@ -68,9 +68,9 @@ flush_cache_all_local(void)
 EXPORT_SYMBOL(flush_cache_all_local);
 
 void
-update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
-       struct page *page = pte_page(pte);
+       struct page *page = pte_page(*ptep);
 
        if (pfn_valid(page_to_pfn(page)) && page_mapping(page) &&
            test_bit(PG_dcache_dirty, &page->flags)) {
index 21207e54825b0566d5edf4c447c6d252ea76b497..89f158731ce37311b35225a43963b05227bf62c1 100644 (file)
@@ -209,7 +209,7 @@ extern void paging_init(void);
  * corresponding HPTE into the hash table ahead of time, instead of
  * waiting for the inevitable extra hash-table miss exception.
  */
-extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
+extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
 
 extern int gup_hugepd(hugepd_t *hugepd, unsigned pdshift, unsigned long addr,
                      unsigned long end, int write, struct page **pages, int *nr);
index b9b152558f9c5de64d70399a37c1aa7dfd001706..311224cdb7ad08c53d0a8b70528b3bf888a4b795 100644 (file)
@@ -494,13 +494,13 @@ EXPORT_SYMBOL(flush_icache_user_range);
  * This must always be called with the pte lock held.
  */
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
-                     pte_t pte)
+                     pte_t *ptep)
 {
 #ifdef CONFIG_PPC_STD_MMU
        unsigned long access = 0, trap;
 
        /* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
-       if (!pte_young(pte) || address >= TASK_SIZE)
+       if (!pte_young(*ptep) || address >= TASK_SIZE)
                return;
 
        /* We try to figure out if we are coming from an instruction
index e2fa79cf06145d4b22fd15638c0cad644f9a8799..9b5b9189c15e86cc9f5053145324fe2123805ce9 100644 (file)
@@ -43,7 +43,7 @@ extern void vmem_map_init(void);
  * The S390 doesn't have any external MMU info: the kernel page
  * tables contain all the necessary information.
  */
-#define update_mmu_cache(vma, address, pte)     do { } while (0)
+#define update_mmu_cache(vma, address, ptep)     do { } while (0)
 
 /*
  * ZERO_PAGE is a global shared page that is always zero: used
index 674934b401703eec2ed153d70b7b42d22289e172..ccf38f06c57d78110e14cd21a0e3984c3c52b52d 100644 (file)
@@ -272,8 +272,9 @@ extern void __update_cache(struct vm_area_struct *vma,
        unsigned long address,  pte_t pte);
 
 static inline void update_mmu_cache(struct vm_area_struct *vma,
-       unsigned long address, pte_t pte)
+       unsigned long address, pte_t *ptep)
 {
+       pte_t pte = *ptep;
        __update_tlb(vma, address, pte);
        __update_cache(vma, address, pte);
 }
index aab76528abb979fe6d7b0c871aa03efb86396751..02f77450cd8f47af3071597916f1c509a7969ab4 100644 (file)
@@ -153,8 +153,9 @@ extern void __update_tlb(struct vm_area_struct *vma,
                         unsigned long address, pte_t pte);
 
 static inline void
-update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
+       pte_t pte = *ptep;
        __update_cache(vma, address, pte);
        __update_tlb(vma, address, pte);
 }
index 28e22839c665d8badf9c9aa359ed555fc3f8539e..8bf79e3b7bddb36af2c7f99a8093dccf512b59df 100644 (file)
@@ -374,7 +374,7 @@ handle_tlbmiss(struct pt_regs *regs, unsigned long writeaccess,
                local_flush_tlb_one(get_asid(), address & PAGE_MASK);
 #endif
 
-       update_mmu_cache(NULL, address, entry);
+       update_mmu_cache(NULL, address, pte);
 
        return 0;
 }
index e0cabe790ec134e762e27b410012d90389a95825..77f906d8cc21f3874ee079aa731edf49f02dea75 100644 (file)
@@ -330,9 +330,9 @@ BTFIXUPDEF_CALL(void, mmu_info, struct seq_file *)
 #define FAULT_CODE_WRITE    0x2
 #define FAULT_CODE_USER     0x4
 
-BTFIXUPDEF_CALL(void, update_mmu_cache, struct vm_area_struct *, unsigned long, pte_t)
+BTFIXUPDEF_CALL(void, update_mmu_cache, struct vm_area_struct *, unsigned long, pte_t *)
 
-#define update_mmu_cache(vma,addr,pte) BTFIXUP_CALL(update_mmu_cache)(vma,addr,pte)
+#define update_mmu_cache(vma,addr,ptep) BTFIXUP_CALL(update_mmu_cache)(vma,addr,ptep)
 
 BTFIXUPDEF_CALL(void, sparc_mapiorange, unsigned int, unsigned long,
     unsigned long, unsigned int)
index f3cb790fa2ae0771a4ac7b2b0ba7c73b14338111..f5b5fa76c02dbb2eb385220a5222c191f1bf2a8e 100644 (file)
@@ -706,7 +706,7 @@ extern unsigned long find_ecache_flush_span(unsigned long size);
 #define mmu_unlockarea(vaddr, len)             do { } while(0)
 
 struct vm_area_struct;
-extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
+extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
 
 /* Encode and de-code a swap entry */
 #define __swp_type(entry)      (((entry).val >> PAGE_SHIFT) & 0xffUL)
index a3413acb8f127ce4bbd92d6305a83a9e428819fe..3fa09ba3845f3dafd06e80439e8214785d297f39 100644 (file)
@@ -378,7 +378,7 @@ asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
                               unsigned long address)
 {
        extern void sun4c_update_mmu_cache(struct vm_area_struct *,
-                                          unsigned long,pte_t);
+                                          unsigned long,pte_t *);
        extern pte_t *sun4c_pte_offset_kernel(pmd_t *,unsigned long);
        struct task_struct *tsk = current;
        struct mm_struct *mm = tsk->mm;
@@ -455,7 +455,7 @@ asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
                 *       on the CPU and doing a shrink_mmap() on this vma.
                 */
                sun4c_update_mmu_cache (find_vma(current->mm, address), address,
-                                       *ptep);
+                                       ptep);
        else
                do_sparc_fault(regs, text_fault, write, address);
 }
index 1886d37d411b2e129c9b711ca381d7856daead4f..9245a822a2f17cf8a20fc9edd12f217156f973ac 100644 (file)
@@ -289,12 +289,13 @@ static void flush_dcache(unsigned long pfn)
        }
 }
 
-void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
        struct mm_struct *mm;
        struct tsb *tsb;
        unsigned long tag, flags;
        unsigned long tsb_index, tsb_hash_shift;
+       pte_t pte = *ptep;
 
        if (tlb_type != hypervisor) {
                unsigned long pfn = pte_pfn(pte);
index 196263f895b7d010eb7d40b1ab9a75b04599234b..4e62c27147c491843bf3747307cc3bc39e196d79 100644 (file)
@@ -62,7 +62,7 @@ pte_t *sun4c_pte_offset_kernel(pmd_t *dir, unsigned long address)
        return NULL;
 }
 
-void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
 }
 
index 367321a030dd00de68506d9aa30f4cfec106eba0..df49b200ca4c12317077c44712d0f89f107ff872 100644 (file)
@@ -694,7 +694,7 @@ extern void tsunami_setup_blockops(void);
  * The following code is a deadwood that may be necessary when
  * we start to make precise page flushes again. --zaitcev
  */
-static void swift_update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte)
+static void swift_update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t *ptep)
 {
 #if 0
        static unsigned long last;
@@ -703,10 +703,10 @@ static void swift_update_mmu_cache(struct vm_area_struct * vma, unsigned long ad
 
        if (address == last) {
                val = srmmu_hwprobe(address);
-               if (val != 0 && pte_val(pte) != val) {
+               if (val != 0 && pte_val(*ptep) != val) {
                        printk("swift_update_mmu_cache: "
                            "addr %lx put %08x probed %08x from %p\n",
-                           address, pte_val(pte), val,
+                           address, pte_val(*ptep), val,
                            __builtin_return_address(0));
                        srmmu_flush_whole_tlb();
                }
index a89baf0d875af3ef7a557675b87a90398ee6fbd3..18652534b91a592a2dfb3c97cce676323fe471f2 100644 (file)
@@ -1887,7 +1887,7 @@ static void sun4c_check_pgt_cache(int low, int high)
 /* An experiment, turn off by default for now... -DaveM */
 #define SUN4C_PRELOAD_PSEG
 
-void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
        unsigned long flags;
        int pseg;
@@ -1929,7 +1929,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p
                        start += PAGE_SIZE;
                }
 #ifndef SUN4C_PRELOAD_PSEG
-               sun4c_put_pte(address, pte_val(pte));
+               sun4c_put_pte(address, pte_val(*ptep));
 #endif
                local_irq_restore(flags);
                return;
@@ -1940,7 +1940,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p
                add_lru(entry);
        }
 
-       sun4c_put_pte(address, pte_val(pte));
+       sun4c_put_pte(address, pte_val(*ptep));
        local_irq_restore(flags);
 }
 
index 9ce3f165111a63607fa91f98a99e3b232fb5080a..a9f7251b4a8dcadd347d7a8d71043e5b312ff673 100644 (file)
@@ -345,7 +345,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 struct mm_struct;
 extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
 
-#define update_mmu_cache(vma,address,pte) do ; while (0)
+#define update_mmu_cache(vma,address,ptep) do ; while (0)
 
 /* Encode and de-code a swap entry */
 #define __swp_type(x)                  (((x).val >> 4) & 0x3f)
index 01fd9461d323b89827afdc9a5a4c205a6bae3407..a28668396508df140ad62ecee2fb330f4ce6bc08 100644 (file)
@@ -80,7 +80,7 @@ do {                                          \
  * The i386 doesn't have any external MMU info: the kernel page
  * tables contain all the necessary information.
  */
-#define update_mmu_cache(vma, address, pte) do { } while (0)
+#define update_mmu_cache(vma, address, ptep) do { } while (0)
 
 #endif /* !__ASSEMBLY__ */
 
index c57a301171496e7b7af33ad3227bcdac5ae45c01..181be528c6128a716f5e19e41d19a054a963ba6e 100644 (file)
@@ -129,7 +129,7 @@ static inline int pgd_large(pgd_t pgd) { return 0; }
 #define pte_unmap(pte) /* NOP */
 #define pte_unmap_nested(pte) /* NOP */
 
-#define update_mmu_cache(vma, address, pte) do { } while (0)
+#define update_mmu_cache(vma, address, ptep) do { } while (0)
 
 /* Encode and de-code a swap entry */
 #if _PAGE_BIT_FILE < _PAGE_BIT_PROTNONE
index a138770c358ed1d134fcb0274b93f4eeee515757..76bf35554117d8044de73e9b3e1138e562379c0c 100644 (file)
@@ -394,7 +394,7 @@ ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 #define kern_addr_valid(addr)  (1)
 
 extern  void update_mmu_cache(struct vm_area_struct * vma,
-                             unsigned long address, pte_t pte);
+                             unsigned long address, pte_t *ptep);
 
 /*
  * remap a physical page `pfn' of size `size' with page protection `prot'
index 3ba990c67676c0b40976ff60d03638ceefba94cd..85df4655d3264d8afda978c5ed0a229567b43989 100644 (file)
@@ -147,9 +147,9 @@ void flush_cache_page(struct vm_area_struct* vma, unsigned long address,
 #endif
 
 void
-update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t pte)
+update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
 {
-       unsigned long pfn = pte_pfn(pte);
+       unsigned long pfn = pte_pfn(*ptep);
        struct page *page;
 
        if (!pfn_valid(pfn))
index 5d1c2603a130f84e8506535a79108ee8691f36d7..2b0bd0b042d6df7bd8513f20232619853c130939 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/i2c-pnx.h>
 #include <linux/io.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
 #include <mach/hardware.h>
 #include <mach/i2c.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
 
 #define I2C_PNX_TIMEOUT                10 /* msec */
 #define I2C_PNX_SPEED_KHZ      100
 #define I2C_PNX_REGION_SIZE    0x100
-#define PNX_DEFAULT_FREQ       13 /* MHz */
 
 static inline int wait_timeout(long timeout, struct i2c_pnx_algo_data *data)
 {
@@ -50,22 +50,21 @@ static inline int wait_reset(long timeout, struct i2c_pnx_algo_data *data)
        return (timeout <= 0);
 }
 
-static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap)
+static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data)
 {
-       struct i2c_pnx_algo_data *data = adap->algo_data;
-       struct timer_list *timer = &data->mif.timer;
-       int expires = I2C_PNX_TIMEOUT / (1000 / HZ);
+       struct timer_list *timer = &alg_data->mif.timer;
+       unsigned long expires = msecs_to_jiffies(I2C_PNX_TIMEOUT);
 
        if (expires <= 1)
                expires = 2;
 
        del_timer_sync(timer);
 
-       dev_dbg(&adap->dev, "Timer armed at %lu plus %u jiffies.\n",
+       dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n",
                jiffies, expires);
 
        timer->expires = jiffies + expires;
-       timer->data = (unsigned long)adap;
+       timer->data = (unsigned long)&alg_data;
 
        add_timer(timer);
 }
@@ -77,34 +76,34 @@ static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap)
  *
  * Generate a START signal in the desired mode.
  */
-static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)
+static int i2c_pnx_start(unsigned char slave_addr,
+       struct i2c_pnx_algo_data *alg_data)
 {
-       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
-
-       dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __func__,
+       dev_dbg(&alg_data->adapter.dev, "%s(): addr 0x%x mode %d\n", __func__,
                slave_addr, alg_data->mif.mode);
 
        /* Check for 7 bit slave addresses only */
        if (slave_addr & ~0x7f) {
-               dev_err(&adap->dev, "%s: Invalid slave address %x. "
-                      "Only 7-bit addresses are supported\n",
-                      adap->name, slave_addr);
+               dev_err(&alg_data->adapter.dev,
+                       "%s: Invalid slave address %x. Only 7-bit addresses are supported\n",
+                       alg_data->adapter.name, slave_addr);
                return -EINVAL;
        }
 
        /* First, make sure bus is idle */
        if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) {
                /* Somebody else is monopolizing the bus */
-               dev_err(&adap->dev, "%s: Bus busy. Slave addr = %02x, "
-                      "cntrl = %x, stat = %x\n",
-                      adap->name, slave_addr,
-                      ioread32(I2C_REG_CTL(alg_data)),
-                      ioread32(I2C_REG_STS(alg_data)));
+               dev_err(&alg_data->adapter.dev,
+                       "%s: Bus busy. Slave addr = %02x, cntrl = %x, stat = %x\n",
+                       alg_data->adapter.name, slave_addr,
+                       ioread32(I2C_REG_CTL(alg_data)),
+                       ioread32(I2C_REG_STS(alg_data)));
                return -EBUSY;
        } else if (ioread32(I2C_REG_STS(alg_data)) & mstatus_afi) {
                /* Sorry, we lost the bus */
-               dev_err(&adap->dev, "%s: Arbitration failure. "
-                      "Slave addr = %02x\n", adap->name, slave_addr);
+               dev_err(&alg_data->adapter.dev,
+                       "%s: Arbitration failure. Slave addr = %02x\n",
+                       alg_data->adapter.name, slave_addr);
                return -EIO;
        }
 
@@ -115,14 +114,14 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)
        iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi,
                  I2C_REG_STS(alg_data));
 
-       dev_dbg(&adap->dev, "%s(): sending %#x\n", __func__,
+       dev_dbg(&alg_data->adapter.dev, "%s(): sending %#x\n", __func__,
                (slave_addr << 1) | start_bit | alg_data->mif.mode);
 
        /* Write the slave address, START bit and R/W bit */
        iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode,
                  I2C_REG_TX(alg_data));
 
-       dev_dbg(&adap->dev, "%s(): exit\n", __func__);
+       dev_dbg(&alg_data->adapter.dev, "%s(): exit\n", __func__);
 
        return 0;
 }
@@ -133,13 +132,12 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)
  *
  * Generate a STOP signal to terminate the master transaction.
  */
-static void i2c_pnx_stop(struct i2c_adapter *adap)
+static void i2c_pnx_stop(struct i2c_pnx_algo_data *alg_data)
 {
-       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
        /* Only 1 msec max timeout due to interrupt context */
        long timeout = 1000;
 
-       dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
+       dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
                __func__, ioread32(I2C_REG_STS(alg_data)));
 
        /* Write a STOP bit to TX FIFO */
@@ -153,7 +151,7 @@ static void i2c_pnx_stop(struct i2c_adapter *adap)
                timeout--;
        }
 
-       dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
+       dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
                __func__, ioread32(I2C_REG_STS(alg_data)));
 }
 
@@ -163,12 +161,11 @@ static void i2c_pnx_stop(struct i2c_adapter *adap)
  *
  * Sends one byte of data to the slave
  */
-static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
+static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
 {
-       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
        u32 val;
 
-       dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
+       dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
                __func__, ioread32(I2C_REG_STS(alg_data)));
 
        if (alg_data->mif.len > 0) {
@@ -184,15 +181,15 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
                alg_data->mif.len--;
                iowrite32(val, I2C_REG_TX(alg_data));
 
-               dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __func__,
-                       val, alg_data->mif.len + 1);
+               dev_dbg(&alg_data->adapter.dev, "%s(): xmit %#x [%d]\n",
+                       __func__, val, alg_data->mif.len + 1);
 
                if (alg_data->mif.len == 0) {
                        if (alg_data->last) {
                                /* Wait until the STOP is seen. */
                                if (wait_timeout(I2C_PNX_TIMEOUT, alg_data))
-                                       dev_err(&adap->dev, "The bus is still "
-                                               "active after timeout\n");
+                                       dev_err(&alg_data->adapter.dev,
+                                               "The bus is still active after timeout\n");
                        }
                        /* Disable master interrupts */
                        iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
@@ -201,14 +198,15 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
 
                        del_timer_sync(&alg_data->mif.timer);
 
-                       dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n",
+                       dev_dbg(&alg_data->adapter.dev,
+                               "%s(): Waking up xfer routine.\n",
                                __func__);
 
                        complete(&alg_data->mif.complete);
                }
        } else if (alg_data->mif.len == 0) {
                /* zero-sized transfer */
-               i2c_pnx_stop(adap);
+               i2c_pnx_stop(alg_data);
 
                /* Disable master interrupts. */
                iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
@@ -217,13 +215,14 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
 
                /* Stop timer. */
                del_timer_sync(&alg_data->mif.timer);
-               dev_dbg(&adap->dev, "%s(): Waking up xfer routine after "
-                       "zero-xfer.\n", __func__);
+               dev_dbg(&alg_data->adapter.dev,
+                       "%s(): Waking up xfer routine after zero-xfer.\n",
+                       __func__);
 
                complete(&alg_data->mif.complete);
        }
 
-       dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
+       dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
                __func__, ioread32(I2C_REG_STS(alg_data)));
 
        return 0;
@@ -235,21 +234,21 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)
  *
  * Reads one byte data from the slave
  */
-static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
+static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
 {
-       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
        unsigned int val = 0;
        u32 ctl = 0;
 
-       dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n",
+       dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
                __func__, ioread32(I2C_REG_STS(alg_data)));
 
        /* Check, whether there is already data,
         * or we didn't 'ask' for it yet.
         */
        if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) {
-               dev_dbg(&adap->dev, "%s(): Write dummy data to fill "
-                       "Rx-fifo...\n", __func__);
+               dev_dbg(&alg_data->adapter.dev,
+                       "%s(): Write dummy data to fill Rx-fifo...\n",
+                       __func__);
 
                if (alg_data->mif.len == 1) {
                        /* Last byte, do not acknowledge next rcv. */
@@ -281,16 +280,16 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
        if (alg_data->mif.len > 0) {
                val = ioread32(I2C_REG_RX(alg_data));
                *alg_data->mif.buf++ = (u8) (val & 0xff);
-               dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __func__, val,
-                       alg_data->mif.len);
+               dev_dbg(&alg_data->adapter.dev, "%s(): rcv 0x%x [%d]\n",
+                       __func__, val, alg_data->mif.len);
 
                alg_data->mif.len--;
                if (alg_data->mif.len == 0) {
                        if (alg_data->last)
                                /* Wait until the STOP is seen. */
                                if (wait_timeout(I2C_PNX_TIMEOUT, alg_data))
-                                       dev_err(&adap->dev, "The bus is still "
-                                               "active after timeout\n");
+                                       dev_err(&alg_data->adapter.dev,
+                                               "The bus is still active after timeout\n");
 
                        /* Disable master interrupts */
                        ctl = ioread32(I2C_REG_CTL(alg_data));
@@ -304,7 +303,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
                }
        }
 
-       dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n",
+       dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
                __func__, ioread32(I2C_REG_STS(alg_data)));
 
        return 0;
@@ -312,11 +311,11 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)
 
 static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
 {
+       struct i2c_pnx_algo_data *alg_data = dev_id;
        u32 stat, ctl;
-       struct i2c_adapter *adap = dev_id;
-       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 
-       dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n",
+       dev_dbg(&alg_data->adapter.dev,
+               "%s(): mstat = %x mctrl = %x, mode = %d\n",
                __func__,
                ioread32(I2C_REG_STS(alg_data)),
                ioread32(I2C_REG_CTL(alg_data)),
@@ -339,10 +338,10 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
                complete(&alg_data->mif.complete);
        } else if (stat & mstatus_nai) {
                /* Slave did not acknowledge, generate a STOP */
-               dev_dbg(&adap->dev, "%s(): "
-                       "Slave did not acknowledge, generating a STOP.\n",
+               dev_dbg(&alg_data->adapter.dev,
+                       "%s(): Slave did not acknowledge, generating a STOP.\n",
                        __func__);
-               i2c_pnx_stop(adap);
+               i2c_pnx_stop(alg_data);
 
                /* Disable master interrupts. */
                ctl = ioread32(I2C_REG_CTL(alg_data));
@@ -368,9 +367,9 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
                 */
                if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) {
                        if (alg_data->mif.mode == I2C_SMBUS_WRITE) {
-                               i2c_pnx_master_xmit(adap);
+                               i2c_pnx_master_xmit(alg_data);
                        } else if (alg_data->mif.mode == I2C_SMBUS_READ) {
-                               i2c_pnx_master_rcv(adap);
+                               i2c_pnx_master_rcv(alg_data);
                        }
                }
        }
@@ -379,7 +378,8 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
        stat = ioread32(I2C_REG_STS(alg_data));
        iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data));
 
-       dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n",
+       dev_dbg(&alg_data->adapter.dev,
+               "%s(): exiting, stat = %x ctrl = %x.\n",
                 __func__, ioread32(I2C_REG_STS(alg_data)),
                 ioread32(I2C_REG_CTL(alg_data)));
 
@@ -388,14 +388,13 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
 
 static void i2c_pnx_timeout(unsigned long data)
 {
-       struct i2c_adapter *adap = (struct i2c_adapter *)data;
-       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+       struct i2c_pnx_algo_data *alg_data = (struct i2c_pnx_algo_data *)data;
        u32 ctl;
 
-       dev_err(&adap->dev, "Master timed out. stat = %04x, cntrl = %04x. "
-              "Resetting master...\n",
-              ioread32(I2C_REG_STS(alg_data)),
-              ioread32(I2C_REG_CTL(alg_data)));
+       dev_err(&alg_data->adapter.dev,
+               "Master timed out. stat = %04x, cntrl = %04x. Resetting master...\n",
+               ioread32(I2C_REG_STS(alg_data)),
+               ioread32(I2C_REG_CTL(alg_data)));
 
        /* Reset master and disable interrupts */
        ctl = ioread32(I2C_REG_CTL(alg_data));
@@ -409,15 +408,14 @@ static void i2c_pnx_timeout(unsigned long data)
        complete(&alg_data->mif.complete);
 }
 
-static inline void bus_reset_if_active(struct i2c_adapter *adap)
+static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data)
 {
-       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
        u32 stat;
 
        if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) {
-               dev_err(&adap->dev,
+               dev_err(&alg_data->adapter.dev,
                        "%s: Bus is still active after xfer. Reset it...\n",
-                      adap->name);
+                       alg_data->adapter.name);
                iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
                          I2C_REG_CTL(alg_data));
                wait_reset(I2C_PNX_TIMEOUT, alg_data);
@@ -451,10 +449,11 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
        struct i2c_pnx_algo_data *alg_data = adap->algo_data;
        u32 stat = ioread32(I2C_REG_STS(alg_data));
 
-       dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n",
+       dev_dbg(&alg_data->adapter.dev,
+               "%s(): entering: %d messages, stat = %04x.\n",
                __func__, num, ioread32(I2C_REG_STS(alg_data)));
 
-       bus_reset_if_active(adap);
+       bus_reset_if_active(alg_data);
 
        /* Process transactions in a loop. */
        for (i = 0; rc >= 0 && i < num; i++) {
@@ -464,9 +463,9 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
                addr = pmsg->addr;
 
                if (pmsg->flags & I2C_M_TEN) {
-                       dev_err(&adap->dev,
+                       dev_err(&alg_data->adapter.dev,
                                "%s: 10 bits addr not supported!\n",
-                               adap->name);
+                               alg_data->adapter.name);
                        rc = -EINVAL;
                        break;
                }
@@ -478,11 +477,10 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
                alg_data->mif.ret = 0;
                alg_data->last = (i == num - 1);
 
-               dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __func__,
-                       alg_data->mif.mode,
-                       alg_data->mif.len);
+               dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n",
+                       __func__, alg_data->mif.mode, alg_data->mif.len);
 
-               i2c_pnx_arm_timer(adap);
+               i2c_pnx_arm_timer(alg_data);
 
                /* initialize the completion var */
                init_completion(&alg_data->mif.complete);
@@ -493,7 +491,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
                          I2C_REG_CTL(alg_data));
 
                /* Put start-code and slave-address on the bus. */
-               rc = i2c_pnx_start(addr, adap);
+               rc = i2c_pnx_start(addr, alg_data);
                if (rc < 0)
                        break;
 
@@ -502,31 +500,32 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 
                if (!(rc = alg_data->mif.ret))
                        completed++;
-               dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n",
+               dev_dbg(&alg_data->adapter.dev,
+                       "%s(): Complete, return code = %d.\n",
                        __func__, rc);
 
                /* Clear TDI and AFI bits in case they are set. */
                if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) {
-                       dev_dbg(&adap->dev,
+                       dev_dbg(&alg_data->adapter.dev,
                                "%s: TDI still set... clearing now.\n",
-                              adap->name);
+                               alg_data->adapter.name);
                        iowrite32(stat, I2C_REG_STS(alg_data));
                }
                if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) {
-                       dev_dbg(&adap->dev,
+                       dev_dbg(&alg_data->adapter.dev,
                                "%s: AFI still set... clearing now.\n",
-                              adap->name);
+                               alg_data->adapter.name);
                        iowrite32(stat, I2C_REG_STS(alg_data));
                }
        }
 
-       bus_reset_if_active(adap);
+       bus_reset_if_active(alg_data);
 
        /* Cleanup to be sure... */
        alg_data->mif.buf = NULL;
        alg_data->mif.len = 0;
 
-       dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n",
+       dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n",
                __func__, ioread32(I2C_REG_STS(alg_data)));
 
        if (completed != num)
@@ -545,69 +544,92 @@ static struct i2c_algorithm pnx_algorithm = {
        .functionality = i2c_pnx_func,
 };
 
+#ifdef CONFIG_PM
 static int i2c_pnx_controller_suspend(struct platform_device *pdev,
                                      pm_message_t state)
 {
-       struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev);
-       return i2c_pnx->suspend(pdev, state);
+       struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
+
+       /* FIXME: shouldn't this be clk_disable? */
+       clk_enable(alg_data->clk);
+
+       return 0;
 }
 
 static int i2c_pnx_controller_resume(struct platform_device *pdev)
 {
-       struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev);
-       return i2c_pnx->resume(pdev);
+       struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
+
+       return clk_enable(alg_data->clk);
 }
+#else
+#define i2c_pnx_controller_suspend     NULL
+#define i2c_pnx_controller_resume      NULL
+#endif
 
 static int __devinit i2c_pnx_probe(struct platform_device *pdev)
 {
        unsigned long tmp;
        int ret = 0;
        struct i2c_pnx_algo_data *alg_data;
-       int freq_mhz;
+       unsigned long freq;
        struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data;
 
-       if (!i2c_pnx || !i2c_pnx->adapter) {
+       if (!i2c_pnx || !i2c_pnx->name) {
                dev_err(&pdev->dev, "%s: no platform data supplied\n",
                       __func__);
                ret = -EINVAL;
                goto out;
        }
 
-       platform_set_drvdata(pdev, i2c_pnx);
-
-       if (i2c_pnx->calculate_input_freq)
-               freq_mhz = i2c_pnx->calculate_input_freq(pdev);
-       else {
-               freq_mhz = PNX_DEFAULT_FREQ;
-               dev_info(&pdev->dev, "Setting bus frequency to default value: "
-                      "%d MHz\n", freq_mhz);
+       alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL);
+       if (!alg_data) {
+               ret = -ENOMEM;
+               goto err_kzalloc;
        }
 
-       i2c_pnx->adapter->algo = &pnx_algorithm;
+       platform_set_drvdata(pdev, alg_data);
+
+       strlcpy(alg_data->adapter.name, i2c_pnx->name,
+               sizeof(alg_data->adapter.name));
+       alg_data->adapter.dev.parent = &pdev->dev;
+       alg_data->adapter.algo = &pnx_algorithm;
+       alg_data->adapter.algo_data = alg_data;
+       alg_data->adapter.nr = pdev->id;
+       alg_data->i2c_pnx = i2c_pnx;
+
+       alg_data->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(alg_data->clk)) {
+               ret = PTR_ERR(alg_data->clk);
+               goto out_drvdata;
+       }
 
-       alg_data = i2c_pnx->adapter->algo_data;
        init_timer(&alg_data->mif.timer);
        alg_data->mif.timer.function = i2c_pnx_timeout;
-       alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter;
+       alg_data->mif.timer.data = (unsigned long)alg_data;
 
        /* Register I/O resource */
-       if (!request_mem_region(alg_data->base, I2C_PNX_REGION_SIZE,
+       if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE,
                                pdev->name)) {
                dev_err(&pdev->dev,
                       "I/O region 0x%08x for I2C already in use.\n",
-                      alg_data->base);
+                      i2c_pnx->base);
                ret = -ENODEV;
-               goto out_drvdata;
+               goto out_clkget;
        }
 
-       if (!(alg_data->ioaddr =
-                       (u32)ioremap(alg_data->base, I2C_PNX_REGION_SIZE))) {
+       alg_data->ioaddr = ioremap(i2c_pnx->base, I2C_PNX_REGION_SIZE);
+       if (!alg_data->ioaddr) {
                dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n");
                ret = -ENOMEM;
                goto out_release;
        }
 
-       i2c_pnx->set_clock_run(pdev);
+       ret = clk_enable(alg_data->clk);
+       if (ret)
+               goto out_unmap;
+
+       freq = clk_get_rate(alg_data->clk);
 
        /*
         * Clock Divisor High This value is the number of system clocks
@@ -620,45 +642,47 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
         * the deglitching filter length.
         */
 
-       tmp = ((freq_mhz * 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
+       tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
        iowrite32(tmp, I2C_REG_CKH(alg_data));
        iowrite32(tmp, I2C_REG_CKL(alg_data));
 
        iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data));
        if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) {
                ret = -ENODEV;
-               goto out_unmap;
+               goto out_clock;
        }
        init_completion(&alg_data->mif.complete);
 
-       ret = request_irq(alg_data->irq, i2c_pnx_interrupt,
-                       0, pdev->name, i2c_pnx->adapter);
+       ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt,
+                       0, pdev->name, alg_data);
        if (ret)
                goto out_clock;
 
        /* Register this adapter with the I2C subsystem */
-       i2c_pnx->adapter->dev.parent = &pdev->dev;
-       i2c_pnx->adapter->nr = pdev->id;
-       ret = i2c_add_numbered_adapter(i2c_pnx->adapter);
+       ret = i2c_add_numbered_adapter(&alg_data->adapter);
        if (ret < 0) {
                dev_err(&pdev->dev, "I2C: Failed to add bus\n");
                goto out_irq;
        }
 
        dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
-              i2c_pnx->adapter->name, alg_data->base, alg_data->irq);
+              alg_data->adapter.name, i2c_pnx->base, i2c_pnx->irq);
 
        return 0;
 
 out_irq:
-       free_irq(alg_data->irq, i2c_pnx->adapter);
+       free_irq(i2c_pnx->irq, alg_data);
 out_clock:
-       i2c_pnx->set_clock_stop(pdev);
+       clk_disable(alg_data->clk);
 out_unmap:
-       iounmap((void *)alg_data->ioaddr);
+       iounmap(alg_data->ioaddr);
 out_release:
-       release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE);
+       release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE);
+out_clkget:
+       clk_put(alg_data->clk);
 out_drvdata:
+       kfree(alg_data);
+err_kzalloc:
        platform_set_drvdata(pdev, NULL);
 out:
        return ret;
@@ -666,15 +690,16 @@ out:
 
 static int __devexit i2c_pnx_remove(struct platform_device *pdev)
 {
-       struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev);
-       struct i2c_adapter *adap = i2c_pnx->adapter;
-       struct i2c_pnx_algo_data *alg_data = adap->algo_data;
-
-       free_irq(alg_data->irq, i2c_pnx->adapter);
-       i2c_del_adapter(adap);
-       i2c_pnx->set_clock_stop(pdev);
-       iounmap((void *)alg_data->ioaddr);
-       release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE);
+       struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
+       struct i2c_pnx_data *i2c_pnx = alg_data->i2c_pnx;
+
+       free_irq(i2c_pnx->irq, alg_data);
+       i2c_del_adapter(&alg_data->adapter);
+       clk_disable(alg_data->clk);
+       iounmap(alg_data->ioaddr);
+       release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE);
+       clk_put(alg_data->clk);
+       kfree(alg_data);
        platform_set_drvdata(pdev, NULL);
 
        return 0;
index 90d168ad03b6ca60574f45c03175b845bb2033b3..84c103a7ee13affecd683762aa9bf5881c174005 100644 (file)
@@ -2,6 +2,7 @@
  *  linux/drivers/mmc/host/mmci.c - ARM PrimeCell MMCI PL180/1 driver
  *
  *  Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
+ *  Copyright (C) 2010 ST-Ericsson AB.
  *
  * 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
@@ -34,9 +35,6 @@
 
 #define DRIVER_NAME "mmci-pl18x"
 
-#define DBG(host,fmt,args...)  \
-       pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args)
-
 static unsigned int fmax = 515633;
 
 /*
@@ -105,8 +103,8 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
        void __iomem *base;
        int blksz_bits;
 
-       DBG(host, "blksz %04x blks %04x flags %08x\n",
-           data->blksz, data->blocks, data->flags);
+       dev_dbg(mmc_dev(host->mmc), "blksz %04x blks %04x flags %08x\n",
+               data->blksz, data->blocks, data->flags);
 
        host->data = data;
        host->size = data->blksz;
@@ -155,7 +153,7 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
 {
        void __iomem *base = host->base;
 
-       DBG(host, "op %02x arg %08x flags %08x\n",
+       dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n",
            cmd->opcode, cmd->arg, cmd->flags);
 
        if (readl(base + MMCICOMMAND) & MCI_CPSM_ENABLE) {
@@ -184,8 +182,20 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
 {
        if (status & MCI_DATABLOCKEND) {
                host->data_xfered += data->blksz;
+#ifdef CONFIG_ARCH_U300
+               /*
+                * On the U300 some signal or other is
+                * badly routed so that a data write does
+                * not properly terminate with a MCI_DATAEND
+                * status flag. This quirk will make writes
+                * work again.
+                */
+               if (data->flags & MMC_DATA_WRITE)
+                       status |= MCI_DATAEND;
+#endif
        }
        if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
+               dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status);
                if (status & MCI_DATACRCFAIL)
                        data->error = -EILSEQ;
                else if (status & MCI_DATATIMEOUT)
@@ -307,7 +317,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
 
        status = readl(base + MMCISTATUS);
 
-       DBG(host, "irq1 %08x\n", status);
+       dev_dbg(mmc_dev(host->mmc), "irq1 (pio) %08x\n", status);
 
        do {
                unsigned long flags;
@@ -401,7 +411,7 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
                status &= readl(host->base + MMCIMASK0);
                writel(status, host->base + MMCICLEAR);
 
-               DBG(host, "irq0 %08x\n", status);
+               dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status);
 
                data = host->data;
                if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|
@@ -428,8 +438,8 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
        WARN_ON(host->mrq != NULL);
 
        if (mrq->data && !is_power_of_2(mrq->data->blksz)) {
-               printk(KERN_ERR "%s: Unsupported block size (%d bytes)\n",
-                       mmc_hostname(mmc), mrq->data->blksz);
+               dev_err(mmc_dev(mmc), "unsupported block size (%d bytes)\n",
+                       mrq->data->blksz);
                mrq->cmd->error = -EINVAL;
                mmc_request_done(mmc, mrq);
                return;
@@ -582,8 +592,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
 
        host->hw_designer = amba_manf(dev);
        host->hw_revision = amba_rev(dev);
-       DBG(host, "designer ID = 0x%02x\n", host->hw_designer);
-       DBG(host, "revision = 0x%01x\n", host->hw_revision);
+       dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
+       dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision);
 
        host->clk = clk_get(&dev->dev, NULL);
        if (IS_ERR(host->clk)) {
@@ -608,7 +618,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
                if (ret < 0)
                        goto clk_disable;
                host->mclk = clk_get_rate(host->clk);
-               DBG(host, "eventual mclk rate: %u Hz\n", host->mclk);
+               dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n",
+                       host->mclk);
        }
        host->base = ioremap(dev->res.start, resource_size(&dev->res));
        if (!host->base) {
@@ -619,6 +630,8 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
        mmc->ops = &mmci_ops;
        mmc->f_min = (host->mclk + 511) / 512;
        mmc->f_max = min(host->mclk, fmax);
+       dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
+
 #ifdef CONFIG_REGULATOR
        /* If we're using the regulator framework, try to fetch a regulator */
        host->vcc = regulator_get(&dev->dev, "vmmc");
@@ -712,7 +725,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
 
        mmc_add_host(mmc);
 
-       printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n",
+       dev_info(&dev->dev, "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n",
                mmc_hostname(mmc), amba_rev(dev), amba_config(dev),
                (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]);
 
index 0264b117893b36eba4616843d0e5a48f10e03721..c256aacfa9542232c121bd6a91a95456a16406c6 100644 (file)
@@ -7,6 +7,9 @@
  *
  * Copyright 2006 (c) MontaVista Software, Inc.
  *
+ * Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
+ * Copyright 2010 (c) ST-Ericsson AB
+ *
  * 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
@@ -18,6 +21,9 @@
 #include <linux/interrupt.h>
 #include <linux/amba/bus.h>
 #include <linux/io.h>
+#include <linux/bcd.h>
+#include <linux/delay.h>
+#include <linux/version.h>
 
 /*
  * Register definitions
 #define        RTC_RIS         0x14    /* Raw interrupt status register */
 #define        RTC_MIS         0x18    /* Masked interrupt status register */
 #define        RTC_ICR         0x1c    /* Interrupt clear register */
+/* ST variants have additional timer functionality */
+#define RTC_TDR                0x20    /* Timer data read register */
+#define RTC_TLR                0x24    /* Timer data load register */
+#define RTC_TCR                0x28    /* Timer control register */
+#define RTC_YDR                0x30    /* Year data read register */
+#define RTC_YMR                0x34    /* Year match register */
+#define RTC_YLR                0x38    /* Year data load register */
+
+#define RTC_CR_CWEN    (1 << 26)       /* Clockwatch enable bit */
+
+#define RTC_TCR_EN     (1 << 1) /* Periodic timer enable bit */
+
+/* Common bit definitions for Interrupt status and control registers */
+#define RTC_BIT_AI     (1 << 0) /* Alarm interrupt bit */
+#define RTC_BIT_PI     (1 << 1) /* Periodic interrupt bit. ST variants only. */
+
+/* Common bit definations for ST v2 for reading/writing time */
+#define RTC_SEC_SHIFT 0
+#define RTC_SEC_MASK (0x3F << RTC_SEC_SHIFT) /* Second [0-59] */
+#define RTC_MIN_SHIFT 6
+#define RTC_MIN_MASK (0x3F << RTC_MIN_SHIFT) /* Minute [0-59] */
+#define RTC_HOUR_SHIFT 12
+#define RTC_HOUR_MASK (0x1F << RTC_HOUR_SHIFT) /* Hour [0-23] */
+#define RTC_WDAY_SHIFT 17
+#define RTC_WDAY_MASK (0x7 << RTC_WDAY_SHIFT) /* Day of Week [1-7] 1=Sunday */
+#define RTC_MDAY_SHIFT 20
+#define RTC_MDAY_MASK (0x1F << RTC_MDAY_SHIFT) /* Day of Month [1-31] */
+#define RTC_MON_SHIFT 25
+#define RTC_MON_MASK (0xF << RTC_MON_SHIFT) /* Month [1-12] 1=January */
+
+#define RTC_TIMER_FREQ 32768
 
 struct pl031_local {
        struct rtc_device *rtc;
        void __iomem *base;
+       u8 hw_designer;
+       u8 hw_revision:4;
 };
 
-static irqreturn_t pl031_interrupt(int irq, void *dev_id)
+static int pl031_alarm_irq_enable(struct device *dev,
+       unsigned int enabled)
+{
+       struct pl031_local *ldata = dev_get_drvdata(dev);
+       unsigned long imsc;
+
+       /* Clear any pending alarm interrupts. */
+       writel(RTC_BIT_AI, ldata->base + RTC_ICR);
+
+       imsc = readl(ldata->base + RTC_IMSC);
+
+       if (enabled == 1)
+               writel(imsc | RTC_BIT_AI, ldata->base + RTC_IMSC);
+       else
+               writel(imsc & ~RTC_BIT_AI, ldata->base + RTC_IMSC);
+
+       return 0;
+}
+
+/*
+ * Convert Gregorian date to ST v2 RTC format.
+ */
+static int pl031_stv2_tm_to_time(struct device *dev,
+                                struct rtc_time *tm, unsigned long *st_time,
+       unsigned long *bcd_year)
+{
+       int year = tm->tm_year + 1900;
+       int wday = tm->tm_wday;
+
+       /* wday masking is not working in hardware so wday must be valid */
+       if (wday < -1 || wday > 6) {
+               dev_err(dev, "invalid wday value %d\n", tm->tm_wday);
+               return -EINVAL;
+       } else if (wday == -1) {
+               /* wday is not provided, calculate it here */
+               unsigned long time;
+               struct rtc_time calc_tm;
+
+               rtc_tm_to_time(tm, &time);
+               rtc_time_to_tm(time, &calc_tm);
+               wday = calc_tm.tm_wday;
+       }
+
+       *bcd_year = (bin2bcd(year % 100) | bin2bcd(year / 100) << 8);
+
+       *st_time = ((tm->tm_mon + 1) << RTC_MON_SHIFT)
+                       |       (tm->tm_mday << RTC_MDAY_SHIFT)
+                       |       ((wday + 1) << RTC_WDAY_SHIFT)
+                       |       (tm->tm_hour << RTC_HOUR_SHIFT)
+                       |       (tm->tm_min << RTC_MIN_SHIFT)
+                       |       (tm->tm_sec << RTC_SEC_SHIFT);
+
+       return 0;
+}
+
+/*
+ * Convert ST v2 RTC format to Gregorian date.
+ */
+static int pl031_stv2_time_to_tm(unsigned long st_time, unsigned long bcd_year,
+       struct rtc_time *tm)
+{
+       tm->tm_year = bcd2bin(bcd_year) + (bcd2bin(bcd_year >> 8) * 100);
+       tm->tm_mon  = ((st_time & RTC_MON_MASK) >> RTC_MON_SHIFT) - 1;
+       tm->tm_mday = ((st_time & RTC_MDAY_MASK) >> RTC_MDAY_SHIFT);
+       tm->tm_wday = ((st_time & RTC_WDAY_MASK) >> RTC_WDAY_SHIFT) - 1;
+       tm->tm_hour = ((st_time & RTC_HOUR_MASK) >> RTC_HOUR_SHIFT);
+       tm->tm_min  = ((st_time & RTC_MIN_MASK) >> RTC_MIN_SHIFT);
+       tm->tm_sec  = ((st_time & RTC_SEC_MASK) >> RTC_SEC_SHIFT);
+
+       tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
+       tm->tm_year -= 1900;
+
+       return 0;
+}
+
+static int pl031_stv2_read_time(struct device *dev, struct rtc_time *tm)
+{
+       struct pl031_local *ldata = dev_get_drvdata(dev);
+
+       pl031_stv2_time_to_tm(readl(ldata->base + RTC_DR),
+                       readl(ldata->base + RTC_YDR), tm);
+
+       return 0;
+}
+
+static int pl031_stv2_set_time(struct device *dev, struct rtc_time *tm)
+{
+       unsigned long time;
+       unsigned long bcd_year;
+       struct pl031_local *ldata = dev_get_drvdata(dev);
+       int ret;
+
+       ret = pl031_stv2_tm_to_time(dev, tm, &time, &bcd_year);
+       if (ret == 0) {
+               writel(bcd_year, ldata->base + RTC_YLR);
+               writel(time, ldata->base + RTC_LR);
+       }
+
+       return ret;
+}
+
+static int pl031_stv2_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-       struct rtc_device *rtc = dev_id;
+       struct pl031_local *ldata = dev_get_drvdata(dev);
+       int ret;
 
-       rtc_update_irq(rtc, 1, RTC_AF);
+       ret = pl031_stv2_time_to_tm(readl(ldata->base + RTC_MR),
+                       readl(ldata->base + RTC_YMR), &alarm->time);
 
-       return IRQ_HANDLED;
+       alarm->pending = readl(ldata->base + RTC_RIS) & RTC_BIT_AI;
+       alarm->enabled = readl(ldata->base + RTC_IMSC) & RTC_BIT_AI;
+
+       return ret;
 }
 
-static int pl031_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+static int pl031_stv2_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
        struct pl031_local *ldata = dev_get_drvdata(dev);
+       unsigned long time;
+       unsigned long bcd_year;
+       int ret;
+
+       /* At the moment, we can only deal with non-wildcarded alarm times. */
+       ret = rtc_valid_tm(&alarm->time);
+       if (ret == 0) {
+               ret = pl031_stv2_tm_to_time(dev, &alarm->time,
+                                           &time, &bcd_year);
+               if (ret == 0) {
+                       writel(bcd_year, ldata->base + RTC_YMR);
+                       writel(time, ldata->base + RTC_MR);
+
+                       pl031_alarm_irq_enable(dev, alarm->enabled);
+               }
+       }
+
+       return ret;
+}
+
+static irqreturn_t pl031_interrupt(int irq, void *dev_id)
+{
+       struct pl031_local *ldata = dev_id;
+       unsigned long rtcmis;
+       unsigned long events = 0;
+
+       rtcmis = readl(ldata->base + RTC_MIS);
+       if (rtcmis) {
+               writel(rtcmis, ldata->base + RTC_ICR);
+
+               if (rtcmis & RTC_BIT_AI)
+                       events |= (RTC_AF | RTC_IRQF);
+
+               /* Timer interrupt is only available in ST variants */
+               if ((rtcmis & RTC_BIT_PI) &&
+                       (ldata->hw_designer == AMBA_VENDOR_ST))
+                       events |= (RTC_PF | RTC_IRQF);
+
+               rtc_update_irq(ldata->rtc, 1, events);
 
-       switch (cmd) {
-       case RTC_AIE_OFF:
-               writel(1, ldata->base + RTC_MIS);
-               return 0;
-       case RTC_AIE_ON:
-               writel(0, ldata->base + RTC_MIS);
-               return 0;
+               return IRQ_HANDLED;
        }
 
-       return -ENOIOCTLCMD;
+       return IRQ_NONE;
 }
 
 static int pl031_read_time(struct device *dev, struct rtc_time *tm)
@@ -74,11 +252,14 @@ static int pl031_set_time(struct device *dev, struct rtc_time *tm)
 {
        unsigned long time;
        struct pl031_local *ldata = dev_get_drvdata(dev);
+       int ret;
 
-       rtc_tm_to_time(tm, &time);
-       writel(time, ldata->base + RTC_LR);
+       ret = rtc_tm_to_time(tm, &time);
 
-       return 0;
+       if (ret == 0)
+               writel(time, ldata->base + RTC_LR);
+
+       return ret;
 }
 
 static int pl031_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
@@ -86,8 +267,9 @@ static int pl031_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
        struct pl031_local *ldata = dev_get_drvdata(dev);
 
        rtc_time_to_tm(readl(ldata->base + RTC_MR), &alarm->time);
-       alarm->pending = readl(ldata->base + RTC_RIS);
-       alarm->enabled = readl(ldata->base + RTC_IMSC);
+
+       alarm->pending = readl(ldata->base + RTC_RIS) & RTC_BIT_AI;
+       alarm->enabled = readl(ldata->base + RTC_IMSC) & RTC_BIT_AI;
 
        return 0;
 }
@@ -96,22 +278,71 @@ static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
        struct pl031_local *ldata = dev_get_drvdata(dev);
        unsigned long time;
+       int ret;
+
+       /* At the moment, we can only deal with non-wildcarded alarm times. */
+       ret = rtc_valid_tm(&alarm->time);
+       if (ret == 0) {
+               ret = rtc_tm_to_time(&alarm->time, &time);
+               if (ret == 0) {
+                       writel(time, ldata->base + RTC_MR);
+                       pl031_alarm_irq_enable(dev, alarm->enabled);
+               }
+       }
+
+       return ret;
+}
+
+/* Periodic interrupt is only available in ST variants. */
+static int pl031_irq_set_state(struct device *dev, int enabled)
+{
+       struct pl031_local *ldata = dev_get_drvdata(dev);
+
+       if (enabled == 1) {
+               /* Clear any pending timer interrupt. */
+               writel(RTC_BIT_PI, ldata->base + RTC_ICR);
+
+               writel(readl(ldata->base + RTC_IMSC) | RTC_BIT_PI,
+                       ldata->base + RTC_IMSC);
 
-       rtc_tm_to_time(&alarm->time, &time);
+               /* Now start the timer */
+               writel(readl(ldata->base + RTC_TCR) | RTC_TCR_EN,
+                       ldata->base + RTC_TCR);
 
-       writel(time, ldata->base + RTC_MR);
-       writel(!alarm->enabled, ldata->base + RTC_MIS);
+       } else {
+               writel(readl(ldata->base + RTC_IMSC) & (~RTC_BIT_PI),
+                       ldata->base + RTC_IMSC);
+
+               /* Also stop the timer */
+               writel(readl(ldata->base + RTC_TCR) & (~RTC_TCR_EN),
+                       ldata->base + RTC_TCR);
+       }
+       /* Wait at least 1 RTC32 clock cycle to ensure next access
+        * to RTC_TCR will succeed.
+        */
+       udelay(40);
 
        return 0;
 }
 
-static const struct rtc_class_ops pl031_ops = {
-       .ioctl = pl031_ioctl,
-       .read_time = pl031_read_time,
-       .set_time = pl031_set_time,
-       .read_alarm = pl031_read_alarm,
-       .set_alarm = pl031_set_alarm,
-};
+static int pl031_irq_set_freq(struct device *dev, int freq)
+{
+       struct pl031_local *ldata = dev_get_drvdata(dev);
+
+       /* Cant set timer if it is already enabled */
+       if (readl(ldata->base + RTC_TCR) & RTC_TCR_EN) {
+               dev_err(dev, "can't change frequency while timer enabled\n");
+               return -EINVAL;
+       }
+
+       /* If self start bit in RTC_TCR is set timer will start here,
+        * but we never set that bit. Instead we start the timer when
+        * set_state is called with enabled == 1.
+        */
+       writel(RTC_TIMER_FREQ / freq, ldata->base + RTC_TLR);
+
+       return 0;
+}
 
 static int pl031_remove(struct amba_device *adev)
 {
@@ -131,18 +362,20 @@ static int pl031_probe(struct amba_device *adev, struct amba_id *id)
 {
        int ret;
        struct pl031_local *ldata;
+       struct rtc_class_ops *ops = id->data;
 
        ret = amba_request_regions(adev, NULL);
        if (ret)
                goto err_req;
 
-       ldata = kmalloc(sizeof(struct pl031_local), GFP_KERNEL);
+       ldata = kzalloc(sizeof(struct pl031_local), GFP_KERNEL);
        if (!ldata) {
                ret = -ENOMEM;
                goto out;
        }
 
        ldata->base = ioremap(adev->res.start, resource_size(&adev->res));
+
        if (!ldata->base) {
                ret = -ENOMEM;
                goto out_no_remap;
@@ -150,24 +383,36 @@ static int pl031_probe(struct amba_device *adev, struct amba_id *id)
 
        amba_set_drvdata(adev, ldata);
 
-       if (request_irq(adev->irq[0], pl031_interrupt, IRQF_DISABLED,
-                       "rtc-pl031", ldata->rtc)) {
-               ret = -EIO;
-               goto out_no_irq;
-       }
+       ldata->hw_designer = amba_manf(adev);
+       ldata->hw_revision = amba_rev(adev);
+
+       dev_dbg(&adev->dev, "designer ID = 0x%02x\n", ldata->hw_designer);
+       dev_dbg(&adev->dev, "revision = 0x%01x\n", ldata->hw_revision);
 
-       ldata->rtc = rtc_device_register("pl031", &adev->dev, &pl031_ops,
-                                        THIS_MODULE);
+       /* Enable the clockwatch on ST Variants */
+       if ((ldata->hw_designer == AMBA_VENDOR_ST) &&
+           (ldata->hw_revision > 1))
+               writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN,
+                      ldata->base + RTC_CR);
+
+       ldata->rtc = rtc_device_register("pl031", &adev->dev, ops,
+                                       THIS_MODULE);
        if (IS_ERR(ldata->rtc)) {
                ret = PTR_ERR(ldata->rtc);
                goto out_no_rtc;
        }
 
+       if (request_irq(adev->irq[0], pl031_interrupt,
+                       IRQF_DISABLED | IRQF_SHARED, "rtc-pl031", ldata)) {
+               ret = -EIO;
+               goto out_no_irq;
+       }
+
        return 0;
 
-out_no_rtc:
-       free_irq(adev->irq[0], ldata->rtc);
 out_no_irq:
+       rtc_device_unregister(ldata->rtc);
+out_no_rtc:
        iounmap(ldata->base);
        amba_set_drvdata(adev, NULL);
 out_no_remap:
@@ -175,13 +420,57 @@ out_no_remap:
 out:
        amba_release_regions(adev);
 err_req:
+
        return ret;
 }
 
+/* Operations for the original ARM version */
+static struct rtc_class_ops arm_pl031_ops = {
+       .read_time = pl031_read_time,
+       .set_time = pl031_set_time,
+       .read_alarm = pl031_read_alarm,
+       .set_alarm = pl031_set_alarm,
+       .alarm_irq_enable = pl031_alarm_irq_enable,
+};
+
+/* The First ST derivative */
+static struct rtc_class_ops stv1_pl031_ops = {
+       .read_time = pl031_read_time,
+       .set_time = pl031_set_time,
+       .read_alarm = pl031_read_alarm,
+       .set_alarm = pl031_set_alarm,
+       .alarm_irq_enable = pl031_alarm_irq_enable,
+       .irq_set_state = pl031_irq_set_state,
+       .irq_set_freq = pl031_irq_set_freq,
+};
+
+/* And the second ST derivative */
+static struct rtc_class_ops stv2_pl031_ops = {
+       .read_time = pl031_stv2_read_time,
+       .set_time = pl031_stv2_set_time,
+       .read_alarm = pl031_stv2_read_alarm,
+       .set_alarm = pl031_stv2_set_alarm,
+       .alarm_irq_enable = pl031_alarm_irq_enable,
+       .irq_set_state = pl031_irq_set_state,
+       .irq_set_freq = pl031_irq_set_freq,
+};
+
 static struct amba_id pl031_ids[] __initdata = {
        {
                .id = 0x00041031,
                .mask = 0x000fffff,
+               .data = &arm_pl031_ops,
+       },
+       /* ST Micro variants */
+       {
+               .id = 0x00180031,
+               .mask = 0x00ffffff,
+               .data = &stv1_pl031_ops,
+       },
+       {
+               .id = 0x00280031,
+               .mask = 0x00ffffff,
+               .data = &stv2_pl031_ops,
        },
        {0, 0},
 };
index ef7adc8135dd4755fbd3cbde2c560988ea2afc0f..ce6c35333ff7b9faaf65acfc087ace884f150c60 100644 (file)
@@ -71,6 +71,7 @@ struct uart_amba_port {
        unsigned int            im;     /* interrupt mask */
        unsigned int            old_status;
        unsigned int            ifls;   /* vendor-specific */
+       bool                    autorts;
 };
 
 /* There is by now at least one vendor with differing details, so handle it */
@@ -308,6 +309,11 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl)
        TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1);
        TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2);
        TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE);
+
+       if (uap->autorts) {
+               /* We need to disable auto-RTS if we want to turn RTS off */
+               TIOCMBIT(TIOCM_RTS, UART011_CR_RTSEN);
+       }
 #undef TIOCMBIT
 
        writew(cr, uap->port.membase + UART011_CR);
@@ -437,6 +443,7 @@ static void pl011_shutdown(struct uart_port *port)
        /*
         * disable the port
         */
+       uap->autorts = false;
        writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR);
 
        /*
@@ -456,6 +463,7 @@ static void
 pl011_set_termios(struct uart_port *port, struct ktermios *termios,
                     struct ktermios *old)
 {
+       struct uart_amba_port *uap = (struct uart_amba_port *)port;
        unsigned int lcr_h, old_cr;
        unsigned long flags;
        unsigned int baud, quot;
@@ -532,6 +540,17 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
        old_cr = readw(port->membase + UART011_CR);
        writew(0, port->membase + UART011_CR);
 
+       if (termios->c_cflag & CRTSCTS) {
+               if (old_cr & UART011_CR_RTS)
+                       old_cr |= UART011_CR_RTSEN;
+
+               old_cr |= UART011_CR_CTSEN;
+               uap->autorts = true;
+       } else {
+               old_cr &= ~(UART011_CR_CTSEN | UART011_CR_RTSEN);
+               uap->autorts = false;
+       }
+
        /* Set baud rate */
        writew(quot & 0x3f, port->membase + UART011_FBRD);
        writew(quot >> 6, port->membase + UART011_IBRD);
index ff5bbb9c43c9961485b94f8cb86e5fd349789823..9aeb6811310001619baa9ffffbc4d4de2274ffcc 100644 (file)
@@ -363,6 +363,7 @@ struct pl022 {
        void                            *rx_end;
        enum ssp_reading                read;
        enum ssp_writing                write;
+       u32                             exp_fifo_level;
 };
 
 /**
@@ -501,6 +502,9 @@ static int flush(struct pl022 *pl022)
                while (readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_RNE)
                        readw(SSP_DR(pl022->virtbase));
        } while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_BSY) && limit--);
+
+       pl022->exp_fifo_level = 0;
+
        return limit;
 }
 
@@ -583,10 +587,9 @@ static void readwriter(struct pl022 *pl022)
         * errons in 8bit wide transfers on ARM variants (just 8 words
         * FIFO, means only 8x8 = 64 bits in FIFO) at least.
         *
-        * FIXME: currently we have no logic to account for this.
-        * perhaps there is even something broken in HW regarding
-        * 8bit transfers (it doesn't fail on 16bit) so this needs
-        * more investigation...
+        * To prevent this issue, the TX FIFO is only filled to the
+        * unused RX FIFO fill length, regardless of what the TX
+        * FIFO status flag indicates.
         */
        dev_dbg(&pl022->adev->dev,
                "%s, rx: %p, rxend: %p, tx: %p, txend: %p\n",
@@ -613,11 +616,12 @@ static void readwriter(struct pl022 *pl022)
                        break;
                }
                pl022->rx += (pl022->cur_chip->n_bytes);
+               pl022->exp_fifo_level--;
        }
        /*
-        * Write as much as you can, while keeping an eye on the RX FIFO!
+        * Write as much as possible up to the RX FIFO size
         */
-       while ((readw(SSP_SR(pl022->virtbase)) & SSP_SR_MASK_TNF)
+       while ((pl022->exp_fifo_level < pl022->vendor->fifodepth)
               && (pl022->tx < pl022->tx_end)) {
                switch (pl022->write) {
                case WRITING_NULL:
@@ -634,6 +638,7 @@ static void readwriter(struct pl022 *pl022)
                        break;
                }
                pl022->tx += (pl022->cur_chip->n_bytes);
+               pl022->exp_fifo_level++;
                /*
                 * This inner reader takes care of things appearing in the RX
                 * FIFO as we're transmitting. This will happen a lot since the
@@ -660,6 +665,7 @@ static void readwriter(struct pl022 *pl022)
                                break;
                        }
                        pl022->rx += (pl022->cur_chip->n_bytes);
+                       pl022->exp_fifo_level--;
                }
        }
        /*
index 430a5848a9a5d40a6bb1aeb770c76e26df357be2..c7a9479934af87558e45bf16a036803060ede2f2 100644 (file)
@@ -96,9 +96,6 @@ static void wdt_enable(void)
 {
        spin_lock(&io_lock);
 
-       if (wdt_clk)
-               clk_set_rate(wdt_clk, 1);
-
        /* stop counter, initiate counter reset */
        __raw_writel(RESET_COUNT, WDTIM_CTRL(wdt_base));
        /*wait for reset to complete. 100% guarantee event */
@@ -125,19 +122,25 @@ static void wdt_disable(void)
        spin_lock(&io_lock);
 
        __raw_writel(0, WDTIM_CTRL(wdt_base));  /*stop counter */
-       if (wdt_clk)
-               clk_set_rate(wdt_clk, 0);
 
        spin_unlock(&io_lock);
 }
 
 static int pnx4008_wdt_open(struct inode *inode, struct file *file)
 {
+       int ret;
+
        if (test_and_set_bit(WDT_IN_USE, &wdt_status))
                return -EBUSY;
 
        clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
 
+       ret = clk_enable(wdt_clk);
+       if (ret) {
+               clear_bit(WDT_IN_USE, &wdt_status);
+               return ret;
+       }
+
        wdt_enable();
 
        return nonseekable_open(inode, file);
@@ -225,6 +228,7 @@ static int pnx4008_wdt_release(struct inode *inode, struct file *file)
                printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n");
 
        wdt_disable();
+       clk_disable(wdt_clk);
        clear_bit(WDT_IN_USE, &wdt_status);
        clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
 
@@ -273,25 +277,33 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
        }
        wdt_base = (void __iomem *)IO_ADDRESS(res->start);
 
-       wdt_clk = clk_get(&pdev->dev, "wdt_ck");
+       wdt_clk = clk_get(&pdev->dev, NULL);
        if (IS_ERR(wdt_clk)) {
                ret = PTR_ERR(wdt_clk);
                release_resource(wdt_mem);
                kfree(wdt_mem);
                goto out;
-       } else
-               clk_set_rate(wdt_clk, 1);
+       }
+
+       ret = clk_enable(wdt_clk);
+       if (ret) {
+               release_resource(wdt_mem);
+               kfree(wdt_mem);
+               goto out;
+       }
 
        ret = misc_register(&pnx4008_wdt_miscdev);
        if (ret < 0) {
                printk(KERN_ERR MODULE_NAME "cannot register misc device\n");
                release_resource(wdt_mem);
                kfree(wdt_mem);
-               clk_set_rate(wdt_clk, 0);
+               clk_disable(wdt_clk);
+               clk_put(wdt_clk);
        } else {
                boot_status = (__raw_readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
                    WDIOF_CARDRESET : 0;
                wdt_disable();          /*disable for now */
+               clk_disable(wdt_clk);
                set_bit(WDT_DEVICE_INITED, &wdt_status);
        }
 
@@ -302,11 +314,10 @@ out:
 static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
 {
        misc_deregister(&pnx4008_wdt_miscdev);
-       if (wdt_clk) {
-               clk_set_rate(wdt_clk, 0);
-               clk_put(wdt_clk);
-               wdt_clk = NULL;
-       }
+
+       clk_disable(wdt_clk);
+       clk_put(wdt_clk);
+
        if (wdt_mem) {
                release_resource(wdt_mem);
                kfree(wdt_mem);
index 9eb07bbc6522bb4508797a7468a22ba465894e34..a87124d4d5338d2704875c71ba5f6d87c8d41a72 100644 (file)
@@ -12,9 +12,8 @@
 #ifndef __I2C_PNX_H__
 #define __I2C_PNX_H__
 
-#include <linux/pm.h>
-
 struct platform_device;
+struct clk;
 
 struct i2c_pnx_mif {
        int                     ret;            /* Return value */
@@ -26,20 +25,18 @@ struct i2c_pnx_mif {
 };
 
 struct i2c_pnx_algo_data {
-       u32                     base;
-       u32                     ioaddr;
-       int                     irq;
+       void __iomem            *ioaddr;
        struct i2c_pnx_mif      mif;
        int                     last;
+       struct clk              *clk;
+       struct i2c_pnx_data     *i2c_pnx;
+       struct i2c_adapter      adapter;
 };
 
 struct i2c_pnx_data {
-       int (*suspend) (struct platform_device *pdev, pm_message_t state);
-       int (*resume) (struct platform_device *pdev);
-       u32 (*calculate_input_freq) (struct platform_device *pdev);
-       int (*set_clock_run) (struct platform_device *pdev);
-       int (*set_clock_stop) (struct platform_device *pdev);
-       struct i2c_adapter *adapter;
+       const char *name;
+       u32 base;
+       int irq;
 };
 
 #endif /* __I2C_PNX_H__ */
index 2d16fa6b8c2d8fb6a40ea5b3f9ea57c77a34d1af..3a5aeb37c1107ed9735b2e0e943db3212bacaf3c 100644 (file)
@@ -2087,7 +2087,7 @@ static void set_huge_ptep_writable(struct vm_area_struct *vma,
 
        entry = pte_mkwrite(pte_mkdirty(huge_ptep_get(ptep)));
        if (huge_ptep_set_access_flags(vma, address, ptep, entry, 1)) {
-               update_mmu_cache(vma, address, entry);
+               update_mmu_cache(vma, address, ptep);
        }
 }
 
@@ -2558,7 +2558,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
        entry = pte_mkyoung(entry);
        if (huge_ptep_set_access_flags(vma, address, ptep, entry,
                                                flags & FAULT_FLAG_WRITE))
-               update_mmu_cache(vma, address, entry);
+               update_mmu_cache(vma, address, ptep);
 
 out_page_table_lock:
        spin_unlock(&mm->page_table_lock);
index 09e4b1be7b67ddda8336eee4bd76bbbf304a82b3..72fb5f39bccc32dd17f3aa58f9567f146661301e 100644 (file)
@@ -1593,7 +1593,7 @@ static int insert_pfn(struct vm_area_struct *vma, unsigned long addr,
        /* Ok, finally just insert the thing.. */
        entry = pte_mkspecial(pfn_pte(pfn, prot));
        set_pte_at(mm, addr, pte, entry);
-       update_mmu_cache(vma, addr, entry); /* XXX: why not for insert_page? */
+       update_mmu_cache(vma, addr, pte); /* XXX: why not for insert_page? */
 
        retval = 0;
 out_unlock:
@@ -2116,7 +2116,7 @@ reuse:
                entry = pte_mkyoung(orig_pte);
                entry = maybe_mkwrite(pte_mkdirty(entry), vma);
                if (ptep_set_access_flags(vma, address, page_table, entry,1))
-                       update_mmu_cache(vma, address, entry);
+                       update_mmu_cache(vma, address, page_table);
                ret |= VM_FAULT_WRITE;
                goto unlock;
        }
@@ -2185,7 +2185,7 @@ gotten:
                 * new page to be mapped directly into the secondary page table.
                 */
                set_pte_at_notify(mm, address, page_table, entry);
-               update_mmu_cache(vma, address, entry);
+               update_mmu_cache(vma, address, page_table);
                if (old_page) {
                        /*
                         * Only after switching the pte to the new page may
@@ -2629,7 +2629,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
        }
 
        /* No need to invalidate - it was non-present before */
-       update_mmu_cache(vma, address, pte);
+       update_mmu_cache(vma, address, page_table);
 unlock:
        pte_unmap_unlock(page_table, ptl);
 out:
@@ -2694,7 +2694,7 @@ setpte:
        set_pte_at(mm, address, page_table, entry);
 
        /* No need to invalidate - it was non-present before */
-       update_mmu_cache(vma, address, entry);
+       update_mmu_cache(vma, address, page_table);
 unlock:
        pte_unmap_unlock(page_table, ptl);
        return 0;
@@ -2855,7 +2855,7 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                set_pte_at(mm, address, page_table, entry);
 
                /* no need to invalidate: a not-present page won't be cached */
-               update_mmu_cache(vma, address, entry);
+               update_mmu_cache(vma, address, page_table);
        } else {
                if (charged)
                        mem_cgroup_uncharge_page(page);
@@ -2992,7 +2992,7 @@ static inline int handle_pte_fault(struct mm_struct *mm,
        }
        entry = pte_mkyoung(entry);
        if (ptep_set_access_flags(vma, address, pte, entry, flags & FAULT_FLAG_WRITE)) {
-               update_mmu_cache(vma, address, entry);
+               update_mmu_cache(vma, address, pte);
        } else {
                /*
                 * This is needed only for protection faults but the arch code
index 880bd592d38ea47af36f5f9b64323e8814d09f24..edb6101ed774da0244cb129f332a6914b73465de 100644 (file)
@@ -134,7 +134,7 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,
                page_add_file_rmap(new);
 
        /* No need to invalidate - it was non-present before */
-       update_mmu_cache(vma, addr, pte);
+       update_mmu_cache(vma, addr, ptep);
 unlock:
        pte_unmap_unlock(ptep, ptl);
 out: