浏览代码

Merge branches 'arm-mm', 'at91', 'clkevts', 'imx', 'iop', 'misc', 'netx', 'ns9xxx', 'omap', 'pxa', 'rpc', 's3c' and 'sa1100' into devel

共有 100 个文件被更改,包括 4885 次插入830 次删除
  1. 1 1
      Documentation/spi/pxa2xx
  2. 20 0
      arch/arm/Kconfig
  3. 6 0
      arch/arm/boot/compressed/head-at91rm9200.S
  4. 1386 0
      arch/arm/configs/picotux200_defconfig
  5. 2 2
      arch/arm/kernel/Makefile
  6. 17 14
      arch/arm/kernel/ecard.c
  7. 56 0
      arch/arm/kernel/ecard.h
  8. 5 1
      arch/arm/kernel/head.S
  9. 3 0
      arch/arm/kernel/process.c
  10. 3 3
      arch/arm/kernel/ptrace.c
  11. 73 0
      arch/arm/kernel/stacktrace.c
  12. 9 0
      arch/arm/kernel/stacktrace.h
  13. 3 1
      arch/arm/kernel/time.c
  14. 3 2
      arch/arm/kernel/traps.c
  15. 7 0
      arch/arm/mach-at91/Kconfig
  16. 1 0
      arch/arm/mach-at91/Makefile
  17. 18 1
      arch/arm/mach-at91/at91rm9200.c
  18. 6 1
      arch/arm/mach-at91/at91sam9260.c
  19. 18 1
      arch/arm/mach-at91/at91sam9261.c
  20. 5 5
      arch/arm/mach-at91/at91sam9261_devices.c
  21. 42 6
      arch/arm/mach-at91/at91sam9263.c
  22. 124 0
      arch/arm/mach-at91/at91sam9263_devices.c
  23. 166 0
      arch/arm/mach-at91/board-picotux200.c
  24. 6 4
      arch/arm/mach-at91/board-sam9260ek.c
  25. 50 2
      arch/arm/mach-at91/board-sam9261ek.c
  26. 70 0
      arch/arm/mach-at91/board-sam9263ek.c
  27. 5 0
      arch/arm/mach-ep93xx/clock.c
  28. 1 0
      arch/arm/mach-iop13xx/Makefile
  29. 4 1
      arch/arm/mach-iop13xx/iq81340mc.c
  30. 4 1
      arch/arm/mach-iop13xx/iq81340sc.c
  31. 4 4
      arch/arm/mach-iop13xx/pci.c
  32. 1 5
      arch/arm/mach-iop13xx/setup.c
  33. 234 0
      arch/arm/mach-iop13xx/tpmi.c
  34. 8 0
      arch/arm/mach-iop32x/Kconfig
  35. 7 4
      arch/arm/mach-iop32x/iq31244.c
  36. 2 1
      arch/arm/mach-iop32x/iq80321.c
  37. 8 0
      arch/arm/mach-iop33x/Kconfig
  38. 2 1
      arch/arm/mach-iop33x/iq80331.c
  39. 2 1
      arch/arm/mach-iop33x/iq80332.c
  40. 74 19
      arch/arm/mach-ixp4xx/common.c
  41. 13 2
      arch/arm/mach-ns9xxx/Kconfig
  42. 1 0
      arch/arm/mach-ns9xxx/Makefile
  43. 17 0
      arch/arm/mach-ns9xxx/board-jscc9p9360.c
  44. 13 0
      arch/arm/mach-ns9xxx/board-jscc9p9360.h
  45. 29 0
      arch/arm/mach-ns9xxx/mach-cc9p9360js.c
  46. 133 73
      arch/arm/mach-omap1/time.c
  47. 2 2
      arch/arm/mach-pxa/generic.c
  48. 70 2
      arch/arm/mach-pxa/irq.c
  49. 2 2
      arch/arm/mach-pxa/lpd270.c
  50. 1 1
      arch/arm/mach-pxa/lubbock.c
  51. 2 2
      arch/arm/mach-pxa/mainstone.c
  52. 2 2
      arch/arm/mach-pxa/pxa27x.c
  53. 6 6
      arch/arm/mach-pxa/ssp.c
  54. 35 0
      arch/arm/mach-rpc/riscpc.c
  55. 1 6
      arch/arm/mach-s3c2410/mach-amlm5900.c
  56. 4 8
      arch/arm/mach-s3c2410/mach-bast.c
  57. 2 7
      arch/arm/mach-s3c2410/mach-h1940.c
  58. 2 6
      arch/arm/mach-s3c2410/mach-n30.c
  59. 5 7
      arch/arm/mach-s3c2410/mach-otom.c
  60. 1 7
      arch/arm/mach-s3c2410/mach-qt2410.c
  61. 7 7
      arch/arm/mach-s3c2410/mach-smdk2410.c
  62. 7 9
      arch/arm/mach-s3c2410/mach-vr1000.c
  63. 9 0
      arch/arm/mach-s3c2412/Kconfig
  64. 1 6
      arch/arm/mach-s3c2412/mach-smdk2413.c
  65. 6 6
      arch/arm/mach-s3c2412/mach-vstms.c
  66. 9 8
      arch/arm/mach-s3c2440/mach-anubis.c
  67. 6 7
      arch/arm/mach-s3c2440/mach-nexcoder.c
  68. 8 8
      arch/arm/mach-s3c2440/mach-osiris.c
  69. 1 7
      arch/arm/mach-s3c2440/mach-rx3715.c
  70. 1 6
      arch/arm/mach-s3c2440/mach-smdk2440.c
  71. 1 6
      arch/arm/mach-s3c2443/mach-smdk2443.c
  72. 13 11
      arch/arm/mach-sa1100/clock.c
  73. 85 44
      arch/arm/mach-versatile/core.c
  74. 17 52
      arch/arm/oprofile/backtrace.c
  75. 139 1
      arch/arm/plat-iop/pci.c
  76. 4 4
      arch/arm/plat-iop/time.c
  77. 1 0
      arch/arm/plat-omap/Kconfig
  78. 50 0
      arch/arm/plat-omap/common.c
  79. 5 1
      arch/arm/plat-omap/devices.c
  80. 2 0
      arch/arm/plat-omap/dmtimer.c
  81. 544 68
      arch/arm/plat-omap/gpio.c
  82. 10 5
      arch/arm/plat-omap/mcbsp.c
  83. 39 100
      arch/arm/plat-omap/timer32k.c
  84. 12 0
      arch/arm/plat-s3c24xx/clock.c
  85. 0 38
      arch/arm/plat-s3c24xx/cpu.c
  86. 6 7
      arch/arm/plat-s3c24xx/dma.c
  87. 0 1
      arch/arm/vfp/vfpdouble.c
  88. 0 1
      arch/arm/vfp/vfpsingle.c
  89. 9 1
      drivers/ata/Kconfig
  90. 1 0
      drivers/ata/Makefile
  91. 686 0
      drivers/ata/pata_icside.c
  92. 10 8
      drivers/i2c/busses/i2c-pxa.c
  93. 2 2
      drivers/mmc/pxamci.c
  94. 6 6
      drivers/net/irda/pxaficp_ir.c
  95. 170 125
      drivers/serial/amba-pl010.c
  96. 7 2
      drivers/serial/atmel_serial.c
  97. 3 0
      drivers/serial/atmel_serial.h
  98. 205 63
      drivers/serial/imx.c
  99. 4 4
      drivers/serial/pxa.c
  100. 2 2
      drivers/usb/gadget/pxa2xx_udc.c

+ 1 - 1
Documentation/spi/pxa2xx

@@ -62,7 +62,7 @@ static struct resource pxa_spi_nssp_resources[] = {
 
 
 static struct pxa2xx_spi_master pxa_nssp_master_info = {
 static struct pxa2xx_spi_master pxa_nssp_master_info = {
 	.ssp_type = PXA25x_NSSP, /* Type of SSP */
 	.ssp_type = PXA25x_NSSP, /* Type of SSP */
-	.clock_enable = CKEN9_NSSP, /* NSSP Peripheral clock */
+	.clock_enable = CKEN_NSSP, /* NSSP Peripheral clock */
 	.num_chipselect = 1, /* Matches the number of chips attached to NSSP */
 	.num_chipselect = 1, /* Matches the number of chips attached to NSSP */
 	.enable_dma = 1, /* Enables NSSP DMA */
 	.enable_dma = 1, /* Enables NSSP DMA */
 };
 };

+ 20 - 0
arch/arm/Kconfig

@@ -29,6 +29,10 @@ config GENERIC_TIME
 	bool
 	bool
 	default n
 	default n
 
 
+config GENERIC_CLOCKEVENTS
+	bool
+	default n
+
 config MMU
 config MMU
 	bool
 	bool
 	default y
 	default y
@@ -67,6 +71,14 @@ config GENERIC_HARDIRQS
 	bool
 	bool
 	default y
 	default y
 
 
+config STACKTRACE_SUPPORT
+	bool
+	default y
+
+config LOCKDEP_SUPPORT
+	bool
+	default y
+
 config TRACE_IRQFLAGS_SUPPORT
 config TRACE_IRQFLAGS_SUPPORT
 	bool
 	bool
 	default y
 	default y
@@ -162,6 +174,8 @@ config ARCH_VERSATILE
 	select ARM_AMBA
 	select ARM_AMBA
 	select ARM_VIC
 	select ARM_VIC
 	select ICST307
 	select ICST307
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
 	help
 	help
 	  This enables support for ARM Ltd Versatile board.
 	  This enables support for ARM Ltd Versatile board.
 
 
@@ -262,6 +276,7 @@ config ARCH_IXP4XX
 	bool "IXP4xx-based"
 	bool "IXP4xx-based"
 	depends on MMU
 	depends on MMU
 	select GENERIC_TIME
 	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
 	help
 	help
 	  Support for Intel's IXP4XX (XScale) family of processors.
 	  Support for Intel's IXP4XX (XScale) family of processors.
 
 
@@ -363,6 +378,7 @@ config ARCH_LH7A40X
 config ARCH_OMAP
 config ARCH_OMAP
 	bool "TI OMAP"
 	bool "TI OMAP"
 	select GENERIC_GPIO
 	select GENERIC_GPIO
+	select GENERIC_TIME
 	help
 	help
 	  Support for TI's OMAP platform (OMAP1 and OMAP2).
 	  Support for TI's OMAP platform (OMAP1 and OMAP2).
 
 
@@ -513,6 +529,8 @@ endmenu
 
 
 menu "Kernel Features"
 menu "Kernel Features"
 
 
+source "kernel/time/Kconfig"
+
 config SMP
 config SMP
 	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
 	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && REALVIEW_MPCORE
 	depends on EXPERIMENTAL && REALVIEW_MPCORE
@@ -572,6 +590,7 @@ config PREEMPT
 
 
 config NO_IDLE_HZ
 config NO_IDLE_HZ
 	bool "Dynamic tick timer"
 	bool "Dynamic tick timer"
+	depends on !GENERIC_CLOCKEVENTS
 	help
 	help
 	  Select this option if you want to disable continuous timer ticks
 	  Select this option if you want to disable continuous timer ticks
 	  and have them programmed to occur as required. This option saves
 	  and have them programmed to occur as required. This option saves
@@ -669,6 +688,7 @@ config LEDS_TIMER
 	bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \
 	bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \
 			    MACH_OMAP_H2 || MACH_OMAP_PERSEUS2
 			    MACH_OMAP_H2 || MACH_OMAP_PERSEUS2
 	depends on LEDS
 	depends on LEDS
+	depends on !GENERIC_CLOCKEVENTS
 	default y if ARCH_EBSA110
 	default y if ARCH_EBSA110
 	help
 	help
 	  If you say Y here, one of the system LEDs (the green one on the
 	  If you say Y here, one of the system LEDs (the green one on the

+ 6 - 0
arch/arm/boot/compressed/head-at91rm9200.S

@@ -61,6 +61,12 @@
 		cmp	r7, r3
 		cmp	r7, r3
 		beq	99f
 		beq	99f
 
 
+		@ picotux 200 : 963
+		mov	r3,	#(MACH_TYPE_PICOTUX2XX & 0xff)
+		orr	r3, r3, #(MACH_TYPE_PICOTUX2XX & 0xff00)
+		cmp	r7, r3
+		beq	99f
+
 		@ Ajeco 1ARM : 1075
 		@ Ajeco 1ARM : 1075
 		mov	r3,	#(MACH_TYPE_ONEARM & 0xff)
 		mov	r3,	#(MACH_TYPE_ONEARM & 0xff)
 		orr	r3, r3, #(MACH_TYPE_ONEARM & 0xff00)
 		orr	r3, r3, #(MACH_TYPE_ONEARM & 0xff00)

+ 1386 - 0
arch/arm/configs/picotux200_defconfig

@@ -0,0 +1,1386 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc4
+# Wed Mar 28 16:19:50 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=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_ZONE_DMA=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=m
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
+# 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_CO285 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_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_NS9XXX 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_OMAP is not set
+
+#
+# Atmel AT91 System-on-Chip
+#
+CONFIG_ARCH_AT91RM9200=y
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+
+#
+# AT91RM9200 Board Type
+#
+# CONFIG_MACH_ONEARM is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+# CONFIG_MACH_AT91RM9200EK is not set
+# CONFIG_MACH_CSB337 is not set
+# CONFIG_MACH_CSB637 is not set
+# CONFIG_MACH_CARMEVA is not set
+# CONFIG_MACH_ATEB9200 is not set
+# CONFIG_MACH_KB9200 is not set
+CONFIG_MACH_PICOTUX2XX=y
+# CONFIG_MACH_KAFA is not set
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4T=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_CACHE_V4WT=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_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_PREEMPT is not set
+CONFIG_NO_IDLE_HZ=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=m
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# 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=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+# 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=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=y
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# 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
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# 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 is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# 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=y
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_AT91_ETHER=y
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# 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_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT91RM9200_WATCHDOG=m
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_AT91=m
+CONFIG_I2C_ISA=m
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_SENSORS_DS1337=m
+CONFIG_SENSORS_DS1374=m
+CONFIG_SENSORS_EEPROM=m
+CONFIG_SENSORS_PCF8574=m
+CONFIG_SENSORS_PCA9539=m
+CONFIG_SENSORS_PCF8591=m
+# CONFIG_SENSORS_MAX6875 is not set
+# 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
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=m
+CONFIG_HWMON_VID=m
+# CONFIG_SENSORS_ABITUGURU is not set
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1029=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+CONFIG_SENSORS_DS1621=m
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+CONFIG_SENSORS_SMSC47B397=m
+# CONFIG_SENSORS_VT1211 is not set
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83L785TS=m
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=m
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# 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
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# 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 is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_TOUCHSCREEN is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET_MII=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+CONFIG_USB_NET_DM9601=m
+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=m
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN 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_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_NAVMAN is not set
+CONFIG_USB_SERIAL_PL2303=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 is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD 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 is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_AT91=m
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_AT91RM9200=m
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_NTFS_RW is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# 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=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# 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
+# CONFIG_9P_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=y
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="utf-8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y

+ 2 - 2
arch/arm/kernel/Makefile

@@ -7,8 +7,8 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
 # Object file lists.
 # Object file lists.
 
 
 obj-y		:= compat.o entry-armv.o entry-common.o irq.o \
 obj-y		:= compat.o entry-armv.o entry-common.o irq.o \
-		   process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
-		   time.o traps.o
+		   process.o ptrace.o semaphore.o setup.o signal.o \
+		   sys_arm.o stacktrace.o time.o traps.o
 
 
 obj-$(CONFIG_ISA_DMA_API)	+= dma.o
 obj-$(CONFIG_ISA_DMA_API)	+= dma.o
 obj-$(CONFIG_ARCH_ACORN)	+= ecard.o 
 obj-$(CONFIG_ARCH_ACORN)	+= ecard.o 

+ 17 - 14
arch/arm/kernel/ecard.c

@@ -40,6 +40,7 @@
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
+#include <linux/kthread.h>
 
 
 #include <asm/dma.h>
 #include <asm/dma.h>
 #include <asm/ecard.h>
 #include <asm/ecard.h>
@@ -50,6 +51,8 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/tlbflush.h>
 #include <asm/tlbflush.h>
 
 
+#include "ecard.h"
+
 #ifndef CONFIG_ARCH_RPC
 #ifndef CONFIG_ARCH_RPC
 #define HAVE_EXPMASK
 #define HAVE_EXPMASK
 #endif
 #endif
@@ -123,7 +126,7 @@ static void ecard_task_reset(struct ecard_request *req)
 
 
 	res = ec->slot_no == 8
 	res = ec->slot_no == 8
 		? &ec->resource[ECARD_RES_MEMC]
 		? &ec->resource[ECARD_RES_MEMC]
-		: ec->type == ECARD_EASI
+		: ec->easi
 		  ? &ec->resource[ECARD_RES_EASI]
 		  ? &ec->resource[ECARD_RES_EASI]
 		  : &ec->resource[ECARD_RES_IOCSYNC];
 		  : &ec->resource[ECARD_RES_IOCSYNC];
 
 
@@ -178,7 +181,7 @@ static void ecard_task_readbytes(struct ecard_request *req)
 			index += 1;
 			index += 1;
 		}
 		}
 	} else {
 	} else {
-		unsigned long base = (ec->type == ECARD_EASI
+		unsigned long base = (ec->easi
 			 ? &ec->resource[ECARD_RES_EASI]
 			 ? &ec->resource[ECARD_RES_EASI]
 			 : &ec->resource[ECARD_RES_IOCSYNC])->start;
 			 : &ec->resource[ECARD_RES_IOCSYNC])->start;
 		void __iomem *pbase = (void __iomem *)base;
 		void __iomem *pbase = (void __iomem *)base;
@@ -263,8 +266,6 @@ static int ecard_init_mm(void)
 static int
 static int
 ecard_task(void * unused)
 ecard_task(void * unused)
 {
 {
-	daemonize("kecardd");
-
 	/*
 	/*
 	 * Allocate a mm.  We're not a lazy-TLB kernel task since we need
 	 * Allocate a mm.  We're not a lazy-TLB kernel task since we need
 	 * to set page table entries where the user space would be.  Note
 	 * to set page table entries where the user space would be.  Note
@@ -727,7 +728,7 @@ static int ecard_prints(char *buffer, ecard_t *ec)
 	char *start = buffer;
 	char *start = buffer;
 
 
 	buffer += sprintf(buffer, "  %d: %s ", ec->slot_no,
 	buffer += sprintf(buffer, "  %d: %s ", ec->slot_no,
-			  ec->type == ECARD_EASI ? "EASI" : "    ");
+			  ec->easi ? "EASI" : "    ");
 
 
 	if (ec->cid.id == 0) {
 	if (ec->cid.id == 0) {
 		struct in_chunk_dir incd;
 		struct in_chunk_dir incd;
@@ -814,7 +815,7 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot)
 	}
 	}
 
 
 	ec->slot_no = slot;
 	ec->slot_no = slot;
-	ec->type = type;
+	ec->easi = type == ECARD_EASI;
 	ec->irq = NO_IRQ;
 	ec->irq = NO_IRQ;
 	ec->fiq = NO_IRQ;
 	ec->fiq = NO_IRQ;
 	ec->dma = NO_DMA;
 	ec->dma = NO_DMA;
@@ -825,6 +826,7 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot)
 	ec->dev.bus = &ecard_bus_type;
 	ec->dev.bus = &ecard_bus_type;
 	ec->dev.dma_mask = &ec->dma_mask;
 	ec->dev.dma_mask = &ec->dma_mask;
 	ec->dma_mask = (u64)0xffffffff;
 	ec->dma_mask = (u64)0xffffffff;
+	ec->dev.coherent_dma_mask = ec->dma_mask;
 
 
 	if (slot < 4) {
 	if (slot < 4) {
 		ec_set_resource(ec, ECARD_RES_MEMC,
 		ec_set_resource(ec, ECARD_RES_MEMC,
@@ -907,7 +909,7 @@ static ssize_t ecard_show_device(struct device *dev, struct device_attribute *at
 static ssize_t ecard_show_type(struct device *dev, struct device_attribute *attr, char *buf)
 static ssize_t ecard_show_type(struct device *dev, struct device_attribute *attr, char *buf)
 {
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	struct expansion_card *ec = ECARD_DEV(dev);
-	return sprintf(buf, "%s\n", ec->type == ECARD_EASI ? "EASI" : "IOC");
+	return sprintf(buf, "%s\n", ec->easi ? "EASI" : "IOC");
 }
 }
 
 
 static struct device_attribute ecard_dev_attrs[] = {
 static struct device_attribute ecard_dev_attrs[] = {
@@ -1058,13 +1060,14 @@ ecard_probe(int slot, card_type_t type)
  */
  */
 static int __init ecard_init(void)
 static int __init ecard_init(void)
 {
 {
-	int slot, irqhw, ret;
-
-	ret = kernel_thread(ecard_task, NULL, CLONE_KERNEL);
-	if (ret < 0) {
-		printk(KERN_ERR "Ecard: unable to create kernel thread: %d\n",
-		       ret);
-		return ret;
+	struct task_struct *task;
+	int slot, irqhw;
+
+	task = kthread_run(ecard_task, NULL, "kecardd");
+	if (IS_ERR(task)) {
+		printk(KERN_ERR "Ecard: unable to create kernel thread: %ld\n",
+		       PTR_ERR(task));
+		return PTR_ERR(task);
 	}
 	}
 
 
 	printk("Probing expansion cards\n");
 	printk("Probing expansion cards\n");

+ 56 - 0
arch/arm/kernel/ecard.h

@@ -0,0 +1,56 @@
+/*
+ *  ecard.h
+ *
+ *  Copyright 2007 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.
+ */
+
+/* Definitions internal to ecard.c - for it's use only!!
+ *
+ * External expansion card header as read from the card
+ */
+struct ex_ecid {
+	unsigned char	r_irq:1;
+	unsigned char	r_zero:1;
+	unsigned char	r_fiq:1;
+	unsigned char	r_id:4;
+	unsigned char	r_a:1;
+
+	unsigned char	r_cd:1;
+	unsigned char	r_is:1;
+	unsigned char	r_w:2;
+	unsigned char	r_r1:4;
+
+	unsigned char	r_r2:8;
+
+	unsigned char	r_prod[2];
+
+	unsigned char	r_manu[2];
+
+	unsigned char	r_country;
+
+	unsigned char	r_fiqmask;
+	unsigned char	r_fiqoff[3];
+
+	unsigned char	r_irqmask;
+	unsigned char	r_irqoff[3];
+};
+
+/*
+ * Chunk directory entry as read from the card
+ */
+struct ex_chunk_dir {
+	unsigned char r_id;
+	unsigned char r_len[3];
+	unsigned long r_start;
+	union {
+		char string[256];
+		char data[1];
+	} d;
+#define c_id(x)		((x)->r_id)
+#define c_len(x)	((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16))
+#define c_start(x)	((x)->r_start)
+};

+ 5 - 1
arch/arm/kernel/head.S

@@ -257,7 +257,9 @@ __create_page_tables:
 	 * Map some ram to cover our .data and .bss areas.
 	 * Map some ram to cover our .data and .bss areas.
 	 */
 	 */
 	orr	r3, r7, #(KERNEL_RAM_PADDR & 0xff000000)
 	orr	r3, r7, #(KERNEL_RAM_PADDR & 0xff000000)
+	.if	(KERNEL_RAM_PADDR & 0x00f00000)
 	orr	r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000)
 	orr	r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000)
+	.endif
 	add	r0, r4,  #(KERNEL_RAM_VADDR & 0xff000000) >> 18
 	add	r0, r4,  #(KERNEL_RAM_VADDR & 0xff000000) >> 18
 	str	r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
 	str	r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
 	ldr	r6, =(_end - 1)
 	ldr	r6, =(_end - 1)
@@ -274,7 +276,9 @@ __create_page_tables:
 	 */
 	 */
 	add	r0, r4, #PAGE_OFFSET >> 18
 	add	r0, r4, #PAGE_OFFSET >> 18
 	orr	r6, r7, #(PHYS_OFFSET & 0xff000000)
 	orr	r6, r7, #(PHYS_OFFSET & 0xff000000)
-	orr	r6, r6, #(PHYS_OFFSET & 0x00e00000)
+	.if	(PHYS_OFFSET & 0x00f00000)
+	orr	r6, r6, #(PHYS_OFFSET & 0x00f00000)
+	.endif
 	str	r6, [r0]
 	str	r6, [r0]
 
 
 #ifdef CONFIG_DEBUG_LL
 #ifdef CONFIG_DEBUG_LL

+ 3 - 0
arch/arm/kernel/process.c

@@ -27,6 +27,7 @@
 #include <linux/cpu.h>
 #include <linux/cpu.h>
 #include <linux/elfcore.h>
 #include <linux/elfcore.h>
 #include <linux/pm.h>
 #include <linux/pm.h>
+#include <linux/tick.h>
 
 
 #include <asm/leds.h>
 #include <asm/leds.h>
 #include <asm/processor.h>
 #include <asm/processor.h>
@@ -159,9 +160,11 @@ void cpu_idle(void)
 		if (!idle)
 		if (!idle)
 			idle = default_idle;
 			idle = default_idle;
 		leds_event(led_idle_start);
 		leds_event(led_idle_start);
+		tick_nohz_stop_sched_tick();
 		while (!need_resched())
 		while (!need_resched())
 			idle();
 			idle();
 		leds_event(led_idle_end);
 		leds_event(led_idle_end);
+		tick_nohz_restart_sched_tick();
 		preempt_enable_no_resched();
 		preempt_enable_no_resched();
 		schedule();
 		schedule();
 		preempt_disable();
 		preempt_disable();

+ 3 - 3
arch/arm/kernel/ptrace.c

@@ -779,8 +779,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 			break;
 			break;
 
 
 		case PTRACE_SET_SYSCALL:
 		case PTRACE_SET_SYSCALL:
+			task_thread_info(child)->syscall = data;
 			ret = 0;
 			ret = 0;
-			child->ptrace_message = data;
 			break;
 			break;
 
 
 #ifdef CONFIG_CRUNCH
 #ifdef CONFIG_CRUNCH
@@ -817,7 +817,7 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
 	ip = regs->ARM_ip;
 	ip = regs->ARM_ip;
 	regs->ARM_ip = why;
 	regs->ARM_ip = why;
 
 
-	current->ptrace_message = scno;
+	current_thread_info()->syscall = scno;
 
 
 	/* the 0x80 provides a way for the tracing parent to distinguish
 	/* the 0x80 provides a way for the tracing parent to distinguish
 	   between a syscall stop and SIGTRAP delivery */
 	   between a syscall stop and SIGTRAP delivery */
@@ -834,5 +834,5 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
 	}
 	}
 	regs->ARM_ip = ip;
 	regs->ARM_ip = ip;
 
 
-	return current->ptrace_message;
+	return current_thread_info()->syscall;
 }
 }

+ 73 - 0
arch/arm/kernel/stacktrace.c

@@ -0,0 +1,73 @@
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+
+#include "stacktrace.h"
+
+int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high,
+		    int (*fn)(struct stackframe *, void *), void *data)
+{
+	struct stackframe *frame;
+
+	do {
+		/*
+		 * Check current frame pointer is within bounds
+		 */
+		if ((fp - 12) < low || fp + 4 >= high)
+			break;
+
+		frame = (struct stackframe *)(fp - 12);
+
+		if (fn(frame, data))
+			break;
+
+		/*
+		 * Update the low bound - the next frame must always
+		 * be at a higher address than the current frame.
+		 */
+		low = fp + 4;
+		fp = frame->fp;
+	} while (fp);
+
+	return 0;
+}
+
+#ifdef CONFIG_STACKTRACE
+struct stack_trace_data {
+	struct stack_trace *trace;
+	unsigned int skip;
+};
+
+static int save_trace(struct stackframe *frame, void *d)
+{
+	struct stack_trace_data *data = d;
+	struct stack_trace *trace = data->trace;
+
+	if (data->skip) {
+		data->skip--;
+		return 0;
+	}
+
+	trace->entries[trace->nr_entries++] = frame->lr;
+
+	return trace->nr_entries >= trace->max_entries;
+}
+
+void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
+{
+	struct stack_trace_data data;
+	unsigned long fp, base;
+
+	data.trace = trace;
+	data.skip = trace->skip;
+
+	if (task) {
+		base = (unsigned long)task_stack_page(task);
+		fp = 0; /* FIXME */
+	} else {
+		base = (unsigned long)task_stack_page(current);
+		asm("mov %0, fp" : "=r" (fp));
+	}
+
+	walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data);
+}
+#endif

+ 9 - 0
arch/arm/kernel/stacktrace.h

@@ -0,0 +1,9 @@
+struct stackframe {
+	unsigned long fp;
+	unsigned long sp;
+	unsigned long lr;
+	unsigned long pc;
+};
+
+int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high,
+		    int (*fn)(struct stackframe *, void *), void *data);

+ 3 - 1
arch/arm/kernel/time.c

@@ -327,6 +327,7 @@ void restore_time_delta(struct timespec *delta, struct timespec *rtc)
 }
 }
 EXPORT_SYMBOL(restore_time_delta);
 EXPORT_SYMBOL(restore_time_delta);
 
 
+#ifndef CONFIG_GENERIC_CLOCKEVENTS
 /*
 /*
  * Kernel system timer support.
  * Kernel system timer support.
  */
  */
@@ -340,8 +341,9 @@ void timer_tick(void)
 	update_process_times(user_mode(get_irq_regs()));
 	update_process_times(user_mode(get_irq_regs()));
 #endif
 #endif
 }
 }
+#endif
 
 
-#ifdef CONFIG_PM
+#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS)
 static int timer_suspend(struct sys_device *dev, pm_message_t state)
 static int timer_suspend(struct sys_device *dev, pm_message_t state)
 {
 {
 	struct sys_timer *timer = container_of(dev, struct sys_timer, dev);
 	struct sys_timer *timer = container_of(dev, struct sys_timer, dev);

+ 3 - 2
arch/arm/kernel/traps.c

@@ -286,6 +286,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
 	struct undef_hook *hook;
 	struct undef_hook *hook;
 	siginfo_t info;
 	siginfo_t info;
 	void __user *pc;
 	void __user *pc;
+	unsigned long flags;
 
 
 	/*
 	/*
 	 * According to the ARM ARM, PC is 2 or 4 bytes ahead,
 	 * According to the ARM ARM, PC is 2 or 4 bytes ahead,
@@ -304,7 +305,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
 		get_user(instr, (u32 __user *)pc);
 		get_user(instr, (u32 __user *)pc);
 	}
 	}
 
 
-	spin_lock_irq(&undef_lock);
+	spin_lock_irqsave(&undef_lock, flags);
 	list_for_each_entry(hook, &undef_hook, node) {
 	list_for_each_entry(hook, &undef_hook, node) {
 		if ((instr & hook->instr_mask) == hook->instr_val &&
 		if ((instr & hook->instr_mask) == hook->instr_val &&
 		    (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) {
 		    (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) {
@@ -314,7 +315,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
 			}
 			}
 		}
 		}
 	}
 	}
-	spin_unlock_irq(&undef_lock);
+	spin_unlock_irqrestore(&undef_lock, flags);
 
 
 #ifdef CONFIG_DEBUG_USER
 #ifdef CONFIG_DEBUG_USER
 	if (user_debug & UDBG_UNDEFINED) {
 	if (user_debug & UDBG_UNDEFINED) {

+ 7 - 0
arch/arm/mach-at91/Kconfig

@@ -81,6 +81,13 @@ config MACH_KB9200
 	  Select this if you are using KwikByte's KB920x board.
 	  Select this if you are using KwikByte's KB920x board.
 	  <http://kwikbyte.com/KB9202_description_new.htm>
 	  <http://kwikbyte.com/KB9202_description_new.htm>
 
 
+config MACH_PICOTUX2XX
+	bool "picotux 200"
+	depends on ARCH_AT91RM9200
+	help
+	  Select this if you are using a picotux 200.
+	  <http://www.picotux.com/>
+
 config MACH_KAFA
 config MACH_KAFA
 	bool "Sperry-Sun KAFA board"
 	bool "Sperry-Sun KAFA board"
 	depends on ARCH_AT91RM9200
 	depends on ARCH_AT91RM9200

+ 1 - 0
arch/arm/mach-at91/Makefile

@@ -25,6 +25,7 @@ obj-$(CONFIG_MACH_CARMEVA)	+= board-carmeva.o
 obj-$(CONFIG_MACH_KB9200)	+= board-kb9202.o
 obj-$(CONFIG_MACH_KB9200)	+= board-kb9202.o
 obj-$(CONFIG_MACH_ATEB9200)	+= board-eb9200.o
 obj-$(CONFIG_MACH_ATEB9200)	+= board-eb9200.o
 obj-$(CONFIG_MACH_KAFA)		+= board-kafa.o
 obj-$(CONFIG_MACH_KAFA)		+= board-kafa.o
+obj-$(CONFIG_MACH_PICOTUX2XX)	+= board-picotux200.o
 
 
 # AT91SAM9260 board-specific support
 # AT91SAM9260 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
 obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o

+ 18 - 1
arch/arm/mach-at91/at91rm9200.c

@@ -117,6 +117,21 @@ static struct clk pioD_clk = {
 	.pmc_mask	= 1 << AT91RM9200_ID_PIOD,
 	.pmc_mask	= 1 << AT91RM9200_ID_PIOD,
 	.type		= CLK_TYPE_PERIPHERAL,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
 };
+static struct clk ssc0_clk = {
+	.name		= "ssc0_clk",
+	.pmc_mask	= 1 << AT91RM9200_ID_SSC0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+	.name		= "ssc1_clk",
+	.pmc_mask	= 1 << AT91RM9200_ID_SSC1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc2_clk = {
+	.name		= "ssc2_clk",
+	.pmc_mask	= 1 << AT91RM9200_ID_SSC2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
 static struct clk tc0_clk = {
 static struct clk tc0_clk = {
 	.name		= "tc0_clk",
 	.name		= "tc0_clk",
 	.pmc_mask	= 1 << AT91RM9200_ID_TC0,
 	.pmc_mask	= 1 << AT91RM9200_ID_TC0,
@@ -161,7 +176,9 @@ static struct clk *periph_clocks[] __initdata = {
 	&udc_clk,
 	&udc_clk,
 	&twi_clk,
 	&twi_clk,
 	&spi_clk,
 	&spi_clk,
-	// ssc 0 .. ssc2
+	&ssc0_clk,
+	&ssc1_clk,
+	&ssc2_clk,
 	&tc0_clk,
 	&tc0_clk,
 	&tc1_clk,
 	&tc1_clk,
 	&tc2_clk,
 	&tc2_clk,

+ 6 - 1
arch/arm/mach-at91/at91sam9260.c

@@ -119,6 +119,11 @@ static struct clk spi1_clk = {
 	.pmc_mask	= 1 << AT91SAM9260_ID_SPI1,
 	.pmc_mask	= 1 << AT91SAM9260_ID_SPI1,
 	.type		= CLK_TYPE_PERIPHERAL,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
 };
+static struct clk ssc_clk = {
+	.name		= "ssc_clk",
+	.pmc_mask	= 1 << AT91SAM9260_ID_SSC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
 static struct clk tc0_clk = {
 static struct clk tc0_clk = {
 	.name		= "tc0_clk",
 	.name		= "tc0_clk",
 	.pmc_mask	= 1 << AT91SAM9260_ID_TC0,
 	.pmc_mask	= 1 << AT91SAM9260_ID_TC0,
@@ -193,7 +198,7 @@ static struct clk *periph_clocks[] __initdata = {
 	&twi_clk,
 	&twi_clk,
 	&spi0_clk,
 	&spi0_clk,
 	&spi1_clk,
 	&spi1_clk,
-	// ssc
+	&ssc_clk,
 	&tc0_clk,
 	&tc0_clk,
 	&tc1_clk,
 	&tc1_clk,
 	&tc2_clk,
 	&tc2_clk,

+ 18 - 1
arch/arm/mach-at91/at91sam9261.c

@@ -97,6 +97,21 @@ static struct clk spi1_clk = {
 	.pmc_mask	= 1 << AT91SAM9261_ID_SPI1,
 	.pmc_mask	= 1 << AT91SAM9261_ID_SPI1,
 	.type		= CLK_TYPE_PERIPHERAL,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
 };
+static struct clk ssc0_clk = {
+	.name		= "ssc0_clk",
+	.pmc_mask	= 1 << AT91SAM9261_ID_SSC0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+	.name		= "ssc1_clk",
+	.pmc_mask	= 1 << AT91SAM9261_ID_SSC1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc2_clk = {
+	.name		= "ssc2_clk",
+	.pmc_mask	= 1 << AT91SAM9261_ID_SSC2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
 static struct clk tc0_clk = {
 static struct clk tc0_clk = {
 	.name		= "tc0_clk",
 	.name		= "tc0_clk",
 	.pmc_mask	= 1 << AT91SAM9261_ID_TC0,
 	.pmc_mask	= 1 << AT91SAM9261_ID_TC0,
@@ -135,7 +150,9 @@ static struct clk *periph_clocks[] __initdata = {
 	&twi_clk,
 	&twi_clk,
 	&spi0_clk,
 	&spi0_clk,
 	&spi1_clk,
 	&spi1_clk,
-	// ssc 0 .. ssc2
+	&ssc0_clk,
+	&ssc1_clk,
+	&ssc2_clk,
 	&tc0_clk,
 	&tc0_clk,
 	&tc1_clk,
 	&tc1_clk,
 	&tc2_clk,
 	&tc2_clk,

+ 5 - 5
arch/arm/mach-at91/at91sam9261_devices.c

@@ -430,9 +430,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
  *  LCD Controller
  *  LCD Controller
  * -------------------------------------------------------------------- */
  * -------------------------------------------------------------------- */
 
 
-#if defined(CONFIG_FB_AT91) || defined(CONFIG_FB_AT91_MODULE)
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
 static u64 lcdc_dmamask = 0xffffffffUL;
 static u64 lcdc_dmamask = 0xffffffffUL;
-static struct at91fb_info lcdc_data;
+static struct atmel_lcdfb_info lcdc_data;
 
 
 static struct resource lcdc_resources[] = {
 static struct resource lcdc_resources[] = {
 	[0] = {
 	[0] = {
@@ -455,7 +455,7 @@ static struct resource lcdc_resources[] = {
 };
 };
 
 
 static struct platform_device at91_lcdc_device = {
 static struct platform_device at91_lcdc_device = {
-	.name		= "at91-fb",
+	.name		= "atmel_lcdfb",
 	.id		= 0,
 	.id		= 0,
 	.dev		= {
 	.dev		= {
 				.dma_mask		= &lcdc_dmamask,
 				.dma_mask		= &lcdc_dmamask,
@@ -466,7 +466,7 @@ static struct platform_device at91_lcdc_device = {
 	.num_resources	= ARRAY_SIZE(lcdc_resources),
 	.num_resources	= ARRAY_SIZE(lcdc_resources),
 };
 };
 
 
-void __init at91_add_device_lcdc(struct at91fb_info *data)
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
 {
 {
 	if (!data) {
 	if (!data) {
 		return;
 		return;
@@ -499,7 +499,7 @@ void __init at91_add_device_lcdc(struct at91fb_info *data)
 	platform_device_register(&at91_lcdc_device);
 	platform_device_register(&at91_lcdc_device);
 }
 }
 #else
 #else
-void __init at91_add_device_lcdc(struct at91fb_info *data) {}
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
 #endif
 #endif
 
 
 
 

+ 42 - 6
arch/arm/mach-at91/at91sam9263.c

@@ -87,6 +87,11 @@ static struct clk mmc1_clk = {
 	.pmc_mask	= 1 << AT91SAM9263_ID_MCI1,
 	.pmc_mask	= 1 << AT91SAM9263_ID_MCI1,
 	.type		= CLK_TYPE_PERIPHERAL,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
 };
+static struct clk can_clk = {
+	.name		= "can_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_CAN,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
 static struct clk twi_clk = {
 static struct clk twi_clk = {
 	.name		= "twi_clk",
 	.name		= "twi_clk",
 	.pmc_mask	= 1 << AT91SAM9263_ID_TWI,
 	.pmc_mask	= 1 << AT91SAM9263_ID_TWI,
@@ -102,16 +107,46 @@ static struct clk spi1_clk = {
 	.pmc_mask	= 1 << AT91SAM9263_ID_SPI1,
 	.pmc_mask	= 1 << AT91SAM9263_ID_SPI1,
 	.type		= CLK_TYPE_PERIPHERAL,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
 };
+static struct clk ssc0_clk = {
+	.name		= "ssc0_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_SSC0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+	.name		= "ssc1_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_SSC1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ac97_clk = {
+	.name		= "ac97_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_AC97C,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
 static struct clk tcb_clk = {
 static struct clk tcb_clk = {
 	.name		= "tcb_clk",
 	.name		= "tcb_clk",
 	.pmc_mask	= 1 << AT91SAM9263_ID_TCB,
 	.pmc_mask	= 1 << AT91SAM9263_ID_TCB,
 	.type		= CLK_TYPE_PERIPHERAL,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
 };
+static struct clk pwmc_clk = {
+	.name		= "pwmc_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_PWMC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
 static struct clk macb_clk = {
 static struct clk macb_clk = {
 	.name		= "macb_clk",
 	.name		= "macb_clk",
 	.pmc_mask	= 1 << AT91SAM9263_ID_EMAC,
 	.pmc_mask	= 1 << AT91SAM9263_ID_EMAC,
 	.type		= CLK_TYPE_PERIPHERAL,
 	.type		= CLK_TYPE_PERIPHERAL,
 };
 };
+static struct clk dma_clk = {
+	.name		= "dma_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_DMA,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk twodge_clk = {
+	.name		= "2dge_clk",
+	.pmc_mask	= 1 << AT91SAM9263_ID_2DGE,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
 static struct clk udc_clk = {
 static struct clk udc_clk = {
 	.name		= "udc_clk",
 	.name		= "udc_clk",
 	.pmc_mask	= 1 << AT91SAM9263_ID_UDP,
 	.pmc_mask	= 1 << AT91SAM9263_ID_UDP,
@@ -142,20 +177,21 @@ static struct clk *periph_clocks[] __initdata = {
 	&usart2_clk,
 	&usart2_clk,
 	&mmc0_clk,
 	&mmc0_clk,
 	&mmc1_clk,
 	&mmc1_clk,
-	// can
+	&can_clk,
 	&twi_clk,
 	&twi_clk,
 	&spi0_clk,
 	&spi0_clk,
 	&spi1_clk,
 	&spi1_clk,
-	// ssc0 .. ssc1
-	// ac97
+	&ssc0_clk,
+	&ssc1_clk,
+	&ac97_clk,
 	&tcb_clk,
 	&tcb_clk,
-	// pwmc
+	&pwmc_clk,
 	&macb_clk,
 	&macb_clk,
-	// 2dge
+	&twodge_clk,
 	&udc_clk,
 	&udc_clk,
 	&isi_clk,
 	&isi_clk,
 	&lcdc_clk,
 	&lcdc_clk,
-	// dma
+	&dma_clk,
 	&ohci_clk,
 	&ohci_clk,
 	// irq0 .. irq1
 	// irq0 .. irq1
 };
 };

+ 124 - 0
arch/arm/mach-at91/at91sam9263_devices.c

@@ -572,6 +572,130 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
 #endif
 #endif
 
 
 
 
+/* --------------------------------------------------------------------
+ *  AC97
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE)
+static u64 ac97_dmamask = 0xffffffffUL;
+static struct atmel_ac97_data ac97_data;
+
+static struct resource ac97_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_BASE_AC97C,
+		.end	= AT91SAM9263_BASE_AC97C + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_AC97C,
+		.end	= AT91SAM9263_ID_AC97C,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9263_ac97_device = {
+	.name		= "ac97c",
+	.id		= 1,
+	.dev		= {
+				.dma_mask		= &ac97_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+				.platform_data		= &ac97_data,
+	},
+	.resource	= ac97_resources,
+	.num_resources	= ARRAY_SIZE(ac97_resources),
+};
+
+void __init at91_add_device_ac97(struct atmel_ac97_data *data)
+{
+	if (!data)
+		return;
+
+	at91_set_A_periph(AT91_PIN_PB0, 0);	/* AC97FS */
+	at91_set_A_periph(AT91_PIN_PB1, 0);	/* AC97CK */
+	at91_set_A_periph(AT91_PIN_PB2, 0);	/* AC97TX */
+	at91_set_A_periph(AT91_PIN_PB3, 0);	/* AC97RX */
+
+	/* reset */
+	if (data->reset_pin)
+		at91_set_gpio_output(data->reset_pin, 0);
+
+	ac97_data = *ek_data;
+	platform_device_register(&at91sam9263_ac97_device);
+}
+#else
+void __init at91_add_device_ac97(struct atmel_ac97_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  LCD Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static u64 lcdc_dmamask = 0xffffffffUL;
+static struct atmel_lcdfb_info lcdc_data;
+
+static struct resource lcdc_resources[] = {
+	[0] = {
+		.start	= AT91SAM9263_LCDC_BASE,
+		.end	= AT91SAM9263_LCDC_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9263_ID_LCDC,
+		.end	= AT91SAM9263_ID_LCDC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91_lcdc_device = {
+	.name		= "atmel_lcdfb",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &lcdc_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+				.platform_data		= &lcdc_data,
+	},
+	.resource	= lcdc_resources,
+	.num_resources	= ARRAY_SIZE(lcdc_resources),
+};
+
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
+{
+	if (!data)
+		return;
+
+	at91_set_A_periph(AT91_PIN_PC1, 0);	/* LCDHSYNC */
+	at91_set_A_periph(AT91_PIN_PC2, 0);	/* LCDDOTCK */
+	at91_set_A_periph(AT91_PIN_PC3, 0);	/* LCDDEN */
+	at91_set_B_periph(AT91_PIN_PB9, 0);	/* LCDCC */
+	at91_set_A_periph(AT91_PIN_PC6, 0);	/* LCDD2 */
+	at91_set_A_periph(AT91_PIN_PC7, 0);	/* LCDD3 */
+	at91_set_A_periph(AT91_PIN_PC8, 0);	/* LCDD4 */
+	at91_set_A_periph(AT91_PIN_PC9, 0);	/* LCDD5 */
+	at91_set_A_periph(AT91_PIN_PC10, 0);	/* LCDD6 */
+	at91_set_A_periph(AT91_PIN_PC11, 0);	/* LCDD7 */
+	at91_set_A_periph(AT91_PIN_PC14, 0);	/* LCDD10 */
+	at91_set_A_periph(AT91_PIN_PC15, 0);	/* LCDD11 */
+	at91_set_A_periph(AT91_PIN_PC16, 0);	/* LCDD12 */
+	at91_set_B_periph(AT91_PIN_PC12, 0);	/* LCDD13 */
+	at91_set_A_periph(AT91_PIN_PC18, 0);	/* LCDD14 */
+	at91_set_A_periph(AT91_PIN_PC19, 0);	/* LCDD15 */
+	at91_set_A_periph(AT91_PIN_PC22, 0);	/* LCDD18 */
+	at91_set_A_periph(AT91_PIN_PC23, 0);	/* LCDD19 */
+	at91_set_A_periph(AT91_PIN_PC24, 0);	/* LCDD20 */
+	at91_set_B_periph(AT91_PIN_PC17, 0);	/* LCDD21 */
+	at91_set_A_periph(AT91_PIN_PC26, 0);	/* LCDD22 */
+	at91_set_A_periph(AT91_PIN_PC27, 0);	/* LCDD23 */
+
+	lcdc_data = *data;
+	platform_device_register(&at91_lcdc_device);
+}
+#else
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
+#endif
+
+
 /* --------------------------------------------------------------------
 /* --------------------------------------------------------------------
  *  LEDs
  *  LEDs
  * -------------------------------------------------------------------- */
  * -------------------------------------------------------------------- */

+ 166 - 0
arch/arm/mach-at91/board-picotux200.c

@@ -0,0 +1,166 @@
+/*
+ * linux/arch/arm/mach-at91/board-picotux200.c
+ *
+ *  Copyright (C) 2005 SAN People
+ *  Copyright (C) 2007 Kleinhenz Elektronik GmbH
+ *
+ * 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/mtd/physmap.h>
+
+#include <asm/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 <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/at91rm9200_mc.h>
+
+#include "generic.h"
+
+
+/*
+ * Serial port configuration.
+ *    0 .. 3 = USART0 .. USART3
+ *    4      = DBGU
+ */
+static struct at91_uart_config __initdata picotux200_uart_config = {
+	.console_tty	= 0,				/* ttyS0 */
+	.nr_tty		= 2,
+	.tty_map	= { 4, 1, -1, -1, -1 }		/* ttyS0, ..., ttyS4 */
+};
+
+static void __init picotux200_map_io(void)
+{
+	/* Initialize processor: 18.432 MHz crystal */
+	at91rm9200_initialize(18432000, AT91RM9200_BGA);
+
+	/* Setup the serial ports and console */
+	at91_init_serial(&picotux200_uart_config);
+}
+
+static void __init picotux200_init_irq(void)
+{
+	at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata picotux200_eth_data = {
+	.phy_irq_pin	= AT91_PIN_PC4,
+	.is_rmii	= 1,
+};
+
+static struct at91_usbh_data __initdata picotux200_usbh_data = {
+	.ports		= 1,
+};
+
+// static struct at91_udc_data __initdata picotux200_udc_data = {
+// 	.vbus_pin	= AT91_PIN_PD4,
+// 	.pullup_pin	= AT91_PIN_PD5,
+// };
+
+static struct at91_mmc_data __initdata picotux200_mmc_data = {
+	.det_pin	= AT91_PIN_PB27,
+	.slot_b		= 0,
+	.wire4		= 1,
+	.wp_pin		= AT91_PIN_PA17,
+};
+
+// static struct spi_board_info picotux200_spi_devices[] = {
+// 	{	/* DataFlash chip */
+// 		.modalias	= "mtd_dataflash",
+// 		.chip_select	= 0,
+// 		.max_speed_hz	= 15 * 1000 * 1000,
+// 	},
+// #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+// 	{	/* DataFlash card */
+// 		.modalias	= "mtd_dataflash",
+// 		.chip_select	= 3,
+// 		.max_speed_hz	= 15 * 1000 * 1000,
+// 	},
+// #endif
+// };
+
+#define PICOTUX200_FLASH_BASE	AT91_CHIPSELECT_0
+#define PICOTUX200_FLASH_SIZE	0x400000
+
+static struct physmap_flash_data picotux200_flash_data = {
+	.width	= 2,
+};
+
+static struct resource picotux200_flash_resource = {
+	.start		= PICOTUX200_FLASH_BASE,
+	.end		= PICOTUX200_FLASH_BASE + PICOTUX200_FLASH_SIZE - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device picotux200_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+				.platform_data	= &picotux200_flash_data,
+			},
+	.resource	= &picotux200_flash_resource,
+	.num_resources	= 1,
+};
+
+static void __init picotux200_board_init(void)
+{
+	/* Serial */
+	at91_add_device_serial();
+	/* Ethernet */
+	at91_add_device_eth(&picotux200_eth_data);
+	/* USB Host */
+	at91_add_device_usbh(&picotux200_usbh_data);
+	/* USB Device */
+	// at91_add_device_udc(&picotux200_udc_data);
+	// at91_set_multi_drive(picotux200_udc_data.pullup_pin, 1);	/* pullup_pin is connected to reset */
+	/* I2C */
+	at91_add_device_i2c();
+	/* SPI */
+	// at91_add_device_spi(picotux200_spi_devices, ARRAY_SIZE(picotux200_spi_devices));
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+	/* DataFlash card */
+	at91_set_gpio_output(AT91_PIN_PB22, 0);
+#else
+	/* MMC */
+	at91_set_gpio_output(AT91_PIN_PB22, 1);	/* this MMC card slot can optionally use SPI signaling (CS3). */
+	at91_add_device_mmc(0, &picotux200_mmc_data);
+#endif
+	/* NOR Flash */
+	platform_device_register(&picotux200_flash);
+}
+
+MACHINE_START(PICOTUX2XX, "picotux 200")
+	/* Maintainer: Kleinhenz Elektronik GmbH */
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91rm9200_timer,
+	.map_io		= picotux200_map_io,
+	.init_irq	= picotux200_init_irq,
+	.init_machine	= picotux200_board_init,
+MACHINE_END

+ 6 - 4
arch/arm/mach-at91/board-sam9260ek.c

@@ -104,9 +104,9 @@ static struct spi_board_info ek_spi_devices[] = {
 	},
 	},
 #endif
 #endif
 #endif
 #endif
-#if defined(CONFIG_SND_AT73C213)
+#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
 	{	/* AT73C213 DAC */
 	{	/* AT73C213 DAC */
-		.modalias	= "snd_at73c213",
+		.modalias	= "at73c213",
 		.chip_select	= 0,
 		.chip_select	= 0,
 		.max_speed_hz	= 10 * 1000 * 1000,
 		.max_speed_hz	= 10 * 1000 * 1000,
 		.bus_num	= 1,
 		.bus_num	= 1,
@@ -118,7 +118,7 @@ static struct spi_board_info ek_spi_devices[] = {
 /*
 /*
  * MACB Ethernet device
  * MACB Ethernet device
  */
  */
-static struct __initdata at91_eth_data ek_macb_data = {
+static struct at91_eth_data __initdata ek_macb_data = {
 	.phy_irq_pin	= AT91_PIN_PA7,
 	.phy_irq_pin	= AT91_PIN_PA7,
 	.is_rmii	= 1,
 	.is_rmii	= 1,
 };
 };
@@ -140,7 +140,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
 	},
 	},
 };
 };
 
 
-static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
 {
 {
 	*num_partitions = ARRAY_SIZE(ek_nand_partition);
 	*num_partitions = ARRAY_SIZE(ek_nand_partition);
 	return ek_nand_partition;
 	return ek_nand_partition;
@@ -188,6 +188,8 @@ static void __init ek_board_init(void)
 	at91_add_device_eth(&ek_macb_data);
 	at91_add_device_eth(&ek_macb_data);
 	/* MMC */
 	/* MMC */
 	at91_add_device_mmc(0, &ek_mmc_data);
 	at91_add_device_mmc(0, &ek_mmc_data);
+	/* I2C */
+	at91_add_device_i2c();
 }
 }
 
 
 MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
 MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")

+ 50 - 2
arch/arm/mach-at91/board-sam9261ek.c

@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
 #include <linux/dm9000.h>
 #include <linux/dm9000.h>
 
 
 #include <asm/hardware.h>
 #include <asm/hardware.h>
@@ -194,6 +195,41 @@ static struct at91_nand_data __initdata ek_nand_data = {
 #endif
 #endif
 };
 };
 
 
+/*
+ * ADS7846 Touchscreen
+ */
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+
+static int ads7843_pendown_state(void)
+{
+	return !at91_get_gpio_value(AT91_PIN_PC2);	/* Touchscreen PENIRQ */
+}
+
+static struct ads7846_platform_data ads_info = {
+	.model			= 7843,
+	.x_min			= 150,
+	.x_max			= 3830,
+	.y_min			= 190,
+	.y_max			= 3830,
+	.vref_delay_usecs	= 100,
+	.x_plate_ohms		= 450,
+	.y_plate_ohms		= 250,
+	.pressure_max		= 15000,
+	.debounce_max		= 1,
+	.debounce_rep		= 0,
+	.debounce_tol		= (~0),
+	.get_pendown_state	= ads7843_pendown_state,
+};
+
+static void __init ek_add_device_ts(void)
+{
+	at91_set_B_periph(AT91_PIN_PC2, 1);	/* External IRQ0, with pullup */
+	at91_set_gpio_input(AT91_PIN_PA11, 1);	/* Touchscreen BUSY signal */
+}
+#else
+static void __init ek_add_device_ts(void) {}
+#endif
+
 /*
 /*
  * SPI devices
  * SPI devices
  */
  */
@@ -204,6 +240,16 @@ static struct spi_board_info ek_spi_devices[] = {
 		.max_speed_hz	= 15 * 1000 * 1000,
 		.max_speed_hz	= 15 * 1000 * 1000,
 		.bus_num	= 0,
 		.bus_num	= 0,
 	},
 	},
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+	{
+		.modalias	= "ads7846",
+		.chip_select	= 2,
+		.max_speed_hz	= 125000 * 26,	/* (max sample rate @ 3V) * (cmd + data + overhead) */
+		.bus_num	= 0,
+		.platform_data	= &ads_info,
+		.irq		= AT91SAM9261_ID_IRQ0,
+	},
+#endif
 #if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
 #if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
 	{	/* DataFlash card - jumper (J12) configurable to CS3 or CS0 */
 	{	/* DataFlash card - jumper (J12) configurable to CS3 or CS0 */
 		.modalias	= "mtd_dataflash",
 		.modalias	= "mtd_dataflash",
@@ -211,9 +257,9 @@ static struct spi_board_info ek_spi_devices[] = {
 		.max_speed_hz	= 15 * 1000 * 1000,
 		.max_speed_hz	= 15 * 1000 * 1000,
 		.bus_num	= 0,
 		.bus_num	= 0,
 	},
 	},
-#elif defined(CONFIG_SND_AT73C213)
+#elif defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
 	{	/* AT73C213 DAC */
 	{	/* AT73C213 DAC */
-		.modalias	= "snd_at73c213",
+		.modalias	= "at73c213",
 		.chip_select	= 3,
 		.chip_select	= 3,
 		.max_speed_hz	= 10 * 1000 * 1000,
 		.max_speed_hz	= 10 * 1000 * 1000,
 		.bus_num	= 0,
 		.bus_num	= 0,
@@ -241,6 +287,8 @@ static void __init ek_board_init(void)
 #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
 #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
 	/* SPI */
 	/* SPI */
 	at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
 	at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+	/* Touchscreen */
+	ek_add_device_ts();
 #else
 #else
 	/* MMC */
 	/* MMC */
 	at91_add_device_mmc(0, &ek_mmc_data);
 	at91_add_device_mmc(0, &ek_mmc_data);

+ 70 - 0
arch/arm/mach-at91/board-sam9263ek.c

@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
 
 
 #include <asm/hardware.h>
 #include <asm/hardware.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
@@ -85,6 +86,40 @@ static struct at91_udc_data __initdata ek_udc_data = {
 };
 };
 
 
 
 
+/*
+ * ADS7846 Touchscreen
+ */
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+static int ads7843_pendown_state(void)
+{
+	return !at91_get_gpio_value(AT91_PIN_PA15);	/* Touchscreen PENIRQ */
+}
+
+static struct ads7846_platform_data ads_info = {
+	.model			= 7843,
+	.x_min			= 150,
+	.x_max			= 3830,
+	.y_min			= 190,
+	.y_max			= 3830,
+	.vref_delay_usecs	= 100,
+	.x_plate_ohms		= 450,
+	.y_plate_ohms		= 250,
+	.pressure_max		= 15000,
+	.debounce_max		= 1,
+	.debounce_rep		= 0,
+	.debounce_tol		= (~0),
+	.get_pendown_state	= ads7843_pendown_state,
+};
+
+static void __init ek_add_device_ts(void)
+{
+	at91_set_B_periph(AT91_PIN_PA15, 1);	/* External IRQ1, with pullup */
+	at91_set_gpio_input(AT91_PIN_PA31, 1);	/* Touchscreen BUSY signal */
+}
+#else
+static void __init ek_add_device_ts(void) {}
+#endif
+
 /*
 /*
  * SPI devices.
  * SPI devices.
  */
  */
@@ -97,6 +132,16 @@ static struct spi_board_info ek_spi_devices[] = {
 		.bus_num	= 0,
 		.bus_num	= 0,
 	},
 	},
 #endif
 #endif
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+	{
+		.modalias	= "ads7846",
+		.chip_select	= 3,
+		.max_speed_hz	= 125000 * 26,	/* (max sample rate @ 3V) * (cmd + data + overhead) */
+		.bus_num	= 0,
+		.platform_data	= &ads_info,
+		.irq		= AT91SAM9263_ID_IRQ1,
+	},
+#endif
 };
 };
 
 
 
 
@@ -111,6 +156,14 @@ static struct at91_mmc_data __initdata ek_mmc_data = {
 };
 };
 
 
 
 
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+	.is_rmii	= 1,
+};
+
+
 /*
 /*
  * NAND flash
  * NAND flash
  */
  */
@@ -148,6 +201,14 @@ static struct at91_nand_data __initdata ek_nand_data = {
 };
 };
 
 
 
 
+/*
+ * AC97
+ */
+static struct atmel_ac97_data ek_ac97_data = {
+	.reset_pin	= AT91_PIN_PA13,
+};
+
+
 static void __init ek_board_init(void)
 static void __init ek_board_init(void)
 {
 {
 	/* Serial */
 	/* Serial */
@@ -157,11 +218,20 @@ static void __init ek_board_init(void)
 	/* USB Device */
 	/* USB Device */
 	at91_add_device_udc(&ek_udc_data);
 	at91_add_device_udc(&ek_udc_data);
 	/* SPI */
 	/* SPI */
+	at91_set_gpio_output(AT91_PIN_PE20, 1);		/* select spi0 clock */
 	at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
 	at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+	/* Touchscreen */
+	ek_add_device_ts();
 	/* MMC */
 	/* MMC */
 	at91_add_device_mmc(1, &ek_mmc_data);
 	at91_add_device_mmc(1, &ek_mmc_data);
+	/* Ethernet */
+	at91_add_device_eth(&ek_macb_data);
 	/* NAND */
 	/* NAND */
 	at91_add_device_nand(&ek_nand_data);
 	at91_add_device_nand(&ek_nand_data);
+	/* I2C */
+	at91_add_device_i2c();
+	/* AC97 */
+	at91_add_device_ac97(&ek_ac97_data);
 }
 }
 
 
 MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
 MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")

+ 5 - 0
arch/arm/mach-ep93xx/clock.c

@@ -27,6 +27,10 @@ struct clk {
 	u32		enable_mask;
 	u32		enable_mask;
 };
 };
 
 
+static struct clk clk_uart = {
+	.name		= "UARTCLK",
+	.rate		= 14745600,
+};
 static struct clk clk_pll1 = {
 static struct clk clk_pll1 = {
 	.name		= "pll1",
 	.name		= "pll1",
 };
 };
@@ -50,6 +54,7 @@ static struct clk clk_usb_host = {
 
 
 
 
 static struct clk *clocks[] = {
 static struct clk *clocks[] = {
+	&clk_uart,
 	&clk_pll1,
 	&clk_pll1,
 	&clk_f,
 	&clk_f,
 	&clk_h,
 	&clk_h,

+ 1 - 0
arch/arm/mach-iop13xx/Makefile

@@ -7,5 +7,6 @@ obj-$(CONFIG_ARCH_IOP13XX) += setup.o
 obj-$(CONFIG_ARCH_IOP13XX) += irq.o
 obj-$(CONFIG_ARCH_IOP13XX) += irq.o
 obj-$(CONFIG_ARCH_IOP13XX) += pci.o
 obj-$(CONFIG_ARCH_IOP13XX) += pci.o
 obj-$(CONFIG_ARCH_IOP13XX) += io.o
 obj-$(CONFIG_ARCH_IOP13XX) += io.o
+obj-$(CONFIG_ARCH_IOP13XX) += tpmi.o
 obj-$(CONFIG_MACH_IQ81340SC) += iq81340sc.o
 obj-$(CONFIG_MACH_IQ81340SC) += iq81340sc.o
 obj-$(CONFIG_MACH_IQ81340MC) += iq81340mc.o
 obj-$(CONFIG_MACH_IQ81340MC) += iq81340mc.o

+ 4 - 1
arch/arm/mach-iop13xx/iq81340mc.c

@@ -75,11 +75,14 @@ static void __init iq81340mc_init(void)
 {
 {
 	iop13xx_platform_init();
 	iop13xx_platform_init();
 	iq81340mc_pci_init();
 	iq81340mc_pci_init();
+	iop13xx_add_tpmi_devices();
 }
 }
 
 
 static void __init iq81340mc_timer_init(void)
 static void __init iq81340mc_timer_init(void)
 {
 {
-	iop_init_time(400000000);
+	unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio();
+	printk(KERN_DEBUG "%s: bus frequency: %lu\n", __FUNCTION__, bus_freq);
+	iop_init_time(bus_freq);
 }
 }
 
 
 static struct sys_timer iq81340mc_timer = {
 static struct sys_timer iq81340mc_timer = {

+ 4 - 1
arch/arm/mach-iop13xx/iq81340sc.c

@@ -77,11 +77,14 @@ static void __init iq81340sc_init(void)
 {
 {
 	iop13xx_platform_init();
 	iop13xx_platform_init();
 	iq81340sc_pci_init();
 	iq81340sc_pci_init();
+	iop13xx_add_tpmi_devices();
 }
 }
 
 
 static void __init iq81340sc_timer_init(void)
 static void __init iq81340sc_timer_init(void)
 {
 {
-	iop_init_time(400000000);
+	unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio();
+	printk(KERN_DEBUG "%s: bus frequency: %lu\n", __FUNCTION__, bus_freq);
+	iop_init_time(bus_freq);
 }
 }
 
 
 static struct sys_timer iq81340sc_timer = {
 static struct sys_timer iq81340sc_timer = {

+ 4 - 4
arch/arm/mach-iop13xx/pci.c

@@ -1023,7 +1023,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
 				  << IOP13XX_ATUX_PCIXSR_FUNC_NUM;
 				  << IOP13XX_ATUX_PCIXSR_FUNC_NUM;
 		__raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR);
 		__raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR);
 
 
-		res[0].start = IOP13XX_PCIX_LOWER_IO_PA;
+		res[0].start = IOP13XX_PCIX_LOWER_IO_PA + IOP13XX_PCIX_IO_BUS_OFFSET;
 		res[0].end   = IOP13XX_PCIX_UPPER_IO_PA;
 		res[0].end   = IOP13XX_PCIX_UPPER_IO_PA;
 		res[0].name  = "IQ81340 ATUX PCI I/O Space";
 		res[0].name  = "IQ81340 ATUX PCI I/O Space";
 		res[0].flags = IORESOURCE_IO;
 		res[0].flags = IORESOURCE_IO;
@@ -1033,7 +1033,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
 		res[1].name  = "IQ81340 ATUX PCI Memory Space";
 		res[1].name  = "IQ81340 ATUX PCI Memory Space";
 		res[1].flags = IORESOURCE_MEM;
 		res[1].flags = IORESOURCE_MEM;
 		sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET;
 		sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET;
-		sys->io_offset = IOP13XX_PCIX_IO_OFFSET;
+		sys->io_offset = IOP13XX_PCIX_LOWER_IO_PA;
 		break;
 		break;
 	case IOP13XX_INIT_ATU_ATUE:
 	case IOP13XX_INIT_ATU_ATUE:
 		/* Note: the function number field in the PCSR is ro */
 		/* Note: the function number field in the PCSR is ro */
@@ -1044,7 +1044,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
 
 
 		__raw_writel(pcsr, IOP13XX_ATUE_PCSR);
 		__raw_writel(pcsr, IOP13XX_ATUE_PCSR);
 
 
-		res[0].start = IOP13XX_PCIE_LOWER_IO_PA;
+		res[0].start = IOP13XX_PCIE_LOWER_IO_PA + IOP13XX_PCIE_IO_BUS_OFFSET;
 		res[0].end   = IOP13XX_PCIE_UPPER_IO_PA;
 		res[0].end   = IOP13XX_PCIE_UPPER_IO_PA;
 		res[0].name  = "IQ81340 ATUE PCI I/O Space";
 		res[0].name  = "IQ81340 ATUE PCI I/O Space";
 		res[0].flags = IORESOURCE_IO;
 		res[0].flags = IORESOURCE_IO;
@@ -1054,7 +1054,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
 		res[1].name  = "IQ81340 ATUE PCI Memory Space";
 		res[1].name  = "IQ81340 ATUE PCI Memory Space";
 		res[1].flags = IORESOURCE_MEM;
 		res[1].flags = IORESOURCE_MEM;
 		sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET;
 		sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET;
-		sys->io_offset = IOP13XX_PCIE_IO_OFFSET;
+		sys->io_offset = IOP13XX_PCIE_LOWER_IO_PA;
 		sys->map_irq = iop13xx_pcie_map_irq;
 		sys->map_irq = iop13xx_pcie_map_irq;
 		break;
 		break;
 	default:
 	default:

+ 1 - 5
arch/arm/mach-iop13xx/setup.c

@@ -258,15 +258,11 @@ void __init iop13xx_platform_init(void)
 
 
 	if (init_uart == IOP13XX_INIT_UART_DEFAULT) {
 	if (init_uart == IOP13XX_INIT_UART_DEFAULT) {
 		switch (iop13xx_dev_id()) {
 		switch (iop13xx_dev_id()) {
-		/* enable both uarts on iop341 and iop342 */
+		/* enable both uarts on iop341 */
 		case 0x3380:
 		case 0x3380:
 		case 0x3384:
 		case 0x3384:
 		case 0x3388:
 		case 0x3388:
 		case 0x338c:
 		case 0x338c:
-		case 0x3382:
-		case 0x3386:
-		case 0x338a:
-		case 0x338e:
 			init_uart |= IOP13XX_INIT_UART_0;
 			init_uart |= IOP13XX_INIT_UART_0;
 			init_uart |= IOP13XX_INIT_UART_1;
 			init_uart |= IOP13XX_INIT_UART_1;
 			break;
 			break;

+ 234 - 0
arch/arm/mach-iop13xx/tpmi.c

@@ -0,0 +1,234 @@
+/*
+ * iop13xx tpmi device resources
+ * Copyright (c) 2005-2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+/* assumes CONTROLLER_ONLY# is never asserted in the ESSR register */
+#define IOP13XX_TPMI_MMR(dev) 	IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12))
+#define IOP13XX_TPMI_MEM(dev) 	IOP13XX_REG_ADDR32_PHYS(0x60000 + (dev << 13))
+#define IOP13XX_TPMI_CTRL(dev)	IOP13XX_REG_ADDR32_PHYS(0x50000 + (dev << 10))
+#define IOP13XX_TPMI_MMR_SIZE	    (SZ_4K - 1)
+#define IOP13XX_TPMI_MEM_SIZE	    (255)
+#define IOP13XX_TPMI_MEM_CTRL	    (SZ_1K - 1)
+#define IOP13XX_TPMI_RESOURCE_MMR  0
+#define IOP13XX_TPMI_RESOURCE_MEM  1
+#define IOP13XX_TPMI_RESOURCE_CTRL 2
+#define IOP13XX_TPMI_RESOURCE_IRQ  3
+
+static struct resource iop13xx_tpmi_0_resources[] = {
+	[IOP13XX_TPMI_RESOURCE_MMR] = {
+		.start = IOP13XX_TPMI_MMR(4), /* tpmi0 starts at dev == 4 */
+		.end = IOP13XX_TPMI_MMR(4) + IOP13XX_TPMI_MMR_SIZE,
+		.flags = IORESOURCE_MEM,
+	},
+	[IOP13XX_TPMI_RESOURCE_MEM] = {
+		.start = IOP13XX_TPMI_MEM(0),
+		.end = IOP13XX_TPMI_MEM(0) + IOP13XX_TPMI_MEM_SIZE,
+		.flags = IORESOURCE_MEM,
+	},
+	[IOP13XX_TPMI_RESOURCE_CTRL] = {
+		.start = IOP13XX_TPMI_CTRL(0),
+		.end = IOP13XX_TPMI_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
+		.flags = IORESOURCE_MEM,
+	},
+	[IOP13XX_TPMI_RESOURCE_IRQ] = {
+		.start = IRQ_IOP13XX_TPMI0_OUT,
+		.end = IRQ_IOP13XX_TPMI0_OUT,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct resource iop13xx_tpmi_1_resources[] = {
+	[IOP13XX_TPMI_RESOURCE_MMR] = {
+		.start = IOP13XX_TPMI_MMR(1),
+		.end = IOP13XX_TPMI_MMR(1) + IOP13XX_TPMI_MMR_SIZE,
+		.flags = IORESOURCE_MEM,
+	},
+	[IOP13XX_TPMI_RESOURCE_MEM] = {
+		.start = IOP13XX_TPMI_MEM(1),
+		.end = IOP13XX_TPMI_MEM(1) + IOP13XX_TPMI_MEM_SIZE,
+		.flags = IORESOURCE_MEM,
+	},
+	[IOP13XX_TPMI_RESOURCE_CTRL] = {
+		.start = IOP13XX_TPMI_CTRL(1),
+		.end = IOP13XX_TPMI_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
+		.flags = IORESOURCE_MEM,
+	},
+	[IOP13XX_TPMI_RESOURCE_IRQ] = {
+		.start = IRQ_IOP13XX_TPMI1_OUT,
+		.end = IRQ_IOP13XX_TPMI1_OUT,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct resource iop13xx_tpmi_2_resources[] = {
+	[IOP13XX_TPMI_RESOURCE_MMR] = {
+		.start = IOP13XX_TPMI_MMR(2),
+		.end = IOP13XX_TPMI_MMR(2) + IOP13XX_TPMI_MMR_SIZE,
+		.flags = IORESOURCE_MEM,
+	},
+	[IOP13XX_TPMI_RESOURCE_MEM] = {
+		.start = IOP13XX_TPMI_MEM(2),
+		.end = IOP13XX_TPMI_MEM(2) + IOP13XX_TPMI_MEM_SIZE,
+		.flags = IORESOURCE_MEM,
+	},
+	[IOP13XX_TPMI_RESOURCE_CTRL] = {
+		.start = IOP13XX_TPMI_CTRL(2),
+		.end = IOP13XX_TPMI_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
+		.flags = IORESOURCE_MEM,
+	},
+	[IOP13XX_TPMI_RESOURCE_IRQ] = {
+		.start = IRQ_IOP13XX_TPMI2_OUT,
+		.end = IRQ_IOP13XX_TPMI2_OUT,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct resource iop13xx_tpmi_3_resources[] = {
+	[IOP13XX_TPMI_RESOURCE_MMR] = {
+		.start = IOP13XX_TPMI_MMR(3),
+		.end = IOP13XX_TPMI_MMR(3) + IOP13XX_TPMI_MMR_SIZE,
+		.flags = IORESOURCE_MEM,
+	},
+	[IOP13XX_TPMI_RESOURCE_MEM] = {
+		.start = IOP13XX_TPMI_MEM(3),
+		.end = IOP13XX_TPMI_MEM(3) + IOP13XX_TPMI_MEM_SIZE,
+		.flags = IORESOURCE_MEM,
+	},
+	[IOP13XX_TPMI_RESOURCE_CTRL] = {
+		.start = IOP13XX_TPMI_CTRL(3),
+		.end = IOP13XX_TPMI_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
+		.flags = IORESOURCE_MEM,
+	},
+	[IOP13XX_TPMI_RESOURCE_IRQ] = {
+		.start = IRQ_IOP13XX_TPMI3_OUT,
+		.end = IRQ_IOP13XX_TPMI3_OUT,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+u64 iop13xx_tpmi_mask = DMA_64BIT_MASK;
+static struct platform_device iop13xx_tpmi_0_device = {
+	.name = "iop-tpmi",
+	.id = 0,
+	.num_resources = 4,
+	.resource = iop13xx_tpmi_0_resources,
+	.dev = {
+		.dma_mask          = &iop13xx_tpmi_mask,
+		.coherent_dma_mask = DMA_64BIT_MASK,
+	},
+};
+
+static struct platform_device iop13xx_tpmi_1_device = {
+	.name = "iop-tpmi",
+	.id = 1,
+	.num_resources = 4,
+	.resource = iop13xx_tpmi_1_resources,
+	.dev = {
+		.dma_mask          = &iop13xx_tpmi_mask,
+		.coherent_dma_mask = DMA_64BIT_MASK,
+	},
+};
+
+static struct platform_device iop13xx_tpmi_2_device = {
+	.name = "iop-tpmi",
+	.id = 2,
+	.num_resources = 4,
+	.resource = iop13xx_tpmi_2_resources,
+	.dev = {
+		.dma_mask          = &iop13xx_tpmi_mask,
+		.coherent_dma_mask = DMA_64BIT_MASK,
+	},
+};
+
+static struct platform_device iop13xx_tpmi_3_device = {
+	.name = "iop-tpmi",
+	.id = 3,
+	.num_resources = 4,
+	.resource = iop13xx_tpmi_3_resources,
+	.dev = {
+		.dma_mask          = &iop13xx_tpmi_mask,
+		.coherent_dma_mask = DMA_64BIT_MASK,
+	},
+};
+
+__init void iop13xx_add_tpmi_devices(void)
+{
+	unsigned short device_id;
+
+	/* tpmi's not present on iop341 or iop342 */
+	if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)
+		/* ATUE must be present */
+		device_id = __raw_readw(IOP13XX_ATUE_DID);
+	else
+		/* ATUX must be present */
+		device_id = __raw_readw(IOP13XX_ATUX_DID);
+
+	switch (device_id) {
+	/* iop34[1|2] 0-tpmi */
+	case 0x3380:
+	case 0x3384:
+	case 0x3388:
+	case 0x338c:
+	case 0x3382:
+	case 0x3386:
+	case 0x338a:
+	case 0x338e:
+		return;
+	/* iop348 1-tpmi */
+	case 0x3310:
+	case 0x3312:
+	case 0x3314:
+	case 0x3318:
+	case 0x331a:
+	case 0x331c:
+	case 0x33c0:
+	case 0x33c2:
+	case 0x33c4:
+	case 0x33c8:
+	case 0x33ca:
+	case 0x33cc:
+	case 0x33b0:
+	case 0x33b2:
+	case 0x33b4:
+	case 0x33b8:
+	case 0x33ba:
+	case 0x33bc:
+	case 0x3320:
+	case 0x3322:
+	case 0x3324:
+	case 0x3328:
+	case 0x332a:
+	case 0x332c:
+		platform_device_register(&iop13xx_tpmi_0_device);
+		return;
+	default:
+		platform_device_register(&iop13xx_tpmi_0_device);
+		platform_device_register(&iop13xx_tpmi_1_device);
+		platform_device_register(&iop13xx_tpmi_2_device);
+		platform_device_register(&iop13xx_tpmi_3_device);
+		return;
+	}
+}

+ 8 - 0
arch/arm/mach-iop32x/Kconfig

@@ -34,6 +34,14 @@ config MACH_N2100
 	  Say Y here if you want to run your kernel on the Thecus n2100
 	  Say Y here if you want to run your kernel on the Thecus n2100
 	  NAS appliance.
 	  NAS appliance.
 
 
+config IOP3XX_ATU
+        bool "Enable the PCI Controller"
+        default y
+        help
+          Say Y here if you want the IOP to initialize its PCI Controller.
+          Say N if the IOP is an add in card, the host system owns the PCI
+          bus in this case.
+
 endmenu
 endmenu
 
 
 endif
 endif

+ 7 - 4
arch/arm/mach-iop32x/iq31244.c

@@ -178,9 +178,10 @@ static struct hw_pci iq31244_pci __initdata = {
 
 
 static int __init iq31244_pci_init(void)
 static int __init iq31244_pci_init(void)
 {
 {
-	if (is_ep80219())
-		pci_common_init(&ep80219_pci);
-	else if (machine_is_iq31244()) {
+	if (is_ep80219()) {
+		if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE)
+			pci_common_init(&ep80219_pci);
+	} else if (machine_is_iq31244()) {
 		if (is_80219()) {
 		if (is_80219()) {
 			printk("note: iq31244 board type has been selected\n");
 			printk("note: iq31244 board type has been selected\n");
 			printk("note: to select ep80219 operation:\n");
 			printk("note: to select ep80219 operation:\n");
@@ -189,7 +190,9 @@ static int __init iq31244_pci_init(void)
 			printk("\t2/ update boot loader to pass"
 			printk("\t2/ update boot loader to pass"
 				" the ep80219 id: %d\n", MACH_TYPE_EP80219);
 				" the ep80219 id: %d\n", MACH_TYPE_EP80219);
 		}
 		}
-		pci_common_init(&iq31244_pci);
+
+		if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE)
+			pci_common_init(&iq31244_pci);
 	}
 	}
 
 
 	return 0;
 	return 0;

+ 2 - 1
arch/arm/mach-iop32x/iq80321.c

@@ -113,7 +113,8 @@ static struct hw_pci iq80321_pci __initdata = {
 
 
 static int __init iq80321_pci_init(void)
 static int __init iq80321_pci_init(void)
 {
 {
-	if (machine_is_iq80321())
+	if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
+		machine_is_iq80321())
 		pci_common_init(&iq80321_pci);
 		pci_common_init(&iq80321_pci);
 
 
 	return 0;
 	return 0;

+ 8 - 0
arch/arm/mach-iop33x/Kconfig

@@ -16,6 +16,14 @@ config MACH_IQ80332
 	  Say Y here if you want to run your kernel on the Intel IQ80332
 	  Say Y here if you want to run your kernel on the Intel IQ80332
 	  evaluation kit for the IOP332 chipset.
 	  evaluation kit for the IOP332 chipset.
 
 
+config IOP3XX_ATU
+	bool "Enable the PCI Controller"
+	default y
+	help
+	  Say Y here if you want the IOP to initialize its PCI Controller.
+	  Say N if the IOP is an add in card, the host system owns the PCI
+	  bus in this case.
+
 endmenu
 endmenu
 
 
 endif
 endif

+ 2 - 1
arch/arm/mach-iop33x/iq80331.c

@@ -96,7 +96,8 @@ static struct hw_pci iq80331_pci __initdata = {
 
 
 static int __init iq80331_pci_init(void)
 static int __init iq80331_pci_init(void)
 {
 {
-	if (machine_is_iq80331())
+	if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
+		machine_is_iq80331())
 		pci_common_init(&iq80331_pci);
 		pci_common_init(&iq80331_pci);
 
 
 	return 0;
 	return 0;

+ 2 - 1
arch/arm/mach-iop33x/iq80332.c

@@ -96,7 +96,8 @@ static struct hw_pci iq80332_pci __initdata = {
 
 
 static int __init iq80332_pci_init(void)
 static int __init iq80332_pci_init(void)
 {
 {
-	if (machine_is_iq80332())
+	if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
+		machine_is_iq80332())
 		pci_common_init(&iq80332_pci);
 		pci_common_init(&iq80332_pci);
 
 
 	return 0;
 	return 0;

+ 74 - 19
arch/arm/mach-ixp4xx/common.c

@@ -27,6 +27,7 @@
 #include <linux/time.h>
 #include <linux/time.h>
 #include <linux/timex.h>
 #include <linux/timex.h>
 #include <linux/clocksource.h>
 #include <linux/clocksource.h>
+#include <linux/clockchips.h>
 
 
 #include <asm/arch/udc.h>
 #include <asm/arch/udc.h>
 #include <asm/hardware.h>
 #include <asm/hardware.h>
@@ -41,6 +42,8 @@
 #include <asm/mach/time.h>
 #include <asm/mach/time.h>
 
 
 static int __init ixp4xx_clocksource_init(void);
 static int __init ixp4xx_clocksource_init(void);
+static int __init ixp4xx_clockevent_init(void);
+static struct clock_event_device clockevent_ixp4xx;
 
 
 /*************************************************************************
 /*************************************************************************
  * IXP4xx chipset I/O mapping
  * IXP4xx chipset I/O mapping
@@ -239,52 +242,40 @@ void __init ixp4xx_init_irq(void)
  * counter as a source of real clock ticks to account for missed jiffies.
  * counter as a source of real clock ticks to account for missed jiffies.
  *************************************************************************/
  *************************************************************************/
 
 
-static unsigned volatile last_jiffy_time;
-
-#define CLOCK_TICKS_PER_USEC	((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC)
-
 static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
 static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
 {
 {
-	write_seqlock(&xtime_lock);
+	struct clock_event_device *evt = &clockevent_ixp4xx;
 
 
 	/* Clear Pending Interrupt by writing '1' to it */
 	/* Clear Pending Interrupt by writing '1' to it */
 	*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
 	*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
 
 
-	/*
-	 * Catch up with the real idea of time
-	 */
-	while ((signed long)(*IXP4XX_OSTS - last_jiffy_time) >= LATCH) {
-		timer_tick();
-		last_jiffy_time += LATCH;
-	}
-
-	write_sequnlock(&xtime_lock);
+	evt->event_handler(evt);
 
 
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
 static struct irqaction ixp4xx_timer_irq = {
 static struct irqaction ixp4xx_timer_irq = {
-	.name		= "IXP4xx Timer Tick",
+	.name		= "timer1",
 	.flags		= IRQF_DISABLED | IRQF_TIMER,
 	.flags		= IRQF_DISABLED | IRQF_TIMER,
 	.handler	= ixp4xx_timer_interrupt,
 	.handler	= ixp4xx_timer_interrupt,
 };
 };
 
 
 static void __init ixp4xx_timer_init(void)
 static void __init ixp4xx_timer_init(void)
 {
 {
+	/* Reset/disable counter */
+	*IXP4XX_OSRT1 = 0;
+
 	/* Clear Pending Interrupt by writing '1' to it */
 	/* Clear Pending Interrupt by writing '1' to it */
 	*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
 	*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
 
 
-	/* Setup the Timer counter value */
-	*IXP4XX_OSRT1 = (LATCH & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE;
-
 	/* Reset time-stamp counter */
 	/* Reset time-stamp counter */
 	*IXP4XX_OSTS = 0;
 	*IXP4XX_OSTS = 0;
-	last_jiffy_time = 0;
 
 
 	/* Connect the interrupt handler and enable the interrupt */
 	/* Connect the interrupt handler and enable the interrupt */
 	setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq);
 	setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq);
 
 
 	ixp4xx_clocksource_init();
 	ixp4xx_clocksource_init();
+	ixp4xx_clockevent_init();
 }
 }
 
 
 struct sys_timer ixp4xx_timer = {
 struct sys_timer ixp4xx_timer = {
@@ -384,6 +375,9 @@ void __init ixp4xx_sys_init(void)
 			ixp4xx_exp_bus_size >> 20);
 			ixp4xx_exp_bus_size >> 20);
 }
 }
 
 
+/*
+ * clocksource
+ */
 cycle_t ixp4xx_get_cycles(void)
 cycle_t ixp4xx_get_cycles(void)
 {
 {
 	return *IXP4XX_OSTS;
 	return *IXP4XX_OSTS;
@@ -408,3 +402,64 @@ static int __init ixp4xx_clocksource_init(void)
 
 
 	return 0;
 	return 0;
 }
 }
+
+/*
+ * clockevents
+ */
+static int ixp4xx_set_next_event(unsigned long evt,
+				 struct clock_event_device *unused)
+{
+	unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
+
+	*IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK) | opts;
+
+	return 0;
+}
+
+static void ixp4xx_set_mode(enum clock_event_mode mode,
+			    struct clock_event_device *evt)
+{
+	unsigned long opts, osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		osrt = LATCH & ~IXP4XX_OST_RELOAD_MASK;
+ 		opts = IXP4XX_OST_ENABLE;
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* period set by 'set next_event' */
+		osrt = 0;
+		opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT;
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+	default:
+		osrt = opts = 0;
+		break;
+	}
+
+	*IXP4XX_OSRT1 = osrt | opts;
+}
+
+static struct clock_event_device clockevent_ixp4xx = {
+	.name		= "ixp4xx timer1",
+	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.rating         = 200,
+	.shift		= 24,
+	.set_mode	= ixp4xx_set_mode,
+	.set_next_event	= ixp4xx_set_next_event,
+};
+
+static int __init ixp4xx_clockevent_init(void)
+{
+	clockevent_ixp4xx.mult = div_sc(FREQ, NSEC_PER_SEC,
+					clockevent_ixp4xx.shift);
+	clockevent_ixp4xx.max_delta_ns =
+		clockevent_delta2ns(0xfffffffe, &clockevent_ixp4xx);
+	clockevent_ixp4xx.min_delta_ns =
+		clockevent_delta2ns(0xf, &clockevent_ixp4xx);
+	clockevent_ixp4xx.cpumask = cpumask_of_cpu(0);
+
+	clockevents_register_device(&clockevent_ixp4xx);
+	return 0;
+}

+ 13 - 2
arch/arm/mach-ns9xxx/Kconfig

@@ -3,19 +3,30 @@ if ARCH_NS9XXX
 menu "NS9xxx Implementations"
 menu "NS9xxx Implementations"
 
 
 config MACH_CC9P9360DEV
 config MACH_CC9P9360DEV
-	bool "Connect Core 9P 9360 on an A9M9750 Devboard"
+	bool "ConnectCore 9P 9360 on an A9M9750 Devboard"
 	select PROCESSOR_NS9360
 	select PROCESSOR_NS9360
 	select BOARD_A9M9750DEV
 	select BOARD_A9M9750DEV
 	help
 	help
-	  Say Y here if you are using the Digi Connect Core 9P 9360
+	  Say Y here if you are using the Digi ConnectCore 9P 9360
 	  on an A9M9750 Development Board.
 	  on an A9M9750 Development Board.
 
 
+config MACH_CC9P9360JS
+	bool "ConnectCore 9P 9360 on a JSCC9P9360 Devboard"
+	select PROCESSOR_NS9360
+	select BOARD_JSCC9P9360
+	help
+	  Say Y here if you are using the Digi ConnectCore 9P 9360
+	  on an JSCC9P9360 Development Board.
+
 config PROCESSOR_NS9360
 config PROCESSOR_NS9360
 	bool
 	bool
 
 
 config BOARD_A9M9750DEV
 config BOARD_A9M9750DEV
 	bool
 	bool
 
 
+config BOARD_JSCC9P9360
+	bool
+
 endmenu
 endmenu
 
 
 endif
 endif

+ 1 - 0
arch/arm/mach-ns9xxx/Makefile

@@ -3,3 +3,4 @@ obj-y := irq.o time.o generic.o
 obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o
 obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o
 
 
 obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o
 obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o
+obj-$(CONFIG_BOARD_JSCC9P9360) += board-jscc9p9360.o

+ 17 - 0
arch/arm/mach-ns9xxx/board-jscc9p9360.c

@@ -0,0 +1,17 @@
+/*
+ * arch/arm/mach-ns9xxx/board-jscc9p9360.c
+ *
+ * Copyright (C) 2006,2007 by Digi International Inc.
+ * All rights reserved.
+ *
+ * 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 "board-jscc9p9360.h"
+
+void __init board_jscc9p9360_init_machine(void)
+{
+	/* TODO: reserve GPIOs for push buttons, etc pp */
+}
+

+ 13 - 0
arch/arm/mach-ns9xxx/board-jscc9p9360.h

@@ -0,0 +1,13 @@
+/*
+ * arch/arm/mach-ns9xxx/board-jscc9p9360.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/init.h>
+
+void __init board_jscc9p9360_init_machine(void);

+ 29 - 0
arch/arm/mach-ns9xxx/mach-cc9p9360js.c

@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-ns9xxx/mach-cc9p9360js.c
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * 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 <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include "board-jscc9p9360.h"
+#include "generic.h"
+
+static void __init mach_cc9p9360js_init_machine(void)
+{
+	ns9xxx_init_machine();
+	board_jscc9p9360_init_machine();
+}
+
+MACHINE_START(CC9P9360DEV, "Digi ConnectCore 9P 9360 on an JSCC9P9360 Devboard")
+	.map_io = ns9xxx_map_io,
+	.init_irq = ns9xxx_init_irq,
+	.init_machine = mach_cc9p9360js_init_machine,
+	.timer = &ns9xxx_timer,
+	.boot_params = 0x100,
+MACHINE_END

+ 133 - 73
arch/arm/mach-omap1/time.c

@@ -39,6 +39,10 @@
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
 
 
 #include <asm/system.h>
 #include <asm/system.h>
 #include <asm/hardware.h>
 #include <asm/hardware.h>
@@ -48,13 +52,7 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 #include <asm/mach/time.h>
 
 
-struct sys_timer omap_timer;
 
 
-/*
- * ---------------------------------------------------------------------------
- * MPU timer
- * ---------------------------------------------------------------------------
- */
 #define OMAP_MPU_TIMER_BASE		OMAP_MPU_TIMER1_BASE
 #define OMAP_MPU_TIMER_BASE		OMAP_MPU_TIMER1_BASE
 #define OMAP_MPU_TIMER_OFFSET		0x100
 #define OMAP_MPU_TIMER_OFFSET		0x100
 
 
@@ -88,21 +86,6 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
 	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
 	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
 }
 }
 
 
-/*
- * MPU_TICKS_PER_SEC must be an even number, otherwise machinecycles_to_usecs
- * will break. On P2, the timer count rate is 6.5 MHz after programming PTV
- * with 0. This divides the 13MHz input by 2, and is undocumented.
- */
-#if defined(CONFIG_MACH_OMAP_PERSEUS2) || defined(CONFIG_MACH_OMAP_FSAMPLE)
-/* REVISIT: This ifdef construct should be replaced by a query to clock
- * framework to see if timer base frequency is 12.0, 13.0 or 19.2 MHz.
- */
-#define MPU_TICKS_PER_SEC		(13000000 / 2)
-#else
-#define MPU_TICKS_PER_SEC		(12000000 / 2)
-#endif
-
-#define MPU_TIMER_TICK_PERIOD		((MPU_TICKS_PER_SEC / HZ) - 1)
 
 
 typedef struct {
 typedef struct {
 	u32 cntl;			/* CNTL_TIMER, R/W */
 	u32 cntl;			/* CNTL_TIMER, R/W */
@@ -120,98 +103,164 @@ static inline unsigned long omap_mpu_timer_read(int nr)
 	return timer->read_tim;
 	return timer->read_tim;
 }
 }
 
 
-static inline void omap_mpu_timer_start(int nr, unsigned long load_val)
+static inline void omap_mpu_set_autoreset(int nr)
 {
 {
 	volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
 	volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
 
 
-	timer->cntl = MPU_TIMER_CLOCK_ENABLE;
-	udelay(1);
-	timer->load_tim = load_val;
-        udelay(1);
-	timer->cntl = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_AR | MPU_TIMER_ST);
+	timer->cntl = timer->cntl | MPU_TIMER_AR;
 }
 }
 
 
-unsigned long omap_mpu_timer_ticks_to_usecs(unsigned long nr_ticks)
+static inline void omap_mpu_remove_autoreset(int nr)
 {
 {
-	unsigned long long nsec;
+	volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
 
 
-	nsec = cycles_2_ns((unsigned long long)nr_ticks);
-	return (unsigned long)nsec / 1000;
+	timer->cntl = timer->cntl & ~MPU_TIMER_AR;
 }
 }
 
 
-/*
- * Last processed system timer interrupt
- */
-static unsigned long omap_mpu_timer_last = 0;
+static inline void omap_mpu_timer_start(int nr, unsigned long load_val,
+					int autoreset)
+{
+	volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
+	unsigned int timerflags = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_ST);
+
+	if (autoreset) timerflags |= MPU_TIMER_AR;
+
+	timer->cntl = MPU_TIMER_CLOCK_ENABLE;
+	udelay(1);
+	timer->load_tim = load_val;
+        udelay(1);
+	timer->cntl = timerflags;
+}
 
 
 /*
 /*
- * Returns elapsed usecs since last system timer interrupt
+ * ---------------------------------------------------------------------------
+ * MPU timer 1 ... count down to zero, interrupt, reload
+ * ---------------------------------------------------------------------------
  */
  */
-static unsigned long omap_mpu_timer_gettimeoffset(void)
+static int omap_mpu_set_next_event(unsigned long cycles,
+				    struct clock_event_device *evt)
 {
 {
-	unsigned long now = 0 - omap_mpu_timer_read(0);
-	unsigned long elapsed = now - omap_mpu_timer_last;
+	omap_mpu_timer_start(0, cycles, 0);
+	return 0;
+}
 
 
-	return omap_mpu_timer_ticks_to_usecs(elapsed);
+static void omap_mpu_set_mode(enum clock_event_mode mode,
+			      struct clock_event_device *evt)
+{
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		omap_mpu_set_autoreset(0);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		omap_mpu_remove_autoreset(0);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		break;
+	}
 }
 }
 
 
-/*
- * Elapsed time between interrupts is calculated using timer0.
- * Latency during the interrupt is calculated using timer1.
- * Both timer0 and timer1 are counting at 6MHz (P2 6.5MHz).
- */
-static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id)
+static struct clock_event_device clockevent_mpu_timer1 = {
+	.name		= "mpu_timer1",
+	.features       = CLOCK_EVT_FEAT_PERIODIC, CLOCK_EVT_FEAT_ONESHOT,
+	.shift		= 32,
+	.set_next_event	= omap_mpu_set_next_event,
+	.set_mode	= omap_mpu_set_mode,
+};
+
+static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id)
 {
 {
-	unsigned long now, latency;
+	struct clock_event_device *evt = &clockevent_mpu_timer1;
 
 
-	write_seqlock(&xtime_lock);
-	now = 0 - omap_mpu_timer_read(0);
-	latency = MPU_TICKS_PER_SEC / HZ - omap_mpu_timer_read(1);
-	omap_mpu_timer_last = now - latency;
-	timer_tick();
-	write_sequnlock(&xtime_lock);
+	evt->event_handler(evt);
 
 
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
-static struct irqaction omap_mpu_timer_irq = {
-	.name		= "mpu timer",
+static struct irqaction omap_mpu_timer1_irq = {
+	.name		= "mpu_timer1",
 	.flags		= IRQF_DISABLED | IRQF_TIMER,
 	.flags		= IRQF_DISABLED | IRQF_TIMER,
-	.handler	= omap_mpu_timer_interrupt,
+	.handler	= omap_mpu_timer1_interrupt,
 };
 };
 
 
-static unsigned long omap_mpu_timer1_overflows;
-static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id)
+static __init void omap_init_mpu_timer(unsigned long rate)
+{
+	set_cyc2ns_scale(rate / 1000);
+
+	setup_irq(INT_TIMER1, &omap_mpu_timer1_irq);
+	omap_mpu_timer_start(0, (rate / HZ) - 1, 1);
+
+	clockevent_mpu_timer1.mult = div_sc(rate, NSEC_PER_SEC,
+					    clockevent_mpu_timer1.shift);
+	clockevent_mpu_timer1.max_delta_ns =
+		clockevent_delta2ns(-1, &clockevent_mpu_timer1);
+	clockevent_mpu_timer1.min_delta_ns =
+		clockevent_delta2ns(1, &clockevent_mpu_timer1);
+
+	clockevent_mpu_timer1.cpumask = cpumask_of_cpu(0);
+	clockevents_register_device(&clockevent_mpu_timer1);
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * MPU timer 2 ... free running 32-bit clock source and scheduler clock
+ * ---------------------------------------------------------------------------
+ */
+
+static unsigned long omap_mpu_timer2_overflows;
+
+static irqreturn_t omap_mpu_timer2_interrupt(int irq, void *dev_id)
 {
 {
-	omap_mpu_timer1_overflows++;
+	omap_mpu_timer2_overflows++;
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
-static struct irqaction omap_mpu_timer1_irq = {
-	.name		= "mpu timer1 overflow",
+static struct irqaction omap_mpu_timer2_irq = {
+	.name		= "mpu_timer2",
 	.flags		= IRQF_DISABLED,
 	.flags		= IRQF_DISABLED,
-	.handler	= omap_mpu_timer1_interrupt,
+	.handler	= omap_mpu_timer2_interrupt,
 };
 };
 
 
-static __init void omap_init_mpu_timer(void)
+static cycle_t mpu_read(void)
 {
 {
-	set_cyc2ns_scale(MPU_TICKS_PER_SEC / 1000);
-	omap_timer.offset = omap_mpu_timer_gettimeoffset;
-	setup_irq(INT_TIMER1, &omap_mpu_timer1_irq);
-	setup_irq(INT_TIMER2, &omap_mpu_timer_irq);
-	omap_mpu_timer_start(0, 0xffffffff);
-	omap_mpu_timer_start(1, MPU_TIMER_TICK_PERIOD);
+	return ~omap_mpu_timer_read(1);
+}
+
+static struct clocksource clocksource_mpu = {
+	.name		= "mpu_timer2",
+	.rating		= 300,
+	.read		= mpu_read,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.shift		= 24,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init omap_init_clocksource(unsigned long rate)
+{
+	static char err[] __initdata = KERN_ERR
+			"%s: can't register clocksource!\n";
+
+	clocksource_mpu.mult
+		= clocksource_khz2mult(rate/1000, clocksource_mpu.shift);
+
+	setup_irq(INT_TIMER2, &omap_mpu_timer2_irq);
+	omap_mpu_timer_start(1, ~0, 1);
+
+	if (clocksource_register(&clocksource_mpu))
+		printk(err, clocksource_mpu.name);
 }
 }
 
 
+
 /*
 /*
  * Scheduler clock - returns current time in nanosec units.
  * Scheduler clock - returns current time in nanosec units.
  */
  */
 unsigned long long sched_clock(void)
 unsigned long long sched_clock(void)
 {
 {
-	unsigned long ticks = 0 - omap_mpu_timer_read(0);
+	unsigned long ticks = 0 - omap_mpu_timer_read(1);
 	unsigned long long ticks64;
 	unsigned long long ticks64;
 
 
-	ticks64 = omap_mpu_timer1_overflows;
+	ticks64 = omap_mpu_timer2_overflows;
 	ticks64 <<= 32;
 	ticks64 <<= 32;
 	ticks64 |= ticks;
 	ticks64 |= ticks;
 
 
@@ -225,10 +274,21 @@ unsigned long long sched_clock(void)
  */
  */
 static void __init omap_timer_init(void)
 static void __init omap_timer_init(void)
 {
 {
-	omap_init_mpu_timer();
+	struct clk	*ck_ref = clk_get(NULL, "ck_ref");
+	unsigned long	rate;
+
+	BUG_ON(IS_ERR(ck_ref));
+
+	rate = clk_get_rate(ck_ref);
+	clk_put(ck_ref);
+
+	/* PTV = 0 */
+	rate /= 2;
+
+	omap_init_mpu_timer(rate);
+	omap_init_clocksource(rate);
 }
 }
 
 
 struct sys_timer omap_timer = {
 struct sys_timer omap_timer = {
 	.init		= omap_timer_init,
 	.init		= omap_timer_init,
-	.offset		= NULL,		/* Initialized later */
 };
 };

+ 2 - 2
arch/arm/mach-pxa/generic.c

@@ -164,9 +164,9 @@ void pxa_set_cken(int clock, int enable)
 	local_irq_save(flags);
 	local_irq_save(flags);
 
 
 	if (enable)
 	if (enable)
-		CKEN |= clock;
+		CKEN |= (1 << clock);
 	else
 	else
-		CKEN &= ~clock;
+		CKEN &= ~(1 << clock);
 
 
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 }
 }

+ 70 - 2
arch/arm/mach-pxa/irq.c

@@ -38,11 +38,33 @@ static void pxa_unmask_low_irq(unsigned int irq)
 	ICMR |= (1 << (irq + PXA_IRQ_SKIP));
 	ICMR |= (1 << (irq + PXA_IRQ_SKIP));
 }
 }
 
 
+static int pxa_set_wake(unsigned int irq, unsigned int on)
+{
+	u32	mask;
+
+	switch (irq) {
+	case IRQ_RTCAlrm:
+		mask = PWER_RTC;
+		break;
+#ifdef CONFIG_PXA27x
+	/* REVISIT can handle USBH1, USBH2, USB, MSL, USIM, ... */
+#endif
+	default:
+		return -EINVAL;
+	}
+	if (on)
+		PWER |= mask;
+	else
+		PWER &= ~mask;
+	return 0;
+}
+
 static struct irq_chip pxa_internal_chip_low = {
 static struct irq_chip pxa_internal_chip_low = {
 	.name		= "SC",
 	.name		= "SC",
 	.ack		= pxa_mask_low_irq,
 	.ack		= pxa_mask_low_irq,
 	.mask		= pxa_mask_low_irq,
 	.mask		= pxa_mask_low_irq,
 	.unmask		= pxa_unmask_low_irq,
 	.unmask		= pxa_unmask_low_irq,
+	.set_wake	= pxa_set_wake,
 };
 };
 
 
 #if PXA_INTERNAL_IRQS > 32
 #if PXA_INTERNAL_IRQS > 32
@@ -70,6 +92,26 @@ static struct irq_chip pxa_internal_chip_high = {
 
 
 #endif
 #endif
 
 
+/* Note that if an input/irq line ever gets changed to an output during
+ * suspend, the relevant PWER, PRER, and PFER bits should be cleared.
+ */
+#ifdef CONFIG_PXA27x
+
+/* PXA27x:  Various gpios can issue wakeup events.  This logic only
+ * handles the simple cases, not the WEMUX2 and WEMUX3 options
+ */
+#define PXA27x_GPIO_NOWAKE_MASK \
+	((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2))
+#define	WAKEMASK(gpio) \
+	(((gpio) <= 15) \
+		? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \
+		: ((gpio == 35) ? (1 << 24) : 0))
+#else
+
+/* pxa 210, 250, 255, 26x:  gpios 0..15 can issue wakeups */
+#define	WAKEMASK(gpio) (((gpio) <= 15) ? (1 << (gpio)) : 0)
+#endif
+
 /*
 /*
  * PXA GPIO edge detection for IRQs:
  * PXA GPIO edge detection for IRQs:
  * IRQs are generated on Falling-Edge, Rising-Edge, or both.
  * IRQs are generated on Falling-Edge, Rising-Edge, or both.
@@ -83,9 +125,11 @@ static long GPIO_IRQ_mask[4];
 static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
 static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
 {
 {
 	int gpio, idx;
 	int gpio, idx;
+	u32 mask;
 
 
 	gpio = IRQ_TO_GPIO(irq);
 	gpio = IRQ_TO_GPIO(irq);
 	idx = gpio >> 5;
 	idx = gpio >> 5;
+	mask = WAKEMASK(gpio);
 
 
 	if (type == IRQT_PROBE) {
 	if (type == IRQT_PROBE) {
 	    /* Don't mess with enabled GPIOs using preconfigured edges or
 	    /* Don't mess with enabled GPIOs using preconfigured edges or
@@ -105,14 +149,20 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
 	if (type & __IRQT_RISEDGE) {
 	if (type & __IRQT_RISEDGE) {
 		/* printk("rising "); */
 		/* printk("rising "); */
 		__set_bit (gpio, GPIO_IRQ_rising_edge);
 		__set_bit (gpio, GPIO_IRQ_rising_edge);
-	} else
+		PRER |= mask;
+	} else {
 		__clear_bit (gpio, GPIO_IRQ_rising_edge);
 		__clear_bit (gpio, GPIO_IRQ_rising_edge);
+		PRER &= ~mask;
+	}
 
 
 	if (type & __IRQT_FALEDGE) {
 	if (type & __IRQT_FALEDGE) {
 		/* printk("falling "); */
 		/* printk("falling "); */
 		__set_bit (gpio, GPIO_IRQ_falling_edge);
 		__set_bit (gpio, GPIO_IRQ_falling_edge);
-	} else
+		PFER |= mask;
+	} else {
 		__clear_bit (gpio, GPIO_IRQ_falling_edge);
 		__clear_bit (gpio, GPIO_IRQ_falling_edge);
+		PFER &= ~mask;
+	}
 
 
 	/* printk("edges\n"); */
 	/* printk("edges\n"); */
 
 
@@ -130,12 +180,29 @@ static void pxa_ack_low_gpio(unsigned int irq)
 	GEDR0 = (1 << (irq - IRQ_GPIO0));
 	GEDR0 = (1 << (irq - IRQ_GPIO0));
 }
 }
 
 
+static int pxa_set_gpio_wake(unsigned int irq, unsigned int on)
+{
+	int	gpio = IRQ_TO_GPIO(irq);
+	u32	mask = WAKEMASK(gpio);
+
+	if (!mask)
+		return -EINVAL;
+
+	if (on)
+		PWER |= mask;
+	else
+		PWER &= ~mask;
+	return 0;
+}
+
+
 static struct irq_chip pxa_low_gpio_chip = {
 static struct irq_chip pxa_low_gpio_chip = {
 	.name		= "GPIO-l",
 	.name		= "GPIO-l",
 	.ack		= pxa_ack_low_gpio,
 	.ack		= pxa_ack_low_gpio,
 	.mask		= pxa_mask_low_irq,
 	.mask		= pxa_mask_low_irq,
 	.unmask		= pxa_unmask_low_irq,
 	.unmask		= pxa_unmask_low_irq,
 	.set_type	= pxa_gpio_irq_type,
 	.set_type	= pxa_gpio_irq_type,
+	.set_wake	= pxa_set_gpio_wake,
 };
 };
 
 
 /*
 /*
@@ -244,6 +311,7 @@ static struct irq_chip pxa_muxed_gpio_chip = {
 	.mask		= pxa_mask_muxed_gpio,
 	.mask		= pxa_mask_muxed_gpio,
 	.unmask		= pxa_unmask_muxed_gpio,
 	.unmask		= pxa_unmask_muxed_gpio,
 	.set_type	= pxa_gpio_irq_type,
 	.set_type	= pxa_gpio_irq_type,
+	.set_wake	= pxa_set_gpio_wake,
 };
 };
 
 
 
 

+ 2 - 2
arch/arm/mach-pxa/lpd270.c

@@ -234,7 +234,7 @@ static void lpd270_backlight_power(int on)
 {
 {
 	if (on) {
 	if (on) {
 		pxa_gpio_mode(GPIO16_PWM0_MD);
 		pxa_gpio_mode(GPIO16_PWM0_MD);
-		pxa_set_cken(CKEN0_PWM0, 1);
+		pxa_set_cken(CKEN_PWM0, 1);
 		PWM_CTRL0 = 0;
 		PWM_CTRL0 = 0;
 		PWM_PWDUTY0 = 0x3ff;
 		PWM_PWDUTY0 = 0x3ff;
 		PWM_PERVAL0 = 0x3ff;
 		PWM_PERVAL0 = 0x3ff;
@@ -242,7 +242,7 @@ static void lpd270_backlight_power(int on)
 		PWM_CTRL0 = 0;
 		PWM_CTRL0 = 0;
 		PWM_PWDUTY0 = 0x0;
 		PWM_PWDUTY0 = 0x0;
 		PWM_PERVAL0 = 0x3FF;
 		PWM_PERVAL0 = 0x3FF;
-		pxa_set_cken(CKEN0_PWM0, 0);
+		pxa_set_cken(CKEN_PWM0, 0);
 	}
 	}
 }
 }
 
 

+ 1 - 1
arch/arm/mach-pxa/lubbock.c

@@ -220,7 +220,7 @@ static struct resource pxa_ssp_resources[] = {
 
 
 static struct pxa2xx_spi_master pxa_ssp_master_info = {
 static struct pxa2xx_spi_master pxa_ssp_master_info = {
 	.ssp_type	= PXA25x_SSP,
 	.ssp_type	= PXA25x_SSP,
-	.clock_enable	= CKEN3_SSP,
+	.clock_enable	= CKEN_SSP,
 	.num_chipselect	= 0,
 	.num_chipselect	= 0,
 };
 };
 
 

+ 2 - 2
arch/arm/mach-pxa/mainstone.c

@@ -266,7 +266,7 @@ static void mainstone_backlight_power(int on)
 {
 {
 	if (on) {
 	if (on) {
 		pxa_gpio_mode(GPIO16_PWM0_MD);
 		pxa_gpio_mode(GPIO16_PWM0_MD);
-		pxa_set_cken(CKEN0_PWM0, 1);
+		pxa_set_cken(CKEN_PWM0, 1);
 		PWM_CTRL0 = 0;
 		PWM_CTRL0 = 0;
 		PWM_PWDUTY0 = 0x3ff;
 		PWM_PWDUTY0 = 0x3ff;
 		PWM_PERVAL0 = 0x3ff;
 		PWM_PERVAL0 = 0x3ff;
@@ -274,7 +274,7 @@ static void mainstone_backlight_power(int on)
 		PWM_CTRL0 = 0;
 		PWM_CTRL0 = 0;
 		PWM_PWDUTY0 = 0x0;
 		PWM_PWDUTY0 = 0x0;
 		PWM_PERVAL0 = 0x3FF;
 		PWM_PERVAL0 = 0x3FF;
-		pxa_set_cken(CKEN0_PWM0, 0);
+		pxa_set_cken(CKEN_PWM0, 0);
 	}
 	}
 }
 }
 
 

+ 2 - 2
arch/arm/mach-pxa/pxa27x.c

@@ -140,9 +140,9 @@ void pxa_cpu_pm_enter(suspend_state_t state)
 	extern void pxa_cpu_resume(void);
 	extern void pxa_cpu_resume(void);
 
 
 	if (state == PM_SUSPEND_STANDBY)
 	if (state == PM_SUSPEND_STANDBY)
-		CKEN = CKEN22_MEMC | CKEN9_OSTIMER | CKEN16_LCD |CKEN0_PWM0;
+		CKEN = CKEN_MEMC | CKEN_OSTIMER | CKEN_LCD | CKEN_PWM0;
 	else
 	else
-		CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
+		CKEN = CKEN_MEMC | CKEN_OSTIMER;
 
 
 	/* ensure voltage-change sequencer not initiated, which hangs */
 	/* ensure voltage-change sequencer not initiated, which hangs */
 	PCFR &= ~PCFR_FVC;
 	PCFR &= ~PCFR_FVC;

+ 6 - 6
arch/arm/mach-pxa/ssp.c

@@ -52,13 +52,13 @@ struct ssp_info_ {
  */
  */
 static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
 static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
 #if defined (CONFIG_PXA27x)
 #if defined (CONFIG_PXA27x)
-	{IRQ_SSP,	CKEN23_SSP1},
-	{IRQ_SSP2,	CKEN3_SSP2},
-	{IRQ_SSP3,	CKEN4_SSP3},
+	{IRQ_SSP,	CKEN_SSP1},
+	{IRQ_SSP2,	CKEN_SSP2},
+	{IRQ_SSP3,	CKEN_SSP3},
 #else
 #else
-	{IRQ_SSP,	CKEN3_SSP},
-	{IRQ_NSSP,	CKEN9_NSSP},
-	{IRQ_ASSP,	CKEN10_ASSP},
+	{IRQ_SSP,	CKEN_SSP},
+	{IRQ_NSSP,	CKEN_NSSP},
+	{IRQ_ASSP,	CKEN_ASSP},
 #endif
 #endif
 };
 };
 
 

+ 35 - 0
arch/arm/mach-rpc/riscpc.c

@@ -17,6 +17,7 @@
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_8250.h>
+#include <linux/pata_platform.h>
 
 
 #include <asm/elf.h>
 #include <asm/elf.h>
 #include <asm/io.h>
 #include <asm/io.h>
@@ -159,11 +160,45 @@ static struct platform_device serial_device = {
 	},
 	},
 };
 };
 
 
+static struct pata_platform_info pata_platform_data = {
+	.ioport_shift		= 2,
+};
+
+static struct resource pata_resources[] = {
+	[0] = {
+		.start		= 0x030107c0,
+		.end		= 0x030107df,
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= 0x03010fd8,
+		.end		= 0x03010fdb,
+		.flags		= IORESOURCE_MEM,
+	},
+	[2] = {
+		.start		= IRQ_HARDDISK,
+		.end		= IRQ_HARDDISK,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device pata_device = {
+	.name			= "pata_platform",
+	.id			= -1,
+	.num_resources		= ARRAY_SIZE(pata_resources),
+	.resource		= pata_resources,
+	.dev			= {
+		.platform_data	= &pata_platform_data,
+		.coherent_dma_mask = ~0,	/* grumble */
+	},
+};
+
 static struct platform_device *devs[] __initdata = {
 static struct platform_device *devs[] __initdata = {
 	&iomd_device,
 	&iomd_device,
 	&kbd_device,
 	&kbd_device,
 	&serial_device,
 	&serial_device,
 	&acornfb_device,
 	&acornfb_device,
+	&pata_device,
 };
 };
 
 
 static int __init rpc_init(void)
 static int __init rpc_init(void)

+ 1 - 6
arch/arm/mach-s3c2410/mach-amlm5900.c

@@ -160,17 +160,11 @@ static struct platform_device *amlm5900_devices[] __initdata = {
 #endif
 #endif
 };
 };
 
 
-static struct s3c24xx_board amlm5900_board __initdata = {
-	.devices       = amlm5900_devices,
-	.devices_count = ARRAY_SIZE(amlm5900_devices)
-};
-
 void __init amlm5900_map_io(void)
 void __init amlm5900_map_io(void)
 {
 {
 	s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
 	s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
 	s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
-	s3c24xx_set_board(&amlm5900_board);
 }
 }
 
 
 #ifdef CONFIG_FB_S3C2410
 #ifdef CONFIG_FB_S3C2410
@@ -247,6 +241,7 @@ static void __init amlm5900_init(void)
 #ifdef CONFIG_FB_S3C2410
 #ifdef CONFIG_FB_S3C2410
 	s3c24xx_fb_set_platdata(&amlm5900_lcd_info);
 	s3c24xx_fb_set_platdata(&amlm5900_lcd_info);
 #endif
 #endif
+	platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices));
 }
 }
 
 
 MACHINE_START(AML_M5900, "AML_M5900")
 MACHINE_START(AML_M5900, "AML_M5900")

+ 4 - 8
arch/arm/mach-s3c2410/mach-bast.c

@@ -464,13 +464,6 @@ static struct clk *bast_clocks[] = {
 	&s3c24xx_uclk,
 	&s3c24xx_uclk,
 };
 };
 
 
-static struct s3c24xx_board bast_board __initdata = {
-	.devices       = bast_devices,
-	.devices_count = ARRAY_SIZE(bast_devices),
-	.clocks	       = bast_clocks,
-	.clocks_count  = ARRAY_SIZE(bast_clocks),
-};
-
 static void __init bast_map_io(void)
 static void __init bast_map_io(void)
 {
 {
 	/* initialise the clocks */
 	/* initialise the clocks */
@@ -486,19 +479,22 @@ static void __init bast_map_io(void)
 
 
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 
+	s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
+
 	s3c_device_nand.dev.platform_data = &bast_nand_info;
 	s3c_device_nand.dev.platform_data = &bast_nand_info;
 	s3c_device_i2c.dev.platform_data = &bast_i2c_info;
 	s3c_device_i2c.dev.platform_data = &bast_i2c_info;
 
 
 	s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
 	s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
 	s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
-	s3c24xx_set_board(&bast_board);
+
 	usb_simtec_init();
 	usb_simtec_init();
 }
 }
 
 
 static void __init bast_init(void)
 static void __init bast_init(void)
 {
 {
 	s3c24xx_fb_set_platdata(&bast_lcd_info);
 	s3c24xx_fb_set_platdata(&bast_lcd_info);
+	platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
 }
 }
 
 
 MACHINE_START(BAST, "Simtec-BAST")
 MACHINE_START(BAST, "Simtec-BAST")

+ 2 - 7
arch/arm/mach-s3c2410/mach-h1940.c

@@ -129,7 +129,6 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
 };
 };
 
 
 
 
-
 /**
 /**
  * Set lcd on or off
  * Set lcd on or off
  **/
  **/
@@ -188,17 +187,11 @@ static struct platform_device *h1940_devices[] __initdata = {
 	&s3c_device_leds,
 	&s3c_device_leds,
 };
 };
 
 
-static struct s3c24xx_board h1940_board __initdata = {
-	.devices       = h1940_devices,
-	.devices_count = ARRAY_SIZE(h1940_devices)
-};
-
 static void __init h1940_map_io(void)
 static void __init h1940_map_io(void)
 {
 {
 	s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
 	s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
 	s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
-	s3c24xx_set_board(&h1940_board);
 
 
 	/* setup PM */
 	/* setup PM */
 
 
@@ -232,6 +225,8 @@ static void __init h1940_init(void)
 	      | (0x02 << S3C2410_PLLCON_PDIVSHIFT)
 	      | (0x02 << S3C2410_PLLCON_PDIVSHIFT)
 	      | (0x03 << S3C2410_PLLCON_SDIVSHIFT);
 	      | (0x03 << S3C2410_PLLCON_SDIVSHIFT);
 	writel(tmp, S3C2410_UPLLCON);
 	writel(tmp, S3C2410_UPLLCON);
+
+	platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
 }
 }
 
 
 MACHINE_START(H1940, "IPAQ-H1940")
 MACHINE_START(H1940, "IPAQ-H1940")

+ 2 - 6
arch/arm/mach-s3c2410/mach-n30.c

@@ -90,17 +90,11 @@ static struct s3c2410_platform_i2c n30_i2ccfg = {
 	.max_freq	= 10*1000,
 	.max_freq	= 10*1000,
 };
 };
 
 
-static struct s3c24xx_board n30_board __initdata = {
-	.devices       = n30_devices,
-	.devices_count = ARRAY_SIZE(n30_devices)
-};
-
 static void __init n30_map_io(void)
 static void __init n30_map_io(void)
 {
 {
 	s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
 	s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
 	s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
-	s3c24xx_set_board(&n30_board);
 }
 }
 
 
 static void __init n30_init_irq(void)
 static void __init n30_init_irq(void)
@@ -120,6 +114,8 @@ static void __init n30_init(void)
 	s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
 	s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
 			      S3C2410_MISCCR_USBSUSPND0 |
 			      S3C2410_MISCCR_USBSUSPND0 |
 			      S3C2410_MISCCR_USBSUSPND1, 0x0);
 			      S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+	platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices));
 }
 }
 
 
 MACHINE_START(N30, "Acer-N30")
 MACHINE_START(N30, "Acer-N30")

+ 5 - 7
arch/arm/mach-s3c2410/mach-otom.c

@@ -100,20 +100,17 @@ static struct platform_device *otom11_devices[] __initdata = {
 	&otom_device_nor,
 	&otom_device_nor,
 };
 };
 
 
-static struct s3c24xx_board otom11_board __initdata = {
-	.devices       = otom11_devices,
-	.devices_count = ARRAY_SIZE(otom11_devices)
-};
-
-
 static void __init otom11_map_io(void)
 static void __init otom11_map_io(void)
 {
 {
 	s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
 	s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs));
 	s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs));
-	s3c24xx_set_board(&otom11_board);
 }
 }
 
 
+static void __init otom11_init(void)
+{
+	platform_add_devices(otom11_devices, ARRAY_SIZE(otom11_devices));
+}
 
 
 MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
 MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
 	/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
 	/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
@@ -121,6 +118,7 @@ MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= otom11_map_io,
 	.map_io		= otom11_map_io,
+	.init_machine	= otom11_init,
 	.init_irq	= s3c24xx_init_irq,
 	.init_irq	= s3c24xx_init_irq,
 	.timer		= &s3c24xx_timer,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
 MACHINE_END

+ 1 - 7
arch/arm/mach-s3c2410/mach-qt2410.c

@@ -29,7 +29,6 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
 #include <linux/serial_core.h>
-#include <linux/mmc/protocol.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
 #include <linux/spi/spi_bitbang.h>
 
 
@@ -331,11 +330,6 @@ static struct platform_device *qt2410_devices[] __initdata = {
 	&qt2410_led,
 	&qt2410_led,
 };
 };
 
 
-static struct s3c24xx_board qt2410_board __initdata = {
-	.devices       = qt2410_devices,
-	.devices_count = ARRAY_SIZE(qt2410_devices)
-};
-
 static struct mtd_partition qt2410_nand_part[] = {
 static struct mtd_partition qt2410_nand_part[] = {
 	[0] = {
 	[0] = {
 		.name	= "U-Boot",
 		.name	= "U-Boot",
@@ -405,7 +399,6 @@ static void __init qt2410_map_io(void)
 	s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
 	s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
 	s3c24xx_init_clocks(12*1000*1000);
 	s3c24xx_init_clocks(12*1000*1000);
 	s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
 	s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
-	s3c24xx_set_board(&qt2410_board);
 }
 }
 
 
 static void __init qt2410_machine_init(void)
 static void __init qt2410_machine_init(void)
@@ -432,6 +425,7 @@ static void __init qt2410_machine_init(void)
 
 
 	s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPIO_OUTPUT);
 	s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPIO_OUTPUT);
 
 
+	platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
 	s3c2410_pm_init();
 	s3c2410_pm_init();
 }
 }
 
 

+ 7 - 7
arch/arm/mach-s3c2410/mach-smdk2410.c

@@ -94,17 +94,17 @@ static struct platform_device *smdk2410_devices[] __initdata = {
 	&s3c_device_iis,
 	&s3c_device_iis,
 };
 };
 
 
-static struct s3c24xx_board smdk2410_board __initdata = {
-	.devices       = smdk2410_devices,
-	.devices_count = ARRAY_SIZE(smdk2410_devices)
-};
-
 static void __init smdk2410_map_io(void)
 static void __init smdk2410_map_io(void)
 {
 {
 	s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
 	s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
 	s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
-	s3c24xx_set_board(&smdk2410_board);
+}
+
+static void __init smdk2410_init(void)
+{
+	platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));
+	smdk_machine_init();
 }
 }
 
 
 MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
 MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
@@ -115,7 +115,7 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= smdk2410_map_io,
 	.map_io		= smdk2410_map_io,
 	.init_irq	= s3c24xx_init_irq,
 	.init_irq	= s3c24xx_init_irq,
-	.init_machine	= smdk_machine_init,
+	.init_machine	= smdk2410_init,
 	.timer		= &s3c24xx_timer,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
 MACHINE_END
 
 

+ 7 - 9
arch/arm/mach-s3c2410/mach-vr1000.c

@@ -384,13 +384,6 @@ static struct clk *vr1000_clocks[] = {
 	&s3c24xx_uclk,
 	&s3c24xx_uclk,
 };
 };
 
 
-static struct s3c24xx_board vr1000_board __initdata = {
-	.devices       = vr1000_devices,
-	.devices_count = ARRAY_SIZE(vr1000_devices),
-	.clocks	       = vr1000_clocks,
-	.clocks_count  = ARRAY_SIZE(vr1000_clocks),
-};
-
 static void vr1000_power_off(void)
 static void vr1000_power_off(void)
 {
 {
 	s3c2410_gpio_cfgpin(S3C2410_GPB9, S3C2410_GPB9_OUTP);
 	s3c2410_gpio_cfgpin(S3C2410_GPB9, S3C2410_GPB9_OUTP);
@@ -412,15 +405,19 @@ static void __init vr1000_map_io(void)
 
 
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 
+	s3c24xx_register_clocks(vr1000_clocks, ARRAY_SIZE(vr1000_clocks));
+
 	pm_power_off = vr1000_power_off;
 	pm_power_off = vr1000_power_off;
 
 
 	s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
 	s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
 	s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
-	s3c24xx_set_board(&vr1000_board);
-	usb_simtec_init();
 }
 }
 
 
+static void __init vr1000_init(void)
+{
+	platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices));
+}
 
 
 MACHINE_START(VR1000, "Thorcom-VR1000")
 MACHINE_START(VR1000, "Thorcom-VR1000")
 	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
 	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
@@ -428,6 +425,7 @@ MACHINE_START(VR1000, "Thorcom-VR1000")
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= vr1000_map_io,
 	.map_io		= vr1000_map_io,
+	.init_machine	= vr1000_init,
 	.init_irq	= s3c24xx_init_irq,
 	.init_irq	= s3c24xx_init_irq,
 	.timer		= &s3c24xx_timer,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
 MACHINE_END

+ 9 - 0
arch/arm/mach-s3c2412/Kconfig

@@ -47,6 +47,15 @@ config MACH_S3C2413
 	  machine_is_s3c2413() will work when MACH_SMDK2413 is
 	  machine_is_s3c2413() will work when MACH_SMDK2413 is
 	  selected
 	  selected
 
 
+config MACH_SMDK2412
+	bool "SMDK2412"
+	select MACH_SMDK2413
+	help
+	  Say Y here if you are using an SMDK2412
+
+	  Note, this shares support with SMDK2413, so will automatically
+	  select MACH_SMDK2413.
+
 config MACH_VSTMS
 config MACH_VSTMS
 	bool "VMSTMS"
 	bool "VMSTMS"
 	select CPU_S3C2412
 	select CPU_S3C2412

+ 1 - 6
arch/arm/mach-s3c2412/mach-smdk2413.c

@@ -110,11 +110,6 @@ static struct platform_device *smdk2413_devices[] __initdata = {
 	&s3c_device_usbgadget,
 	&s3c_device_usbgadget,
 };
 };
 
 
-static struct s3c24xx_board smdk2413_board __initdata = {
-	.devices       = smdk2413_devices,
-	.devices_count = ARRAY_SIZE(smdk2413_devices)
-};
-
 static void __init smdk2413_fixup(struct machine_desc *desc,
 static void __init smdk2413_fixup(struct machine_desc *desc,
 				  struct tag *tags, char **cmdline,
 				  struct tag *tags, char **cmdline,
 				  struct meminfo *mi)
 				  struct meminfo *mi)
@@ -132,7 +127,6 @@ static void __init smdk2413_map_io(void)
 	s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
 	s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
 	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
 	s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
-	s3c24xx_set_board(&smdk2413_board);
 }
 }
 
 
 static void __init smdk2413_machine_init(void)
 static void __init smdk2413_machine_init(void)
@@ -149,6 +143,7 @@ static void __init smdk2413_machine_init(void)
 
 
  	s3c24xx_udc_set_platdata(&smdk2413_udc_cfg);
  	s3c24xx_udc_set_platdata(&smdk2413_udc_cfg);
 
 
+	platform_add_devices(smdk2413_devices, ARRAY_SIZE(smdk2413_devices));
 	smdk_machine_init();
 	smdk_machine_init();
 }
 }
 
 

+ 6 - 6
arch/arm/mach-s3c2412/mach-vstms.c

@@ -129,11 +129,6 @@ static struct platform_device *vstms_devices[] __initdata = {
 	&s3c_device_nand,
 	&s3c_device_nand,
 };
 };
 
 
-static struct s3c24xx_board vstms_board __initdata = {
-	.devices       = vstms_devices,
-	.devices_count = ARRAY_SIZE(vstms_devices)
-};
-
 static void __init vstms_fixup(struct machine_desc *desc,
 static void __init vstms_fixup(struct machine_desc *desc,
 				  struct tag *tags, char **cmdline,
 				  struct tag *tags, char **cmdline,
 				  struct meminfo *mi)
 				  struct meminfo *mi)
@@ -153,7 +148,11 @@ static void __init vstms_map_io(void)
 	s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
 	s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
 	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
 	s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
-	s3c24xx_set_board(&vstms_board);
+}
+
+static void __init vstms_init(void)
+{
+	platform_add_devices(vstms_devices, ARRAY_SIZE(vstms_devices));
 }
 }
 
 
 MACHINE_START(VSTMS, "VSTMS")
 MACHINE_START(VSTMS, "VSTMS")
@@ -163,6 +162,7 @@ MACHINE_START(VSTMS, "VSTMS")
 
 
 	.fixup		= vstms_fixup,
 	.fixup		= vstms_fixup,
 	.init_irq	= s3c24xx_init_irq,
 	.init_irq	= s3c24xx_init_irq,
+	.init_machine	= vstms_init,
 	.map_io		= vstms_map_io,
 	.map_io		= vstms_map_io,
 	.timer		= &s3c24xx_timer,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
 MACHINE_END

+ 9 - 8
arch/arm/mach-s3c2440/mach-anubis.c

@@ -281,13 +281,6 @@ static struct clk *anubis_clocks[] = {
 	&s3c24xx_uclk,
 	&s3c24xx_uclk,
 };
 };
 
 
-static struct s3c24xx_board anubis_board __initdata = {
-	.devices       = anubis_devices,
-	.devices_count = ARRAY_SIZE(anubis_devices),
-	.clocks	       = anubis_clocks,
-	.clocks_count  = ARRAY_SIZE(anubis_clocks),
-};
-
 static void __init anubis_map_io(void)
 static void __init anubis_map_io(void)
 {
 {
 	/* initialise the clocks */
 	/* initialise the clocks */
@@ -303,23 +296,31 @@ static void __init anubis_map_io(void)
 
 
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 
+	s3c24xx_register_clocks(anubis_clocks, ARRAY_SIZE(anubis_clocks));
+
 	s3c_device_nand.dev.platform_data = &anubis_nand_info;
 	s3c_device_nand.dev.platform_data = &anubis_nand_info;
 
 
 	s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
 	s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
 	s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
-	s3c24xx_set_board(&anubis_board);
 
 
 	/* ensure that the GPIO is setup */
 	/* ensure that the GPIO is setup */
 	s3c2410_gpio_setpin(S3C2410_GPA0, 1);
 	s3c2410_gpio_setpin(S3C2410_GPA0, 1);
 }
 }
 
 
+static void __init anubis_init(void)
+{
+	platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices));
+}
+
+
 MACHINE_START(ANUBIS, "Simtec-Anubis")
 MACHINE_START(ANUBIS, "Simtec-Anubis")
 	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
 	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
 	.phys_io	= S3C2410_PA_UART,
 	.phys_io	= S3C2410_PA_UART,
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= anubis_map_io,
 	.map_io		= anubis_map_io,
+	.init_machine	= anubis_init,
 	.init_irq	= s3c24xx_init_irq,
 	.init_irq	= s3c24xx_init_irq,
 	.timer		= &s3c24xx_timer,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
 MACHINE_END

+ 6 - 7
arch/arm/mach-s3c2440/mach-nexcoder.c

@@ -116,12 +116,6 @@ static struct platform_device *nexcoder_devices[] __initdata = {
 	&nexcoder_device_nor,
 	&nexcoder_device_nor,
 };
 };
 
 
-static struct s3c24xx_board nexcoder_board __initdata = {
-	.devices       = nexcoder_devices,
-	.devices_count = ARRAY_SIZE(nexcoder_devices),
-};
-
-
 static void __init nexcoder_sensorboard_init(void)
 static void __init nexcoder_sensorboard_init(void)
 {
 {
 	// Initialize SCCB bus
 	// Initialize SCCB bus
@@ -142,10 +136,14 @@ static void __init nexcoder_map_io(void)
 	s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
 	s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
 	s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
-	s3c24xx_set_board(&nexcoder_board);
+
 	nexcoder_sensorboard_init();
 	nexcoder_sensorboard_init();
 }
 }
 
 
+static void __init nexcoder_init(void)
+{
+	platform_add_devices(nexcoder_devices, ARRAY_SIZE(nexcoder_devices));
+};
 
 
 MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
 MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
 	/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
 	/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
@@ -153,6 +151,7 @@ MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= nexcoder_map_io,
 	.map_io		= nexcoder_map_io,
+	.init_machine	= nexcoder_init,
 	.init_irq	= s3c24xx_init_irq,
 	.init_irq	= s3c24xx_init_irq,
 	.timer		= &s3c24xx_timer,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
 MACHINE_END

+ 8 - 8
arch/arm/mach-s3c2440/mach-osiris.c

@@ -251,13 +251,6 @@ static struct clk *osiris_clocks[] = {
 	&s3c24xx_uclk,
 	&s3c24xx_uclk,
 };
 };
 
 
-static struct s3c24xx_board osiris_board __initdata = {
-	.devices       = osiris_devices,
-	.devices_count = ARRAY_SIZE(osiris_devices),
-	.clocks	       = osiris_clocks,
-	.clocks_count  = ARRAY_SIZE(osiris_clocks),
-};
-
 static void __init osiris_map_io(void)
 static void __init osiris_map_io(void)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
@@ -275,12 +268,13 @@ static void __init osiris_map_io(void)
 
 
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 
+	s3c24xx_register_clocks(osiris_clocks, ARRAY_SIZE(osiris_clocks));
+
 	s3c_device_nand.dev.platform_data = &osiris_nand_info;
 	s3c_device_nand.dev.platform_data = &osiris_nand_info;
 
 
 	s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
 	s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
 	s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
-	s3c24xx_set_board(&osiris_board);
 
 
 	/* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */
 	/* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */
 
 
@@ -292,12 +286,18 @@ static void __init osiris_map_io(void)
 	s3c2410_gpio_setpin(S3C2410_GPA0, 1);
 	s3c2410_gpio_setpin(S3C2410_GPA0, 1);
 }
 }
 
 
+static void __init osiris_init(void)
+{
+	platform_add_devices(osiris_devices, ARRAY_SIZE(osiris_devices));
+};
+
 MACHINE_START(OSIRIS, "Simtec-OSIRIS")
 MACHINE_START(OSIRIS, "Simtec-OSIRIS")
 	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
 	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
 	.phys_io	= S3C2410_PA_UART,
 	.phys_io	= S3C2410_PA_UART,
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= osiris_map_io,
 	.map_io		= osiris_map_io,
+	.init_machine	= osiris_init,
 	.init_irq	= s3c24xx_init_irq,
 	.init_irq	= s3c24xx_init_irq,
 	.timer		= &s3c24xx_timer,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
 MACHINE_END

+ 1 - 7
arch/arm/mach-s3c2440/mach-rx3715.c

@@ -202,11 +202,6 @@ static struct platform_device *rx3715_devices[] __initdata = {
 	&s3c_device_nand,
 	&s3c_device_nand,
 };
 };
 
 
-static struct s3c24xx_board rx3715_board __initdata = {
-	.devices       = rx3715_devices,
-	.devices_count = ARRAY_SIZE(rx3715_devices)
-};
-
 static void __init rx3715_map_io(void)
 static void __init rx3715_map_io(void)
 {
 {
 	s3c_device_nand.dev.platform_data = &rx3715_nand_info;
 	s3c_device_nand.dev.platform_data = &rx3715_nand_info;
@@ -214,7 +209,6 @@ static void __init rx3715_map_io(void)
 	s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
 	s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
 	s3c24xx_init_clocks(16934000);
 	s3c24xx_init_clocks(16934000);
 	s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
 	s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
-	s3c24xx_set_board(&rx3715_board);
 }
 }
 
 
 static void __init rx3715_init_irq(void)
 static void __init rx3715_init_irq(void)
@@ -230,9 +224,9 @@ static void __init rx3715_init_machine(void)
 	s3c2410_pm_init();
 	s3c2410_pm_init();
 
 
 	s3c24xx_fb_set_platdata(&rx3715_lcdcfg);
 	s3c24xx_fb_set_platdata(&rx3715_lcdcfg);
+	platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices));
 }
 }
 
 
-
 MACHINE_START(RX3715, "IPAQ-RX3715")
 MACHINE_START(RX3715, "IPAQ-RX3715")
 	/* Maintainer: Ben Dooks <ben@fluff.org> */
 	/* Maintainer: Ben Dooks <ben@fluff.org> */
 	.phys_io	= S3C2410_PA_UART,
 	.phys_io	= S3C2410_PA_UART,

+ 1 - 6
arch/arm/mach-s3c2440/mach-smdk2440.c

@@ -174,23 +174,18 @@ static struct platform_device *smdk2440_devices[] __initdata = {
 	&s3c_device_iis,
 	&s3c_device_iis,
 };
 };
 
 
-static struct s3c24xx_board smdk2440_board __initdata = {
-	.devices       = smdk2440_devices,
-	.devices_count = ARRAY_SIZE(smdk2440_devices)
-};
-
 static void __init smdk2440_map_io(void)
 static void __init smdk2440_map_io(void)
 {
 {
 	s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
 	s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
 	s3c24xx_init_clocks(16934400);
 	s3c24xx_init_clocks(16934400);
 	s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
 	s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
-	s3c24xx_set_board(&smdk2440_board);
 }
 }
 
 
 static void __init smdk2440_machine_init(void)
 static void __init smdk2440_machine_init(void)
 {
 {
 	s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
 	s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
 
 
+	platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
 	smdk_machine_init();
 	smdk_machine_init();
 }
 }
 
 

+ 1 - 6
arch/arm/mach-s3c2443/mach-smdk2443.c

@@ -106,21 +106,16 @@ static struct platform_device *smdk2443_devices[] __initdata = {
 	&s3c_device_i2c,
 	&s3c_device_i2c,
 };
 };
 
 
-static struct s3c24xx_board smdk2443_board __initdata = {
-	.devices       = smdk2443_devices,
-	.devices_count = ARRAY_SIZE(smdk2443_devices)
-};
-
 static void __init smdk2443_map_io(void)
 static void __init smdk2443_map_io(void)
 {
 {
 	s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
 	s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
 	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
 	s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
-	s3c24xx_set_board(&smdk2443_board);
 }
 }
 
 
 static void __init smdk2443_machine_init(void)
 static void __init smdk2443_machine_init(void)
 {
 {
+	platform_add_devices(smdk2443_devices, ARRAY_SIZE(smdk2443_devices));
 	smdk_machine_init();
 	smdk_machine_init();
 }
 }
 
 

+ 13 - 11
arch/arm/mach-sa1100/clock.c

@@ -9,14 +9,17 @@
 #include <linux/string.h>
 #include <linux/string.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
+#include <linux/mutex.h>
 
 
 #include <asm/hardware.h>
 #include <asm/hardware.h>
-#include <asm/semaphore.h>
 
 
+/*
+ * Very simple clock implementation - we only have one clock to
+ * deal with at the moment, so we only match using the "name".
+ */
 struct clk {
 struct clk {
 	struct list_head	node;
 	struct list_head	node;
 	unsigned long		rate;
 	unsigned long		rate;
-	struct module		*owner;
 	const char		*name;
 	const char		*name;
 	unsigned int		enabled;
 	unsigned int		enabled;
 	void			(*enable)(void);
 	void			(*enable)(void);
@@ -24,21 +27,21 @@ struct clk {
 };
 };
 
 
 static LIST_HEAD(clocks);
 static LIST_HEAD(clocks);
-static DECLARE_MUTEX(clocks_sem);
+static DEFINE_MUTEX(clocks_mutex);
 static DEFINE_SPINLOCK(clocks_lock);
 static DEFINE_SPINLOCK(clocks_lock);
 
 
 struct clk *clk_get(struct device *dev, const char *id)
 struct clk *clk_get(struct device *dev, const char *id)
 {
 {
 	struct clk *p, *clk = ERR_PTR(-ENOENT);
 	struct clk *p, *clk = ERR_PTR(-ENOENT);
 
 
-	down(&clocks_sem);
+	mutex_lock(&clocks_mutex);
 	list_for_each_entry(p, &clocks, node) {
 	list_for_each_entry(p, &clocks, node) {
-		if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+		if (strcmp(id, p->name) == 0) {
 			clk = p;
 			clk = p;
 			break;
 			break;
 		}
 		}
 	}
 	}
-	up(&clocks_sem);
+	mutex_unlock(&clocks_mutex);
 
 
 	return clk;
 	return clk;
 }
 }
@@ -46,7 +49,6 @@ EXPORT_SYMBOL(clk_get);
 
 
 void clk_put(struct clk *clk)
 void clk_put(struct clk *clk)
 {
 {
-	module_put(clk->owner);
 }
 }
 EXPORT_SYMBOL(clk_put);
 EXPORT_SYMBOL(clk_put);
 
 
@@ -109,18 +111,18 @@ static struct clk clk_gpio27 = {
 
 
 int clk_register(struct clk *clk)
 int clk_register(struct clk *clk)
 {
 {
-	down(&clocks_sem);
+	mutex_lock(&clocks_mutex);
 	list_add(&clk->node, &clocks);
 	list_add(&clk->node, &clocks);
-	up(&clocks_sem);
+	mutex_unlock(&clocks_mutex);
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL(clk_register);
 EXPORT_SYMBOL(clk_register);
 
 
 void clk_unregister(struct clk *clk)
 void clk_unregister(struct clk *clk)
 {
 {
-	down(&clocks_sem);
+	mutex_lock(&clocks_mutex);
 	list_del(&clk->node);
 	list_del(&clk->node);
-	up(&clocks_sem);
+	mutex_unlock(&clocks_mutex);
 }
 }
 EXPORT_SYMBOL(clk_unregister);
 EXPORT_SYMBOL(clk_unregister);
 
 

+ 85 - 44
arch/arm/mach-versatile/core.c

@@ -26,6 +26,8 @@
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
 #include <linux/amba/clcd.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
 
 
 #include <asm/cnt32_to_63.h>
 #include <asm/cnt32_to_63.h>
 #include <asm/system.h>
 #include <asm/system.h>
@@ -828,59 +830,61 @@ void __init versatile_init(void)
 #define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
 #define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
 #endif
 #endif
 
 
-/*
- * Returns number of ms since last clock interrupt.  Note that interrupts
- * will have been disabled by do_gettimeoffset()
- */
-static unsigned long versatile_gettimeoffset(void)
+static void timer_set_mode(enum clock_event_mode mode,
+			   struct clock_event_device *clk)
 {
 {
-	unsigned long ticks1, ticks2, status;
+	unsigned long ctrl;
 
 
-	/*
-	 * Get the current number of ticks.  Note that there is a race
-	 * condition between us reading the timer and checking for
-	 * an interrupt.  We get around this by ensuring that the
-	 * counter has not reloaded between our two reads.
-	 */
-	ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
-	do {
-		ticks1 = ticks2;
-		status = __raw_readl(VA_IC_BASE + VIC_RAW_STATUS);
-		ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
-	} while (ticks2 > ticks1);
+	switch(mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
 
 
-	/*
-	 * Number of ticks since last interrupt.
-	 */
-	ticks1 = TIMER_RELOAD - ticks2;
+		ctrl = TIMER_CTRL_PERIODIC;
+		ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE;
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* period set, and timer enabled in 'next_event' hook */
+		ctrl = TIMER_CTRL_ONESHOT;
+		ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE;
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	default:
+		ctrl = 0;
+	}
 
 
-	/*
-	 * Interrupt pending?  If so, we've reloaded once already.
-	 *
-	 * FIXME: Need to check this is effectively timer 0 that expires
-	 */
-	if (status & IRQMASK_TIMERINT0_1)
-		ticks1 += TIMER_RELOAD;
+	writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL);
+}
 
 
-	/*
-	 * Convert the ticks to usecs
-	 */
-	return TICKS2USECS(ticks1);
+static int timer_set_next_event(unsigned long evt,
+				struct clock_event_device *unused)
+{
+	unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL);
+
+	writel(evt, TIMER0_VA_BASE + TIMER_LOAD);
+	writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL);
+
+	return 0;
 }
 }
 
 
+static struct clock_event_device timer0_clockevent =	 {
+	.name		= "timer0",
+	.shift		= 32,
+	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode	= timer_set_mode,
+	.set_next_event	= timer_set_next_event,
+};
+
 /*
 /*
  * IRQ handler for the timer
  * IRQ handler for the timer
  */
  */
 static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id)
 static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id)
 {
 {
-	write_seqlock(&xtime_lock);
+	struct clock_event_device *evt = &timer0_clockevent;
 
 
-	// ...clear the interrupt
 	writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
 	writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
 
 
-	timer_tick();
-
-	write_sequnlock(&xtime_lock);
+	evt->event_handler(evt);
 
 
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
@@ -891,6 +895,36 @@ static struct irqaction versatile_timer_irq = {
 	.handler	= versatile_timer_interrupt,
 	.handler	= versatile_timer_interrupt,
 };
 };
 
 
+static cycle_t versatile_get_cycles(void)
+{
+	return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
+}
+
+static struct clocksource clocksource_versatile = {
+	.name 		= "timer3",
+ 	.rating		= 200,
+ 	.read		= versatile_get_cycles,
+	.mask		= CLOCKSOURCE_MASK(32),
+ 	.shift 		= 20,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init versatile_clocksource_init(void)
+{
+	/* setup timer3 as free-running clocksource */
+	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
+	writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD);
+	writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE);
+	writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
+	       TIMER3_VA_BASE + TIMER_CTRL);
+
+ 	clocksource_versatile.mult =
+ 		clocksource_khz2mult(1000, clocksource_versatile.shift);
+ 	clocksource_register(&clocksource_versatile);
+
+ 	return 0;
+}
+
 /*
 /*
  * Set up timer interrupt, and return the current time in seconds.
  * Set up timer interrupt, and return the current time in seconds.
  */
  */
@@ -918,18 +952,25 @@ static void __init versatile_timer_init(void)
 	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
 	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
 	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
 	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
 
 
-	writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
-	writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE);
-	writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC |
-	       TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL);
-
 	/* 
 	/* 
 	 * Make irqs happen for the system timer
 	 * Make irqs happen for the system timer
 	 */
 	 */
 	setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq);
 	setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq);
+
+	versatile_clocksource_init();
+
+	timer0_clockevent.mult =
+		div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
+	timer0_clockevent.max_delta_ns =
+		clockevent_delta2ns(0xffffffff, &timer0_clockevent);
+	timer0_clockevent.min_delta_ns =
+		clockevent_delta2ns(0xf, &timer0_clockevent);
+
+	timer0_clockevent.cpumask = cpumask_of_cpu(0);
+	clockevents_register_device(&timer0_clockevent);
 }
 }
 
 
 struct sys_timer versatile_timer = {
 struct sys_timer versatile_timer = {
 	.init		= versatile_timer_init,
 	.init		= versatile_timer_init,
-	.offset		= versatile_gettimeoffset,
 };
 };
+

+ 17 - 52
arch/arm/oprofile/backtrace.c

@@ -19,6 +19,19 @@
 #include <asm/ptrace.h>
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 
 
+#include "../kernel/stacktrace.h"
+
+static int report_trace(struct stackframe *frame, void *d)
+{
+	unsigned int *depth = d;
+
+	if (*depth) {
+		oprofile_add_trace(frame->lr);
+		(*depth)--;
+	}
+
+	return *depth == 0;
+}
 
 
 /*
 /*
  * The registers we're interested in are at the end of the variable
  * The registers we're interested in are at the end of the variable
@@ -32,21 +45,6 @@ struct frame_tail {
 	unsigned long lr;
 	unsigned long lr;
 } __attribute__((packed));
 } __attribute__((packed));
 
 
-
-#ifdef CONFIG_FRAME_POINTER
-static struct frame_tail* kernel_backtrace(struct frame_tail *tail)
-{
-	oprofile_add_trace(tail->lr);
-
-	/* frame pointers should strictly progress back up the stack
-	 * (towards higher addresses) */
-	if (tail >= tail->fp)
-		return NULL;
-
-	return tail->fp-1;
-}
-#endif
-
 static struct frame_tail* user_backtrace(struct frame_tail *tail)
 static struct frame_tail* user_backtrace(struct frame_tail *tail)
 {
 {
 	struct frame_tail buftail[2];
 	struct frame_tail buftail[2];
@@ -67,47 +65,14 @@ static struct frame_tail* user_backtrace(struct frame_tail *tail)
 	return buftail[0].fp-1;
 	return buftail[0].fp-1;
 }
 }
 
 
-/*
- * |             | /\ Higher addresses
- * |             |
- * --------------- stack base (address of current_thread_info)
- * | thread info |
- * .             .
- * |    stack    |
- * --------------- saved regs->ARM_fp value if valid (frame_tail address)
- * .             .
- * --------------- struct pt_regs stored on stack (struct pt_regs *)
- * |             |
- * .             .
- * |             |
- * --------------- %esp
- * |             |
- * |             | \/ Lower addresses
- *
- * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values
- */
-static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs)
-{
-	unsigned long tailaddr = (unsigned long)tail;
-	unsigned long stack = (unsigned long)regs;
-	unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
-
-	return (tailaddr > stack) && (tailaddr < stack_base);
-}
-
 void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
 void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
 {
 {
-	struct frame_tail *tail;
-
-	tail = ((struct frame_tail *) regs->ARM_fp) - 1;
+	struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1;
 
 
 	if (!user_mode(regs)) {
 	if (!user_mode(regs)) {
-
-#ifdef CONFIG_FRAME_POINTER
-		while (depth-- && tail && valid_kernel_stack(tail, regs)) {
-			tail = kernel_backtrace(tail);
-		}
-#endif
+		unsigned long base = ((unsigned long)regs) & ~(THREAD_SIZE - 1);
+		walk_stackframe(regs->ARM_fp, base, base + THREAD_SIZE,
+				report_trace, &depth);
 		return;
 		return;
 	}
 	}
 
 

+ 139 - 1
arch/arm/plat-iop/pci.c

@@ -55,7 +55,7 @@ static u32 iop3xx_cfg_address(struct pci_bus *bus, int devfn, int where)
  * This routine checks the status of the last configuration cycle.  If an error
  * This routine checks the status of the last configuration cycle.  If an error
  * was detected it returns a 1, else it returns a 0.  The errors being checked
  * was detected it returns a 1, else it returns a 0.  The errors being checked
  * are parity, master abort, target abort (master and target).  These types of
  * are parity, master abort, target abort (master and target).  These types of
- * errors occure during a config cycle where there is no device, like during
+ * errors occur during a config cycle where there is no device, like during
  * the discovery stage.
  * the discovery stage.
  */
  */
 static int iop3xx_pci_status(void)
 static int iop3xx_pci_status(void)
@@ -223,8 +223,111 @@ struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys)
 	return pci_scan_bus(sys->busnr, &iop3xx_ops, sys);
 	return pci_scan_bus(sys->busnr, &iop3xx_ops, sys);
 }
 }
 
 
+void __init iop3xx_atu_setup(void)
+{
+	/* BAR 0 ( Disabled ) */
+	*IOP3XX_IAUBAR0 = 0x0;
+	*IOP3XX_IABAR0  = 0x0;
+	*IOP3XX_IATVR0  = 0x0;
+	*IOP3XX_IALR0   = 0x0;
+
+	/* BAR 1 ( Disabled ) */
+	*IOP3XX_IAUBAR1 = 0x0;
+	*IOP3XX_IABAR1  = 0x0;
+	*IOP3XX_IALR1   = 0x0;
+
+	/* BAR 2 (1:1 mapping with Physical RAM) */
+	/* Set limit and enable */
+	*IOP3XX_IALR2 = ~((u32)IOP3XX_MAX_RAM_SIZE - 1) & ~0x1;
+	*IOP3XX_IAUBAR2 = 0x0;
+
+	/* Align the inbound bar with the base of memory */
+	*IOP3XX_IABAR2 = PHYS_OFFSET |
+			       PCI_BASE_ADDRESS_MEM_TYPE_64 |
+			       PCI_BASE_ADDRESS_MEM_PREFETCH;
+
+	*IOP3XX_IATVR2 = PHYS_OFFSET;
+
+	/* Outbound window 0 */
+	*IOP3XX_OMWTVR0 = IOP3XX_PCI_LOWER_MEM_PA;
+	*IOP3XX_OUMWTVR0 = 0;
+
+	/* Outbound window 1 */
+	*IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE;
+	*IOP3XX_OUMWTVR1 = 0;
+
+	/* BAR 3 ( Disabled ) */
+	*IOP3XX_IAUBAR3 = 0x0;
+	*IOP3XX_IABAR3  = 0x0;
+	*IOP3XX_IATVR3  = 0x0;
+	*IOP3XX_IALR3   = 0x0;
+
+	/* Setup the I/O Bar
+	 */
+	*IOP3XX_OIOWTVR = IOP3XX_PCI_LOWER_IO_PA;;
+
+	/* Enable inbound and outbound cycles
+	 */
+	*IOP3XX_ATUCMD |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+			       PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+	*IOP3XX_ATUCR |= IOP3XX_ATUCR_OUT_EN;
+}
+
+void __init iop3xx_atu_disable(void)
+{
+	*IOP3XX_ATUCMD = 0;
+	*IOP3XX_ATUCR = 0;
+
+	/* wait for cycles to quiesce */
+	while (*IOP3XX_PCSR & (IOP3XX_PCSR_OUT_Q_BUSY |
+				     IOP3XX_PCSR_IN_Q_BUSY))
+		cpu_relax();
+
+	/* BAR 0 ( Disabled ) */
+	*IOP3XX_IAUBAR0 = 0x0;
+	*IOP3XX_IABAR0  = 0x0;
+	*IOP3XX_IATVR0  = 0x0;
+	*IOP3XX_IALR0   = 0x0;
+
+	/* BAR 1 ( Disabled ) */
+	*IOP3XX_IAUBAR1 = 0x0;
+	*IOP3XX_IABAR1  = 0x0;
+	*IOP3XX_IALR1   = 0x0;
+
+	/* BAR 2 ( Disabled ) */
+	*IOP3XX_IAUBAR2 = 0x0;
+	*IOP3XX_IABAR2  = 0x0;
+	*IOP3XX_IATVR2  = 0x0;
+	*IOP3XX_IALR2   = 0x0;
+
+	/* BAR 3 ( Disabled ) */
+	*IOP3XX_IAUBAR3 = 0x0;
+	*IOP3XX_IABAR3  = 0x0;
+	*IOP3XX_IATVR3  = 0x0;
+	*IOP3XX_IALR3   = 0x0;
+
+	/* Clear the outbound windows */
+	*IOP3XX_OIOWTVR  = 0;
+
+	/* Outbound window 0 */
+	*IOP3XX_OMWTVR0 = 0;
+	*IOP3XX_OUMWTVR0 = 0;
+
+	/* Outbound window 1 */
+	*IOP3XX_OMWTVR1 = 0;
+	*IOP3XX_OUMWTVR1 = 0;
+}
+
+/* Flag to determine whether the ATU is initialized and the PCI bus scanned */
+int init_atu;
+
 void iop3xx_pci_preinit(void)
 void iop3xx_pci_preinit(void)
 {
 {
+	if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) {
+		iop3xx_atu_disable();
+		iop3xx_atu_setup();
+	}
+
 	DBG("PCI:  Intel 803xx PCI init code.\n");
 	DBG("PCI:  Intel 803xx PCI init code.\n");
 	DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD);
 	DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD);
 	DBG("ATU: IOP3XX_OMWTVR0=0x%04x, IOP3XX_OIOWTVR=0x%04x\n",
 	DBG("ATU: IOP3XX_OMWTVR0=0x%04x, IOP3XX_OIOWTVR=0x%04x\n",
@@ -245,3 +348,38 @@ void iop3xx_pci_preinit(void)
 
 
 	hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort");
 	hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort");
 }
 }
+
+/* allow init_atu to be user overridden */
+static int __init iop3xx_init_atu_setup(char *str)
+{
+	init_atu = IOP3XX_INIT_ATU_DEFAULT;
+	if (str) {
+		while (*str != '\0') {
+			switch (*str) {
+			case 'y':
+			case 'Y':
+				init_atu = IOP3XX_INIT_ATU_ENABLE;
+				break;
+			case 'n':
+			case 'N':
+				init_atu = IOP3XX_INIT_ATU_DISABLE;
+				break;
+			case ',':
+			case '=':
+				break;
+			default:
+				printk(KERN_DEBUG "\"%s\" malformed at "
+					    "character: \'%c\'",
+					    __FUNCTION__,
+					    *str);
+				*(str + 1) = '\0';
+			}
+			str++;
+		}
+	}
+
+	return 1;
+}
+
+__setup("iop3xx_init_atu", iop3xx_init_atu_setup);
+

+ 4 - 4
arch/arm/plat-iop/time.c

@@ -32,22 +32,22 @@ static unsigned long next_jiffy_time;
 
 
 unsigned long iop_gettimeoffset(void)
 unsigned long iop_gettimeoffset(void)
 {
 {
-	unsigned long offset, temp1, temp2;
+	unsigned long offset, temp;
 
 
 	/* enable cp6, if necessary, to avoid taking the overhead of an
 	/* enable cp6, if necessary, to avoid taking the overhead of an
 	 * undefined instruction trap
 	 * undefined instruction trap
 	 */
 	 */
 	asm volatile (
 	asm volatile (
 	"mrc	p15, 0, %0, c15, c1, 0\n\t"
 	"mrc	p15, 0, %0, c15, c1, 0\n\t"
-	"ands	%1, %0, #(1 << 6)\n\t"
+	"tst	%0, #(1 << 6)\n\t"
 	"orreq	%0, %0, #(1 << 6)\n\t"
 	"orreq	%0, %0, #(1 << 6)\n\t"
 	"mcreq	p15, 0, %0, c15, c1, 0\n\t"
 	"mcreq	p15, 0, %0, c15, c1, 0\n\t"
-#ifdef CONFIG_XSCALE
+#ifdef CONFIG_CPU_XSCALE
 	"mrceq	p15, 0, %0, c15, c1, 0\n\t"
 	"mrceq	p15, 0, %0, c15, c1, 0\n\t"
 	"moveq	%0, %0\n\t"
 	"moveq	%0, %0\n\t"
 	"subeq	pc, pc, #4\n\t"
 	"subeq	pc, pc, #4\n\t"
 #endif
 #endif
-	: "=r"(temp1), "=r"(temp2) : : "cc");
+	: "=r"(temp) : : "cc");
 
 
 	offset = next_jiffy_time - read_tcr1();
 	offset = next_jiffy_time - read_tcr1();
 
 

+ 1 - 0
arch/arm/plat-omap/Kconfig

@@ -11,6 +11,7 @@ choice
 
 
 config ARCH_OMAP1
 config ARCH_OMAP1
 	bool "TI OMAP1"
 	bool "TI OMAP1"
+	select GENERIC_CLOCKEVENTS
 
 
 config ARCH_OMAP2
 config ARCH_OMAP2
 	bool "TI OMAP2"
 	bool "TI OMAP2"

+ 50 - 0
arch/arm/plat-omap/common.c

@@ -156,3 +156,53 @@ static int __init omap_add_serial_console(void)
 	return add_preferred_console("ttyS", line, opt);
 	return add_preferred_console("ttyS", line, opt);
 }
 }
 console_initcall(omap_add_serial_console);
 console_initcall(omap_add_serial_console);
+
+
+/*
+ * 32KHz clocksource ... always available, on pretty most chips except
+ * OMAP 730 and 1510.  Other timers could be used as clocksources, with
+ * higher resolution in free-running counter modes (e.g. 12 MHz xtal),
+ * but systems won't necessarily want to spend resources that way.
+ */
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+#define TIMER_32K_SYNCHRONIZED		0xfffbc410
+#elif defined(CONFIG_ARCH_OMAP24XX)
+#define TIMER_32K_SYNCHRONIZED		0x48004010
+#endif
+
+#ifdef	TIMER_32K_SYNCHRONIZED
+
+#include <linux/clocksource.h>
+
+static cycle_t omap_32k_read(void)
+{
+	return omap_readl(TIMER_32K_SYNCHRONIZED);
+}
+
+static struct clocksource clocksource_32k = {
+	.name		= "32k_counter",
+	.rating		= 250,
+	.read		= omap_32k_read,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.shift		= 10,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init omap_init_clocksource_32k(void)
+{
+	static char err[] __initdata = KERN_ERR
+			"%s: can't register clocksource!\n";
+
+	if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
+		clocksource_32k.mult = clocksource_hz2mult(32768,
+					    clocksource_32k.shift);
+
+		if (clocksource_register(&clocksource_32k))
+			printk(err, clocksource_32k.name);
+	}
+	return 0;
+}
+arch_initcall(omap_init_clocksource_32k);
+
+#endif	/* TIMER_32K_SYNCHRONIZED */

+ 5 - 1
arch/arm/plat-omap/devices.c

@@ -429,6 +429,10 @@ static inline void omap_init_rng(void) {}
  */
  */
 static int __init omap_init_devices(void)
 static int __init omap_init_devices(void)
 {
 {
+/*
+ * Need to enable relevant once for 2430 SDP
+ */
+#ifndef CONFIG_MACH_OMAP_2430SDP
 	/* please keep these calls, and their implementations above,
 	/* please keep these calls, and their implementations above,
 	 * in alphabetical order so they're easier to sort through.
 	 * in alphabetical order so they're easier to sort through.
 	 */
 	 */
@@ -438,7 +442,7 @@ static int __init omap_init_devices(void)
 	omap_init_uwire();
 	omap_init_uwire();
 	omap_init_wdt();
 	omap_init_wdt();
 	omap_init_rng();
 	omap_init_rng();
-
+#endif
 	return 0;
 	return 0;
 }
 }
 arch_initcall(omap_init_devices);
 arch_initcall(omap_init_devices);

+ 2 - 0
arch/arm/plat-omap/dmtimer.c

@@ -506,6 +506,8 @@ int omap_dm_timer_init(void)
 		BUG_ON(dm_source_clocks[i] == NULL);
 		BUG_ON(dm_source_clocks[i] == NULL);
 	}
 	}
 #endif
 #endif
+	if (cpu_is_omap243x())
+		dm_timers[0].phys_base = 0x49018000;
 
 
 	for (i = 0; i < dm_timer_count; i++) {
 	for (i = 0; i < dm_timer_count; i++) {
 #ifdef CONFIG_ARCH_OMAP2
 #ifdef CONFIG_ARCH_OMAP2

+ 544 - 68
arch/arm/plat-omap/gpio.c

@@ -85,10 +85,17 @@
 /*
 /*
  * omap24xx specific GPIO registers
  * omap24xx specific GPIO registers
  */
  */
-#define OMAP24XX_GPIO1_BASE		(void __iomem *)0x48018000
-#define OMAP24XX_GPIO2_BASE		(void __iomem *)0x4801a000
-#define OMAP24XX_GPIO3_BASE		(void __iomem *)0x4801c000
-#define OMAP24XX_GPIO4_BASE		(void __iomem *)0x4801e000
+#define OMAP242X_GPIO1_BASE		(void __iomem *)0x48018000
+#define OMAP242X_GPIO2_BASE		(void __iomem *)0x4801a000
+#define OMAP242X_GPIO3_BASE		(void __iomem *)0x4801c000
+#define OMAP242X_GPIO4_BASE		(void __iomem *)0x4801e000
+
+#define OMAP243X_GPIO1_BASE		(void __iomem *)0x4900C000
+#define OMAP243X_GPIO2_BASE		(void __iomem *)0x4900E000
+#define OMAP243X_GPIO3_BASE		(void __iomem *)0x49010000
+#define OMAP243X_GPIO4_BASE		(void __iomem *)0x49012000
+#define OMAP243X_GPIO5_BASE		(void __iomem *)0x480B6000
+
 #define OMAP24XX_GPIO_REVISION		0x0000
 #define OMAP24XX_GPIO_REVISION		0x0000
 #define OMAP24XX_GPIO_SYSCONFIG		0x0010
 #define OMAP24XX_GPIO_SYSCONFIG		0x0010
 #define OMAP24XX_GPIO_SYSSTATUS		0x0014
 #define OMAP24XX_GPIO_SYSSTATUS		0x0014
@@ -117,8 +124,18 @@ struct gpio_bank {
 	u16 virtual_irq_start;
 	u16 virtual_irq_start;
 	int method;
 	int method;
 	u32 reserved_map;
 	u32 reserved_map;
+#if defined (CONFIG_ARCH_OMAP16XX) || defined (CONFIG_ARCH_OMAP24XX)
 	u32 suspend_wakeup;
 	u32 suspend_wakeup;
 	u32 saved_wakeup;
 	u32 saved_wakeup;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
+	u32 non_wakeup_gpios;
+	u32 enabled_non_wakeup_gpios;
+
+	u32 saved_datain;
+	u32 saved_fallingdetect;
+	u32 saved_risingdetect;
+#endif
 	spinlock_t lock;
 	spinlock_t lock;
 };
 };
 
 
@@ -158,12 +175,22 @@ static struct gpio_bank gpio_bank_730[7] = {
 #endif
 #endif
 
 
 #ifdef CONFIG_ARCH_OMAP24XX
 #ifdef CONFIG_ARCH_OMAP24XX
-static struct gpio_bank gpio_bank_24xx[4] = {
-	{ OMAP24XX_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,	METHOD_GPIO_24XX },
-	{ OMAP24XX_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,	METHOD_GPIO_24XX },
-	{ OMAP24XX_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,	METHOD_GPIO_24XX },
-	{ OMAP24XX_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,	METHOD_GPIO_24XX },
+
+static struct gpio_bank gpio_bank_242x[4] = {
+	{ OMAP242X_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,	METHOD_GPIO_24XX },
+	{ OMAP242X_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,	METHOD_GPIO_24XX },
+	{ OMAP242X_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,	METHOD_GPIO_24XX },
+	{ OMAP242X_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,	METHOD_GPIO_24XX },
+};
+
+static struct gpio_bank gpio_bank_243x[5] = {
+	{ OMAP243X_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE,	METHOD_GPIO_24XX },
+	{ OMAP243X_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32,	METHOD_GPIO_24XX },
+	{ OMAP243X_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64,	METHOD_GPIO_24XX },
+	{ OMAP243X_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96,	METHOD_GPIO_24XX },
+	{ OMAP243X_GPIO5_BASE, INT_24XX_GPIO_BANK5, IH_GPIO_BASE + 128, METHOD_GPIO_24XX },
 };
 };
+
 #endif
 #endif
 
 
 static struct gpio_bank *gpio_bank;
 static struct gpio_bank *gpio_bank;
@@ -257,21 +284,34 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
 	u32 l;
 	u32 l;
 
 
 	switch (bank->method) {
 	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
 	case METHOD_MPUIO:
 	case METHOD_MPUIO:
 		reg += OMAP_MPUIO_IO_CNTL;
 		reg += OMAP_MPUIO_IO_CNTL;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
 	case METHOD_GPIO_1510:
 	case METHOD_GPIO_1510:
 		reg += OMAP1510_GPIO_DIR_CONTROL;
 		reg += OMAP1510_GPIO_DIR_CONTROL;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
 	case METHOD_GPIO_1610:
 	case METHOD_GPIO_1610:
 		reg += OMAP1610_GPIO_DIRECTION;
 		reg += OMAP1610_GPIO_DIRECTION;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
 	case METHOD_GPIO_730:
 	case METHOD_GPIO_730:
 		reg += OMAP730_GPIO_DIR_CONTROL;
 		reg += OMAP730_GPIO_DIR_CONTROL;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
 	case METHOD_GPIO_24XX:
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_OE;
 		reg += OMAP24XX_GPIO_OE;
 		break;
 		break;
+#endif
+	default:
+		WARN_ON(1);
+		return;
 	}
 	}
 	l = __raw_readl(reg);
 	l = __raw_readl(reg);
 	if (is_input)
 	if (is_input)
@@ -299,6 +339,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 	u32 l = 0;
 	u32 l = 0;
 
 
 	switch (bank->method) {
 	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
 	case METHOD_MPUIO:
 	case METHOD_MPUIO:
 		reg += OMAP_MPUIO_OUTPUT;
 		reg += OMAP_MPUIO_OUTPUT;
 		l = __raw_readl(reg);
 		l = __raw_readl(reg);
@@ -307,6 +348,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 		else
 		else
 			l &= ~(1 << gpio);
 			l &= ~(1 << gpio);
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
 	case METHOD_GPIO_1510:
 	case METHOD_GPIO_1510:
 		reg += OMAP1510_GPIO_DATA_OUTPUT;
 		reg += OMAP1510_GPIO_DATA_OUTPUT;
 		l = __raw_readl(reg);
 		l = __raw_readl(reg);
@@ -315,6 +358,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 		else
 		else
 			l &= ~(1 << gpio);
 			l &= ~(1 << gpio);
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
 	case METHOD_GPIO_1610:
 	case METHOD_GPIO_1610:
 		if (enable)
 		if (enable)
 			reg += OMAP1610_GPIO_SET_DATAOUT;
 			reg += OMAP1610_GPIO_SET_DATAOUT;
@@ -322,6 +367,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 			reg += OMAP1610_GPIO_CLEAR_DATAOUT;
 			reg += OMAP1610_GPIO_CLEAR_DATAOUT;
 		l = 1 << gpio;
 		l = 1 << gpio;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
 	case METHOD_GPIO_730:
 	case METHOD_GPIO_730:
 		reg += OMAP730_GPIO_DATA_OUTPUT;
 		reg += OMAP730_GPIO_DATA_OUTPUT;
 		l = __raw_readl(reg);
 		l = __raw_readl(reg);
@@ -330,6 +377,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 		else
 		else
 			l &= ~(1 << gpio);
 			l &= ~(1 << gpio);
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
 	case METHOD_GPIO_24XX:
 	case METHOD_GPIO_24XX:
 		if (enable)
 		if (enable)
 			reg += OMAP24XX_GPIO_SETDATAOUT;
 			reg += OMAP24XX_GPIO_SETDATAOUT;
@@ -337,8 +386,9 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 			reg += OMAP24XX_GPIO_CLEARDATAOUT;
 			reg += OMAP24XX_GPIO_CLEARDATAOUT;
 		l = 1 << gpio;
 		l = 1 << gpio;
 		break;
 		break;
+#endif
 	default:
 	default:
-		BUG();
+		WARN_ON(1);
 		return;
 		return;
 	}
 	}
 	__raw_writel(l, reg);
 	__raw_writel(l, reg);
@@ -362,28 +412,37 @@ int omap_get_gpio_datain(int gpio)
 	void __iomem *reg;
 	void __iomem *reg;
 
 
 	if (check_gpio(gpio) < 0)
 	if (check_gpio(gpio) < 0)
-		return -1;
+		return -EINVAL;
 	bank = get_gpio_bank(gpio);
 	bank = get_gpio_bank(gpio);
 	reg = bank->base;
 	reg = bank->base;
 	switch (bank->method) {
 	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
 	case METHOD_MPUIO:
 	case METHOD_MPUIO:
 		reg += OMAP_MPUIO_INPUT_LATCH;
 		reg += OMAP_MPUIO_INPUT_LATCH;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
 	case METHOD_GPIO_1510:
 	case METHOD_GPIO_1510:
 		reg += OMAP1510_GPIO_DATA_INPUT;
 		reg += OMAP1510_GPIO_DATA_INPUT;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
 	case METHOD_GPIO_1610:
 	case METHOD_GPIO_1610:
 		reg += OMAP1610_GPIO_DATAIN;
 		reg += OMAP1610_GPIO_DATAIN;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
 	case METHOD_GPIO_730:
 	case METHOD_GPIO_730:
 		reg += OMAP730_GPIO_DATA_INPUT;
 		reg += OMAP730_GPIO_DATA_INPUT;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
 	case METHOD_GPIO_24XX:
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_DATAIN;
 		reg += OMAP24XX_GPIO_DATAIN;
 		break;
 		break;
+#endif
 	default:
 	default:
-		BUG();
-		return -1;
+		return -EINVAL;
 	}
 	}
 	return (__raw_readl(reg)
 	return (__raw_readl(reg)
 			& (1 << get_gpio_index(gpio))) != 0;
 			& (1 << get_gpio_index(gpio))) != 0;
@@ -397,8 +456,10 @@ do {	\
 	__raw_writel(l, base + reg); \
 	__raw_writel(l, base + reg); \
 } while(0)
 } while(0)
 
 
-static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int trigger)
+#ifdef CONFIG_ARCH_OMAP24XX
+static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 {
 {
+	void __iomem *base = bank->base;
 	u32 gpio_bit = 1 << gpio;
 	u32 gpio_bit = 1 << gpio;
 
 
 	MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
 	MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
@@ -409,9 +470,21 @@ static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int tr
 		trigger & __IRQT_RISEDGE);
 		trigger & __IRQT_RISEDGE);
 	MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
 	MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
 		trigger & __IRQT_FALEDGE);
 		trigger & __IRQT_FALEDGE);
+	if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
+		if (trigger != 0)
+			__raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_SETWKUENA);
+		else
+			__raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_CLEARWKUENA);
+	} else {
+		if (trigger != 0)
+			bank->enabled_non_wakeup_gpios |= gpio_bit;
+		else
+			bank->enabled_non_wakeup_gpios &= ~gpio_bit;
+	}
 	/* FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only level
 	/* FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only level
 	 * triggering requested. */
 	 * triggering requested. */
 }
 }
+#endif
 
 
 static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 {
 {
@@ -419,6 +492,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 	u32 l = 0;
 	u32 l = 0;
 
 
 	switch (bank->method) {
 	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
 	case METHOD_MPUIO:
 	case METHOD_MPUIO:
 		reg += OMAP_MPUIO_GPIO_INT_EDGE;
 		reg += OMAP_MPUIO_GPIO_INT_EDGE;
 		l = __raw_readl(reg);
 		l = __raw_readl(reg);
@@ -429,6 +503,8 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 		else
 		else
 			goto bad;
 			goto bad;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
 	case METHOD_GPIO_1510:
 	case METHOD_GPIO_1510:
 		reg += OMAP1510_GPIO_INT_CONTROL;
 		reg += OMAP1510_GPIO_INT_CONTROL;
 		l = __raw_readl(reg);
 		l = __raw_readl(reg);
@@ -439,22 +515,28 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 		else
 		else
 			goto bad;
 			goto bad;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
 	case METHOD_GPIO_1610:
 	case METHOD_GPIO_1610:
 		if (gpio & 0x08)
 		if (gpio & 0x08)
 			reg += OMAP1610_GPIO_EDGE_CTRL2;
 			reg += OMAP1610_GPIO_EDGE_CTRL2;
 		else
 		else
 			reg += OMAP1610_GPIO_EDGE_CTRL1;
 			reg += OMAP1610_GPIO_EDGE_CTRL1;
 		gpio &= 0x07;
 		gpio &= 0x07;
-		/* We allow only edge triggering, i.e. two lowest bits */
-		if (trigger & (__IRQT_LOWLVL | __IRQT_HIGHLVL))
-			BUG();
 		l = __raw_readl(reg);
 		l = __raw_readl(reg);
 		l &= ~(3 << (gpio << 1));
 		l &= ~(3 << (gpio << 1));
 		if (trigger & __IRQT_RISEDGE)
 		if (trigger & __IRQT_RISEDGE)
 			l |= 2 << (gpio << 1);
 			l |= 2 << (gpio << 1);
 		if (trigger & __IRQT_FALEDGE)
 		if (trigger & __IRQT_FALEDGE)
 			l |= 1 << (gpio << 1);
 			l |= 1 << (gpio << 1);
+		if (trigger)
+			/* Enable wake-up during idle for dynamic tick */
+			__raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_SET_WAKEUPENA);
+		else
+			__raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA);
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
 	case METHOD_GPIO_730:
 	case METHOD_GPIO_730:
 		reg += OMAP730_GPIO_INT_CONTROL;
 		reg += OMAP730_GPIO_INT_CONTROL;
 		l = __raw_readl(reg);
 		l = __raw_readl(reg);
@@ -465,11 +547,13 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
 		else
 		else
 			goto bad;
 			goto bad;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
 	case METHOD_GPIO_24XX:
 	case METHOD_GPIO_24XX:
-		set_24xx_gpio_triggering(reg, gpio, trigger);
+		set_24xx_gpio_triggering(bank, gpio, trigger);
 		break;
 		break;
+#endif
 	default:
 	default:
-		BUG();
 		goto bad;
 		goto bad;
 	}
 	}
 	__raw_writel(l, reg);
 	__raw_writel(l, reg);
@@ -484,7 +568,7 @@ static int gpio_irq_type(unsigned irq, unsigned type)
 	unsigned gpio;
 	unsigned gpio;
 	int retval;
 	int retval;
 
 
-	if (irq > IH_MPUIO_BASE)
+	if (!cpu_is_omap24xx() && irq > IH_MPUIO_BASE)
 		gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
 		gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
 	else
 	else
 		gpio = irq - IH_GPIO_BASE;
 		gpio = irq - IH_GPIO_BASE;
@@ -492,14 +576,21 @@ static int gpio_irq_type(unsigned irq, unsigned type)
 	if (check_gpio(gpio) < 0)
 	if (check_gpio(gpio) < 0)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	if (type & IRQT_PROBE)
+	if (type & ~IRQ_TYPE_SENSE_MASK)
 		return -EINVAL;
 		return -EINVAL;
-	if (!cpu_is_omap24xx() && (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL)))
+
+	/* OMAP1 allows only only edge triggering */
+	if (!cpu_is_omap24xx()
+			&& (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	bank = get_gpio_bank(gpio);
+	bank = get_irq_chip_data(irq);
 	spin_lock(&bank->lock);
 	spin_lock(&bank->lock);
 	retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
 	retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
+	if (retval == 0) {
+		irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
+		irq_desc[irq].status |= type;
+	}
 	spin_unlock(&bank->lock);
 	spin_unlock(&bank->lock);
 	return retval;
 	return retval;
 }
 }
@@ -509,24 +600,34 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
 	void __iomem *reg = bank->base;
 	void __iomem *reg = bank->base;
 
 
 	switch (bank->method) {
 	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
 	case METHOD_MPUIO:
 	case METHOD_MPUIO:
 		/* MPUIO irqstatus is reset by reading the status register,
 		/* MPUIO irqstatus is reset by reading the status register,
 		 * so do nothing here */
 		 * so do nothing here */
 		return;
 		return;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
 	case METHOD_GPIO_1510:
 	case METHOD_GPIO_1510:
 		reg += OMAP1510_GPIO_INT_STATUS;
 		reg += OMAP1510_GPIO_INT_STATUS;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
 	case METHOD_GPIO_1610:
 	case METHOD_GPIO_1610:
 		reg += OMAP1610_GPIO_IRQSTATUS1;
 		reg += OMAP1610_GPIO_IRQSTATUS1;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
 	case METHOD_GPIO_730:
 	case METHOD_GPIO_730:
 		reg += OMAP730_GPIO_INT_STATUS;
 		reg += OMAP730_GPIO_INT_STATUS;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
 	case METHOD_GPIO_24XX:
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_IRQSTATUS1;
 		reg += OMAP24XX_GPIO_IRQSTATUS1;
 		break;
 		break;
+#endif
 	default:
 	default:
-		BUG();
+		WARN_ON(1);
 		return;
 		return;
 	}
 	}
 	__raw_writel(gpio_mask, reg);
 	__raw_writel(gpio_mask, reg);
@@ -549,31 +650,41 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
 	u32 mask;
 	u32 mask;
 
 
 	switch (bank->method) {
 	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
 	case METHOD_MPUIO:
 	case METHOD_MPUIO:
 		reg += OMAP_MPUIO_GPIO_MASKIT;
 		reg += OMAP_MPUIO_GPIO_MASKIT;
 		mask = 0xffff;
 		mask = 0xffff;
 		inv = 1;
 		inv = 1;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
 	case METHOD_GPIO_1510:
 	case METHOD_GPIO_1510:
 		reg += OMAP1510_GPIO_INT_MASK;
 		reg += OMAP1510_GPIO_INT_MASK;
 		mask = 0xffff;
 		mask = 0xffff;
 		inv = 1;
 		inv = 1;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
 	case METHOD_GPIO_1610:
 	case METHOD_GPIO_1610:
 		reg += OMAP1610_GPIO_IRQENABLE1;
 		reg += OMAP1610_GPIO_IRQENABLE1;
 		mask = 0xffff;
 		mask = 0xffff;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
 	case METHOD_GPIO_730:
 	case METHOD_GPIO_730:
 		reg += OMAP730_GPIO_INT_MASK;
 		reg += OMAP730_GPIO_INT_MASK;
 		mask = 0xffffffff;
 		mask = 0xffffffff;
 		inv = 1;
 		inv = 1;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
 	case METHOD_GPIO_24XX:
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_IRQENABLE1;
 		reg += OMAP24XX_GPIO_IRQENABLE1;
 		mask = 0xffffffff;
 		mask = 0xffffffff;
 		break;
 		break;
+#endif
 	default:
 	default:
-		BUG();
+		WARN_ON(1);
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -590,6 +701,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
 	u32 l;
 	u32 l;
 
 
 	switch (bank->method) {
 	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
 	case METHOD_MPUIO:
 	case METHOD_MPUIO:
 		reg += OMAP_MPUIO_GPIO_MASKIT;
 		reg += OMAP_MPUIO_GPIO_MASKIT;
 		l = __raw_readl(reg);
 		l = __raw_readl(reg);
@@ -598,6 +710,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
 		else
 		else
 			l |= gpio_mask;
 			l |= gpio_mask;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
 	case METHOD_GPIO_1510:
 	case METHOD_GPIO_1510:
 		reg += OMAP1510_GPIO_INT_MASK;
 		reg += OMAP1510_GPIO_INT_MASK;
 		l = __raw_readl(reg);
 		l = __raw_readl(reg);
@@ -606,6 +720,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
 		else
 		else
 			l |= gpio_mask;
 			l |= gpio_mask;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
 	case METHOD_GPIO_1610:
 	case METHOD_GPIO_1610:
 		if (enable)
 		if (enable)
 			reg += OMAP1610_GPIO_SET_IRQENABLE1;
 			reg += OMAP1610_GPIO_SET_IRQENABLE1;
@@ -613,6 +729,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
 			reg += OMAP1610_GPIO_CLEAR_IRQENABLE1;
 			reg += OMAP1610_GPIO_CLEAR_IRQENABLE1;
 		l = gpio_mask;
 		l = gpio_mask;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
 	case METHOD_GPIO_730:
 	case METHOD_GPIO_730:
 		reg += OMAP730_GPIO_INT_MASK;
 		reg += OMAP730_GPIO_INT_MASK;
 		l = __raw_readl(reg);
 		l = __raw_readl(reg);
@@ -621,6 +739,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
 		else
 		else
 			l |= gpio_mask;
 			l |= gpio_mask;
 		break;
 		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
 	case METHOD_GPIO_24XX:
 	case METHOD_GPIO_24XX:
 		if (enable)
 		if (enable)
 			reg += OMAP24XX_GPIO_SETIRQENABLE1;
 			reg += OMAP24XX_GPIO_SETIRQENABLE1;
@@ -628,8 +748,9 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
 			reg += OMAP24XX_GPIO_CLEARIRQENABLE1;
 			reg += OMAP24XX_GPIO_CLEARIRQENABLE1;
 		l = gpio_mask;
 		l = gpio_mask;
 		break;
 		break;
+#endif
 	default:
 	default:
-		BUG();
+		WARN_ON(1);
 		return;
 		return;
 	}
 	}
 	__raw_writel(l, reg);
 	__raw_writel(l, reg);
@@ -651,15 +772,39 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena
 static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
 static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
 {
 {
 	switch (bank->method) {
 	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP16XX
+	case METHOD_MPUIO:
 	case METHOD_GPIO_1610:
 	case METHOD_GPIO_1610:
+		spin_lock(&bank->lock);
+		if (enable) {
+			bank->suspend_wakeup |= (1 << gpio);
+			enable_irq_wake(bank->irq);
+		} else {
+			disable_irq_wake(bank->irq);
+			bank->suspend_wakeup &= ~(1 << gpio);
+		}
+		spin_unlock(&bank->lock);
+		return 0;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
 	case METHOD_GPIO_24XX:
 	case METHOD_GPIO_24XX:
+		if (bank->non_wakeup_gpios & (1 << gpio)) {
+			printk(KERN_ERR "Unable to modify wakeup on "
+					"non-wakeup GPIO%d\n",
+					(bank - gpio_bank) * 32 + gpio);
+			return -EINVAL;
+		}
 		spin_lock(&bank->lock);
 		spin_lock(&bank->lock);
-		if (enable)
+		if (enable) {
 			bank->suspend_wakeup |= (1 << gpio);
 			bank->suspend_wakeup |= (1 << gpio);
-		else
+			enable_irq_wake(bank->irq);
+		} else {
+			disable_irq_wake(bank->irq);
 			bank->suspend_wakeup &= ~(1 << gpio);
 			bank->suspend_wakeup &= ~(1 << gpio);
+		}
 		spin_unlock(&bank->lock);
 		spin_unlock(&bank->lock);
 		return 0;
 		return 0;
+#endif
 	default:
 	default:
 		printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n",
 		printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n",
 		       bank->method);
 		       bank->method);
@@ -684,7 +829,7 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable)
 
 
 	if (check_gpio(gpio) < 0)
 	if (check_gpio(gpio) < 0)
 		return -ENODEV;
 		return -ENODEV;
-	bank = get_gpio_bank(gpio);
+	bank = get_irq_chip_data(irq);
 	retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
 	retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
 
 
 	return retval;
 	return retval;
@@ -720,20 +865,6 @@ int omap_request_gpio(int gpio)
 		reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
 		reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
 		__raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg);
 		__raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg);
 	}
 	}
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	if (bank->method == METHOD_GPIO_1610) {
-		/* Enable wake-up during idle for dynamic tick */
-		void __iomem *reg = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
-		__raw_writel(1 << get_gpio_index(gpio), reg);
-	}
-#endif
-#ifdef CONFIG_ARCH_OMAP24XX
-	if (bank->method == METHOD_GPIO_24XX) {
-		/* Enable wake-up during idle for dynamic tick */
-		void __iomem *reg = bank->base + OMAP24XX_GPIO_SETWKUENA;
-		__raw_writel(1 << get_gpio_index(gpio), reg);
-	}
 #endif
 #endif
 	spin_unlock(&bank->lock);
 	spin_unlock(&bank->lock);
 
 
@@ -794,8 +925,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	desc->chip->ack(irq);
 	desc->chip->ack(irq);
 
 
 	bank = get_irq_data(irq);
 	bank = get_irq_data(irq);
+#ifdef CONFIG_ARCH_OMAP1
 	if (bank->method == METHOD_MPUIO)
 	if (bank->method == METHOD_MPUIO)
 		isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
 		isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
+#endif
 #ifdef CONFIG_ARCH_OMAP15XX
 #ifdef CONFIG_ARCH_OMAP15XX
 	if (bank->method == METHOD_GPIO_1510)
 	if (bank->method == METHOD_GPIO_1510)
 		isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
 		isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
@@ -911,7 +1044,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 static void gpio_irq_shutdown(unsigned int irq)
 static void gpio_irq_shutdown(unsigned int irq)
 {
 {
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	unsigned int gpio = irq - IH_GPIO_BASE;
-	struct gpio_bank *bank = get_gpio_bank(gpio);
+	struct gpio_bank *bank = get_irq_chip_data(irq);
 
 
 	_reset_gpio(bank, gpio);
 	_reset_gpio(bank, gpio);
 }
 }
@@ -919,7 +1052,7 @@ static void gpio_irq_shutdown(unsigned int irq)
 static void gpio_ack_irq(unsigned int irq)
 static void gpio_ack_irq(unsigned int irq)
 {
 {
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	unsigned int gpio = irq - IH_GPIO_BASE;
-	struct gpio_bank *bank = get_gpio_bank(gpio);
+	struct gpio_bank *bank = get_irq_chip_data(irq);
 
 
 	_clear_gpio_irqstatus(bank, gpio);
 	_clear_gpio_irqstatus(bank, gpio);
 }
 }
@@ -927,7 +1060,7 @@ static void gpio_ack_irq(unsigned int irq)
 static void gpio_mask_irq(unsigned int irq)
 static void gpio_mask_irq(unsigned int irq)
 {
 {
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	unsigned int gpio = irq - IH_GPIO_BASE;
-	struct gpio_bank *bank = get_gpio_bank(gpio);
+	struct gpio_bank *bank = get_irq_chip_data(irq);
 
 
 	_set_gpio_irqenable(bank, gpio, 0);
 	_set_gpio_irqenable(bank, gpio, 0);
 }
 }
@@ -936,11 +1069,27 @@ static void gpio_unmask_irq(unsigned int irq)
 {
 {
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	unsigned int gpio = irq - IH_GPIO_BASE;
 	unsigned int gpio_idx = get_gpio_index(gpio);
 	unsigned int gpio_idx = get_gpio_index(gpio);
-	struct gpio_bank *bank = get_gpio_bank(gpio);
+	struct gpio_bank *bank = get_irq_chip_data(irq);
 
 
 	_set_gpio_irqenable(bank, gpio_idx, 1);
 	_set_gpio_irqenable(bank, gpio_idx, 1);
 }
 }
 
 
+static struct irq_chip gpio_irq_chip = {
+	.name		= "GPIO",
+	.shutdown	= gpio_irq_shutdown,
+	.ack		= gpio_ack_irq,
+	.mask		= gpio_mask_irq,
+	.unmask		= gpio_unmask_irq,
+	.set_type	= gpio_irq_type,
+	.set_wake	= gpio_wake_enable,
+};
+
+/*---------------------------------------------------------------------*/
+
+#ifdef CONFIG_ARCH_OMAP1
+
+/* MPUIO uses the always-on 32k clock */
+
 static void mpuio_ack_irq(unsigned int irq)
 static void mpuio_ack_irq(unsigned int irq)
 {
 {
 	/* The ISR is reset automatically, so do nothing here. */
 	/* The ISR is reset automatically, so do nothing here. */
@@ -949,7 +1098,7 @@ static void mpuio_ack_irq(unsigned int irq)
 static void mpuio_mask_irq(unsigned int irq)
 static void mpuio_mask_irq(unsigned int irq)
 {
 {
 	unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
 	unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
-	struct gpio_bank *bank = get_gpio_bank(gpio);
+	struct gpio_bank *bank = get_irq_chip_data(irq);
 
 
 	_set_gpio_irqenable(bank, gpio, 0);
 	_set_gpio_irqenable(bank, gpio, 0);
 }
 }
@@ -957,33 +1106,108 @@ static void mpuio_mask_irq(unsigned int irq)
 static void mpuio_unmask_irq(unsigned int irq)
 static void mpuio_unmask_irq(unsigned int irq)
 {
 {
 	unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
 	unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
-	struct gpio_bank *bank = get_gpio_bank(gpio);
+	struct gpio_bank *bank = get_irq_chip_data(irq);
 
 
 	_set_gpio_irqenable(bank, gpio, 1);
 	_set_gpio_irqenable(bank, gpio, 1);
 }
 }
 
 
-static struct irq_chip gpio_irq_chip = {
-	.name		= "GPIO",
-	.shutdown	= gpio_irq_shutdown,
-	.ack		= gpio_ack_irq,
-	.mask		= gpio_mask_irq,
-	.unmask		= gpio_unmask_irq,
+static struct irq_chip mpuio_irq_chip = {
+	.name		= "MPUIO",
+	.ack		= mpuio_ack_irq,
+	.mask		= mpuio_mask_irq,
+	.unmask		= mpuio_unmask_irq,
 	.set_type	= gpio_irq_type,
 	.set_type	= gpio_irq_type,
+#ifdef CONFIG_ARCH_OMAP16XX
+	/* REVISIT: assuming only 16xx supports MPUIO wake events */
 	.set_wake	= gpio_wake_enable,
 	.set_wake	= gpio_wake_enable,
+#endif
 };
 };
 
 
-static struct irq_chip mpuio_irq_chip = {
-	.name	  = "MPUIO",
-	.ack	  = mpuio_ack_irq,
-	.mask	  = mpuio_mask_irq,
-	.unmask	  = mpuio_unmask_irq,
-	.set_type = gpio_irq_type,
+
+#define bank_is_mpuio(bank)	((bank)->method == METHOD_MPUIO)
+
+
+#ifdef CONFIG_ARCH_OMAP16XX
+
+#include <linux/platform_device.h>
+
+static int omap_mpuio_suspend_late(struct platform_device *pdev, pm_message_t mesg)
+{
+	struct gpio_bank	*bank = platform_get_drvdata(pdev);
+	void __iomem		*mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
+
+	spin_lock(&bank->lock);
+	bank->saved_wakeup = __raw_readl(mask_reg);
+	__raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg);
+	spin_unlock(&bank->lock);
+
+	return 0;
+}
+
+static int omap_mpuio_resume_early(struct platform_device *pdev)
+{
+	struct gpio_bank	*bank = platform_get_drvdata(pdev);
+	void __iomem		*mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
+
+	spin_lock(&bank->lock);
+	__raw_writel(bank->saved_wakeup, mask_reg);
+	spin_unlock(&bank->lock);
+
+	return 0;
+}
+
+/* use platform_driver for this, now that there's no longer any
+ * point to sys_device (other than not disturbing old code).
+ */
+static struct platform_driver omap_mpuio_driver = {
+	.suspend_late	= omap_mpuio_suspend_late,
+	.resume_early	= omap_mpuio_resume_early,
+	.driver		= {
+		.name	= "mpuio",
+	},
+};
+
+static struct platform_device omap_mpuio_device = {
+	.name		= "mpuio",
+	.id		= -1,
+	.dev = {
+		.driver = &omap_mpuio_driver.driver,
+	}
+	/* could list the /proc/iomem resources */
 };
 };
 
 
+static inline void mpuio_init(void)
+{
+	platform_set_drvdata(&omap_mpuio_device, &gpio_bank_1610[0]);
+
+	if (platform_driver_register(&omap_mpuio_driver) == 0)
+		(void) platform_device_register(&omap_mpuio_device);
+}
+
+#else
+static inline void mpuio_init(void) {}
+#endif	/* 16xx */
+
+#else
+
+extern struct irq_chip mpuio_irq_chip;
+
+#define bank_is_mpuio(bank)	0
+static inline void mpuio_init(void) {}
+
+#endif
+
+/*---------------------------------------------------------------------*/
+
 static int initialized;
 static int initialized;
 static struct clk * gpio_ick;
 static struct clk * gpio_ick;
 static struct clk * gpio_fck;
 static struct clk * gpio_fck;
 
 
+#ifdef CONFIG_ARCH_OMAP2430
+static struct clk * gpio5_ick;
+static struct clk * gpio5_fck;
+#endif
+
 static int __init _omap_gpio_init(void)
 static int __init _omap_gpio_init(void)
 {
 {
 	int i;
 	int i;
@@ -1009,7 +1233,25 @@ static int __init _omap_gpio_init(void)
 			printk("Could not get gpios_fck\n");
 			printk("Could not get gpios_fck\n");
 		else
 		else
 			clk_enable(gpio_fck);
 			clk_enable(gpio_fck);
-	}
+
+		/*
+		 * On 2430 GPIO 5 uses CORE L4 ICLK
+		 */
+#ifdef CONFIG_ARCH_OMAP2430
+		if (cpu_is_omap2430()) {
+			gpio5_ick = clk_get(NULL, "gpio5_ick");
+			if (IS_ERR(gpio5_ick))
+				printk("Could not get gpio5_ick\n");
+			else
+				clk_enable(gpio5_ick);
+			gpio5_fck = clk_get(NULL, "gpio5_fck");
+			if (IS_ERR(gpio5_fck))
+				printk("Could not get gpio5_fck\n");
+			else
+				clk_enable(gpio5_fck);
+		}
+#endif
+}
 
 
 #ifdef CONFIG_ARCH_OMAP15XX
 #ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap15xx()) {
 	if (cpu_is_omap15xx()) {
@@ -1036,14 +1278,24 @@ static int __init _omap_gpio_init(void)
 		gpio_bank = gpio_bank_730;
 		gpio_bank = gpio_bank_730;
 	}
 	}
 #endif
 #endif
+
 #ifdef CONFIG_ARCH_OMAP24XX
 #ifdef CONFIG_ARCH_OMAP24XX
-	if (cpu_is_omap24xx()) {
+	if (cpu_is_omap242x()) {
 		int rev;
 		int rev;
 
 
 		gpio_bank_count = 4;
 		gpio_bank_count = 4;
-		gpio_bank = gpio_bank_24xx;
+		gpio_bank = gpio_bank_242x;
+		rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+		printk(KERN_INFO "OMAP242x GPIO hardware version %d.%d\n",
+			(rev >> 4) & 0x0f, rev & 0x0f);
+	}
+	if (cpu_is_omap243x()) {
+		int rev;
+
+		gpio_bank_count = 5;
+		gpio_bank = gpio_bank_243x;
 		rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
 		rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
-		printk(KERN_INFO "OMAP24xx GPIO hardware version %d.%d\n",
+		printk(KERN_INFO "OMAP243x GPIO hardware version %d.%d\n",
 			(rev >> 4) & 0x0f, rev & 0x0f);
 			(rev >> 4) & 0x0f, rev & 0x0f);
 	}
 	}
 #endif
 #endif
@@ -1054,9 +1306,8 @@ static int __init _omap_gpio_init(void)
 		bank->reserved_map = 0;
 		bank->reserved_map = 0;
 		bank->base = IO_ADDRESS(bank->base);
 		bank->base = IO_ADDRESS(bank->base);
 		spin_lock_init(&bank->lock);
 		spin_lock_init(&bank->lock);
-		if (bank->method == METHOD_MPUIO) {
+		if (bank_is_mpuio(bank))
 			omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
 			omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
-		}
 #ifdef CONFIG_ARCH_OMAP15XX
 #ifdef CONFIG_ARCH_OMAP15XX
 		if (bank->method == METHOD_GPIO_1510) {
 		if (bank->method == METHOD_GPIO_1510) {
 			__raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
 			__raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
@@ -1080,15 +1331,25 @@ static int __init _omap_gpio_init(void)
 #endif
 #endif
 #ifdef CONFIG_ARCH_OMAP24XX
 #ifdef CONFIG_ARCH_OMAP24XX
 		if (bank->method == METHOD_GPIO_24XX) {
 		if (bank->method == METHOD_GPIO_24XX) {
+			static const u32 non_wakeup_gpios[] = {
+				0xe203ffc0, 0x08700040
+			};
+
 			__raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1);
 			__raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1);
 			__raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1);
 			__raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1);
+			__raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG);
 
 
+			/* Initialize interface clock ungated, module enabled */
+			__raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
+			if (i < ARRAY_SIZE(non_wakeup_gpios))
+				bank->non_wakeup_gpios = non_wakeup_gpios[i];
 			gpio_count = 32;
 			gpio_count = 32;
 		}
 		}
 #endif
 #endif
 		for (j = bank->virtual_irq_start;
 		for (j = bank->virtual_irq_start;
 		     j < bank->virtual_irq_start + gpio_count; j++) {
 		     j < bank->virtual_irq_start + gpio_count; j++) {
-			if (bank->method == METHOD_MPUIO)
+			set_irq_chip_data(j, bank);
+			if (bank_is_mpuio(bank))
 				set_irq_chip(j, &mpuio_irq_chip);
 				set_irq_chip(j, &mpuio_irq_chip);
 			else
 			else
 				set_irq_chip(j, &gpio_irq_chip);
 				set_irq_chip(j, &gpio_irq_chip);
@@ -1104,6 +1365,12 @@ static int __init _omap_gpio_init(void)
 	if (cpu_is_omap16xx())
 	if (cpu_is_omap16xx())
 		omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
 		omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
 
 
+#ifdef CONFIG_ARCH_OMAP24XX
+	/* Enable autoidle for the OCP interface */
+	if (cpu_is_omap24xx())
+		omap_writel(1 << 0, 0x48019010);
+#endif
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1122,16 +1389,20 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
 		void __iomem *wake_set;
 		void __iomem *wake_set;
 
 
 		switch (bank->method) {
 		switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP16XX
 		case METHOD_GPIO_1610:
 		case METHOD_GPIO_1610:
 			wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE;
 			wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE;
 			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
 			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
 			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
 			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
 			break;
 			break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
 		case METHOD_GPIO_24XX:
 		case METHOD_GPIO_24XX:
 			wake_status = bank->base + OMAP24XX_GPIO_SETWKUENA;
 			wake_status = bank->base + OMAP24XX_GPIO_SETWKUENA;
 			wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
 			wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
 			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
 			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
 			break;
 			break;
+#endif
 		default:
 		default:
 			continue;
 			continue;
 		}
 		}
@@ -1159,14 +1430,18 @@ static int omap_gpio_resume(struct sys_device *dev)
 		void __iomem *wake_set;
 		void __iomem *wake_set;
 
 
 		switch (bank->method) {
 		switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP16XX
 		case METHOD_GPIO_1610:
 		case METHOD_GPIO_1610:
 			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
 			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
 			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
 			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
 			break;
 			break;
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
 		case METHOD_GPIO_24XX:
 		case METHOD_GPIO_24XX:
 			wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
 			wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
 			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
 			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
 			break;
 			break;
+#endif
 		default:
 		default:
 			continue;
 			continue;
 		}
 		}
@@ -1190,6 +1465,80 @@ static struct sys_device omap_gpio_device = {
 	.id		= 0,
 	.id		= 0,
 	.cls		= &omap_gpio_sysclass,
 	.cls		= &omap_gpio_sysclass,
 };
 };
+
+#endif
+
+#ifdef CONFIG_ARCH_OMAP24XX
+
+static int workaround_enabled;
+
+void omap2_gpio_prepare_for_retention(void)
+{
+	int i, c = 0;
+
+	/* Remove triggering for all non-wakeup GPIOs.  Otherwise spurious
+	 * IRQs will be generated.  See OMAP2420 Errata item 1.101. */
+	for (i = 0; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		u32 l1, l2;
+
+		if (!(bank->enabled_non_wakeup_gpios))
+			continue;
+		bank->saved_datain = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
+		l1 = __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+		l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
+		bank->saved_fallingdetect = l1;
+		bank->saved_risingdetect = l2;
+		l1 &= ~bank->enabled_non_wakeup_gpios;
+		l2 &= ~bank->enabled_non_wakeup_gpios;
+		__raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+		__raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT);
+		c++;
+	}
+	if (!c) {
+		workaround_enabled = 0;
+		return;
+	}
+	workaround_enabled = 1;
+}
+
+void omap2_gpio_resume_after_retention(void)
+{
+	int i;
+
+	if (!workaround_enabled)
+		return;
+	for (i = 0; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		u32 l;
+
+		if (!(bank->enabled_non_wakeup_gpios))
+			continue;
+		__raw_writel(bank->saved_fallingdetect,
+				 bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+		__raw_writel(bank->saved_risingdetect,
+				 bank->base + OMAP24XX_GPIO_RISINGDETECT);
+		/* Check if any of the non-wakeup interrupt GPIOs have changed
+		 * state.  If so, generate an IRQ by software.  This is
+		 * horribly racy, but it's the best we can do to work around
+		 * this silicon bug. */
+		l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
+		l ^= bank->saved_datain;
+		l &= bank->non_wakeup_gpios;
+		if (l) {
+			u32 old0, old1;
+
+			old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+			old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+			__raw_writel(old0 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+			__raw_writel(old1 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+			__raw_writel(old0, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+			__raw_writel(old1, bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+		}
+	}
+
+}
+
 #endif
 #endif
 
 
 /*
 /*
@@ -1211,6 +1560,8 @@ static int __init omap_gpio_sysinit(void)
 	if (!initialized)
 	if (!initialized)
 		ret = _omap_gpio_init();
 		ret = _omap_gpio_init();
 
 
+	mpuio_init();
+
 #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX)
 #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX)
 	if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
 	if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
 		if (ret == 0) {
 		if (ret == 0) {
@@ -1231,3 +1582,128 @@ EXPORT_SYMBOL(omap_set_gpio_dataout);
 EXPORT_SYMBOL(omap_get_gpio_datain);
 EXPORT_SYMBOL(omap_get_gpio_datain);
 
 
 arch_initcall(omap_gpio_sysinit);
 arch_initcall(omap_gpio_sysinit);
+
+
+#ifdef	CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static int gpio_is_input(struct gpio_bank *bank, int mask)
+{
+	void __iomem *reg = bank->base;
+
+	switch (bank->method) {
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_IO_CNTL;
+		break;
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_DIR_CONTROL;
+		break;
+	case METHOD_GPIO_1610:
+		reg += OMAP1610_GPIO_DIRECTION;
+		break;
+	case METHOD_GPIO_730:
+		reg += OMAP730_GPIO_DIR_CONTROL;
+		break;
+	case METHOD_GPIO_24XX:
+		reg += OMAP24XX_GPIO_OE;
+		break;
+	}
+	return __raw_readl(reg) & mask;
+}
+
+
+static int dbg_gpio_show(struct seq_file *s, void *unused)
+{
+	unsigned	i, j, gpio;
+
+	for (i = 0, gpio = 0; i < gpio_bank_count; i++) {
+		struct gpio_bank	*bank = gpio_bank + i;
+		unsigned		bankwidth = 16;
+		u32			mask = 1;
+
+		if (bank_is_mpuio(bank))
+			gpio = OMAP_MPUIO(0);
+		else if (cpu_is_omap24xx() || cpu_is_omap730())
+			bankwidth = 32;
+
+		for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) {
+			unsigned	irq, value, is_in, irqstat;
+
+			if (!(bank->reserved_map & mask))
+				continue;
+
+			irq = bank->virtual_irq_start + j;
+			value = omap_get_gpio_datain(gpio);
+			is_in = gpio_is_input(bank, mask);
+
+			if (bank_is_mpuio(bank))
+				seq_printf(s, "MPUIO %2d: ", j);
+			else
+				seq_printf(s, "GPIO %3d: ", gpio);
+			seq_printf(s, "%s %s",
+					is_in ? "in " : "out",
+					value ? "hi"  : "lo");
+
+			irqstat = irq_desc[irq].status;
+			if (is_in && ((bank->suspend_wakeup & mask)
+					|| irqstat & IRQ_TYPE_SENSE_MASK)) {
+				char	*trigger = NULL;
+
+				switch (irqstat & IRQ_TYPE_SENSE_MASK) {
+				case IRQ_TYPE_EDGE_FALLING:
+					trigger = "falling";
+					break;
+				case IRQ_TYPE_EDGE_RISING:
+					trigger = "rising";
+					break;
+				case IRQ_TYPE_EDGE_BOTH:
+					trigger = "bothedge";
+					break;
+				case IRQ_TYPE_LEVEL_LOW:
+					trigger = "low";
+					break;
+				case IRQ_TYPE_LEVEL_HIGH:
+					trigger = "high";
+					break;
+				case IRQ_TYPE_NONE:
+					trigger = "(unspecified)";
+					break;
+				}
+				seq_printf(s, ", irq-%d %s%s",
+						irq, trigger,
+						(bank->suspend_wakeup & mask)
+							? " wakeup" : "");
+			}
+			seq_printf(s, "\n");
+		}
+
+		if (bank_is_mpuio(bank)) {
+			seq_printf(s, "\n");
+			gpio = 0;
+		}
+	}
+	return 0;
+}
+
+static int dbg_gpio_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, dbg_gpio_show, &inode->i_private);
+}
+
+static const struct file_operations debug_fops = {
+	.open		= dbg_gpio_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init omap_gpio_debuginit(void)
+{
+	(void) debugfs_create_file("omap_gpio", S_IRUGO,
+					NULL, NULL, &debug_fops);
+	return 0;
+}
+late_initcall(omap_gpio_debuginit);
+#endif

+ 10 - 5
arch/arm/plat-omap/mcbsp.c

@@ -225,11 +225,16 @@ static void omap_mcbsp_dsp_free(void)
 #ifdef CONFIG_ARCH_OMAP2
 #ifdef CONFIG_ARCH_OMAP2
 static void omap2_mcbsp2_mux_setup(void)
 static void omap2_mcbsp2_mux_setup(void)
 {
 {
-	omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
-	omap_cfg_reg(R14_24XX_MCBSP2_FSX);
-	omap_cfg_reg(W15_24XX_MCBSP2_DR);
-	omap_cfg_reg(V15_24XX_MCBSP2_DX);
-	omap_cfg_reg(V14_24XX_GPIO117);
+	if (cpu_is_omap2420()) {
+		omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
+		omap_cfg_reg(R14_24XX_MCBSP2_FSX);
+		omap_cfg_reg(W15_24XX_MCBSP2_DR);
+		omap_cfg_reg(V15_24XX_MCBSP2_DX);
+		omap_cfg_reg(V14_24XX_GPIO117);
+	}
+	/*
+	 * Need to add MUX settings for OMAP 2430 SDP
+	 */
 }
 }
 #endif
 #endif
 
 

+ 39 - 100
arch/arm/plat-omap/timer32k.c

@@ -42,6 +42,8 @@
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
 
 
 #include <asm/system.h>
 #include <asm/system.h>
 #include <asm/hardware.h>
 #include <asm/hardware.h>
@@ -80,13 +82,13 @@ struct sys_timer omap_timer;
 #define OMAP1_32K_TIMER_TVR		0x00
 #define OMAP1_32K_TIMER_TVR		0x00
 #define OMAP1_32K_TIMER_TCR		0x04
 #define OMAP1_32K_TIMER_TCR		0x04
 
 
-#define OMAP_32K_TICKS_PER_HZ		(32768 / HZ)
+#define OMAP_32K_TICKS_PER_SEC		(32768)
 
 
 /*
 /*
  * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
  * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
  * so with HZ = 128, TVR = 255.
  * so with HZ = 128, TVR = 255.
  */
  */
-#define OMAP_32K_TIMER_TICK_PERIOD	((32768 / HZ) - 1)
+#define OMAP_32K_TIMER_TICK_PERIOD	((OMAP_32K_TICKS_PER_SEC / HZ) - 1)
 
 
 #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate)			\
 #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate)			\
 				(((nr_jiffies) * (clock_rate)) / HZ)
 				(((nr_jiffies) * (clock_rate)) / HZ)
@@ -142,6 +144,28 @@ static inline void omap_32k_timer_ack_irq(void)
 
 
 #endif
 #endif
 
 
+static void omap_32k_timer_set_mode(enum clock_event_mode mode,
+				    struct clock_event_device *evt)
+{
+	switch (mode) {
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_PERIODIC:
+		omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		omap_32k_timer_stop();
+		break;
+	}
+}
+
+static struct clock_event_device clockevent_32k_timer = {
+	.name		= "32k-timer",
+	.features       = CLOCK_EVT_FEAT_PERIODIC,
+	.shift		= 32,
+	.set_mode	= omap_32k_timer_set_mode,
+};
+
 /*
 /*
  * The 32KHz synchronized timer is an additional timer on 16xx.
  * The 32KHz synchronized timer is an additional timer on 16xx.
  * It is always running.
  * It is always running.
@@ -170,15 +194,6 @@ omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
 
 
 static unsigned long omap_32k_last_tick = 0;
 static unsigned long omap_32k_last_tick = 0;
 
 
-/*
- * Returns elapsed usecs since last 32k timer interrupt
- */
-static unsigned long omap_32k_timer_gettimeoffset(void)
-{
-	unsigned long now = omap_32k_sync_timer_read();
-	return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
-}
-
 /*
 /*
  * Returns current time from boot in nsecs. It's OK for this to wrap
  * Returns current time from boot in nsecs. It's OK for this to wrap
  * around for now, as it's just a relative time stamp.
  * around for now, as it's just a relative time stamp.
@@ -188,95 +203,16 @@ unsigned long long sched_clock(void)
 	return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
 	return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
 }
 }
 
 
-/*
- * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
- * function is also called from other interrupts to remove latency
- * issues with dynamic tick. In the dynamic tick case, we need to lock
- * with irqsave.
- */
-static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id)
-{
-	unsigned long now;
-
-	omap_32k_timer_ack_irq();
-	now = omap_32k_sync_timer_read();
-
-	while ((signed long)(now - omap_32k_last_tick)
-						>= OMAP_32K_TICKS_PER_HZ) {
-		omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
-		timer_tick();
-	}
-
-	/* Restart timer so we don't drift off due to modulo or dynamic tick.
-	 * By default we program the next timer to be continuous to avoid
-	 * latencies during high system load. During dynamic tick operation the
-	 * continuous timer can be overridden from pm_idle to be longer.
-	 */
-	omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id)
-{
-	return _omap_32k_timer_interrupt(irq, dev_id);
-}
-
 static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
 static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
 {
 {
-	unsigned long flags;
+	struct clock_event_device *evt = &clockevent_32k_timer;
+	omap_32k_timer_ack_irq();
 
 
-	write_seqlock_irqsave(&xtime_lock, flags);
-	_omap_32k_timer_interrupt(irq, dev_id);
-	write_sequnlock_irqrestore(&xtime_lock, flags);
+	evt->event_handler(evt);
 
 
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
-#ifdef CONFIG_NO_IDLE_HZ
-/*
- * Programs the next timer interrupt needed. Called when dynamic tick is
- * enabled, and to reprogram the ticks to skip from pm_idle. Note that
- * we can keep the timer continuous, and don't need to set it to run in
- * one-shot mode. This is because the timer will get reprogrammed again
- * after next interrupt.
- */
-void omap_32k_timer_reprogram(unsigned long next_tick)
-{
-	unsigned long ticks = JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1;
-	unsigned long now = omap_32k_sync_timer_read();
-	unsigned long idled = now - omap_32k_last_tick;
-
-	if (idled + 1 < ticks)
-		ticks -= idled;
-	else
-		ticks = 1;
-	omap_32k_timer_start(ticks);
-}
-
-static struct irqaction omap_32k_timer_irq;
-extern struct timer_update_handler timer_update;
-
-static int omap_32k_timer_enable_dyn_tick(void)
-{
-	/* No need to reprogram timer, just use the next interrupt */
-	return 0;
-}
-
-static int omap_32k_timer_disable_dyn_tick(void)
-{
-	omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
-	return 0;
-}
-
-static struct dyn_tick_timer omap_dyn_tick_timer = {
-	.enable		= omap_32k_timer_enable_dyn_tick,
-	.disable	= omap_32k_timer_disable_dyn_tick,
-	.reprogram	= omap_32k_timer_reprogram,
-	.handler	= omap_32k_timer_handler,
-};
-#endif	/* CONFIG_NO_IDLE_HZ */
-
 static struct irqaction omap_32k_timer_irq = {
 static struct irqaction omap_32k_timer_irq = {
 	.name		= "32KHz timer",
 	.name		= "32KHz timer",
 	.flags		= IRQF_DISABLED | IRQF_TIMER,
 	.flags		= IRQF_DISABLED | IRQF_TIMER,
@@ -285,13 +221,8 @@ static struct irqaction omap_32k_timer_irq = {
 
 
 static __init void omap_init_32k_timer(void)
 static __init void omap_init_32k_timer(void)
 {
 {
-#ifdef CONFIG_NO_IDLE_HZ
-	omap_timer.dyn_tick = &omap_dyn_tick_timer;
-#endif
-
 	if (cpu_class_is_omap1())
 	if (cpu_class_is_omap1())
 		setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
 		setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
-	omap_timer.offset  = omap_32k_timer_gettimeoffset;
 	omap_32k_last_tick = omap_32k_sync_timer_read();
 	omap_32k_last_tick = omap_32k_sync_timer_read();
 
 
 #ifdef CONFIG_ARCH_OMAP2
 #ifdef CONFIG_ARCH_OMAP2
@@ -308,7 +239,16 @@ static __init void omap_init_32k_timer(void)
 	}
 	}
 #endif
 #endif
 
 
-	omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
+	clockevent_32k_timer.mult = div_sc(OMAP_32K_TICKS_PER_SEC,
+					   NSEC_PER_SEC,
+					   clockevent_32k_timer.shift);
+	clockevent_32k_timer.max_delta_ns =
+		clockevent_delta2ns(0xfffffffe, &clockevent_32k_timer);
+	clockevent_32k_timer.min_delta_ns =
+		clockevent_delta2ns(1, &clockevent_32k_timer);
+
+	clockevent_32k_timer.cpumask = cpumask_of_cpu(0);
+	clockevents_register_device(&clockevent_32k_timer);
 }
 }
 
 
 /*
 /*
@@ -326,5 +266,4 @@ static void __init omap_timer_init(void)
 
 
 struct sys_timer omap_timer = {
 struct sys_timer omap_timer = {
 	.init		= omap_timer_init,
 	.init		= omap_timer_init,
-	.offset		= NULL,		/* Initialized later */
 };
 };

+ 12 - 0
arch/arm/plat-s3c24xx/clock.c

@@ -404,6 +404,18 @@ int s3c24xx_register_clock(struct clk *clk)
 	return 0;
 	return 0;
 }
 }
 
 
+int s3c24xx_register_clocks(struct clk **clks, int nr_clks)
+{
+	int fails = 0;
+
+	for (; nr_clks > 0; nr_clks--, clks++) {
+		if (s3c24xx_register_clock(*clks) < 0)
+			fails++;
+	}
+
+	return fails;
+}
+
 /* initalise all the clocks */
 /* initalise all the clocks */
 
 
 int __init s3c24xx_setup_clocks(unsigned long xtal,
 int __init s3c24xx_setup_clocks(unsigned long xtal,

+ 0 - 38
arch/arm/plat-s3c24xx/cpu.c

@@ -181,24 +181,6 @@ s3c_lookup_cpu(unsigned long idcode)
 	return NULL;
 	return NULL;
 }
 }
 
 
-/* board information */
-
-static struct s3c24xx_board *board;
-
-void s3c24xx_set_board(struct s3c24xx_board *b)
-{
-	int i;
-
-	board = b;
-
-	if (b->clocks_count != 0) {
-		struct clk **ptr = b->clocks;
-
-		for (i = b->clocks_count; i > 0; i--, ptr++)
-			s3c24xx_register_clock(*ptr);
-	}
-}
-
 /* cpu information */
 /* cpu information */
 
 
 static struct cpu_table *cpu;
 static struct cpu_table *cpu;
@@ -342,26 +324,6 @@ static int __init s3c_arch_init(void)
 		return ret;
 		return ret;
 
 
 	ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
 	ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
-	if (ret != 0)
-		return ret;
-
-	if (board != NULL) {
-		struct platform_device **ptr = board->devices;
-		int i;
-
-		for (i = 0; i < board->devices_count; i++, ptr++) {
-			ret = platform_device_register(*ptr);
-
-			if (ret) {
-				printk(KERN_ERR "s3c24xx: failed to add board device %s (%d) @%p\n", (*ptr)->name, ret, *ptr);
-			}
-		}
-
-		/* mask any error, we may not need all these board
-		 * devices */
-		ret = 0;
-	}
-
 	return ret;
 	return ret;
 }
 }
 
 

+ 6 - 7
arch/arm/plat-s3c24xx/dma.c

@@ -44,7 +44,7 @@ static struct kmem_cache *dma_kmem;
 
 
 static int dma_channels;
 static int dma_channels;
 
 
-struct s3c24xx_dma_selection dma_sel;
+static struct s3c24xx_dma_selection dma_sel;
 
 
 /* dma channel state information */
 /* dma channel state information */
 struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
 struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
@@ -880,7 +880,7 @@ static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
 	return 0;
 	return 0;
 }
 }
 
 
-void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
+static void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
 {
 {
 	unsigned long tmp;
 	unsigned long tmp;
 	unsigned int timeout = 0x10000;
 	unsigned int timeout = 0x10000;
@@ -957,8 +957,7 @@ static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
 	return 0;
 	return 0;
 }
 }
 
 
-int
-s3c2410_dma_started(struct s3c2410_dma_chan *chan)
+static int s3c2410_dma_started(struct s3c2410_dma_chan *chan)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 
 
@@ -1280,7 +1279,7 @@ static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long
 
 
 /* initialisation code */
 /* initialisation code */
 
 
-int __init s3c24xx_dma_sysclass_init(void)
+static int __init s3c24xx_dma_sysclass_init(void)
 {
 {
 	int ret = sysdev_class_register(&dma_sysclass);
 	int ret = sysdev_class_register(&dma_sysclass);
 
 
@@ -1292,7 +1291,7 @@ int __init s3c24xx_dma_sysclass_init(void)
 
 
 core_initcall(s3c24xx_dma_sysclass_init);
 core_initcall(s3c24xx_dma_sysclass_init);
 
 
-int __init s3c24xx_dma_sysdev_register(void)
+static int __init s3c24xx_dma_sysdev_register(void)
 {
 {
 	struct s3c2410_dma_chan *cp = s3c2410_chans;
 	struct s3c2410_dma_chan *cp = s3c2410_chans;
 	int channel, ret;
 	int channel, ret;
@@ -1396,7 +1395,7 @@ static struct s3c24xx_dma_order *dma_order;
  * channel
  * channel
 */
 */
 
 
-struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
+static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
 {
 {
 	struct s3c24xx_dma_order_ch *ord = NULL;
 	struct s3c24xx_dma_order_ch *ord = NULL;
 	struct s3c24xx_dma_map *ch_map;
 	struct s3c24xx_dma_map *ch_map;

+ 0 - 1
arch/arm/vfp/vfpdouble.c

@@ -34,7 +34,6 @@
 #include <linux/bitops.h>
 #include <linux/bitops.h>
 
 
 #include <asm/div64.h>
 #include <asm/div64.h>
-#include <asm/ptrace.h>
 #include <asm/vfp.h>
 #include <asm/vfp.h>
 
 
 #include "vfpinstr.h"
 #include "vfpinstr.h"

+ 0 - 1
arch/arm/vfp/vfpsingle.c

@@ -34,7 +34,6 @@
 #include <linux/bitops.h>
 #include <linux/bitops.h>
 
 
 #include <asm/div64.h>
 #include <asm/div64.h>
-#include <asm/ptrace.h>
 #include <asm/vfp.h>
 #include <asm/vfp.h>
 
 
 #include "vfpinstr.h"
 #include "vfpinstr.h"

+ 9 - 1
drivers/ata/Kconfig

@@ -545,13 +545,21 @@ config PATA_WINBOND_VLB
 
 
 config PATA_PLATFORM
 config PATA_PLATFORM
 	tristate "Generic platform device PATA support"
 	tristate "Generic platform device PATA support"
-	depends on EMBEDDED
+	depends on EMBEDDED || ARCH_RPC
 	help
 	help
 	  This option enables support for generic directly connected ATA
 	  This option enables support for generic directly connected ATA
 	  devices commonly found on embedded systems.
 	  devices commonly found on embedded systems.
 
 
 	  If unsure, say N.
 	  If unsure, say N.
 
 
+config PATA_ICSIDE
+	tristate "Acorn ICS PATA support"
+	depends on ARM && ARCH_ACORN
+	help
+	  On Acorn systems, say Y here if you wish to use the ICS PATA
+	  interface card.  This is not required for ICS partition support.
+	  If you are unsure, say N to this.
+
 config PATA_IXP4XX_CF
 config PATA_IXP4XX_CF
 	tristate "IXP4XX Compact Flash support"
 	tristate "IXP4XX Compact Flash support"
 	depends on ARCH_IXP4XX
 	depends on ARCH_IXP4XX

+ 1 - 0
drivers/ata/Makefile

@@ -61,6 +61,7 @@ obj-$(CONFIG_PATA_TRIFLEX)	+= pata_triflex.o
 obj-$(CONFIG_PATA_IXP4XX_CF)	+= pata_ixp4xx_cf.o
 obj-$(CONFIG_PATA_IXP4XX_CF)	+= pata_ixp4xx_cf.o
 obj-$(CONFIG_PATA_SCC)		+= pata_scc.o
 obj-$(CONFIG_PATA_SCC)		+= pata_scc.o
 obj-$(CONFIG_PATA_PLATFORM)	+= pata_platform.o
 obj-$(CONFIG_PATA_PLATFORM)	+= pata_platform.o
+obj-$(CONFIG_PATA_ICSIDE)	+= pata_icside.o
 # Should be last but one libata driver
 # Should be last but one libata driver
 obj-$(CONFIG_ATA_GENERIC)	+= ata_generic.o
 obj-$(CONFIG_ATA_GENERIC)	+= ata_generic.o
 # Should be last libata driver
 # Should be last libata driver

+ 686 - 0
drivers/ata/pata_icside.c

@@ -0,0 +1,686 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <scsi/scsi_host.h>
+#include <linux/ata.h>
+#include <linux/libata.h>
+
+#include <asm/dma.h>
+#include <asm/ecard.h>
+
+#define DRV_NAME	"pata_icside"
+
+#define ICS_IDENT_OFFSET		0x2280
+
+#define ICS_ARCIN_V5_INTRSTAT		0x0000
+#define ICS_ARCIN_V5_INTROFFSET		0x0004
+
+#define ICS_ARCIN_V6_INTROFFSET_1	0x2200
+#define ICS_ARCIN_V6_INTRSTAT_1		0x2290
+#define ICS_ARCIN_V6_INTROFFSET_2	0x3200
+#define ICS_ARCIN_V6_INTRSTAT_2		0x3290
+
+struct portinfo {
+	unsigned int dataoffset;
+	unsigned int ctrloffset;
+	unsigned int stepping;
+};
+
+static const struct portinfo pata_icside_portinfo_v5 = {
+	.dataoffset	= 0x2800,
+	.ctrloffset	= 0x2b80,
+	.stepping	= 6,
+};
+
+static const struct portinfo pata_icside_portinfo_v6_1 = {
+	.dataoffset	= 0x2000,
+	.ctrloffset	= 0x2380,
+	.stepping	= 6,
+};
+
+static const struct portinfo pata_icside_portinfo_v6_2 = {
+	.dataoffset	= 0x3000,
+	.ctrloffset	= 0x3380,
+	.stepping	= 6,
+};
+
+#define PATA_ICSIDE_MAX_SG	128
+
+struct pata_icside_state {
+	void __iomem *irq_port;
+	void __iomem *ioc_base;
+	unsigned int type;
+	unsigned int dma;
+	struct {
+		u8 port_sel;
+		u8 disabled;
+		unsigned int speed[ATA_MAX_DEVICES];
+	} port[2];
+	struct scatterlist sg[PATA_ICSIDE_MAX_SG];
+};
+
+#define ICS_TYPE_A3IN	0
+#define ICS_TYPE_A3USER	1
+#define ICS_TYPE_V6	3
+#define ICS_TYPE_V5	15
+#define ICS_TYPE_NOTYPE	((unsigned int)-1)
+
+/* ---------------- Version 5 PCB Support Functions --------------------- */
+/* Prototype: pata_icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
+ * Purpose  : enable interrupts from card
+ */
+static void pata_icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
+{
+	struct pata_icside_state *state = ec->irq_data;
+
+	writeb(0, state->irq_port + ICS_ARCIN_V5_INTROFFSET);
+}
+
+/* Prototype: pata_icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
+ * Purpose  : disable interrupts from card
+ */
+static void pata_icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
+{
+	struct pata_icside_state *state = ec->irq_data;
+
+	readb(state->irq_port + ICS_ARCIN_V5_INTROFFSET);
+}
+
+static const expansioncard_ops_t pata_icside_ops_arcin_v5 = {
+	.irqenable	= pata_icside_irqenable_arcin_v5,
+	.irqdisable	= pata_icside_irqdisable_arcin_v5,
+};
+
+
+/* ---------------- Version 6 PCB Support Functions --------------------- */
+/* Prototype: pata_icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
+ * Purpose  : enable interrupts from card
+ */
+static void pata_icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
+{
+	struct pata_icside_state *state = ec->irq_data;
+	void __iomem *base = state->irq_port;
+
+	if (!state->port[0].disabled)
+		writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
+	if (!state->port[1].disabled)
+		writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
+}
+
+/* Prototype: pata_icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
+ * Purpose  : disable interrupts from card
+ */
+static void pata_icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
+{
+	struct pata_icside_state *state = ec->irq_data;
+
+	readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
+	readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
+}
+
+/* Prototype: pata_icside_irqprobe(struct expansion_card *ec)
+ * Purpose  : detect an active interrupt from card
+ */
+static int pata_icside_irqpending_arcin_v6(struct expansion_card *ec)
+{
+	struct pata_icside_state *state = ec->irq_data;
+
+	return readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||
+	       readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;
+}
+
+static const expansioncard_ops_t pata_icside_ops_arcin_v6 = {
+	.irqenable	= pata_icside_irqenable_arcin_v6,
+	.irqdisable	= pata_icside_irqdisable_arcin_v6,
+	.irqpending	= pata_icside_irqpending_arcin_v6,
+};
+
+
+/*
+ * SG-DMA support.
+ *
+ * Similar to the BM-DMA, but we use the RiscPCs IOMD DMA controllers.
+ * There is only one DMA controller per card, which means that only
+ * one drive can be accessed at one time.  NOTE! We do not enforce that
+ * here, but we rely on the main IDE driver spotting that both
+ * interfaces use the same IRQ, which should guarantee this.
+ */
+
+/*
+ * Configure the IOMD to give the appropriate timings for the transfer
+ * mode being requested.  We take the advice of the ATA standards, and
+ * calculate the cycle time based on the transfer mode, and the EIDE
+ * MW DMA specs that the drive provides in the IDENTIFY command.
+ *
+ * We have the following IOMD DMA modes to choose from:
+ *
+ *	Type	Active		Recovery	Cycle
+ *	A	250 (250)	312 (550)	562 (800)
+ *	B	187 (200)	250 (550)	437 (750)
+ *	C	125 (125)	125 (375)	250 (500)
+ *	D	62  (50)	125 (375)	187 (425)
+ *
+ * (figures in brackets are actual measured timings on DIOR/DIOW)
+ *
+ * However, we also need to take care of the read/write active and
+ * recovery timings:
+ *
+ *			Read	Write
+ *  	Mode	Active	-- Recovery --	Cycle	IOMD type
+ *	MW0	215	50	215	480	A
+ *	MW1	80	50	50	150	C
+ *	MW2	70	25	25	120	C
+ */
+static void pata_icside_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+	struct pata_icside_state *state = ap->host->private_data;
+	struct ata_timing t;
+	unsigned int cycle;
+	char iomd_type;
+
+	/*
+	 * DMA is based on a 16MHz clock
+	 */
+	if (ata_timing_compute(adev, adev->dma_mode, &t, 1000, 1))
+		return;
+
+	/*
+	 * Choose the IOMD cycle timing which ensure that the interface
+	 * satisfies the measured active, recovery and cycle times.
+	 */
+	if (t.active <= 50 && t.recover <= 375 && t.cycle <= 425)
+		iomd_type = 'D', cycle = 187;
+	else if (t.active <= 125 && t.recover <= 375 && t.cycle <= 500)
+		iomd_type = 'C', cycle = 250;
+	else if (t.active <= 200 && t.recover <= 550 && t.cycle <= 750)
+		iomd_type = 'B', cycle = 437;
+	else
+		iomd_type = 'A', cycle = 562;
+
+	ata_dev_printk(adev, KERN_INFO, "timings: act %dns rec %dns cyc %dns (%c)\n",
+		t.active, t.recover, t.cycle, iomd_type);
+
+	state->port[ap->port_no].speed[adev->devno] = cycle;
+}
+
+static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct pata_icside_state *state = ap->host->private_data;
+	struct scatterlist *sg, *rsg = state->sg;
+	unsigned int write = qc->tf.flags & ATA_TFLAG_WRITE;
+
+	/*
+	 * We are simplex; BUG if we try to fiddle with DMA
+	 * while it's active.
+	 */
+	BUG_ON(dma_channel_active(state->dma));
+
+	/*
+	 * Copy ATAs scattered sg list into a contiguous array of sg
+	 */
+	ata_for_each_sg(sg, qc) {
+		memcpy(rsg, sg, sizeof(*sg));
+		rsg++;
+	}
+
+	/*
+	 * Route the DMA signals to the correct interface
+	 */
+	writeb(state->port[ap->port_no].port_sel, state->ioc_base);
+
+	set_dma_speed(state->dma, state->port[ap->port_no].speed[qc->dev->devno]);
+	set_dma_sg(state->dma, state->sg, rsg - state->sg);
+	set_dma_mode(state->dma, write ? DMA_MODE_WRITE : DMA_MODE_READ);
+
+	/* issue r/w command */
+	ap->ops->exec_command(ap, &qc->tf);
+}
+
+static void pata_icside_bmdma_start(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct pata_icside_state *state = ap->host->private_data;
+
+	BUG_ON(dma_channel_active(state->dma));
+	enable_dma(state->dma);
+}
+
+static void pata_icside_bmdma_stop(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct pata_icside_state *state = ap->host->private_data;
+
+	disable_dma(state->dma);
+
+	/* see ata_bmdma_stop */
+	ata_altstatus(ap);
+}
+
+static u8 pata_icside_bmdma_status(struct ata_port *ap)
+{
+	struct pata_icside_state *state = ap->host->private_data;
+	void __iomem *irq_port;
+
+	irq_port = state->irq_port + (ap->port_no ? ICS_ARCIN_V6_INTRSTAT_2 :
+						    ICS_ARCIN_V6_INTRSTAT_1);
+
+	return readb(irq_port) & 1 ? ATA_DMA_INTR : 0;
+}
+
+static int icside_dma_init(struct ata_probe_ent *ae, struct expansion_card *ec)
+{
+	struct pata_icside_state *state = ae->private_data;
+	int i;
+
+	for (i = 0; i < ATA_MAX_DEVICES; i++) {
+		state->port[0].speed[i] = 480;
+		state->port[1].speed[i] = 480;
+	}
+
+	if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) {
+		state->dma = ec->dma;
+		ae->mwdma_mask = 0x07;	/* MW0..2 */
+	}
+
+	return 0;
+}
+
+
+static int pata_icside_port_start(struct ata_port *ap)
+{
+	/* No PRD to alloc */
+	return ata_pad_alloc(ap, ap->dev);
+}
+
+static struct scsi_host_template pata_icside_sht = {
+	.module			= THIS_MODULE,
+	.name			= DRV_NAME,
+	.ioctl			= ata_scsi_ioctl,
+	.queuecommand		= ata_scsi_queuecmd,
+	.can_queue		= ATA_DEF_QUEUE,
+	.this_id		= ATA_SHT_THIS_ID,
+	.sg_tablesize		= PATA_ICSIDE_MAX_SG,
+	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
+	.emulated		= ATA_SHT_EMULATED,
+	.use_clustering		= ATA_SHT_USE_CLUSTERING,
+	.proc_name		= DRV_NAME,
+	.dma_boundary		= ~0, /* no dma boundaries */
+	.slave_configure	= ata_scsi_slave_config,
+	.slave_destroy		= ata_scsi_slave_destroy,
+	.bios_param		= ata_std_bios_param,
+};
+
+/* wish this was exported from libata-core */
+static void ata_dummy_noret(struct ata_port *port)
+{
+}
+
+/*
+ * We need to shut down unused ports to prevent spurious interrupts.
+ * FIXME: the libata core doesn't call this function for PATA interfaces.
+ */
+static void pata_icside_port_disable(struct ata_port *ap)
+{
+	struct pata_icside_state *state = ap->host->private_data;
+
+	ata_port_printk(ap, KERN_ERR, "disabling icside port\n");
+
+	ata_port_disable(ap);
+
+	state->port[ap->port_no].disabled = 1;
+
+	if (state->type == ICS_TYPE_V6) {
+		/*
+		 * Disable interrupts from this port, otherwise we
+		 * receive spurious interrupts from the floating
+		 * interrupt line.
+		 */
+		void __iomem *irq_port = state->irq_port +
+				(ap->port_no ? ICS_ARCIN_V6_INTROFFSET_2 : ICS_ARCIN_V6_INTROFFSET_1);
+		readb(irq_port);
+	}
+}
+
+static u8 pata_icside_irq_ack(struct ata_port *ap, unsigned int chk_drq)
+{
+	unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
+	u8 status;
+
+	status = ata_busy_wait(ap, bits, 1000);
+	if (status & bits)
+		if (ata_msg_err(ap))
+			printk(KERN_ERR "abnormal status 0x%X\n", status);
+
+	if (ata_msg_intr(ap))
+		printk(KERN_INFO "%s: irq ack: drv_stat 0x%X\n",
+			__FUNCTION__, status);
+
+	return status;
+}
+
+static struct ata_port_operations pata_icside_port_ops = {
+	.port_disable		= pata_icside_port_disable,
+
+	.set_dmamode		= pata_icside_set_dmamode,
+
+	.tf_load		= ata_tf_load,
+	.tf_read		= ata_tf_read,
+	.exec_command		= ata_exec_command,
+	.check_status		= ata_check_status,
+	.dev_select		= ata_std_dev_select,
+
+	.bmdma_setup		= pata_icside_bmdma_setup,
+	.bmdma_start		= pata_icside_bmdma_start,
+
+	.data_xfer		= ata_data_xfer_noirq,
+
+	/* no need to build any PRD tables for DMA */
+	.qc_prep		= ata_noop_qc_prep,
+	.qc_issue		= ata_qc_issue_prot,
+
+	.freeze			= ata_bmdma_freeze,
+	.thaw			= ata_bmdma_thaw,
+	.error_handler		= ata_bmdma_error_handler,
+	.post_internal_cmd	= pata_icside_bmdma_stop,
+
+	.irq_handler		= ata_interrupt,
+	.irq_clear		= ata_dummy_noret,
+	.irq_on			= ata_irq_on,
+	.irq_ack		= pata_icside_irq_ack,
+
+	.port_start		= pata_icside_port_start,
+
+	.bmdma_stop		= pata_icside_bmdma_stop,
+	.bmdma_status		= pata_icside_bmdma_status,
+};
+
+static void
+pata_icside_add_port(struct ata_probe_ent *ae, void __iomem *base,
+		     const struct portinfo *info)
+{
+	struct ata_ioports *ioaddr = &ae->port[ae->n_ports++];
+	void __iomem *cmd = base + info->dataoffset;
+
+	ioaddr->cmd_addr	= cmd;
+	ioaddr->data_addr	= cmd + (ATA_REG_DATA    << info->stepping);
+	ioaddr->error_addr	= cmd + (ATA_REG_ERR     << info->stepping);
+	ioaddr->feature_addr	= cmd + (ATA_REG_FEATURE << info->stepping);
+	ioaddr->nsect_addr	= cmd + (ATA_REG_NSECT   << info->stepping);
+	ioaddr->lbal_addr	= cmd + (ATA_REG_LBAL    << info->stepping);
+	ioaddr->lbam_addr	= cmd + (ATA_REG_LBAM    << info->stepping);
+	ioaddr->lbah_addr	= cmd + (ATA_REG_LBAH    << info->stepping);
+	ioaddr->device_addr	= cmd + (ATA_REG_DEVICE  << info->stepping);
+	ioaddr->status_addr	= cmd + (ATA_REG_STATUS  << info->stepping);
+	ioaddr->command_addr	= cmd + (ATA_REG_CMD     << info->stepping);
+
+	ioaddr->ctl_addr	= base + info->ctrloffset;
+	ioaddr->altstatus_addr	= ioaddr->ctl_addr;
+}
+
+static int __init
+pata_icside_register_v5(struct ata_probe_ent *ae, struct expansion_card *ec)
+{
+	struct pata_icside_state *state = ae->private_data;
+	void __iomem *base;
+
+	base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
+		       ecard_resource_len(ec, ECARD_RES_MEMC));
+	if (!base)
+		return -ENOMEM;
+
+	state->irq_port = base;
+
+	ec->irqaddr = base + ICS_ARCIN_V5_INTRSTAT;
+	ec->irqmask = 1;
+	ec->irq_data = state;
+	ec->ops = &pata_icside_ops_arcin_v5;
+
+	/*
+	 * Be on the safe side - disable interrupts
+	 */
+	ec->ops->irqdisable(ec, ec->irq);
+
+	pata_icside_add_port(ae, base, &pata_icside_portinfo_v5);
+
+	return 0;
+}
+
+static int __init
+pata_icside_register_v6(struct ata_probe_ent *ae, struct expansion_card *ec)
+{
+	struct pata_icside_state *state = ae->private_data;
+	void __iomem *ioc_base, *easi_base;
+	unsigned int sel = 0;
+	int ret;
+
+	ioc_base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
+			   ecard_resource_len(ec, ECARD_RES_IOCFAST));
+	if (!ioc_base) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	easi_base = ioc_base;
+
+	if (ecard_resource_flags(ec, ECARD_RES_EASI)) {
+		easi_base = ioremap(ecard_resource_start(ec, ECARD_RES_EASI),
+				    ecard_resource_len(ec, ECARD_RES_EASI));
+		if (!easi_base) {
+			ret = -ENOMEM;
+			goto unmap_slot;
+		}
+
+		/*
+		 * Enable access to the EASI region.
+		 */
+		sel = 1 << 5;
+	}
+
+	writeb(sel, ioc_base);
+
+	ec->irq_data = state;
+	ec->ops = &pata_icside_ops_arcin_v6;
+
+	state->irq_port = easi_base;
+	state->ioc_base = ioc_base;
+	state->port[0].port_sel = sel;
+	state->port[1].port_sel = sel | 1;
+
+	/*
+	 * Be on the safe side - disable interrupts
+	 */
+	ec->ops->irqdisable(ec, ec->irq);
+
+	/*
+	 * Find and register the interfaces.
+	 */
+	pata_icside_add_port(ae, easi_base, &pata_icside_portinfo_v6_1);
+	pata_icside_add_port(ae, easi_base, &pata_icside_portinfo_v6_2);
+
+	/*
+	 * FIXME: work around libata's aversion to calling port_disable.
+	 * This permanently disables interrupts on port 0 - bad luck if
+	 * you have a drive on that port.
+	 */
+	state->port[0].disabled = 1;
+
+	return icside_dma_init(ae, ec);
+
+ unmap_slot:
+	iounmap(ioc_base);
+ out:
+	return ret;
+}
+
+static int __devinit
+pata_icside_probe(struct expansion_card *ec, const struct ecard_id *id)
+{
+	struct pata_icside_state *state;
+	struct ata_probe_ent ae;
+	void __iomem *idmem;
+	int ret;
+
+	ret = ecard_request_resources(ec);
+	if (ret)
+		goto out;
+
+	state = kzalloc(sizeof(struct pata_icside_state), GFP_KERNEL);
+	if (!state) {
+		ret = -ENOMEM;
+		goto release;
+	}
+
+	state->type = ICS_TYPE_NOTYPE;
+	state->dma = NO_DMA;
+
+	idmem = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST),
+			ecard_resource_len(ec, ECARD_RES_IOCFAST));
+	if (idmem) {
+		unsigned int type;
+
+		type = readb(idmem + ICS_IDENT_OFFSET) & 1;
+		type |= (readb(idmem + ICS_IDENT_OFFSET + 4) & 1) << 1;
+		type |= (readb(idmem + ICS_IDENT_OFFSET + 8) & 1) << 2;
+		type |= (readb(idmem + ICS_IDENT_OFFSET + 12) & 1) << 3;
+		iounmap(idmem);
+
+		state->type = type;
+	}
+
+	memset(&ae, 0, sizeof(ae));
+	INIT_LIST_HEAD(&ae.node);
+	ae.dev          = &ec->dev;
+	ae.port_ops     = &pata_icside_port_ops;
+	ae.sht          = &pata_icside_sht;
+	ae.pio_mask     = 0x1f;
+	ae.irq          = ec->irq;
+	ae.port_flags   = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
+	ae._host_flags  = ATA_HOST_SIMPLEX;
+	ae.private_data = state;
+
+	switch (state->type) {
+	case ICS_TYPE_A3IN:
+		dev_warn(&ec->dev, "A3IN unsupported\n");
+		ret = -ENODEV;
+		break;
+
+	case ICS_TYPE_A3USER:
+		dev_warn(&ec->dev, "A3USER unsupported\n");
+		ret = -ENODEV;
+		break;
+
+	case ICS_TYPE_V5:
+		ret = pata_icside_register_v5(&ae, ec);
+		break;
+
+	case ICS_TYPE_V6:
+		ret = pata_icside_register_v6(&ae, ec);
+		break;
+
+	default:
+		dev_warn(&ec->dev, "unknown interface type\n");
+		ret = -ENODEV;
+		break;
+	}
+
+	if (ret == 0)
+		ret = ata_device_add(&ae) == 0 ? -ENODEV : 0;
+
+	if (ret == 0)
+		goto out;
+
+	kfree(state);
+ release:
+	ecard_release_resources(ec);
+ out:
+	return ret;
+}
+
+static void pata_icside_shutdown(struct expansion_card *ec)
+{
+	struct ata_host *host = ecard_get_drvdata(ec);
+	unsigned long flags;
+
+	/*
+	 * Disable interrupts from this card.  We need to do
+	 * this before disabling EASI since we may be accessing
+	 * this register via that region.
+	 */
+	local_irq_save(flags);
+	if (ec->ops)
+		ec->ops->irqdisable(ec, ec->irq);
+	local_irq_restore(flags);
+
+	/*
+	 * Reset the ROM pointer so that we can read the ROM
+	 * after a soft reboot.  This also disables access to
+	 * the IDE taskfile via the EASI region.
+	 */
+	if (host) {
+		struct pata_icside_state *state = host->private_data;
+		if (state->ioc_base)
+			writeb(0, state->ioc_base);
+	}
+}
+
+static void __devexit pata_icside_remove(struct expansion_card *ec)
+{
+	struct ata_host *host = ecard_get_drvdata(ec);
+	struct pata_icside_state *state = host->private_data;
+
+	ata_host_detach(host);
+
+	pata_icside_shutdown(ec);
+
+	/*
+	 * don't NULL out the drvdata - devres/libata wants it
+	 * to free the ata_host structure.
+	 */
+	ec->ops = NULL;
+	ec->irq_data = NULL;
+
+	if (state->dma != NO_DMA)
+		free_dma(state->dma);
+	if (state->ioc_base)
+		iounmap(state->ioc_base);
+	if (state->ioc_base != state->irq_port)
+		iounmap(state->irq_port);
+
+	kfree(state);
+	ecard_release_resources(ec);
+}
+
+static const struct ecard_id pata_icside_ids[] = {
+	{ MANU_ICS,  PROD_ICS_IDE  },
+	{ MANU_ICS2, PROD_ICS2_IDE },
+	{ 0xffff, 0xffff }
+};
+
+static struct ecard_driver pata_icside_driver = {
+	.probe		= pata_icside_probe,
+	.remove 	= __devexit_p(pata_icside_remove),
+	.shutdown	= pata_icside_shutdown,
+	.id_table	= pata_icside_ids,
+	.drv = {
+		.name	= DRV_NAME,
+	},
+};
+
+static int __init pata_icside_init(void)
+{
+	return ecard_register_driver(&pata_icside_driver);
+}
+
+static void __exit pata_icside_exit(void)
+{
+	ecard_remove_driver(&pata_icside_driver);
+}
+
+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ICS PATA driver");
+
+module_init(pata_icside_init);
+module_exit(pata_icside_exit);

+ 10 - 8
drivers/i2c/busses/i2c-pxa.c

@@ -839,9 +839,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
 {
 {
 	struct pxa_i2c *i2c = &i2c_pxa;
 	struct pxa_i2c *i2c = &i2c_pxa;
 	struct resource *res;
 	struct resource *res;
-#ifdef CONFIG_I2C_PXA_SLAVE
 	struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
 	struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
-#endif
 	int ret;
 	int ret;
 	int irq;
 	int irq;
 
 
@@ -889,14 +887,14 @@ static int i2c_pxa_probe(struct platform_device *dev)
 		pxa_gpio_mode(GPIO117_I2CSCL_MD);
 		pxa_gpio_mode(GPIO117_I2CSCL_MD);
 		pxa_gpio_mode(GPIO118_I2CSDA_MD);
 		pxa_gpio_mode(GPIO118_I2CSDA_MD);
 #endif
 #endif
-		pxa_set_cken(CKEN14_I2C, 1);
+		pxa_set_cken(CKEN_I2C, 1);
 		break;
 		break;
 #ifdef CONFIG_PXA27x
 #ifdef CONFIG_PXA27x
 	case 1:
 	case 1:
 		local_irq_disable();
 		local_irq_disable();
 		PCFR |= PCFR_PI2CEN;
 		PCFR |= PCFR_PI2CEN;
 		local_irq_enable();
 		local_irq_enable();
-		pxa_set_cken(CKEN15_PWRI2C, 1);
+		pxa_set_cken(CKEN_PWRI2C, 1);
 #endif
 #endif
 	}
 	}
 
 
@@ -911,6 +909,10 @@ static int i2c_pxa_probe(struct platform_device *dev)
 	i2c->adap.algo_data = i2c;
 	i2c->adap.algo_data = i2c;
 	i2c->adap.dev.parent = &dev->dev;
 	i2c->adap.dev.parent = &dev->dev;
 
 
+	if (plat) {
+		i2c->adap.class = plat->class;
+	}
+
 	ret = i2c_add_adapter(&i2c->adap);
 	ret = i2c_add_adapter(&i2c->adap);
 	if (ret < 0) {
 	if (ret < 0) {
 		printk(KERN_INFO "I2C: Failed to add bus\n");
 		printk(KERN_INFO "I2C: Failed to add bus\n");
@@ -933,11 +935,11 @@ eadapt:
 ereqirq:
 ereqirq:
 	switch (dev->id) {
 	switch (dev->id) {
 	case 0:
 	case 0:
-		pxa_set_cken(CKEN14_I2C, 0);
+		pxa_set_cken(CKEN_I2C, 0);
 		break;
 		break;
 #ifdef CONFIG_PXA27x
 #ifdef CONFIG_PXA27x
 	case 1:
 	case 1:
-		pxa_set_cken(CKEN15_PWRI2C, 0);
+		pxa_set_cken(CKEN_PWRI2C, 0);
 		local_irq_disable();
 		local_irq_disable();
 		PCFR &= ~PCFR_PI2CEN;
 		PCFR &= ~PCFR_PI2CEN;
 		local_irq_enable();
 		local_irq_enable();
@@ -960,11 +962,11 @@ static int i2c_pxa_remove(struct platform_device *dev)
 	free_irq(i2c->irq, i2c);
 	free_irq(i2c->irq, i2c);
 	switch (dev->id) {
 	switch (dev->id) {
 	case 0:
 	case 0:
-		pxa_set_cken(CKEN14_I2C, 0);
+		pxa_set_cken(CKEN_I2C, 0);
 		break;
 		break;
 #ifdef CONFIG_PXA27x
 #ifdef CONFIG_PXA27x
 	case 1:
 	case 1:
-		pxa_set_cken(CKEN15_PWRI2C, 0);
+		pxa_set_cken(CKEN_PWRI2C, 0);
 		local_irq_disable();
 		local_irq_disable();
 		PCFR &= ~PCFR_PI2CEN;
 		PCFR &= ~PCFR_PI2CEN;
 		local_irq_enable();
 		local_irq_enable();

+ 2 - 2
drivers/mmc/pxamci.c

@@ -369,14 +369,14 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		if (CLOCKRATE / clk > ios->clock)
 		if (CLOCKRATE / clk > ios->clock)
 			clk <<= 1;
 			clk <<= 1;
 		host->clkrt = fls(clk) - 1;
 		host->clkrt = fls(clk) - 1;
-		pxa_set_cken(CKEN12_MMC, 1);
+		pxa_set_cken(CKEN_MMC, 1);
 
 
 		/*
 		/*
 		 * we write clkrt on the next command
 		 * we write clkrt on the next command
 		 */
 		 */
 	} else {
 	} else {
 		pxamci_stop_clock(host);
 		pxamci_stop_clock(host);
-		pxa_set_cken(CKEN12_MMC, 0);
+		pxa_set_cken(CKEN_MMC, 0);
 	}
 	}
 
 
 	if (host->power_mode != ios->power_mode) {
 	if (host->power_mode != ios->power_mode) {

+ 6 - 6
drivers/net/irda/pxaficp_ir.c

@@ -134,7 +134,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
 			DCSR(si->rxdma) &= ~DCSR_RUN;
 			DCSR(si->rxdma) &= ~DCSR_RUN;
 			/* disable FICP */
 			/* disable FICP */
 			ICCR0 = 0;
 			ICCR0 = 0;
-			pxa_set_cken(CKEN13_FICP, 0);
+			pxa_set_cken(CKEN_FICP, 0);
 
 
 			/* set board transceiver to SIR mode */
 			/* set board transceiver to SIR mode */
 			si->pdata->transceiver_mode(si->dev, IR_SIRMODE);
 			si->pdata->transceiver_mode(si->dev, IR_SIRMODE);
@@ -144,7 +144,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
 			pxa_gpio_mode(GPIO47_STTXD_MD);
 			pxa_gpio_mode(GPIO47_STTXD_MD);
 
 
 			/* enable the STUART clock */
 			/* enable the STUART clock */
-			pxa_set_cken(CKEN5_STUART, 1);
+			pxa_set_cken(CKEN_STUART, 1);
 		}
 		}
 
 
 		/* disable STUART first */
 		/* disable STUART first */
@@ -169,7 +169,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
 		/* disable STUART */
 		/* disable STUART */
 		STIER = 0;
 		STIER = 0;
 		STISR = 0;
 		STISR = 0;
-		pxa_set_cken(CKEN5_STUART, 0);
+		pxa_set_cken(CKEN_STUART, 0);
 
 
 		/* disable FICP first */
 		/* disable FICP first */
 		ICCR0 = 0;
 		ICCR0 = 0;
@@ -182,7 +182,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
 		pxa_gpio_mode(GPIO47_ICPTXD_MD);
 		pxa_gpio_mode(GPIO47_ICPTXD_MD);
 
 
 		/* enable the FICP clock */
 		/* enable the FICP clock */
-		pxa_set_cken(CKEN13_FICP, 1);
+		pxa_set_cken(CKEN_FICP, 1);
 
 
 		si->speed = speed;
 		si->speed = speed;
 		pxa_irda_fir_dma_rx_start(si);
 		pxa_irda_fir_dma_rx_start(si);
@@ -593,7 +593,7 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
 	/* disable STUART SIR mode */
 	/* disable STUART SIR mode */
 	STISR = 0;
 	STISR = 0;
 	/* disable the STUART clock */
 	/* disable the STUART clock */
-	pxa_set_cken(CKEN5_STUART, 0);
+	pxa_set_cken(CKEN_STUART, 0);
 
 
 	/* disable DMA */
 	/* disable DMA */
 	DCSR(si->txdma) &= ~DCSR_RUN;
 	DCSR(si->txdma) &= ~DCSR_RUN;
@@ -601,7 +601,7 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
 	/* disable FICP */
 	/* disable FICP */
 	ICCR0 = 0;
 	ICCR0 = 0;
 	/* disable the FICP clock */
 	/* disable the FICP clock */
-	pxa_set_cken(CKEN13_FICP, 0);
+	pxa_set_cken(CKEN_FICP, 0);
 
 
 	DRCMR17 = 0;
 	DRCMR17 = 0;
 	DRCMR18 = 0;
 	DRCMR18 = 0;

+ 170 - 125
drivers/serial/amba-pl010.c

@@ -48,6 +48,7 @@
 #include <linux/serial.h>
 #include <linux/serial.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/serial.h>
 #include <linux/amba/serial.h>
+#include <linux/clk.h>
 
 
 #include <asm/io.h>
 #include <asm/io.h>
 
 
@@ -70,6 +71,7 @@
  */
  */
 struct uart_amba_port {
 struct uart_amba_port {
 	struct uart_port	port;
 	struct uart_port	port;
+	struct clk		*clk;
 	struct amba_device	*dev;
 	struct amba_device	*dev;
 	struct amba_pl010_data	*data;
 	struct amba_pl010_data	*data;
 	unsigned int		old_status;
 	unsigned int		old_status;
@@ -77,73 +79,77 @@ struct uart_amba_port {
 
 
 static void pl010_stop_tx(struct uart_port *port)
 static void pl010_stop_tx(struct uart_port *port)
 {
 {
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
 	unsigned int cr;
 	unsigned int cr;
 
 
-	cr = readb(port->membase + UART010_CR);
+	cr = readb(uap->port.membase + UART010_CR);
 	cr &= ~UART010_CR_TIE;
 	cr &= ~UART010_CR_TIE;
-	writel(cr, port->membase + UART010_CR);
+	writel(cr, uap->port.membase + UART010_CR);
 }
 }
 
 
 static void pl010_start_tx(struct uart_port *port)
 static void pl010_start_tx(struct uart_port *port)
 {
 {
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
 	unsigned int cr;
 	unsigned int cr;
 
 
-	cr = readb(port->membase + UART010_CR);
+	cr = readb(uap->port.membase + UART010_CR);
 	cr |= UART010_CR_TIE;
 	cr |= UART010_CR_TIE;
-	writel(cr, port->membase + UART010_CR);
+	writel(cr, uap->port.membase + UART010_CR);
 }
 }
 
 
 static void pl010_stop_rx(struct uart_port *port)
 static void pl010_stop_rx(struct uart_port *port)
 {
 {
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
 	unsigned int cr;
 	unsigned int cr;
 
 
-	cr = readb(port->membase + UART010_CR);
+	cr = readb(uap->port.membase + UART010_CR);
 	cr &= ~(UART010_CR_RIE | UART010_CR_RTIE);
 	cr &= ~(UART010_CR_RIE | UART010_CR_RTIE);
-	writel(cr, port->membase + UART010_CR);
+	writel(cr, uap->port.membase + UART010_CR);
 }
 }
 
 
 static void pl010_enable_ms(struct uart_port *port)
 static void pl010_enable_ms(struct uart_port *port)
 {
 {
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
 	unsigned int cr;
 	unsigned int cr;
 
 
-	cr = readb(port->membase + UART010_CR);
+	cr = readb(uap->port.membase + UART010_CR);
 	cr |= UART010_CR_MSIE;
 	cr |= UART010_CR_MSIE;
-	writel(cr, port->membase + UART010_CR);
+	writel(cr, uap->port.membase + UART010_CR);
 }
 }
 
 
-static void pl010_rx_chars(struct uart_port *port)
+static void pl010_rx_chars(struct uart_amba_port *uap)
 {
 {
-	struct tty_struct *tty = port->info->tty;
+	struct tty_struct *tty = uap->port.info->tty;
 	unsigned int status, ch, flag, rsr, max_count = 256;
 	unsigned int status, ch, flag, rsr, max_count = 256;
 
 
-	status = readb(port->membase + UART01x_FR);
+	status = readb(uap->port.membase + UART01x_FR);
 	while (UART_RX_DATA(status) && max_count--) {
 	while (UART_RX_DATA(status) && max_count--) {
-		ch = readb(port->membase + UART01x_DR);
+		ch = readb(uap->port.membase + UART01x_DR);
 		flag = TTY_NORMAL;
 		flag = TTY_NORMAL;
 
 
-		port->icount.rx++;
+		uap->port.icount.rx++;
 
 
 		/*
 		/*
 		 * Note that the error handling code is
 		 * Note that the error handling code is
 		 * out of the main execution path
 		 * out of the main execution path
 		 */
 		 */
-		rsr = readb(port->membase + UART01x_RSR) | UART_DUMMY_RSR_RX;
+		rsr = readb(uap->port.membase + UART01x_RSR) | UART_DUMMY_RSR_RX;
 		if (unlikely(rsr & UART01x_RSR_ANY)) {
 		if (unlikely(rsr & UART01x_RSR_ANY)) {
-			writel(0, port->membase + UART01x_ECR);
+			writel(0, uap->port.membase + UART01x_ECR);
 
 
 			if (rsr & UART01x_RSR_BE) {
 			if (rsr & UART01x_RSR_BE) {
 				rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE);
 				rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE);
-				port->icount.brk++;
-				if (uart_handle_break(port))
+				uap->port.icount.brk++;
+				if (uart_handle_break(&uap->port))
 					goto ignore_char;
 					goto ignore_char;
 			} else if (rsr & UART01x_RSR_PE)
 			} else if (rsr & UART01x_RSR_PE)
-				port->icount.parity++;
+				uap->port.icount.parity++;
 			else if (rsr & UART01x_RSR_FE)
 			else if (rsr & UART01x_RSR_FE)
-				port->icount.frame++;
+				uap->port.icount.frame++;
 			if (rsr & UART01x_RSR_OE)
 			if (rsr & UART01x_RSR_OE)
-				port->icount.overrun++;
+				uap->port.icount.overrun++;
 
 
-			rsr &= port->read_status_mask;
+			rsr &= uap->port.read_status_mask;
 
 
 			if (rsr & UART01x_RSR_BE)
 			if (rsr & UART01x_RSR_BE)
 				flag = TTY_BREAK;
 				flag = TTY_BREAK;
@@ -153,53 +159,52 @@ static void pl010_rx_chars(struct uart_port *port)
 				flag = TTY_FRAME;
 				flag = TTY_FRAME;
 		}
 		}
 
 
-		if (uart_handle_sysrq_char(port, ch))
+		if (uart_handle_sysrq_char(&uap->port, ch))
 			goto ignore_char;
 			goto ignore_char;
 
 
-		uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag);
+		uart_insert_char(&uap->port, rsr, UART01x_RSR_OE, ch, flag);
 
 
 	ignore_char:
 	ignore_char:
-		status = readb(port->membase + UART01x_FR);
+		status = readb(uap->port.membase + UART01x_FR);
 	}
 	}
 	tty_flip_buffer_push(tty);
 	tty_flip_buffer_push(tty);
 	return;
 	return;
 }
 }
 
 
-static void pl010_tx_chars(struct uart_port *port)
+static void pl010_tx_chars(struct uart_amba_port *uap)
 {
 {
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &uap->port.info->xmit;
 	int count;
 	int count;
 
 
-	if (port->x_char) {
-		writel(port->x_char, port->membase + UART01x_DR);
-		port->icount.tx++;
-		port->x_char = 0;
+	if (uap->port.x_char) {
+		writel(uap->port.x_char, uap->port.membase + UART01x_DR);
+		uap->port.icount.tx++;
+		uap->port.x_char = 0;
 		return;
 		return;
 	}
 	}
-	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-		pl010_stop_tx(port);
+	if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) {
+		pl010_stop_tx(&uap->port);
 		return;
 		return;
 	}
 	}
 
 
-	count = port->fifosize >> 1;
+	count = uap->port.fifosize >> 1;
 	do {
 	do {
-		writel(xmit->buf[xmit->tail], port->membase + UART01x_DR);
+		writel(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR);
 		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-		port->icount.tx++;
+		uap->port.icount.tx++;
 		if (uart_circ_empty(xmit))
 		if (uart_circ_empty(xmit))
 			break;
 			break;
 	} while (--count > 0);
 	} while (--count > 0);
 
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-		uart_write_wakeup(port);
+		uart_write_wakeup(&uap->port);
 
 
 	if (uart_circ_empty(xmit))
 	if (uart_circ_empty(xmit))
-		pl010_stop_tx(port);
+		pl010_stop_tx(&uap->port);
 }
 }
 
 
-static void pl010_modem_status(struct uart_port *port)
+static void pl010_modem_status(struct uart_amba_port *uap)
 {
 {
-	struct uart_amba_port *uap = (struct uart_amba_port *)port;
 	unsigned int status, delta;
 	unsigned int status, delta;
 
 
 	writel(0, uap->port.membase + UART010_ICR);
 	writel(0, uap->port.membase + UART010_ICR);
@@ -226,47 +231,50 @@ static void pl010_modem_status(struct uart_port *port)
 
 
 static irqreturn_t pl010_int(int irq, void *dev_id)
 static irqreturn_t pl010_int(int irq, void *dev_id)
 {
 {
-	struct uart_port *port = dev_id;
+	struct uart_amba_port *uap = dev_id;
 	unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
 	unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
 	int handled = 0;
 	int handled = 0;
 
 
-	spin_lock(&port->lock);
+	spin_lock(&uap->port.lock);
 
 
-	status = readb(port->membase + UART010_IIR);
+	status = readb(uap->port.membase + UART010_IIR);
 	if (status) {
 	if (status) {
 		do {
 		do {
 			if (status & (UART010_IIR_RTIS | UART010_IIR_RIS))
 			if (status & (UART010_IIR_RTIS | UART010_IIR_RIS))
-				pl010_rx_chars(port);
+				pl010_rx_chars(uap);
 			if (status & UART010_IIR_MIS)
 			if (status & UART010_IIR_MIS)
-				pl010_modem_status(port);
+				pl010_modem_status(uap);
 			if (status & UART010_IIR_TIS)
 			if (status & UART010_IIR_TIS)
-				pl010_tx_chars(port);
+				pl010_tx_chars(uap);
 
 
 			if (pass_counter-- == 0)
 			if (pass_counter-- == 0)
 				break;
 				break;
 
 
-			status = readb(port->membase + UART010_IIR);
+			status = readb(uap->port.membase + UART010_IIR);
 		} while (status & (UART010_IIR_RTIS | UART010_IIR_RIS |
 		} while (status & (UART010_IIR_RTIS | UART010_IIR_RIS |
 				   UART010_IIR_TIS));
 				   UART010_IIR_TIS));
 		handled = 1;
 		handled = 1;
 	}
 	}
 
 
-	spin_unlock(&port->lock);
+	spin_unlock(&uap->port.lock);
 
 
 	return IRQ_RETVAL(handled);
 	return IRQ_RETVAL(handled);
 }
 }
 
 
 static unsigned int pl010_tx_empty(struct uart_port *port)
 static unsigned int pl010_tx_empty(struct uart_port *port)
 {
 {
-	return readb(port->membase + UART01x_FR) & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT;
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
+	unsigned int status = readb(uap->port.membase + UART01x_FR);
+	return status & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT;
 }
 }
 
 
 static unsigned int pl010_get_mctrl(struct uart_port *port)
 static unsigned int pl010_get_mctrl(struct uart_port *port)
 {
 {
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
 	unsigned int result = 0;
 	unsigned int result = 0;
 	unsigned int status;
 	unsigned int status;
 
 
-	status = readb(port->membase + UART01x_FR);
+	status = readb(uap->port.membase + UART01x_FR);
 	if (status & UART01x_FR_DCD)
 	if (status & UART01x_FR_DCD)
 		result |= TIOCM_CAR;
 		result |= TIOCM_CAR;
 	if (status & UART01x_FR_DSR)
 	if (status & UART01x_FR_DSR)
@@ -287,17 +295,18 @@ static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl)
 
 
 static void pl010_break_ctl(struct uart_port *port, int break_state)
 static void pl010_break_ctl(struct uart_port *port, int break_state)
 {
 {
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
 	unsigned long flags;
 	unsigned long flags;
 	unsigned int lcr_h;
 	unsigned int lcr_h;
 
 
-	spin_lock_irqsave(&port->lock, flags);
-	lcr_h = readb(port->membase + UART010_LCRH);
+	spin_lock_irqsave(&uap->port.lock, flags);
+	lcr_h = readb(uap->port.membase + UART010_LCRH);
 	if (break_state == -1)
 	if (break_state == -1)
 		lcr_h |= UART01x_LCRH_BRK;
 		lcr_h |= UART01x_LCRH_BRK;
 	else
 	else
 		lcr_h &= ~UART01x_LCRH_BRK;
 		lcr_h &= ~UART01x_LCRH_BRK;
-	writel(lcr_h, port->membase + UART010_LCRH);
-	spin_unlock_irqrestore(&port->lock, flags);
+	writel(lcr_h, uap->port.membase + UART010_LCRH);
+	spin_unlock_irqrestore(&uap->port.lock, flags);
 }
 }
 
 
 static int pl010_startup(struct uart_port *port)
 static int pl010_startup(struct uart_port *port)
@@ -305,49 +314,71 @@ static int pl010_startup(struct uart_port *port)
 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
 	int retval;
 	int retval;
 
 
+	/*
+	 * Try to enable the clock producer.
+	 */
+	retval = clk_enable(uap->clk);
+	if (retval)
+		goto out;
+
+	uap->port.uartclk = clk_get_rate(uap->clk);
+
 	/*
 	/*
 	 * Allocate the IRQ
 	 * Allocate the IRQ
 	 */
 	 */
-	retval = request_irq(port->irq, pl010_int, 0, "uart-pl010", port);
+	retval = request_irq(uap->port.irq, pl010_int, 0, "uart-pl010", uap);
 	if (retval)
 	if (retval)
-		return retval;
+		goto clk_dis;
 
 
 	/*
 	/*
 	 * initialise the old status of the modem signals
 	 * initialise the old status of the modem signals
 	 */
 	 */
-	uap->old_status = readb(port->membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
+	uap->old_status = readb(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
 
 
 	/*
 	/*
 	 * Finally, enable interrupts
 	 * Finally, enable interrupts
 	 */
 	 */
 	writel(UART01x_CR_UARTEN | UART010_CR_RIE | UART010_CR_RTIE,
 	writel(UART01x_CR_UARTEN | UART010_CR_RIE | UART010_CR_RTIE,
-	       port->membase + UART010_CR);
+	       uap->port.membase + UART010_CR);
 
 
 	return 0;
 	return 0;
+
+ clk_dis:
+	clk_disable(uap->clk);
+ out:
+	return retval;
 }
 }
 
 
 static void pl010_shutdown(struct uart_port *port)
 static void pl010_shutdown(struct uart_port *port)
 {
 {
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
+
 	/*
 	/*
 	 * Free the interrupt
 	 * Free the interrupt
 	 */
 	 */
-	free_irq(port->irq, port);
+	free_irq(uap->port.irq, uap);
 
 
 	/*
 	/*
 	 * disable all interrupts, disable the port
 	 * disable all interrupts, disable the port
 	 */
 	 */
-	writel(0, port->membase + UART010_CR);
+	writel(0, uap->port.membase + UART010_CR);
 
 
 	/* disable break condition and fifos */
 	/* disable break condition and fifos */
-	writel(readb(port->membase + UART010_LCRH) &
+	writel(readb(uap->port.membase + UART010_LCRH) &
 		~(UART01x_LCRH_BRK | UART01x_LCRH_FEN),
 		~(UART01x_LCRH_BRK | UART01x_LCRH_FEN),
-	       port->membase + UART010_LCRH);
+	       uap->port.membase + UART010_LCRH);
+
+	/*
+	 * Shut down the clock producer
+	 */
+	clk_disable(uap->clk);
 }
 }
 
 
 static void
 static void
 pl010_set_termios(struct uart_port *port, struct ktermios *termios,
 pl010_set_termios(struct uart_port *port, struct ktermios *termios,
 		     struct ktermios *old)
 		     struct ktermios *old)
 {
 {
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
 	unsigned int lcr_h, old_cr;
 	unsigned int lcr_h, old_cr;
 	unsigned long flags;
 	unsigned long flags;
 	unsigned int baud, quot;
 	unsigned int baud, quot;
@@ -355,7 +386,7 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios,
 	/*
 	/*
 	 * Ask the core to calculate the divisor for us.
 	 * Ask the core to calculate the divisor for us.
 	 */
 	 */
-	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
+	baud = uart_get_baud_rate(port, termios, old, 0, uap->port.uartclk/16); 
 	quot = uart_get_divisor(port, baud);
 	quot = uart_get_divisor(port, baud);
 
 
 	switch (termios->c_cflag & CSIZE) {
 	switch (termios->c_cflag & CSIZE) {
@@ -379,66 +410,66 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios,
 		if (!(termios->c_cflag & PARODD))
 		if (!(termios->c_cflag & PARODD))
 			lcr_h |= UART01x_LCRH_EPS;
 			lcr_h |= UART01x_LCRH_EPS;
 	}
 	}
-	if (port->fifosize > 1)
+	if (uap->port.fifosize > 1)
 		lcr_h |= UART01x_LCRH_FEN;
 		lcr_h |= UART01x_LCRH_FEN;
 
 
-	spin_lock_irqsave(&port->lock, flags);
+	spin_lock_irqsave(&uap->port.lock, flags);
 
 
 	/*
 	/*
 	 * Update the per-port timeout.
 	 * Update the per-port timeout.
 	 */
 	 */
 	uart_update_timeout(port, termios->c_cflag, baud);
 	uart_update_timeout(port, termios->c_cflag, baud);
 
 
-	port->read_status_mask = UART01x_RSR_OE;
+	uap->port.read_status_mask = UART01x_RSR_OE;
 	if (termios->c_iflag & INPCK)
 	if (termios->c_iflag & INPCK)
-		port->read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
+		uap->port.read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
 	if (termios->c_iflag & (BRKINT | PARMRK))
 	if (termios->c_iflag & (BRKINT | PARMRK))
-		port->read_status_mask |= UART01x_RSR_BE;
+		uap->port.read_status_mask |= UART01x_RSR_BE;
 
 
 	/*
 	/*
 	 * Characters to ignore
 	 * Characters to ignore
 	 */
 	 */
-	port->ignore_status_mask = 0;
+	uap->port.ignore_status_mask = 0;
 	if (termios->c_iflag & IGNPAR)
 	if (termios->c_iflag & IGNPAR)
-		port->ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
+		uap->port.ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
 	if (termios->c_iflag & IGNBRK) {
 	if (termios->c_iflag & IGNBRK) {
-		port->ignore_status_mask |= UART01x_RSR_BE;
+		uap->port.ignore_status_mask |= UART01x_RSR_BE;
 		/*
 		/*
 		 * If we're ignoring parity and break indicators,
 		 * If we're ignoring parity and break indicators,
 		 * ignore overruns too (for real raw support).
 		 * ignore overruns too (for real raw support).
 		 */
 		 */
 		if (termios->c_iflag & IGNPAR)
 		if (termios->c_iflag & IGNPAR)
-			port->ignore_status_mask |= UART01x_RSR_OE;
+			uap->port.ignore_status_mask |= UART01x_RSR_OE;
 	}
 	}
 
 
 	/*
 	/*
 	 * Ignore all characters if CREAD is not set.
 	 * Ignore all characters if CREAD is not set.
 	 */
 	 */
 	if ((termios->c_cflag & CREAD) == 0)
 	if ((termios->c_cflag & CREAD) == 0)
-		port->ignore_status_mask |= UART_DUMMY_RSR_RX;
+		uap->port.ignore_status_mask |= UART_DUMMY_RSR_RX;
 
 
 	/* first, disable everything */
 	/* first, disable everything */
-	old_cr = readb(port->membase + UART010_CR) & ~UART010_CR_MSIE;
+	old_cr = readb(uap->port.membase + UART010_CR) & ~UART010_CR_MSIE;
 
 
 	if (UART_ENABLE_MS(port, termios->c_cflag))
 	if (UART_ENABLE_MS(port, termios->c_cflag))
 		old_cr |= UART010_CR_MSIE;
 		old_cr |= UART010_CR_MSIE;
 
 
-	writel(0, port->membase + UART010_CR);
+	writel(0, uap->port.membase + UART010_CR);
 
 
 	/* Set baud rate */
 	/* Set baud rate */
 	quot -= 1;
 	quot -= 1;
-	writel((quot & 0xf00) >> 8, port->membase + UART010_LCRM);
-	writel(quot & 0xff, port->membase + UART010_LCRL);
+	writel((quot & 0xf00) >> 8, uap->port.membase + UART010_LCRM);
+	writel(quot & 0xff, uap->port.membase + UART010_LCRL);
 
 
 	/*
 	/*
 	 * ----------v----------v----------v----------v-----
 	 * ----------v----------v----------v----------v-----
 	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
 	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
 	 * ----------^----------^----------^----------^-----
 	 * ----------^----------^----------^----------^-----
 	 */
 	 */
-	writel(lcr_h, port->membase + UART010_LCRH);
-	writel(old_cr, port->membase + UART010_CR);
+	writel(lcr_h, uap->port.membase + UART010_LCRH);
+	writel(old_cr, uap->port.membase + UART010_CR);
 
 
-	spin_unlock_irqrestore(&port->lock, flags);
+	spin_unlock_irqrestore(&uap->port.lock, flags);
 }
 }
 
 
 static const char *pl010_type(struct uart_port *port)
 static const char *pl010_type(struct uart_port *port)
@@ -514,47 +545,52 @@ static struct uart_amba_port *amba_ports[UART_NR];
 
 
 static void pl010_console_putchar(struct uart_port *port, int ch)
 static void pl010_console_putchar(struct uart_port *port, int ch)
 {
 {
+	struct uart_amba_port *uap = (struct uart_amba_port *)port;
 	unsigned int status;
 	unsigned int status;
 
 
 	do {
 	do {
-		status = readb(port->membase + UART01x_FR);
+		status = readb(uap->port.membase + UART01x_FR);
 		barrier();
 		barrier();
 	} while (!UART_TX_READY(status));
 	} while (!UART_TX_READY(status));
-	writel(ch, port->membase + UART01x_DR);
+	writel(ch, uap->port.membase + UART01x_DR);
 }
 }
 
 
 static void
 static void
 pl010_console_write(struct console *co, const char *s, unsigned int count)
 pl010_console_write(struct console *co, const char *s, unsigned int count)
 {
 {
-	struct uart_port *port = &amba_ports[co->index]->port;
+	struct uart_amba_port *uap = amba_ports[co->index];
 	unsigned int status, old_cr;
 	unsigned int status, old_cr;
 
 
+	clk_enable(uap->clk);
+
 	/*
 	/*
 	 *	First save the CR then disable the interrupts
 	 *	First save the CR then disable the interrupts
 	 */
 	 */
-	old_cr = readb(port->membase + UART010_CR);
-	writel(UART01x_CR_UARTEN, port->membase + UART010_CR);
+	old_cr = readb(uap->port.membase + UART010_CR);
+	writel(UART01x_CR_UARTEN, uap->port.membase + UART010_CR);
 
 
-	uart_console_write(port, s, count, pl010_console_putchar);
+	uart_console_write(&uap->port, s, count, pl010_console_putchar);
 
 
 	/*
 	/*
 	 *	Finally, wait for transmitter to become empty
 	 *	Finally, wait for transmitter to become empty
 	 *	and restore the TCR
 	 *	and restore the TCR
 	 */
 	 */
 	do {
 	do {
-		status = readb(port->membase + UART01x_FR);
+		status = readb(uap->port.membase + UART01x_FR);
 		barrier();
 		barrier();
 	} while (status & UART01x_FR_BUSY);
 	} while (status & UART01x_FR_BUSY);
-	writel(old_cr, port->membase + UART010_CR);
+	writel(old_cr, uap->port.membase + UART010_CR);
+
+	clk_disable(uap->clk);
 }
 }
 
 
 static void __init
 static void __init
-pl010_console_get_options(struct uart_port *port, int *baud,
+pl010_console_get_options(struct uart_amba_port *uap, int *baud,
 			     int *parity, int *bits)
 			     int *parity, int *bits)
 {
 {
-	if (readb(port->membase + UART010_CR) & UART01x_CR_UARTEN) {
+	if (readb(uap->port.membase + UART010_CR) & UART01x_CR_UARTEN) {
 		unsigned int lcr_h, quot;
 		unsigned int lcr_h, quot;
-		lcr_h = readb(port->membase + UART010_LCRH);
+		lcr_h = readb(uap->port.membase + UART010_LCRH);
 
 
 		*parity = 'n';
 		*parity = 'n';
 		if (lcr_h & UART01x_LCRH_PEN) {
 		if (lcr_h & UART01x_LCRH_PEN) {
@@ -569,14 +605,15 @@ pl010_console_get_options(struct uart_port *port, int *baud,
 		else
 		else
 			*bits = 8;
 			*bits = 8;
 
 
-		quot = readb(port->membase + UART010_LCRL) | readb(port->membase + UART010_LCRM) << 8;
-		*baud = port->uartclk / (16 * (quot + 1));
+		quot = readb(uap->port.membase + UART010_LCRL) |
+		       readb(uap->port.membase + UART010_LCRM) << 8;
+		*baud = uap->port.uartclk / (16 * (quot + 1));
 	}
 	}
 }
 }
 
 
 static int __init pl010_console_setup(struct console *co, char *options)
 static int __init pl010_console_setup(struct console *co, char *options)
 {
 {
-	struct uart_port *port;
+	struct uart_amba_port *uap;
 	int baud = 38400;
 	int baud = 38400;
 	int bits = 8;
 	int bits = 8;
 	int parity = 'n';
 	int parity = 'n';
@@ -589,16 +626,18 @@ static int __init pl010_console_setup(struct console *co, char *options)
 	 */
 	 */
 	if (co->index >= UART_NR)
 	if (co->index >= UART_NR)
 		co->index = 0;
 		co->index = 0;
-	if (!amba_ports[co->index])
+	uap = amba_ports[co->index];
+	if (!uap)
 		return -ENODEV;
 		return -ENODEV;
-	port = &amba_ports[co->index]->port;
+
+	uap->port.uartclk = clk_get_rate(uap->clk);
 
 
 	if (options)
 	if (options)
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
 	else
 	else
-		pl010_console_get_options(port, &baud, &parity, &bits);
+		pl010_console_get_options(uap, &baud, &parity, &bits);
 
 
-	return uart_set_options(port, co, baud, parity, bits, flow);
+	return uart_set_options(&uap->port, co, baud, parity, bits, flow);
 }
 }
 
 
 static struct uart_driver amba_reg;
 static struct uart_driver amba_reg;
@@ -629,7 +668,7 @@ static struct uart_driver amba_reg = {
 
 
 static int pl010_probe(struct amba_device *dev, void *id)
 static int pl010_probe(struct amba_device *dev, void *id)
 {
 {
-	struct uart_amba_port *port;
+	struct uart_amba_port *uap;
 	void __iomem *base;
 	void __iomem *base;
 	int i, ret;
 	int i, ret;
 
 
@@ -642,8 +681,8 @@ static int pl010_probe(struct amba_device *dev, void *id)
 		goto out;
 		goto out;
 	}
 	}
 
 
-	port = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
-	if (!port) {
+	uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
+	if (!uap) {
 		ret = -ENOMEM;
 		ret = -ENOMEM;
 		goto out;
 		goto out;
 	}
 	}
@@ -654,51 +693,57 @@ static int pl010_probe(struct amba_device *dev, void *id)
 		goto free;
 		goto free;
 	}
 	}
 
 
-	port->port.dev = &dev->dev;
-	port->port.mapbase = dev->res.start;
-	port->port.membase = base;
-	port->port.iotype = UPIO_MEM;
-	port->port.irq = dev->irq[0];
-	port->port.uartclk = 14745600;
-	port->port.fifosize = 16;
-	port->port.ops = &amba_pl010_pops;
-	port->port.flags = UPF_BOOT_AUTOCONF;
-	port->port.line = i;
-	port->dev = dev;
-	port->data = dev->dev.platform_data;
-
-	amba_ports[i] = port;
-
-	amba_set_drvdata(dev, port);
-	ret = uart_add_one_port(&amba_reg, &port->port);
+	uap->clk = clk_get(&dev->dev, "UARTCLK");
+	if (IS_ERR(uap->clk)) {
+		ret = PTR_ERR(uap->clk);
+		goto unmap;
+	}
+
+	uap->port.dev = &dev->dev;
+	uap->port.mapbase = dev->res.start;
+	uap->port.membase = base;
+	uap->port.iotype = UPIO_MEM;
+	uap->port.irq = dev->irq[0];
+	uap->port.fifosize = 16;
+	uap->port.ops = &amba_pl010_pops;
+	uap->port.flags = UPF_BOOT_AUTOCONF;
+	uap->port.line = i;
+	uap->dev = dev;
+	uap->data = dev->dev.platform_data;
+
+	amba_ports[i] = uap;
+
+	amba_set_drvdata(dev, uap);
+	ret = uart_add_one_port(&amba_reg, &uap->port);
 	if (ret) {
 	if (ret) {
 		amba_set_drvdata(dev, NULL);
 		amba_set_drvdata(dev, NULL);
 		amba_ports[i] = NULL;
 		amba_ports[i] = NULL;
+		clk_put(uap->clk);
+ unmap:
 		iounmap(base);
 		iounmap(base);
  free:
  free:
-		kfree(port);
+		kfree(uap);
 	}
 	}
-
  out:
  out:
 	return ret;
 	return ret;
 }
 }
 
 
 static int pl010_remove(struct amba_device *dev)
 static int pl010_remove(struct amba_device *dev)
 {
 {
-	struct uart_amba_port *port = amba_get_drvdata(dev);
+	struct uart_amba_port *uap = amba_get_drvdata(dev);
 	int i;
 	int i;
 
 
 	amba_set_drvdata(dev, NULL);
 	amba_set_drvdata(dev, NULL);
 
 
-	uart_remove_one_port(&amba_reg, &port->port);
+	uart_remove_one_port(&amba_reg, &uap->port);
 
 
 	for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
 	for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
-		if (amba_ports[i] == port)
+		if (amba_ports[i] == uap)
 			amba_ports[i] = NULL;
 			amba_ports[i] = NULL;
 
 
-	iounmap(port->port.membase);
-	kfree(port);
-
+	iounmap(uap->port.membase);
+	clk_put(uap->clk);
+	kfree(uap);
 	return 0;
 	return 0;
 }
 }
 
 

+ 7 - 2
drivers/serial/atmel_serial.c

@@ -484,11 +484,16 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios * termios,
 	unsigned long flags;
 	unsigned long flags;
 	unsigned int mode, imr, quot, baud;
 	unsigned int mode, imr, quot, baud;
 
 
+	/* Get current mode register */
+	mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL | ATMEL_US_NBSTOP | ATMEL_US_PAR);
+
 	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
 	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
 	quot = uart_get_divisor(port, baud);
 	quot = uart_get_divisor(port, baud);
 
 
-	/* Get current mode register */
-	mode = UART_GET_MR(port) & ~(ATMEL_US_CHRL | ATMEL_US_NBSTOP | ATMEL_US_PAR);
+	if (quot > 65535) {		/* BRGR is 16-bit, so switch to slower clock */
+		quot /= 8;
+		mode |= ATMEL_US_USCLKS_MCK_DIV8;
+	}
 
 
 	/* byte size */
 	/* byte size */
 	switch (termios->c_cflag & CSIZE) {
 	switch (termios->c_cflag & CSIZE) {

+ 3 - 0
drivers/serial/atmel_serial.h

@@ -46,6 +46,9 @@
 #define			ATMEL_US_USMODE_ISO7816_T1	6
 #define			ATMEL_US_USMODE_ISO7816_T1	6
 #define			ATMEL_US_USMODE_IRDA		8
 #define			ATMEL_US_USMODE_IRDA		8
 #define		ATMEL_US_USCLKS		(3   <<  4)		/* Clock Selection */
 #define		ATMEL_US_USCLKS		(3   <<  4)		/* Clock Selection */
+#define			ATMEL_US_USCLKS_MCK		(0 <<  4)
+#define			ATMEL_US_USCLKS_MCK_DIV8	(1 <<  4)
+#define			ATMEL_US_USCLKS_SCK		(3 <<  4)
 #define		ATMEL_US_CHRL		(3   <<  6)		/* Character Length */
 #define		ATMEL_US_CHRL		(3   <<  6)		/* Character Length */
 #define			ATMEL_US_CHRL_5			(0 <<  6)
 #define			ATMEL_US_CHRL_5			(0 <<  6)
 #define			ATMEL_US_CHRL_6			(1 <<  6)
 #define			ATMEL_US_CHRL_6			(1 <<  6)

+ 205 - 63
drivers/serial/imx.c

@@ -46,6 +46,122 @@
 #include <asm/hardware.h>
 #include <asm/hardware.h>
 #include <asm/arch/imx-uart.h>
 #include <asm/arch/imx-uart.h>
 
 
+/* Register definitions */
+#define URXD0 0x0  /* Receiver Register */
+#define URTX0 0x40 /* Transmitter Register */
+#define UCR1  0x80 /* Control Register 1 */
+#define UCR2  0x84 /* Control Register 2 */
+#define UCR3  0x88 /* Control Register 3 */
+#define UCR4  0x8c /* Control Register 4 */
+#define UFCR  0x90 /* FIFO Control Register */
+#define USR1  0x94 /* Status Register 1 */
+#define USR2  0x98 /* Status Register 2 */
+#define UESC  0x9c /* Escape Character Register */
+#define UTIM  0xa0 /* Escape Timer Register */
+#define UBIR  0xa4 /* BRM Incremental Register */
+#define UBMR  0xa8 /* BRM Modulator Register */
+#define UBRC  0xac /* Baud Rate Count Register */
+#define BIPR1 0xb0 /* Incremental Preset Register 1 */
+#define BIPR2 0xb4 /* Incremental Preset Register 2 */
+#define BIPR3 0xb8 /* Incremental Preset Register 3 */
+#define BIPR4 0xbc /* Incremental Preset Register 4 */
+#define BMPR1 0xc0 /* BRM Modulator Register 1 */
+#define BMPR2 0xc4 /* BRM Modulator Register 2 */
+#define BMPR3 0xc8 /* BRM Modulator Register 3 */
+#define BMPR4 0xcc /* BRM Modulator Register 4 */
+#define UTS   0xd0 /* UART Test Register */
+
+/* UART Control Register Bit Fields.*/
+#define  URXD_CHARRDY    (1<<15)
+#define  URXD_ERR        (1<<14)
+#define  URXD_OVRRUN     (1<<13)
+#define  URXD_FRMERR     (1<<12)
+#define  URXD_BRK        (1<<11)
+#define  URXD_PRERR      (1<<10)
+#define  UCR1_ADEN       (1<<15) /* Auto dectect interrupt */
+#define  UCR1_ADBR       (1<<14) /* Auto detect baud rate */
+#define  UCR1_TRDYEN     (1<<13) /* Transmitter ready interrupt enable */
+#define  UCR1_IDEN       (1<<12) /* Idle condition interrupt */
+#define  UCR1_RRDYEN     (1<<9)	 /* Recv ready interrupt enable */
+#define  UCR1_RDMAEN     (1<<8)	 /* Recv ready DMA enable */
+#define  UCR1_IREN       (1<<7)	 /* Infrared interface enable */
+#define  UCR1_TXMPTYEN   (1<<6)	 /* Transimitter empty interrupt enable */
+#define  UCR1_RTSDEN     (1<<5)	 /* RTS delta interrupt enable */
+#define  UCR1_SNDBRK     (1<<4)	 /* Send break */
+#define  UCR1_TDMAEN     (1<<3)	 /* Transmitter ready DMA enable */
+#define  UCR1_UARTCLKEN  (1<<2)	 /* UART clock enabled */
+#define  UCR1_DOZE       (1<<1)	 /* Doze */
+#define  UCR1_UARTEN     (1<<0)	 /* UART enabled */
+#define  UCR2_ESCI     	 (1<<15) /* Escape seq interrupt enable */
+#define  UCR2_IRTS  	 (1<<14) /* Ignore RTS pin */
+#define  UCR2_CTSC  	 (1<<13) /* CTS pin control */
+#define  UCR2_CTS        (1<<12) /* Clear to send */
+#define  UCR2_ESCEN      (1<<11) /* Escape enable */
+#define  UCR2_PREN       (1<<8)  /* Parity enable */
+#define  UCR2_PROE       (1<<7)  /* Parity odd/even */
+#define  UCR2_STPB       (1<<6)	 /* Stop */
+#define  UCR2_WS         (1<<5)	 /* Word size */
+#define  UCR2_RTSEN      (1<<4)	 /* Request to send interrupt enable */
+#define  UCR2_TXEN       (1<<2)	 /* Transmitter enabled */
+#define  UCR2_RXEN       (1<<1)	 /* Receiver enabled */
+#define  UCR2_SRST 	 (1<<0)	 /* SW reset */
+#define  UCR3_DTREN 	 (1<<13) /* DTR interrupt enable */
+#define  UCR3_PARERREN   (1<<12) /* Parity enable */
+#define  UCR3_FRAERREN   (1<<11) /* Frame error interrupt enable */
+#define  UCR3_DSR        (1<<10) /* Data set ready */
+#define  UCR3_DCD        (1<<9)  /* Data carrier detect */
+#define  UCR3_RI         (1<<8)  /* Ring indicator */
+#define  UCR3_TIMEOUTEN  (1<<7)  /* Timeout interrupt enable */
+#define  UCR3_RXDSEN	 (1<<6)  /* Receive status interrupt enable */
+#define  UCR3_AIRINTEN   (1<<5)  /* Async IR wake interrupt enable */
+#define  UCR3_AWAKEN	 (1<<4)  /* Async wake interrupt enable */
+#define  UCR3_REF25 	 (1<<3)  /* Ref freq 25 MHz */
+#define  UCR3_REF30 	 (1<<2)  /* Ref Freq 30 MHz */
+#define  UCR3_INVT  	 (1<<1)  /* Inverted Infrared transmission */
+#define  UCR3_BPEN  	 (1<<0)  /* Preset registers enable */
+#define  UCR4_CTSTL_32   (32<<10) /* CTS trigger level (32 chars) */
+#define  UCR4_INVR  	 (1<<9)  /* Inverted infrared reception */
+#define  UCR4_ENIRI 	 (1<<8)  /* Serial infrared interrupt enable */
+#define  UCR4_WKEN  	 (1<<7)  /* Wake interrupt enable */
+#define  UCR4_REF16 	 (1<<6)  /* Ref freq 16 MHz */
+#define  UCR4_IRSC  	 (1<<5)  /* IR special case */
+#define  UCR4_TCEN  	 (1<<3)  /* Transmit complete interrupt enable */
+#define  UCR4_BKEN  	 (1<<2)  /* Break condition interrupt enable */
+#define  UCR4_OREN  	 (1<<1)  /* Receiver overrun interrupt enable */
+#define  UCR4_DREN  	 (1<<0)  /* Recv data ready interrupt enable */
+#define  UFCR_RXTL_SHF   0       /* Receiver trigger level shift */
+#define  UFCR_RFDIV      (7<<7)  /* Reference freq divider mask */
+#define  UFCR_TXTL_SHF   10      /* Transmitter trigger level shift */
+#define  USR1_PARITYERR  (1<<15) /* Parity error interrupt flag */
+#define  USR1_RTSS  	 (1<<14) /* RTS pin status */
+#define  USR1_TRDY  	 (1<<13) /* Transmitter ready interrupt/dma flag */
+#define  USR1_RTSD  	 (1<<12) /* RTS delta */
+#define  USR1_ESCF  	 (1<<11) /* Escape seq interrupt flag */
+#define  USR1_FRAMERR    (1<<10) /* Frame error interrupt flag */
+#define  USR1_RRDY       (1<<9)	 /* Receiver ready interrupt/dma flag */
+#define  USR1_TIMEOUT    (1<<7)	 /* Receive timeout interrupt status */
+#define  USR1_RXDS  	 (1<<6)	 /* Receiver idle interrupt flag */
+#define  USR1_AIRINT	 (1<<5)	 /* Async IR wake interrupt flag */
+#define  USR1_AWAKE 	 (1<<4)	 /* Aysnc wake interrupt flag */
+#define  USR2_ADET  	 (1<<15) /* Auto baud rate detect complete */
+#define  USR2_TXFE  	 (1<<14) /* Transmit buffer FIFO empty */
+#define  USR2_DTRF  	 (1<<13) /* DTR edge interrupt flag */
+#define  USR2_IDLE  	 (1<<12) /* Idle condition */
+#define  USR2_IRINT 	 (1<<8)	 /* Serial infrared interrupt flag */
+#define  USR2_WAKE  	 (1<<7)	 /* Wake */
+#define  USR2_RTSF  	 (1<<4)	 /* RTS edge interrupt flag */
+#define  USR2_TXDC  	 (1<<3)	 /* Transmitter complete */
+#define  USR2_BRCD  	 (1<<2)	 /* Break condition */
+#define  USR2_ORE        (1<<1)	 /* Overrun error */
+#define  USR2_RDR        (1<<0)	 /* Recv data ready */
+#define  UTS_FRCPERR	 (1<<13) /* Force parity error */
+#define  UTS_LOOP        (1<<12) /* Loop tx and rx */
+#define  UTS_TXEMPTY	 (1<<6)	 /* TxFIFO empty */
+#define  UTS_RXEMPTY	 (1<<5)	 /* RxFIFO empty */
+#define  UTS_TXFULL 	 (1<<4)	 /* TxFIFO full */
+#define  UTS_RXFULL 	 (1<<3)	 /* RxFIFO full */
+#define  UTS_SOFTRST	 (1<<0)	 /* Software reset */
+
 /* We've been assigned a range on the "Low-density serial ports" major */
 /* We've been assigned a range on the "Low-density serial ports" major */
 #define SERIAL_IMX_MAJOR	204
 #define SERIAL_IMX_MAJOR	204
 #define MINOR_START		41
 #define MINOR_START		41
@@ -128,7 +244,10 @@ static void imx_timeout(unsigned long data)
 static void imx_stop_tx(struct uart_port *port)
 static void imx_stop_tx(struct uart_port *port)
 {
 {
 	struct imx_port *sport = (struct imx_port *)port;
 	struct imx_port *sport = (struct imx_port *)port;
-	UCR1((u32)sport->port.membase) &= ~UCR1_TXMPTYEN;
+	unsigned long temp;
+
+	temp = readl(sport->port.membase + UCR1);
+	writel(temp & ~UCR1_TXMPTYEN, sport->port.membase + UCR1);
 }
 }
 
 
 /*
 /*
@@ -137,7 +256,10 @@ static void imx_stop_tx(struct uart_port *port)
 static void imx_stop_rx(struct uart_port *port)
 static void imx_stop_rx(struct uart_port *port)
 {
 {
 	struct imx_port *sport = (struct imx_port *)port;
 	struct imx_port *sport = (struct imx_port *)port;
-	UCR2((u32)sport->port.membase) &= ~UCR2_RXEN;
+	unsigned long temp;
+
+	temp = readl(sport->port.membase + UCR2);
+	writel(temp &~ UCR2_RXEN, sport->port.membase + UCR2);
 }
 }
 
 
 /*
 /*
@@ -154,10 +276,10 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
 {
 {
 	struct circ_buf *xmit = &sport->port.info->xmit;
 	struct circ_buf *xmit = &sport->port.info->xmit;
 
 
-	while (!(UTS((u32)sport->port.membase) & UTS_TXFULL)) {
+	while (!(readl(sport->port.membase + UTS) & UTS_TXFULL)) {
 		/* send xmit->buf[xmit->tail]
 		/* send xmit->buf[xmit->tail]
 		 * out the port here */
 		 * out the port here */
-		URTX0((u32)sport->port.membase) = xmit->buf[xmit->tail];
+		writel(xmit->buf[xmit->tail], sport->port.membase + URTX0);
 		xmit->tail = (xmit->tail + 1) &
 		xmit->tail = (xmit->tail + 1) &
 		         (UART_XMIT_SIZE - 1);
 		         (UART_XMIT_SIZE - 1);
 		sport->port.icount.tx++;
 		sport->port.icount.tx++;
@@ -175,21 +297,24 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
 static void imx_start_tx(struct uart_port *port)
 static void imx_start_tx(struct uart_port *port)
 {
 {
 	struct imx_port *sport = (struct imx_port *)port;
 	struct imx_port *sport = (struct imx_port *)port;
+	unsigned long temp;
 
 
-	UCR1((u32)sport->port.membase) |= UCR1_TXMPTYEN;
+	temp = readl(sport->port.membase + UCR1);
+	writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1);
 
 
-	imx_transmit_buffer(sport);
+	if (readl(sport->port.membase + UTS) & UTS_TXEMPTY)
+		imx_transmit_buffer(sport);
 }
 }
 
 
 static irqreturn_t imx_rtsint(int irq, void *dev_id)
 static irqreturn_t imx_rtsint(int irq, void *dev_id)
 {
 {
 	struct imx_port *sport = (struct imx_port *)dev_id;
 	struct imx_port *sport = (struct imx_port *)dev_id;
-	unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS;
+	unsigned int val = readl(sport->port.membase + USR1) & USR1_RTSS;
 	unsigned long flags;
 	unsigned long flags;
 
 
 	spin_lock_irqsave(&sport->port.lock, flags);
 	spin_lock_irqsave(&sport->port.lock, flags);
 
 
-	USR1((u32)sport->port.membase) = USR1_RTSD;
+	writel(USR1_RTSD, sport->port.membase + USR1);
 	uart_handle_cts_change(&sport->port, !!val);
 	uart_handle_cts_change(&sport->port, !!val);
 	wake_up_interruptible(&sport->port.info->delta_msr_wait);
 	wake_up_interruptible(&sport->port.info->delta_msr_wait);
 
 
@@ -207,7 +332,7 @@ static irqreturn_t imx_txint(int irq, void *dev_id)
 	if (sport->port.x_char)
 	if (sport->port.x_char)
 	{
 	{
 		/* Send next char */
 		/* Send next char */
-		URTX0((u32)sport->port.membase) = sport->port.x_char;
+		writel(sport->port.x_char, sport->port.membase + URTX0);
 		goto out;
 		goto out;
 	}
 	}
 
 
@@ -231,17 +356,18 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
 	struct imx_port *sport = dev_id;
 	struct imx_port *sport = dev_id;
 	unsigned int rx,flg,ignored = 0;
 	unsigned int rx,flg,ignored = 0;
 	struct tty_struct *tty = sport->port.info->tty;
 	struct tty_struct *tty = sport->port.info->tty;
-	unsigned long flags;
+	unsigned long flags, temp;
 
 
-	rx = URXD0((u32)sport->port.membase);
+	rx = readl(sport->port.membase + URXD0);
 	spin_lock_irqsave(&sport->port.lock,flags);
 	spin_lock_irqsave(&sport->port.lock,flags);
 
 
 	do {
 	do {
 		flg = TTY_NORMAL;
 		flg = TTY_NORMAL;
 		sport->port.icount.rx++;
 		sport->port.icount.rx++;
 
 
-		if( USR2((u32)sport->port.membase) & USR2_BRCD ) {
-			USR2((u32)sport->port.membase) |= USR2_BRCD;
+		temp = readl(sport->port.membase + USR2);
+		if( temp & USR2_BRCD ) {
+			writel(temp | USR2_BRCD, sport->port.membase + USR2);
 			if(uart_handle_break(&sport->port))
 			if(uart_handle_break(&sport->port))
 				goto ignore_char;
 				goto ignore_char;
 		}
 		}
@@ -257,7 +383,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
 		tty_insert_flip_char(tty, rx, flg);
 		tty_insert_flip_char(tty, rx, flg);
 
 
 	ignore_char:
 	ignore_char:
-		rx = URXD0((u32)sport->port.membase);
+		rx = readl(sport->port.membase + URXD0);
 	} while(rx & URXD_CHARRDY);
 	} while(rx & URXD_CHARRDY);
 
 
 out:
 out:
@@ -301,7 +427,7 @@ static unsigned int imx_tx_empty(struct uart_port *port)
 {
 {
 	struct imx_port *sport = (struct imx_port *)port;
 	struct imx_port *sport = (struct imx_port *)port;
 
 
-	return USR2((u32)sport->port.membase) & USR2_TXDC ?  TIOCSER_TEMT : 0;
+	return (readl(sport->port.membase + USR2) & USR2_TXDC) ?  TIOCSER_TEMT : 0;
 }
 }
 
 
 /*
 /*
@@ -312,10 +438,10 @@ static unsigned int imx_get_mctrl(struct uart_port *port)
         struct imx_port *sport = (struct imx_port *)port;
         struct imx_port *sport = (struct imx_port *)port;
         unsigned int tmp = TIOCM_DSR | TIOCM_CAR;
         unsigned int tmp = TIOCM_DSR | TIOCM_CAR;
 
 
-        if (USR1((u32)sport->port.membase) & USR1_RTSS)
+        if (readl(sport->port.membase + USR1) & USR1_RTSS)
                 tmp |= TIOCM_CTS;
                 tmp |= TIOCM_CTS;
 
 
-        if (UCR2((u32)sport->port.membase) & UCR2_CTS)
+        if (readl(sport->port.membase + UCR2) & UCR2_CTS)
                 tmp |= TIOCM_RTS;
                 tmp |= TIOCM_RTS;
 
 
         return tmp;
         return tmp;
@@ -324,11 +450,14 @@ static unsigned int imx_get_mctrl(struct uart_port *port)
 static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl)
 static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
 {
         struct imx_port *sport = (struct imx_port *)port;
         struct imx_port *sport = (struct imx_port *)port;
+	unsigned long temp;
+
+	temp = readl(sport->port.membase + UCR2) & ~UCR2_CTS;
 
 
         if (mctrl & TIOCM_RTS)
         if (mctrl & TIOCM_RTS)
-                UCR2((u32)sport->port.membase) |= UCR2_CTS;
-        else
-                UCR2((u32)sport->port.membase) &= ~UCR2_CTS;
+		temp |= UCR2_CTS;
+
+	writel(temp, sport->port.membase + UCR2);
 }
 }
 
 
 /*
 /*
@@ -337,14 +466,16 @@ static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl)
 static void imx_break_ctl(struct uart_port *port, int break_state)
 static void imx_break_ctl(struct uart_port *port, int break_state)
 {
 {
 	struct imx_port *sport = (struct imx_port *)port;
 	struct imx_port *sport = (struct imx_port *)port;
-	unsigned long flags;
+	unsigned long flags, temp;
 
 
 	spin_lock_irqsave(&sport->port.lock, flags);
 	spin_lock_irqsave(&sport->port.lock, flags);
 
 
+	temp = readl(sport->port.membase + UCR1) & ~UCR1_SNDBRK;
+
 	if ( break_state != 0 )
 	if ( break_state != 0 )
-		UCR1((u32)sport->port.membase) |= UCR1_SNDBRK;
-	else
-		UCR1((u32)sport->port.membase) &= ~UCR1_SNDBRK;
+		temp |= UCR1_SNDBRK;
+
+	writel(temp, sport->port.membase + UCR1);
 
 
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 }
 }
@@ -360,7 +491,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
 	/* set receiver / transmitter trigger level.
 	/* set receiver / transmitter trigger level.
 	 * RFDIV is set such way to satisfy requested uartclk value
 	 * RFDIV is set such way to satisfy requested uartclk value
 	 */
 	 */
-	val = TXTL<<10 | RXTL;
+	val = TXTL << 10 | RXTL;
 	ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk;
 	ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk;
 
 
 	if(!ufcr_rfdiv)
 	if(!ufcr_rfdiv)
@@ -373,7 +504,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
 
 
 	val |= UFCR_RFDIV & (ufcr_rfdiv << 7);
 	val |= UFCR_RFDIV & (ufcr_rfdiv << 7);
 
 
-	UFCR((u32)sport->port.membase) = val;
+	writel(val, sport->port.membase + UFCR);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -382,14 +513,15 @@ static int imx_startup(struct uart_port *port)
 {
 {
 	struct imx_port *sport = (struct imx_port *)port;
 	struct imx_port *sport = (struct imx_port *)port;
 	int retval;
 	int retval;
-	unsigned long flags;
+	unsigned long flags, temp;
 
 
 	imx_setup_ufcr(sport, 0);
 	imx_setup_ufcr(sport, 0);
 
 
 	/* disable the DREN bit (Data Ready interrupt enable) before
 	/* disable the DREN bit (Data Ready interrupt enable) before
 	 * requesting IRQs
 	 * requesting IRQs
 	 */
 	 */
-	UCR4((u32)sport->port.membase) &= ~UCR4_DREN;
+	temp = readl(sport->port.membase + UCR4);
+	writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
 
 
 	/*
 	/*
 	 * Allocate the IRQ
 	 * Allocate the IRQ
@@ -411,12 +543,16 @@ static int imx_startup(struct uart_port *port)
 	/*
 	/*
 	 * Finally, clear and enable interrupts
 	 * Finally, clear and enable interrupts
 	 */
 	 */
+	writel(USR1_RTSD, sport->port.membase + USR1);
+
+	temp = readl(sport->port.membase + UCR1);
+	temp |= (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
+	writel(temp, sport->port.membase + UCR1);
 
 
-	USR1((u32)sport->port.membase) = USR1_RTSD;
-	UCR1((u32)sport->port.membase) |=
-	                 (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
+	temp = readl(sport->port.membase + UCR2);
+	temp |= (UCR2_RXEN | UCR2_TXEN);
+	writel(temp, sport->port.membase + UCR2);
 
 
-	UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN);
 	/*
 	/*
 	 * Enable modem status interrupts
 	 * Enable modem status interrupts
 	 */
 	 */
@@ -437,6 +573,7 @@ error_out1:
 static void imx_shutdown(struct uart_port *port)
 static void imx_shutdown(struct uart_port *port)
 {
 {
 	struct imx_port *sport = (struct imx_port *)port;
 	struct imx_port *sport = (struct imx_port *)port;
+	unsigned long temp;
 
 
 	/*
 	/*
 	 * Stop our timer.
 	 * Stop our timer.
@@ -454,8 +591,9 @@ static void imx_shutdown(struct uart_port *port)
 	 * Disable all interrupts, port and break condition.
 	 * Disable all interrupts, port and break condition.
 	 */
 	 */
 
 
-	UCR1((u32)sport->port.membase) &=
-	                 ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
+	temp = readl(sport->port.membase + UCR1);
+	temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
+	writel(temp, sport->port.membase + UCR1);
 }
 }
 
 
 static void
 static void
@@ -548,18 +686,18 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
 	/*
 	/*
 	 * disable interrupts and drain transmitter
 	 * disable interrupts and drain transmitter
 	 */
 	 */
-	old_ucr1 = UCR1((u32)sport->port.membase);
-	UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
+	old_ucr1 = readl(sport->port.membase + UCR1);
+	writel(old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN),
+			sport->port.membase + UCR1);
 
 
-	while ( !(USR2((u32)sport->port.membase) & USR2_TXDC))
+	while ( !(readl(sport->port.membase + USR2) & USR2_TXDC))
 		barrier();
 		barrier();
 
 
 	/* then, disable everything */
 	/* then, disable everything */
-	old_txrxen = UCR2((u32)sport->port.membase) & ( UCR2_TXEN | UCR2_RXEN );
-	UCR2((u32)sport->port.membase) &= ~( UCR2_TXEN | UCR2_RXEN);
-
-	/* set the parity, stop bits and data size */
-	UCR2((u32)sport->port.membase) = ucr2;
+	old_txrxen = readl(sport->port.membase + UCR2);
+	writel(old_txrxen & ~( UCR2_TXEN | UCR2_RXEN),
+			sport->port.membase + UCR2);
+	old_txrxen &= (UCR2_TXEN | UCR2_RXEN);
 
 
 	/* set the baud rate. We assume uartclk = 16 MHz
 	/* set the baud rate. We assume uartclk = 16 MHz
 	 *
 	 *
@@ -567,11 +705,13 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
 	 * --------- = --------
 	 * --------- = --------
 	 *  uartclk    UBMR - 1
 	 *  uartclk    UBMR - 1
 	 */
 	 */
-	UBIR((u32)sport->port.membase) = (baud / 100) - 1;
-	UBMR((u32)sport->port.membase) = 10000 - 1;
+	writel((baud / 100) - 1, sport->port.membase + UBIR);
+	writel(10000 - 1, sport->port.membase + UBMR);
+
+	writel(old_ucr1, sport->port.membase + UCR1);
 
 
-	UCR1((u32)sport->port.membase) = old_ucr1;
-	UCR2((u32)sport->port.membase) |= old_txrxen;
+	/* set the parity, stop bits and data size */
+	writel(ucr2 | old_txrxen, sport->port.membase + UCR2);
 
 
 	if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
 	if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
 		imx_enable_ms(&sport->port);
 		imx_enable_ms(&sport->port);
@@ -730,9 +870,11 @@ static void __init imx_init_ports(void)
 static void imx_console_putchar(struct uart_port *port, int ch)
 static void imx_console_putchar(struct uart_port *port, int ch)
 {
 {
 	struct imx_port *sport = (struct imx_port *)port;
 	struct imx_port *sport = (struct imx_port *)port;
-	while ((UTS((u32)sport->port.membase) & UTS_TXFULL))
+
+	while (readl(sport->port.membase + UTS) & UTS_TXFULL)
 		barrier();
 		barrier();
-	URTX0((u32)sport->port.membase) = ch;
+
+	writel(ch, sport->port.membase + URTX0);
 }
 }
 
 
 /*
 /*
@@ -747,13 +889,14 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
 	/*
 	/*
 	 *	First, save UCR1/2 and then disable interrupts
 	 *	First, save UCR1/2 and then disable interrupts
 	 */
 	 */
-	old_ucr1 = UCR1((u32)sport->port.membase);
-	old_ucr2 = UCR2((u32)sport->port.membase);
+	old_ucr1 = readl(sport->port.membase + UCR1);
+	old_ucr2 = readl(sport->port.membase + UCR2);
 
 
-	UCR1((u32)sport->port.membase) =
-	                   (old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN)
-	                   & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
-	UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN;
+	writel((old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) &
+		~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN),
+		sport->port.membase + UCR1);
+
+	writel(old_ucr2 | UCR2_TXEN, sport->port.membase + UCR2);
 
 
 	uart_console_write(&sport->port, s, count, imx_console_putchar);
 	uart_console_write(&sport->port, s, count, imx_console_putchar);
 
 
@@ -761,10 +904,10 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
 	 *	Finally, wait for transmitter to become empty
 	 *	Finally, wait for transmitter to become empty
 	 *	and restore UCR1/2
 	 *	and restore UCR1/2
 	 */
 	 */
-	while (!(USR2((u32)sport->port.membase) & USR2_TXDC));
+	while (!(readl(sport->port.membase + USR2) & USR2_TXDC));
 
 
-	UCR1((u32)sport->port.membase) = old_ucr1;
-	UCR2((u32)sport->port.membase) = old_ucr2;
+	writel(old_ucr1, sport->port.membase + UCR1);
+	writel(old_ucr2, sport->port.membase + UCR2);
 }
 }
 
 
 /*
 /*
@@ -776,13 +919,13 @@ imx_console_get_options(struct imx_port *sport, int *baud,
 			   int *parity, int *bits)
 			   int *parity, int *bits)
 {
 {
 
 
-	if ( UCR1((u32)sport->port.membase) | UCR1_UARTEN ) {
+	if ( readl(sport->port.membase + UCR1) | UCR1_UARTEN ) {
 		/* ok, the port was enabled */
 		/* ok, the port was enabled */
 		unsigned int ucr2, ubir,ubmr, uartclk;
 		unsigned int ucr2, ubir,ubmr, uartclk;
 		unsigned int baud_raw;
 		unsigned int baud_raw;
 		unsigned int ucfr_rfdiv;
 		unsigned int ucfr_rfdiv;
 
 
-		ucr2 = UCR2((u32)sport->port.membase);
+		ucr2 = readl(sport->port.membase + UCR2);
 
 
 		*parity = 'n';
 		*parity = 'n';
 		if (ucr2 & UCR2_PREN) {
 		if (ucr2 & UCR2_PREN) {
@@ -797,11 +940,10 @@ imx_console_get_options(struct imx_port *sport, int *baud,
 		else
 		else
 			*bits = 7;
 			*bits = 7;
 
 
-		ubir = UBIR((u32)sport->port.membase) & 0xffff;
-		ubmr = UBMR((u32)sport->port.membase) & 0xffff;
-
+		ubir = readl(sport->port.membase + UBIR) & 0xffff;
+		ubmr = readl(sport->port.membase + UBMR) & 0xffff;
 
 
-		ucfr_rfdiv = (UFCR((u32)sport->port.membase) & UFCR_RFDIV) >> 7;
+		ucfr_rfdiv = (readl(sport->port.membase + UFCR) & UFCR_RFDIV) >> 7;
 		if (ucfr_rfdiv == 6)
 		if (ucfr_rfdiv == 6)
 			ucfr_rfdiv = 7;
 			ucfr_rfdiv = 7;
 		else
 		else

+ 4 - 4
drivers/serial/pxa.c

@@ -717,7 +717,7 @@ struct uart_ops serial_pxa_pops = {
 static struct uart_pxa_port serial_pxa_ports[] = {
 static struct uart_pxa_port serial_pxa_ports[] = {
      {	/* FFUART */
      {	/* FFUART */
 	.name	= "FFUART",
 	.name	= "FFUART",
-	.cken	= CKEN6_FFUART,
+	.cken	= CKEN_FFUART,
 	.port	= {
 	.port	= {
 		.type		= PORT_PXA,
 		.type		= PORT_PXA,
 		.iotype		= UPIO_MEM,
 		.iotype		= UPIO_MEM,
@@ -731,7 +731,7 @@ static struct uart_pxa_port serial_pxa_ports[] = {
 	},
 	},
   }, {	/* BTUART */
   }, {	/* BTUART */
 	.name	= "BTUART",
 	.name	= "BTUART",
-	.cken	= CKEN7_BTUART,
+	.cken	= CKEN_BTUART,
 	.port	= {
 	.port	= {
 		.type		= PORT_PXA,
 		.type		= PORT_PXA,
 		.iotype		= UPIO_MEM,
 		.iotype		= UPIO_MEM,
@@ -745,7 +745,7 @@ static struct uart_pxa_port serial_pxa_ports[] = {
 	},
 	},
   }, {	/* STUART */
   }, {	/* STUART */
 	.name	= "STUART",
 	.name	= "STUART",
-	.cken	= CKEN5_STUART,
+	.cken	= CKEN_STUART,
 	.port	= {
 	.port	= {
 		.type		= PORT_PXA,
 		.type		= PORT_PXA,
 		.iotype		= UPIO_MEM,
 		.iotype		= UPIO_MEM,
@@ -759,7 +759,7 @@ static struct uart_pxa_port serial_pxa_ports[] = {
 	},
 	},
   }, {  /* HWUART */
   }, {  /* HWUART */
 	.name	= "HWUART",
 	.name	= "HWUART",
-	.cken	= CKEN4_HWUART,
+	.cken	= CKEN_HWUART,
 	.port = {
 	.port = {
 		.type		= PORT_PXA,
 		.type		= PORT_PXA,
 		.iotype		= UPIO_MEM,
 		.iotype		= UPIO_MEM,

+ 2 - 2
drivers/usb/gadget/pxa2xx_udc.c

@@ -1497,7 +1497,7 @@ static void udc_disable(struct pxa2xx_udc *dev)
 
 
 #ifdef	CONFIG_ARCH_PXA
 #ifdef	CONFIG_ARCH_PXA
         /* Disable clock for USB device */
         /* Disable clock for USB device */
-	pxa_set_cken(CKEN11_USB, 0);
+	pxa_set_cken(CKEN_USB, 0);
 #endif
 #endif
 
 
 	ep0_idle (dev);
 	ep0_idle (dev);
@@ -1543,7 +1543,7 @@ static void udc_enable (struct pxa2xx_udc *dev)
 
 
 #ifdef	CONFIG_ARCH_PXA
 #ifdef	CONFIG_ARCH_PXA
         /* Enable clock for USB device */
         /* Enable clock for USB device */
-	pxa_set_cken(CKEN11_USB, 1);
+	pxa_set_cken(CKEN_USB, 1);
 	udelay(5);
 	udelay(5);
 #endif
 #endif
 
 

部分文件因为文件数量过多而无法显示