浏览代码

Merge with /home/shaggy/git/linus-clean/

Dave Kleikamp 19 年之前
父节点
当前提交
ca86991236
共有 100 个文件被更改,包括 10895 次插入2185 次删除
  1. 56 0
      Documentation/networking/dccp.txt
  2. 5 0
      Documentation/networking/ip-sysctl.txt
  3. 1 1
      MAINTAINERS
  4. 2 2
      Makefile
  5. 2 0
      arch/arm/Kconfig
  6. 1 0
      arch/arm/Makefile
  7. 19 19
      arch/arm/common/locomo.c
  8. 21 21
      arch/arm/common/sa1111.c
  9. 15 15
      arch/arm/common/scoop.c
  10. 66 31
      arch/arm/configs/omap_h2_1610_defconfig
  11. 4 0
      arch/arm/lib/csumpartial.S
  12. 10 0
      arch/arm/mach-ixp4xx/Kconfig
  13. 1 0
      arch/arm/mach-ixp4xx/Makefile
  14. 77 0
      arch/arm/mach-ixp4xx/nslu2-pci.c
  15. 92 0
      arch/arm/mach-ixp4xx/nslu2-power.c
  16. 134 0
      arch/arm/mach-ixp4xx/nslu2-setup.c
  17. 21 11
      arch/arm/mach-omap1/Kconfig
  18. 3 2
      arch/arm/mach-omap1/Makefile
  19. 9 24
      arch/arm/mach-omap1/board-generic.c
  20. 12 3
      arch/arm/mach-omap1/board-h2.c
  21. 14 5
      arch/arm/mach-omap1/board-h3.c
  22. 30 12
      arch/arm/mach-omap1/board-innovator.c
  23. 12 3
      arch/arm/mach-omap1/board-netstar.c
  24. 13 4
      arch/arm/mach-omap1/board-osk.c
  25. 87 0
      arch/arm/mach-omap1/board-palmte.c
  26. 19 4
      arch/arm/mach-omap1/board-perseus2.c
  27. 6 3
      arch/arm/mach-omap1/board-voiceblue.c
  28. 792 0
      arch/arm/mach-omap1/clock.c
  29. 768 0
      arch/arm/mach-omap1/clock.h
  30. 3 218
      arch/arm/mach-omap1/devices.c
  31. 9 0
      arch/arm/mach-omap1/id.c
  32. 8 5
      arch/arm/mach-omap1/io.c
  33. 17 6
      arch/arm/mach-omap1/irq.c
  34. 34 9
      arch/arm/mach-omap1/leds-h2p2-debug.c
  35. 0 1
      arch/arm/mach-omap1/leds.c
  36. 289 0
      arch/arm/mach-omap1/mux.c
  37. 7 2
      arch/arm/mach-omap1/serial.c
  38. 2 2
      arch/arm/mach-omap1/time.c
  39. 22 0
      arch/arm/mach-omap2/Kconfig
  40. 13 0
      arch/arm/mach-omap2/Makefile
  41. 3 0
      arch/arm/mach-omap2/Makefile.boot
  42. 80 0
      arch/arm/mach-omap2/board-generic.c
  43. 197 0
      arch/arm/mach-omap2/board-h4.c
  44. 1129 0
      arch/arm/mach-omap2/clock.c
  45. 2103 0
      arch/arm/mach-omap2/clock.h
  46. 89 0
      arch/arm/mach-omap2/devices.c
  47. 124 0
      arch/arm/mach-omap2/id.c
  48. 53 0
      arch/arm/mach-omap2/io.c
  49. 149 0
      arch/arm/mach-omap2/irq.c
  50. 65 0
      arch/arm/mach-omap2/mux.c
  51. 419 0
      arch/arm/mach-omap2/prcm.h
  52. 180 0
      arch/arm/mach-omap2/serial.c
  53. 333 0
      arch/arm/mach-omap2/sram-fn.S
  54. 126 0
      arch/arm/mach-omap2/timer-gp.c
  55. 7 0
      arch/arm/mach-pxa/Kconfig
  56. 3 2
      arch/arm/mach-pxa/Makefile
  57. 10 9
      arch/arm/mach-pxa/corgi_ssp.c
  58. 87 0
      arch/arm/mach-pxa/sharpsl.h
  59. 992 0
      arch/arm/mach-pxa/sharpsl_pm.c
  60. 40 88
      arch/arm/mach-pxa/ssp.c
  61. 16 15
      arch/arm/mach-sa1100/neponset.c
  62. 3 3
      arch/arm/mm/Kconfig
  63. 1 1
      arch/arm/plat-omap/Makefile
  64. 117 988
      arch/arm/plat-omap/clock.c
  65. 0 120
      arch/arm/plat-omap/clock.h
  66. 37 13
      arch/arm/plat-omap/common.c
  67. 381 0
      arch/arm/plat-omap/devices.c
  68. 541 224
      arch/arm/plat-omap/dma.c
  69. 27 13
      arch/arm/plat-omap/gpio.c
  70. 14 8
      arch/arm/plat-omap/mcbsp.c
  71. 51 14
      arch/arm/plat-omap/mux.c
  72. 82 21
      arch/arm/plat-omap/pm.c
  73. 134 5
      arch/arm/plat-omap/sleep.S
  74. 116 27
      arch/arm/plat-omap/sram.c
  75. 0 21
      arch/arm/plat-omap/sram.h
  76. 9 2
      arch/arm/plat-omap/usb.c
  77. 1 2
      arch/i386/pci/fixup.c
  78. 1 1
      arch/ia64/kernel/efi.c
  79. 13 9
      arch/ia64/kernel/kprobes.c
  80. 95 25
      arch/ia64/kernel/mca.c
  81. 13 4
      arch/ia64/kernel/mca_drv.c
  82. 6 0
      arch/ia64/kernel/process.c
  83. 1 0
      arch/ia64/kernel/setup.c
  84. 5 6
      arch/ia64/kernel/signal.c
  85. 20 24
      arch/ia64/kernel/traps.c
  86. 9 10
      arch/ia64/mm/discontig.c
  87. 43 42
      arch/ia64/mm/tlb.c
  88. 82 24
      arch/ia64/pci/pci.c
  89. 1 1
      arch/ia64/sn/kernel/io_init.c
  90. 1 1
      arch/ia64/sn/kernel/xpc.h
  91. 102 0
      arch/ia64/sn/kernel/xpc_main.c
  92. 4 4
      arch/ia64/sn/kernel/xpc_partition.c
  93. 3 3
      arch/ia64/sn/pci/tioce_provider.c
  94. 7 8
      arch/powerpc/Kconfig
  95. 16 3
      arch/powerpc/kernel/Makefile
  96. 31 15
      arch/powerpc/kernel/asm-offsets.c
  97. 4 4
      arch/powerpc/kernel/cpu_setup_power4.S
  98. 11 8
      arch/powerpc/kernel/cputable.c
  99. 0 2
      arch/powerpc/kernel/firmware.c
  100. 12 12
      arch/powerpc/kernel/fpu.S

+ 56 - 0
Documentation/networking/dccp.txt

@@ -0,0 +1,56 @@
+DCCP protocol
+============
+
+Last updated: 10 November 2005
+
+Contents
+========
+
+- Introduction
+- Missing features
+- Socket options
+- Notes
+
+Introduction
+============
+
+Datagram Congestion Control Protocol (DCCP) is an unreliable, connection
+based protocol designed to solve issues present in UDP and TCP particularly
+for real time and multimedia traffic.
+
+It has a base protocol and pluggable congestion control IDs (CCIDs).
+
+It is at draft RFC status and the homepage for DCCP as a protocol is at:
+	http://www.icir.org/kohler/dcp/
+
+Missing features
+================
+
+The DCCP implementation does not currently have all the features that are in
+the draft RFC.
+
+In particular the following are missing:
+- CCID2 support
+- feature negotiation
+
+When testing against other implementations it appears that elapsed time
+options are not coded compliant to the specification.
+
+Socket options
+==============
+
+DCCP_SOCKOPT_PACKET_SIZE is used for CCID3 to set default packet size for
+calculations.
+
+DCCP_SOCKOPT_SERVICE sets the service. This is compulsory as per the
+specification. If you don't set it you will get EPROTO.
+
+Notes
+=====
+
+SELinux does not yet have support for DCCP. You will need to turn it off or
+else you will get EACCES.
+
+DCCP does not travel through NAT successfully at present. This is because
+the checksum covers the psuedo-header as per TCP and UDP. It should be
+relatively trivial to add Linux NAT support for DCCP.

+ 5 - 0
Documentation/networking/ip-sysctl.txt

@@ -78,6 +78,11 @@ inet_peer_gc_maxtime - INTEGER
 
 
 TCP variables: 
 TCP variables: 
 
 
+tcp_abc - INTEGER
+	Controls Appropriate Byte Count defined in RFC3465. If set to
+	0 then does congestion avoid once per ack. 1 is conservative
+	value, and 2 is more agressive.
+
 tcp_syn_retries - INTEGER
 tcp_syn_retries - INTEGER
 	Number of times initial SYNs for an active TCP connection attempt
 	Number of times initial SYNs for an active TCP connection attempt
 	will be retransmitted. Should not be higher than 255. Default value
 	will be retransmitted. Should not be higher than 255. Default value

+ 1 - 1
MAINTAINERS

@@ -707,7 +707,7 @@ DCCP PROTOCOL
 P:	Arnaldo Carvalho de Melo
 P:	Arnaldo Carvalho de Melo
 M:	acme@mandriva.com
 M:	acme@mandriva.com
 L:	dccp@vger.kernel.org
 L:	dccp@vger.kernel.org
-W:	http://www.wlug.org.nz/DCCP
+W:	http://linux-net.osdl.org/index.php/DCCP
 S:	Maintained
 S:	Maintained
 
 
 DECnet NETWORK LAYER
 DECnet NETWORK LAYER

+ 2 - 2
Makefile

@@ -347,7 +347,7 @@ AFLAGS_KERNEL	=
 # Needed to be compatible with the O= option
 # Needed to be compatible with the O= option
 LINUXINCLUDE    := -Iinclude \
 LINUXINCLUDE    := -Iinclude \
                    $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
                    $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
-		   -imacros include/linux/autoconf.h
+		   -include include/linux/autoconf.h
 
 
 CPPFLAGS        := -D__KERNEL__ $(LINUXINCLUDE)
 CPPFLAGS        := -D__KERNEL__ $(LINUXINCLUDE)
 
 
@@ -407,7 +407,7 @@ outputmakefile:
 # of make so .config is not included in this case either (for *config).
 # of make so .config is not included in this case either (for *config).
 
 
 no-dot-config-targets := clean mrproper distclean \
 no-dot-config-targets := clean mrproper distclean \
-			 cscope TAGS tags help %docs check%
+			 cscope TAGS tags help %docs check% kernelrelease
 
 
 config-targets := 0
 config-targets := 0
 mixed-targets  := 0
 mixed-targets  := 0

+ 2 - 0
arch/arm/Kconfig

@@ -239,6 +239,8 @@ source "arch/arm/plat-omap/Kconfig"
 
 
 source "arch/arm/mach-omap1/Kconfig"
 source "arch/arm/mach-omap1/Kconfig"
 
 
+source "arch/arm/mach-omap2/Kconfig"
+
 source "arch/arm/mach-s3c2410/Kconfig"
 source "arch/arm/mach-s3c2410/Kconfig"
 
 
 source "arch/arm/mach-lh7a40x/Kconfig"
 source "arch/arm/mach-lh7a40x/Kconfig"

+ 1 - 0
arch/arm/Makefile

@@ -93,6 +93,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET)   := 0xc0008000
  machine-$(CONFIG_ARCH_IXP4XX)	   := ixp4xx
  machine-$(CONFIG_ARCH_IXP4XX)	   := ixp4xx
  machine-$(CONFIG_ARCH_IXP2000)    := ixp2000
  machine-$(CONFIG_ARCH_IXP2000)    := ixp2000
  machine-$(CONFIG_ARCH_OMAP1)	   := omap1
  machine-$(CONFIG_ARCH_OMAP1)	   := omap1
+ machine-$(CONFIG_ARCH_OMAP2)	   := omap2
   incdir-$(CONFIG_ARCH_OMAP)	   := omap
   incdir-$(CONFIG_ARCH_OMAP)	   := omap
  machine-$(CONFIG_ARCH_S3C2410)	   := s3c2410
  machine-$(CONFIG_ARCH_S3C2410)	   := s3c2410
  machine-$(CONFIG_ARCH_LH7A40X)	   := lh7a40x
  machine-$(CONFIG_ARCH_LH7A40X)	   := lh7a40x

+ 19 - 19
arch/arm/common/locomo.c

@@ -550,9 +550,9 @@ struct locomo_save_data {
 	u16	LCM_SPIMD;
 	u16	LCM_SPIMD;
 };
 };
 
 
-static int locomo_suspend(struct device *dev, pm_message_t state)
+static int locomo_suspend(struct platform_device *dev, pm_message_t state)
 {
 {
-	struct locomo *lchip = dev_get_drvdata(dev);
+	struct locomo *lchip = platform_get_drvdata(dev);
 	struct locomo_save_data *save;
 	struct locomo_save_data *save;
 	unsigned long flags;
 	unsigned long flags;
 
 
@@ -560,7 +560,7 @@ static int locomo_suspend(struct device *dev, pm_message_t state)
 	if (!save)
 	if (!save)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	dev->power.saved_state = (void *) save;
+	dev->dev.power.saved_state = (void *) save;
 
 
 	spin_lock_irqsave(&lchip->lock, flags);
 	spin_lock_irqsave(&lchip->lock, flags);
 
 
@@ -594,14 +594,14 @@ static int locomo_suspend(struct device *dev, pm_message_t state)
 	return 0;
 	return 0;
 }
 }
 
 
-static int locomo_resume(struct device *dev)
+static int locomo_resume(struct platform_device *dev)
 {
 {
-	struct locomo *lchip = dev_get_drvdata(dev);
+	struct locomo *lchip = platform_get_drvdata(dev);
 	struct locomo_save_data *save;
 	struct locomo_save_data *save;
 	unsigned long r;
 	unsigned long r;
 	unsigned long flags;
 	unsigned long flags;
 	
 	
-	save = (struct locomo_save_data *) dev->power.saved_state;
+	save = (struct locomo_save_data *) dev->dev.power.saved_state;
 	if (!save)
 	if (!save)
 		return 0;
 		return 0;
 
 
@@ -760,27 +760,26 @@ static void __locomo_remove(struct locomo *lchip)
 	kfree(lchip);
 	kfree(lchip);
 }
 }
 
 
-static int locomo_probe(struct device *dev)
+static int locomo_probe(struct platform_device *dev)
 {
 {
-	struct platform_device *pdev = to_platform_device(dev);
 	struct resource *mem;
 	struct resource *mem;
 	int irq;
 	int irq;
 
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
 	if (!mem)
 	if (!mem)
 		return -EINVAL;
 		return -EINVAL;
-	irq = platform_get_irq(pdev, 0);
+	irq = platform_get_irq(dev, 0);
 
 
-	return __locomo_probe(dev, mem, irq);
+	return __locomo_probe(&dev->dev, mem, irq);
 }
 }
 
 
-static int locomo_remove(struct device *dev)
+static int locomo_remove(struct platform_device *dev)
 {
 {
-	struct locomo *lchip = dev_get_drvdata(dev);
+	struct locomo *lchip = platform__get_drvdata(dev);
 
 
 	if (lchip) {
 	if (lchip) {
 		__locomo_remove(lchip);
 		__locomo_remove(lchip);
-		dev_set_drvdata(dev, NULL);
+		platform_set_drvdata(dev, NULL);
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -792,15 +791,16 @@ static int locomo_remove(struct device *dev)
  *	the per-machine level, and then have this driver pick
  *	the per-machine level, and then have this driver pick
  *	up the registered devices.
  *	up the registered devices.
  */
  */
-static struct device_driver locomo_device_driver = {
-	.name		= "locomo",
-	.bus		= &platform_bus_type,
+static struct platform_driver locomo_device_driver = {
 	.probe		= locomo_probe,
 	.probe		= locomo_probe,
 	.remove		= locomo_remove,
 	.remove		= locomo_remove,
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM
 	.suspend	= locomo_suspend,
 	.suspend	= locomo_suspend,
 	.resume		= locomo_resume,
 	.resume		= locomo_resume,
 #endif
 #endif
+	.driver		= {
+		.name	= "locomo",
+	},
 };
 };
 
 
 /*
 /*
@@ -1126,13 +1126,13 @@ static int __init locomo_init(void)
 {
 {
 	int ret = bus_register(&locomo_bus_type);
 	int ret = bus_register(&locomo_bus_type);
 	if (ret == 0)
 	if (ret == 0)
-		driver_register(&locomo_device_driver);
+		platform_driver_register(&locomo_device_driver);
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit locomo_exit(void)
 static void __exit locomo_exit(void)
 {
 {
-	driver_unregister(&locomo_device_driver);
+	platform_driver_unregister(&locomo_device_driver);
 	bus_unregister(&locomo_bus_type);
 	bus_unregister(&locomo_bus_type);
 }
 }
 
 

+ 21 - 21
arch/arm/common/sa1111.c

@@ -801,9 +801,9 @@ struct sa1111_save_data {
 
 
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM
 
 
-static int sa1111_suspend(struct device *dev, pm_message_t state)
+static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
 {
 {
-	struct sa1111 *sachip = dev_get_drvdata(dev);
+	struct sa1111 *sachip = platform_get_drvdata(dev);
 	struct sa1111_save_data *save;
 	struct sa1111_save_data *save;
 	unsigned long flags;
 	unsigned long flags;
 	unsigned int val;
 	unsigned int val;
@@ -812,7 +812,7 @@ static int sa1111_suspend(struct device *dev, pm_message_t state)
 	save = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL);
 	save = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL);
 	if (!save)
 	if (!save)
 		return -ENOMEM;
 		return -ENOMEM;
-	dev->power.saved_state = save;
+	dev->dev.power.saved_state = save;
 
 
 	spin_lock_irqsave(&sachip->lock, flags);
 	spin_lock_irqsave(&sachip->lock, flags);
 
 
@@ -859,14 +859,14 @@ static int sa1111_suspend(struct device *dev, pm_message_t state)
  *	restored by their respective drivers, and must be called
  *	restored by their respective drivers, and must be called
  *	via LDM after this function.
  *	via LDM after this function.
  */
  */
-static int sa1111_resume(struct device *dev)
+static int sa1111_resume(struct platform_device *dev)
 {
 {
-	struct sa1111 *sachip = dev_get_drvdata(dev);
+	struct sa1111 *sachip = platform_get_drvdata(dev);
 	struct sa1111_save_data *save;
 	struct sa1111_save_data *save;
 	unsigned long flags, id;
 	unsigned long flags, id;
 	void __iomem *base;
 	void __iomem *base;
 
 
-	save = (struct sa1111_save_data *)dev->power.saved_state;
+	save = (struct sa1111_save_data *)dev->dev.power.saved_state;
 	if (!save)
 	if (!save)
 		return 0;
 		return 0;
 
 
@@ -879,7 +879,7 @@ static int sa1111_resume(struct device *dev)
 	id = sa1111_readl(sachip->base + SA1111_SKID);
 	id = sa1111_readl(sachip->base + SA1111_SKID);
 	if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
 	if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
 		__sa1111_remove(sachip);
 		__sa1111_remove(sachip);
-		dev_set_drvdata(dev, NULL);
+		platform_set_drvdata(dev, NULL);
 		kfree(save);
 		kfree(save);
 		return 0;
 		return 0;
 	}
 	}
@@ -911,7 +911,7 @@ static int sa1111_resume(struct device *dev)
 
 
 	spin_unlock_irqrestore(&sachip->lock, flags);
 	spin_unlock_irqrestore(&sachip->lock, flags);
 
 
-	dev->power.saved_state = NULL;
+	dev->dev.power.saved_state = NULL;
 	kfree(save);
 	kfree(save);
 
 
 	return 0;
 	return 0;
@@ -922,9 +922,8 @@ static int sa1111_resume(struct device *dev)
 #define sa1111_resume  NULL
 #define sa1111_resume  NULL
 #endif
 #endif
 
 
-static int sa1111_probe(struct device *dev)
+static int sa1111_probe(struct platform_device *pdev)
 {
 {
-	struct platform_device *pdev = to_platform_device(dev);
 	struct resource *mem;
 	struct resource *mem;
 	int irq;
 	int irq;
 
 
@@ -933,20 +932,20 @@ static int sa1111_probe(struct device *dev)
 		return -EINVAL;
 		return -EINVAL;
 	irq = platform_get_irq(pdev, 0);
 	irq = platform_get_irq(pdev, 0);
 
 
-	return __sa1111_probe(dev, mem, irq);
+	return __sa1111_probe(&pdev->dev, mem, irq);
 }
 }
 
 
-static int sa1111_remove(struct device *dev)
+static int sa1111_remove(struct platform_device *pdev)
 {
 {
-	struct sa1111 *sachip = dev_get_drvdata(dev);
+	struct sa1111 *sachip = platform_get_drvdata(pdev);
 
 
 	if (sachip) {
 	if (sachip) {
 		__sa1111_remove(sachip);
 		__sa1111_remove(sachip);
-		dev_set_drvdata(dev, NULL);
+		platform_set_drvdata(pdev, NULL);
 
 
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM
-		kfree(dev->power.saved_state);
-		dev->power.saved_state = NULL;
+		kfree(pdev->dev.power.saved_state);
+		pdev->dev.power.saved_state = NULL;
 #endif
 #endif
 	}
 	}
 
 
@@ -962,13 +961,14 @@ static int sa1111_remove(struct device *dev)
  *	We also need to handle the SDRAM configuration for
  *	We also need to handle the SDRAM configuration for
  *	PXA250/SA1110 machine classes.
  *	PXA250/SA1110 machine classes.
  */
  */
-static struct device_driver sa1111_device_driver = {
-	.name		= "sa1111",
-	.bus		= &platform_bus_type,
+static struct platform_driver sa1111_device_driver = {
 	.probe		= sa1111_probe,
 	.probe		= sa1111_probe,
 	.remove		= sa1111_remove,
 	.remove		= sa1111_remove,
 	.suspend	= sa1111_suspend,
 	.suspend	= sa1111_suspend,
 	.resume		= sa1111_resume,
 	.resume		= sa1111_resume,
+	.driver		= {
+		.name	= "sa1111",
+	},
 };
 };
 
 
 /*
 /*
@@ -1256,13 +1256,13 @@ static int __init sa1111_init(void)
 {
 {
 	int ret = bus_register(&sa1111_bus_type);
 	int ret = bus_register(&sa1111_bus_type);
 	if (ret == 0)
 	if (ret == 0)
-		driver_register(&sa1111_device_driver);
+		platform_driver_register(&sa1111_device_driver);
 	return ret;
 	return ret;
 }
 }
 
 
 static void __exit sa1111_exit(void)
 static void __exit sa1111_exit(void)
 {
 {
-	driver_unregister(&sa1111_device_driver);
+	platform_driver_unregister(&sa1111_device_driver);
 	bus_unregister(&sa1111_bus_type);
 	bus_unregister(&sa1111_bus_type);
 }
 }
 
 

+ 15 - 15
arch/arm/common/scoop.c

@@ -98,9 +98,9 @@ static void check_scoop_reg(struct scoop_dev *sdev)
 }
 }
 
 
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM
-static int scoop_suspend(struct device *dev, pm_message_t state)
+static int scoop_suspend(struct platform_device *dev, pm_message_t state)
 {
 {
-	struct scoop_dev *sdev = dev_get_drvdata(dev);
+	struct scoop_dev *sdev = platform_get_drvdata(dev);
 
 
 	check_scoop_reg(sdev);
 	check_scoop_reg(sdev);
 	sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
 	sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
@@ -109,9 +109,9 @@ static int scoop_suspend(struct device *dev, pm_message_t state)
 	return 0;
 	return 0;
 }
 }
 
 
-static int scoop_resume(struct device *dev)
+static int scoop_resume(struct platform_device *dev)
 {
 {
-	struct scoop_dev *sdev = dev_get_drvdata(dev);
+	struct scoop_dev *sdev = platform_get_drvdata(dev);
 
 
 	check_scoop_reg(sdev);
 	check_scoop_reg(sdev);
 	SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
 	SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
@@ -123,11 +123,10 @@ static int scoop_resume(struct device *dev)
 #define scoop_resume	NULL
 #define scoop_resume	NULL
 #endif
 #endif
 
 
-int __init scoop_probe(struct device *dev)
+int __init scoop_probe(struct platform_device *pdev)
 {
 {
 	struct scoop_dev *devptr;
 	struct scoop_dev *devptr;
 	struct scoop_config *inf;
 	struct scoop_config *inf;
-	struct platform_device *pdev = to_platform_device(dev);
 	struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
 
 	if (!mem)
 	if (!mem)
@@ -141,7 +140,7 @@ int __init scoop_probe(struct device *dev)
 	memset(devptr, 0, sizeof(struct scoop_dev));
 	memset(devptr, 0, sizeof(struct scoop_dev));
 	spin_lock_init(&devptr->scoop_lock);
 	spin_lock_init(&devptr->scoop_lock);
 
 
-	inf = dev->platform_data;
+	inf = pdev->dev.platform_data;
 	devptr->base = ioremap(mem->start, mem->end - mem->start + 1);
 	devptr->base = ioremap(mem->start, mem->end - mem->start + 1);
 
 
 	if (!devptr->base) {
 	if (!devptr->base) {
@@ -149,7 +148,7 @@ int __init scoop_probe(struct device *dev)
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
-	dev_set_drvdata(dev, devptr);
+	platform_set_drvdata(pdev, devptr);
 
 
 	printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem->start,(unsigned int)devptr->base);
 	printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem->start,(unsigned int)devptr->base);
 
 
@@ -164,29 +163,30 @@ int __init scoop_probe(struct device *dev)
 	return 0;
 	return 0;
 }
 }
 
 
-static int scoop_remove(struct device *dev)
+static int scoop_remove(struct platform_device *pdev)
 {
 {
-	struct scoop_dev *sdev = dev_get_drvdata(dev);
+	struct scoop_dev *sdev = platform_get_drvdata(pdev);
 	if (sdev) {
 	if (sdev) {
 		iounmap(sdev->base);
 		iounmap(sdev->base);
 		kfree(sdev);
 		kfree(sdev);
-		dev_set_drvdata(dev, NULL);
+		platform_set_drvdata(pdev, NULL);
 	}
 	}
 	return 0;
 	return 0;
 }
 }
 
 
-static struct device_driver scoop_driver = {
-	.name		= "sharp-scoop",
-	.bus		= &platform_bus_type,
+static struct platform_driver scoop_driver = {
 	.probe		= scoop_probe,
 	.probe		= scoop_probe,
 	.remove 	= scoop_remove,
 	.remove 	= scoop_remove,
 	.suspend	= scoop_suspend,
 	.suspend	= scoop_suspend,
 	.resume		= scoop_resume,
 	.resume		= scoop_resume,
+	.driver		= {
+		.name	= "sharp-scoop",
+	},
 };
 };
 
 
 int __init scoop_init(void)
 int __init scoop_init(void)
 {
 {
-	return driver_register(&scoop_driver);
+	return platform_driver_register(&scoop_driver);
 }
 }
 
 
 subsys_initcall(scoop_init);
 subsys_initcall(scoop_init);

+ 66 - 31
arch/arm/configs/omap_h2_1610_defconfig

@@ -1,7 +1,7 @@
 #
 #
 # Automatically generated make config: don't edit
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13
-# Mon Sep  5 18:07:12 2005
+# Linux kernel version: 2.6.14
+# Wed Nov  9 18:53:40 2005
 #
 #
 CONFIG_ARM=y
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_MMU=y
@@ -22,6 +22,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
 # General setup
 # General setup
 #
 #
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_POSIX_MQUEUE is not set
@@ -31,6 +32,7 @@ CONFIG_SYSCTL=y
 # CONFIG_HOTPLUG is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_EMBEDDED is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -59,6 +61,23 @@ CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 # CONFIG_KMOD is not set
 
 
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
 #
 #
 # System Type
 # System Type
 #
 #
@@ -81,6 +100,7 @@ CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_LH7A40X is not set
 CONFIG_ARCH_OMAP=y
 CONFIG_ARCH_OMAP=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_AAEC2000 is not set
 # CONFIG_ARCH_AAEC2000 is not set
@@ -112,7 +132,7 @@ CONFIG_OMAP_SERIAL_WAKE=y
 # OMAP Core Type
 # OMAP Core Type
 #
 #
 # CONFIG_ARCH_OMAP730 is not set
 # CONFIG_ARCH_OMAP730 is not set
-# CONFIG_ARCH_OMAP1510 is not set
+# CONFIG_ARCH_OMAP15XX is not set
 CONFIG_ARCH_OMAP16XX=y
 CONFIG_ARCH_OMAP16XX=y
 
 
 #
 #
@@ -177,6 +197,8 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
 # CONFIG_LEDS is not set
 # CONFIG_LEDS is not set
 CONFIG_ALIGNMENT_TRAP=y
 CONFIG_ALIGNMENT_TRAP=y
 
 
@@ -258,13 +280,18 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_BIC=y
 CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_NETFILTER is not set
 
 
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
 #
 #
 # SCTP Configuration (EXPERIMENTAL)
 # SCTP Configuration (EXPERIMENTAL)
 #
 #
@@ -281,6 +308,10 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_NET_DIVERT is not set
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 # CONFIG_NET_SCHED is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_NET_CLS_ROUTE is not set
 # CONFIG_NET_CLS_ROUTE is not set
 
 
@@ -291,6 +322,7 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 
 #
 #
 # Device Drivers
 # Device Drivers
@@ -328,21 +360,13 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 CONFIG_ATA_OVER_ETH=m
 CONFIG_ATA_OVER_ETH=m
 
 
 #
 #
 # SCSI device support
 # SCSI device support
 #
 #
+# CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI=y
 CONFIG_SCSI_PROC_FS=y
 CONFIG_SCSI_PROC_FS=y
 
 
@@ -369,10 +393,12 @@ CONFIG_SCSI_PROC_FS=y
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
 
 
 #
 #
 # SCSI low-level drivers
 # SCSI low-level drivers
 #
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DEBUG is not set
 
 
@@ -403,6 +429,11 @@ CONFIG_NETDEVICES=y
 # CONFIG_EQUALIZER is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_TUN is not set
 
 
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
 #
 #
 # Ethernet (10 or 100Mbit)
 # Ethernet (10 or 100Mbit)
 #
 #
@@ -439,6 +470,7 @@ CONFIG_PPP=y
 # CONFIG_PPP_SYNC_TTY is not set
 # CONFIG_PPP_SYNC_TTY is not set
 # CONFIG_PPP_DEFLATE is not set
 # CONFIG_PPP_DEFLATE is not set
 # CONFIG_PPP_BSDCOMP is not set
 # CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
 # CONFIG_PPPOE is not set
 CONFIG_SLIP=y
 CONFIG_SLIP=y
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_COMPRESSED=y
@@ -541,24 +573,28 @@ CONFIG_WATCHDOG_NOWAYOUT=y
 #
 #
 # TPM devices
 # TPM devices
 #
 #
+# CONFIG_TELCLOCK is not set
 
 
 #
 #
 # I2C support
 # I2C support
 #
 #
 # CONFIG_I2C is not set
 # CONFIG_I2C is not set
-# CONFIG_I2C_SENSOR is not set
-CONFIG_ISP1301_OMAP=y
 
 
 #
 #
 # Hardware Monitoring support
 # Hardware Monitoring support
 #
 #
 CONFIG_HWMON=y
 CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 
 #
 #
 # Misc devices
 # Misc devices
 #
 #
 
 
+#
+# Multimedia Capabilities Port drivers
+#
+
 #
 #
 # Multimedia devices
 # Multimedia devices
 #
 #
@@ -576,7 +612,6 @@ CONFIG_FB=y
 # CONFIG_FB_CFB_FILLRECT is not set
 # CONFIG_FB_CFB_FILLRECT is not set
 # CONFIG_FB_CFB_COPYAREA is not set
 # CONFIG_FB_CFB_COPYAREA is not set
 # CONFIG_FB_CFB_IMAGEBLIT is not set
 # CONFIG_FB_CFB_IMAGEBLIT is not set
-# CONFIG_FB_SOFT_CURSOR is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_MACMODES is not set
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_TILEBLITTING is not set
@@ -589,6 +624,7 @@ CONFIG_FB_MODE_HELPERS=y
 # CONFIG_VGA_CONSOLE is not set
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_FONTS=y
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
 CONFIG_FONT_8x16=y
@@ -600,6 +636,7 @@ CONFIG_FONT_8x16=y
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN12x22 is not set
 # CONFIG_FONT_SUN12x22 is not set
 # CONFIG_FONT_10x18 is not set
 # CONFIG_FONT_10x18 is not set
+# CONFIG_FONT_RL is not set
 
 
 #
 #
 # Logo configuration
 # Logo configuration
@@ -624,10 +661,10 @@ CONFIG_SOUND=y
 # Open Sound System
 # Open Sound System
 #
 #
 CONFIG_SOUND_PRIME=y
 CONFIG_SOUND_PRIME=y
+# CONFIG_OBSOLETE_OSS_DRIVER is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
 # CONFIG_SOUND_MSNDPIN is not set
 # CONFIG_SOUND_OSS is not set
 # CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_AD1980 is not set
 
 
 #
 #
 # USB support
 # USB support
@@ -636,23 +673,22 @@ CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 # CONFIG_USB is not set
 # CONFIG_USB is not set
 
 
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
 #
 #
 # USB Gadget Support
 # USB Gadget Support
 #
 #
-CONFIG_USB_GADGET=y
-# CONFIG_USB_GADGET_DEBUG_FILES is not set
-CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET is not set
 # CONFIG_USB_GADGET_NET2280 is not set
 # CONFIG_USB_GADGET_NET2280 is not set
 # CONFIG_USB_GADGET_PXA2XX is not set
 # CONFIG_USB_GADGET_PXA2XX is not set
 # CONFIG_USB_GADGET_GOKU is not set
 # CONFIG_USB_GADGET_GOKU is not set
 # CONFIG_USB_GADGET_LH7A40X is not set
 # CONFIG_USB_GADGET_LH7A40X is not set
-CONFIG_USB_GADGET_OMAP=y
-CONFIG_USB_OMAP=y
+# CONFIG_USB_GADGET_OMAP is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_GADGET_DUALSPEED is not set
 # CONFIG_USB_ZERO is not set
 # CONFIG_USB_ZERO is not set
-CONFIG_USB_ETH=y
-CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH is not set
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_GADGETFS is not set
 # CONFIG_USB_FILE_STORAGE is not set
 # CONFIG_USB_FILE_STORAGE is not set
 # CONFIG_USB_G_SERIAL is not set
 # CONFIG_USB_G_SERIAL is not set
@@ -673,10 +709,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_FS_POSIX_ACL is not set
-
-#
-# XFS support
-#
 # CONFIG_XFS_FS is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
 CONFIG_ROMFS_FS=y
@@ -685,6 +717,7 @@ CONFIG_INOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 
 #
 #
 # CD-ROM/DVD Filesystems
 # CD-ROM/DVD Filesystems
@@ -706,10 +739,10 @@ CONFIG_FAT_DEFAULT_CODEPAGE=437
 #
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
 # CONFIG_TMPFS is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
 
 
 #
 #
 # Miscellaneous filesystems
 # Miscellaneous filesystems
@@ -750,6 +783,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_NCP_FS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 
 #
 #
 # Partition Types
 # Partition Types
@@ -859,6 +893,7 @@ CONFIG_CRYPTO_DES=y
 # Library routines
 # Library routines
 #
 #
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_INFLATE=y

+ 4 - 0
arch/arm/lib/csumpartial.S

@@ -39,6 +39,7 @@ td3	.req	lr
 
 
 		/* we must have at least one byte. */
 		/* we must have at least one byte. */
 		tst	buf, #1			@ odd address?
 		tst	buf, #1			@ odd address?
+		movne	sum, sum, ror #8
 		ldrneb	td0, [buf], #1
 		ldrneb	td0, [buf], #1
 		subne	len, len, #1
 		subne	len, len, #1
 		adcnes	sum, sum, td0, put_byte_1
 		adcnes	sum, sum, td0, put_byte_1
@@ -103,6 +104,9 @@ ENTRY(csum_partial)
 		cmp	len, #8			@ Ensure that we have at least
 		cmp	len, #8			@ Ensure that we have at least
 		blo	.less8			@ 8 bytes to copy.
 		blo	.less8			@ 8 bytes to copy.
 
 
+		tst	buf, #1
+		movne	sum, sum, ror #8
+
 		adds	sum, sum, #0		@ C = 0
 		adds	sum, sum, #0		@ C = 0
 		tst	buf, #3			@ Test destination alignment
 		tst	buf, #3			@ Test destination alignment
 		blne	.not_aligned		@ aligh destination, return here
 		blne	.not_aligned		@ aligh destination, return here

+ 10 - 0
arch/arm/mach-ixp4xx/Kconfig

@@ -8,6 +8,16 @@ menu "Intel IXP4xx Implementation Options"
 
 
 comment "IXP4xx Platforms"
 comment "IXP4xx Platforms"
 
 
+# This entry is placed on top because otherwise it would have
+# been shown as a submenu.
+config MACH_NSLU2
+	bool
+	prompt "NSLU2" if !(MACH_IXDP465 || MACH_IXDPG425 || ARCH_IXDP425 || ARCH_ADI_COYOTE || ARCH_AVILA || ARCH_IXCDP1100 || ARCH_PRPMC1100 || MACH_GTWX5715)
+	help
+	  Say 'Y' here if you want your kernel to support Linksys's
+	  NSLU2 NAS device. For more information on this platform,
+	  see http://www.nslu2-linux.org
+
 config ARCH_AVILA
 config ARCH_AVILA
 	bool "Avila"
 	bool "Avila"
 	help
 	help

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

@@ -8,4 +8,5 @@ obj-$(CONFIG_ARCH_IXDP4XX)	+= ixdp425-pci.o ixdp425-setup.o
 obj-$(CONFIG_MACH_IXDPG425)	+= ixdpg425-pci.o coyote-setup.o
 obj-$(CONFIG_MACH_IXDPG425)	+= ixdpg425-pci.o coyote-setup.o
 obj-$(CONFIG_ARCH_ADI_COYOTE)	+= coyote-pci.o coyote-setup.o
 obj-$(CONFIG_ARCH_ADI_COYOTE)	+= coyote-pci.o coyote-setup.o
 obj-$(CONFIG_MACH_GTWX5715)	+= gtwx5715-pci.o gtwx5715-setup.o
 obj-$(CONFIG_MACH_GTWX5715)	+= gtwx5715-pci.o gtwx5715-setup.o
+obj-$(CONFIG_MACH_NSLU2)	+= nslu2-pci.o nslu2-setup.o nslu2-power.o
 
 

+ 77 - 0
arch/arm/mach-ixp4xx/nslu2-pci.c

@@ -0,0 +1,77 @@
+/*
+ * arch/arm/mach-ixp4xx/nslu2-pci.c
+ *
+ * NSLU2 board-level PCI initialization
+ *
+ * based on ixdp425-pci.c:
+ *	Copyright (C) 2002 Intel Corporation.
+ *	Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Maintainer: http://www.nslu2-linux.org/
+ *
+ * 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/config.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+void __init nslu2_pci_preinit(void)
+{
+	set_irq_type(IRQ_NSLU2_PCI_INTA, IRQT_LOW);
+	set_irq_type(IRQ_NSLU2_PCI_INTB, IRQT_LOW);
+	set_irq_type(IRQ_NSLU2_PCI_INTC, IRQT_LOW);
+
+	gpio_line_isr_clear(NSLU2_PCI_INTA_PIN);
+	gpio_line_isr_clear(NSLU2_PCI_INTB_PIN);
+	gpio_line_isr_clear(NSLU2_PCI_INTC_PIN);
+
+	/* INTD is not configured as GPIO is used
+	 * for the power input button.
+	 */
+
+	ixp4xx_pci_preinit();
+}
+
+static int __init nslu2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	static int pci_irq_table[NSLU2_PCI_IRQ_LINES] = {
+		IRQ_NSLU2_PCI_INTA,
+		IRQ_NSLU2_PCI_INTB,
+		IRQ_NSLU2_PCI_INTC,
+	};
+
+	int irq = -1;
+
+	if (slot >= 1 && slot <= NSLU2_PCI_MAX_DEV &&
+		pin >= 1 && pin <= NSLU2_PCI_IRQ_LINES) {
+			irq = pci_irq_table[(slot + pin - 2) % NSLU2_PCI_IRQ_LINES];
+	}
+
+	return irq;
+}
+
+struct hw_pci __initdata nslu2_pci = {
+	.nr_controllers = 1,
+	.preinit	= nslu2_pci_preinit,
+	.swizzle	= pci_std_swizzle,
+	.setup		= ixp4xx_setup,
+	.scan		= ixp4xx_scan_bus,
+	.map_irq	= nslu2_map_irq,
+};
+
+int __init nslu2_pci_init(void) /* monkey see, monkey do */
+{
+	if (machine_is_nslu2())
+		pci_common_init(&nslu2_pci);
+
+	return 0;
+}
+
+subsys_initcall(nslu2_pci_init);

+ 92 - 0
arch/arm/mach-ixp4xx/nslu2-power.c

@@ -0,0 +1,92 @@
+/*
+ * arch/arm/mach-ixp4xx/nslu2-power.c
+ *
+ * NSLU2 Power/Reset driver
+ *
+ * Copyright (C) 2005 Tower Technologies
+ *
+ * based on nslu2-io.c
+ *  Copyright (C) 2004 Karen Spearel
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+
+extern void ctrl_alt_del(void);
+
+static irqreturn_t nslu2_power_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* Signal init to do the ctrlaltdel action, this will bypass init if
+	 * it hasn't started and do a kernel_restart.
+	 */
+	ctrl_alt_del();
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t nslu2_reset_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* This is the paper-clip reset, it shuts the machine down directly.
+	 */
+	machine_power_off();
+
+	return IRQ_HANDLED;
+}
+
+static int __init nslu2_power_init(void)
+{
+	if (!(machine_is_nslu2()))
+		return 0;
+
+	*IXP4XX_GPIO_GPISR = 0x20400000;	/* read the 2 irqs to clr */
+
+	set_irq_type(NSLU2_RB_IRQ, IRQT_LOW);
+	set_irq_type(NSLU2_PB_IRQ, IRQT_HIGH);
+
+	gpio_line_isr_clear(NSLU2_RB_GPIO);
+	gpio_line_isr_clear(NSLU2_PB_GPIO);
+
+	if (request_irq(NSLU2_RB_IRQ, &nslu2_reset_handler,
+		SA_INTERRUPT, "NSLU2 reset button", NULL) < 0) {
+
+		printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
+			NSLU2_RB_IRQ);
+
+		return -EIO;
+	}
+
+	if (request_irq(NSLU2_PB_IRQ, &nslu2_power_handler,
+		SA_INTERRUPT, "NSLU2 power button", NULL) < 0) {
+
+		printk(KERN_DEBUG "Power Button IRQ %d not available\n",
+			NSLU2_PB_IRQ);
+
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void __exit nslu2_power_exit(void)
+{
+	free_irq(NSLU2_RB_IRQ, NULL);
+	free_irq(NSLU2_PB_IRQ, NULL);
+}
+
+module_init(nslu2_power_init);
+module_exit(nslu2_power_exit);
+
+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
+MODULE_DESCRIPTION("NSLU2 Power/Reset driver");
+MODULE_LICENSE("GPL");

+ 134 - 0
arch/arm/mach-ixp4xx/nslu2-setup.c

@@ -0,0 +1,134 @@
+/*
+ * arch/arm/mach-ixp4xx/nslu2-setup.c
+ *
+ * NSLU2 board-setup
+ *
+ * based ixdp425-setup.c:
+ *      Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Author: Mark Rakes <mrakes at mac.com>
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ * Fixed missing init_time in MACHINE_START kas11 10/22/04
+ * Changed to conform to new style __init ixdp425 kas11 10/22/04
+ */
+
+#include <linux/kernel.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+static struct flash_platform_data nslu2_flash_data = {
+	.map_name		= "cfi_probe",
+	.width			= 2,
+};
+
+static struct resource nslu2_flash_resource = {
+	.start			= NSLU2_FLASH_BASE,
+	.end			= NSLU2_FLASH_BASE + NSLU2_FLASH_SIZE,
+	.flags			= IORESOURCE_MEM,
+};
+
+static struct platform_device nslu2_flash = {
+	.name			= "IXP4XX-Flash",
+	.id			= 0,
+	.dev.platform_data	= &nslu2_flash_data,
+	.num_resources		= 1,
+	.resource		= &nslu2_flash_resource,
+};
+
+static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = {
+	.sda_pin		= NSLU2_SDA_PIN,
+	.scl_pin		= NSLU2_SCL_PIN,
+};
+
+static struct platform_device nslu2_i2c_controller = {
+	.name			= "IXP4XX-I2C",
+	.id			= 0,
+	.dev.platform_data	= &nslu2_i2c_gpio_pins,
+	.num_resources		= 0,
+};
+
+static struct resource nslu2_uart_resources[] = {
+	{
+		.start		= IXP4XX_UART1_BASE_PHYS,
+		.end		= IXP4XX_UART1_BASE_PHYS + 0x0fff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= IXP4XX_UART2_BASE_PHYS,
+		.end		= IXP4XX_UART2_BASE_PHYS + 0x0fff,
+		.flags		= IORESOURCE_MEM,
+	}
+};
+
+static struct plat_serial8250_port nslu2_uart_data[] = {
+	{
+		.mapbase	= IXP4XX_UART1_BASE_PHYS,
+		.membase	= (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+		.irq		= IRQ_IXP4XX_UART1,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IXP4XX_UART_XTAL,
+	},
+	{
+		.mapbase	= IXP4XX_UART2_BASE_PHYS,
+		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+		.irq		= IRQ_IXP4XX_UART2,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IXP4XX_UART_XTAL,
+	},
+	{ }
+};
+
+static struct platform_device nslu2_uart = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev.platform_data	= nslu2_uart_data,
+	.num_resources		= 2,
+	.resource		= nslu2_uart_resources,
+};
+
+static struct platform_device *nslu2_devices[] __initdata = {
+	&nslu2_i2c_controller,
+	&nslu2_flash,
+	&nslu2_uart,
+};
+
+static void nslu2_power_off(void)
+{
+	/* This causes the box to drop the power and go dead. */
+
+	/* enable the pwr cntl gpio */
+	gpio_line_config(NSLU2_PO_GPIO, IXP4XX_GPIO_OUT);
+
+	/* do the deed */
+	gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH);
+}
+
+static void __init nslu2_init(void)
+{
+	ixp4xx_sys_init();
+
+	pm_power_off = nslu2_power_off;
+
+	platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices));
+}
+
+MACHINE_START(NSLU2, "Linksys NSLU2")
+	/* Maintainer: www.nslu2-linux.org */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.map_io		= ixp4xx_map_io,
+	.init_irq	= ixp4xx_init_irq,
+	.timer          = &ixp4xx_timer,
+	.init_machine	= nslu2_init,
+MACHINE_END

+ 21 - 11
arch/arm/mach-omap1/Kconfig

@@ -6,10 +6,10 @@ config ARCH_OMAP730
 	bool "OMAP730 Based System"
 	bool "OMAP730 Based System"
 	select ARCH_OMAP_OTG
 	select ARCH_OMAP_OTG
 
 
-config ARCH_OMAP1510
+config ARCH_OMAP15XX
 	depends on ARCH_OMAP1
 	depends on ARCH_OMAP1
 	default y
 	default y
-	bool "OMAP1510 Based System"
+	bool "OMAP15xx Based System"
 
 
 config ARCH_OMAP16XX
 config ARCH_OMAP16XX
 	depends on ARCH_OMAP1
 	depends on ARCH_OMAP1
@@ -21,7 +21,7 @@ comment "OMAP Board Type"
 
 
 config MACH_OMAP_INNOVATOR
 config MACH_OMAP_INNOVATOR
 	bool "TI Innovator"
 	bool "TI Innovator"
-	depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX)
+	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
 	help
 	help
           TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
           TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
           have such a board.
           have such a board.
@@ -64,20 +64,30 @@ config MACH_OMAP_PERSEUS2
 
 
 config MACH_VOICEBLUE
 config MACH_VOICEBLUE
 	bool "Voiceblue"
 	bool "Voiceblue"
-	depends on ARCH_OMAP1 && ARCH_OMAP1510
+	depends on ARCH_OMAP1 && ARCH_OMAP15XX
 	help
 	help
 	  Support for Voiceblue GSM/VoIP gateway. Say Y here if you have
 	  Support for Voiceblue GSM/VoIP gateway. Say Y here if you have
 	  such a board.
 	  such a board.
 
 
 config MACH_NETSTAR
 config MACH_NETSTAR
 	bool "NetStar"
 	bool "NetStar"
-	depends on ARCH_OMAP1 && ARCH_OMAP1510
+	depends on ARCH_OMAP1 && ARCH_OMAP15XX
 	help
 	help
 	  Support for NetStar PBX. Say Y here if you have such a board.
 	  Support for NetStar PBX. Say Y here if you have such a board.
 
 
+config MACH_OMAP_PALMTE
+	bool "Palm Tungsten E"
+	depends on ARCH_OMAP1 && ARCH_OMAP15XX
+	help
+          Support for the Palm Tungsten E PDA. Currently only the LCD panel
+          is supported. To boot the kernel, you'll need a PalmOS compatible
+          bootloader; check out http://palmtelinux.sourceforge.net for more
+          informations.
+          Say Y here if you have such a PDA, say NO otherwise.
+
 config MACH_OMAP_GENERIC
 config MACH_OMAP_GENERIC
 	bool "Generic OMAP board"
 	bool "Generic OMAP board"
-	depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX)
+	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
 	help
 	help
           Support for generic OMAP-1510, 1610 or 1710 board with
           Support for generic OMAP-1510, 1610 or 1710 board with
           no FPGA. Can be used as template for porting Linux to
           no FPGA. Can be used as template for porting Linux to
@@ -121,32 +131,32 @@ config OMAP_ARM_182MHZ
 
 
 config OMAP_ARM_168MHZ
 config OMAP_ARM_168MHZ
 	bool "OMAP ARM 168 MHz CPU"
 	bool "OMAP ARM 168 MHz CPU"
-	depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
+	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
 	help
 	help
           Enable 168MHz clock for OMAP CPU. If unsure, say N.
           Enable 168MHz clock for OMAP CPU. If unsure, say N.
 
 
 config OMAP_ARM_150MHZ
 config OMAP_ARM_150MHZ
 	bool "OMAP ARM 150 MHz CPU"
 	bool "OMAP ARM 150 MHz CPU"
-	depends on ARCH_OMAP1 && ARCH_OMAP1510
+	depends on ARCH_OMAP1 && ARCH_OMAP15XX
 	help
 	help
 	  Enable 150MHz clock for OMAP CPU. If unsure, say N.
 	  Enable 150MHz clock for OMAP CPU. If unsure, say N.
 
 
 config OMAP_ARM_120MHZ
 config OMAP_ARM_120MHZ
 	bool "OMAP ARM 120 MHz CPU"
 	bool "OMAP ARM 120 MHz CPU"
-	depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
+	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
 	help
 	help
           Enable 120MHz clock for OMAP CPU. If unsure, say N.
           Enable 120MHz clock for OMAP CPU. If unsure, say N.
 
 
 config OMAP_ARM_60MHZ
 config OMAP_ARM_60MHZ
 	bool "OMAP ARM 60 MHz CPU"
 	bool "OMAP ARM 60 MHz CPU"
-	depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
+	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
         default y
         default y
 	help
 	help
           Enable 60MHz clock for OMAP CPU. If unsure, say Y.
           Enable 60MHz clock for OMAP CPU. If unsure, say Y.
 
 
 config OMAP_ARM_30MHZ
 config OMAP_ARM_30MHZ
 	bool "OMAP ARM 30 MHz CPU"
 	bool "OMAP ARM 30 MHz CPU"
-	depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
+	depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
 	help
 	help
           Enable 30MHz clock for OMAP CPU. If unsure, say N.
           Enable 30MHz clock for OMAP CPU. If unsure, say N.
 
 

+ 3 - 2
arch/arm/mach-omap1/Makefile

@@ -3,7 +3,7 @@
 #
 #
 
 
 # Common support
 # Common support
-obj-y := io.o id.o irq.o time.o serial.o devices.o
+obj-y := io.o id.o clock.o irq.o time.o mux.o serial.o devices.o
 led-y := leds.o
 led-y := leds.o
 
 
 # Specific board support
 # Specific board support
@@ -15,8 +15,9 @@ obj-$(CONFIG_MACH_OMAP_OSK)		+= board-osk.o
 obj-$(CONFIG_MACH_OMAP_H3)		+= board-h3.o
 obj-$(CONFIG_MACH_OMAP_H3)		+= board-h3.o
 obj-$(CONFIG_MACH_VOICEBLUE)		+= board-voiceblue.o
 obj-$(CONFIG_MACH_VOICEBLUE)		+= board-voiceblue.o
 obj-$(CONFIG_MACH_NETSTAR)		+= board-netstar.o
 obj-$(CONFIG_MACH_NETSTAR)		+= board-netstar.o
+obj-$(CONFIG_MACH_OMAP_PALMTE)		+= board-palmte.o
 
 
-ifeq ($(CONFIG_ARCH_OMAP1510),y)
+ifeq ($(CONFIG_ARCH_OMAP15XX),y)
 # Innovator-1510 FPGA
 # Innovator-1510 FPGA
 obj-$(CONFIG_MACH_OMAP_INNOVATOR)	+= fpga.o
 obj-$(CONFIG_MACH_OMAP_INNOVATOR)	+= fpga.o
 endif
 endif

+ 9 - 24
arch/arm/mach-omap1/board-generic.c

@@ -15,7 +15,7 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 
 #include <asm/hardware.h>
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
@@ -28,8 +28,6 @@
 #include <asm/arch/board.h>
 #include <asm/arch/board.h>
 #include <asm/arch/common.h>
 #include <asm/arch/common.h>
 
 
-static int __initdata generic_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
 static void __init omap_generic_init_irq(void)
 static void __init omap_generic_init_irq(void)
 {
 {
 	omap_init_irq();
 	omap_init_irq();
@@ -37,7 +35,7 @@ static void __init omap_generic_init_irq(void)
 
 
 /* assume no Mini-AB port */
 /* assume no Mini-AB port */
 
 
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 static struct omap_usb_config generic1510_usb_config __initdata = {
 static struct omap_usb_config generic1510_usb_config __initdata = {
 	.register_host	= 1,
 	.register_host	= 1,
 	.register_dev	= 1,
 	.register_dev	= 1,
@@ -76,21 +74,19 @@ static struct omap_mmc_config generic_mmc_config __initdata = {
 
 
 #endif
 #endif
 
 
+static struct omap_uart_config generic_uart_config __initdata = {
+	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
 static struct omap_board_config_kernel generic_config[] = {
 static struct omap_board_config_kernel generic_config[] = {
 	{ OMAP_TAG_USB,           NULL },
 	{ OMAP_TAG_USB,           NULL },
 	{ OMAP_TAG_MMC,           &generic_mmc_config },
 	{ OMAP_TAG_MMC,           &generic_mmc_config },
+	{ OMAP_TAG_UART,	&generic_uart_config },
 };
 };
 
 
 static void __init omap_generic_init(void)
 static void __init omap_generic_init(void)
 {
 {
-	const struct omap_uart_config *uart_conf;
-
-	/*
-	 * Make sure the serial ports are muxed on at this point.
-	 * You have to mux them off in device drivers later on
-	 * if not needed.
-	 */
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
 	if (cpu_is_omap1510()) {
 		generic_config[0].data = &generic1510_usb_config;
 		generic_config[0].data = &generic1510_usb_config;
 	}
 	}
@@ -101,20 +97,9 @@ static void __init omap_generic_init(void)
 	}
 	}
 #endif
 #endif
 
 
-	uart_conf = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
-	if (uart_conf != NULL) {
-		unsigned int enabled_ports, i;
-
-		enabled_ports = uart_conf->enabled_uarts;
-		for (i = 0; i < 3; i++) {
-			if (!(enabled_ports & (1 << i)))
-				generic_serial_ports[i] = 0;
-		}
-	}
-
 	omap_board_config = generic_config;
 	omap_board_config = generic_config;
 	omap_board_config_size = ARRAY_SIZE(generic_config);
 	omap_board_config_size = ARRAY_SIZE(generic_config);
-	omap_serial_init(generic_serial_ports);
+	omap_serial_init();
 }
 }
 
 
 static void __init omap_generic_map_io(void)
 static void __init omap_generic_map_io(void)

+ 12 - 3
arch/arm/mach-omap1/board-h2.c

@@ -40,8 +40,6 @@
 
 
 extern int omap_gpio_init(void);
 extern int omap_gpio_init(void);
 
 
-static int __initdata h2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
 static struct mtd_partition h2_partitions[] = {
 static struct mtd_partition h2_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	/* bootloader (U-Boot, etc) in first sector */
 	{
 	{
@@ -160,9 +158,20 @@ static struct omap_mmc_config h2_mmc_config __initdata = {
 	},
 	},
 };
 };
 
 
+static struct omap_uart_config h2_uart_config __initdata = {
+	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_lcd_config h2_lcd_config __initdata = {
+	.panel_name	= "h2",
+	.ctrl_name	= "internal",
+};
+
 static struct omap_board_config_kernel h2_config[] = {
 static struct omap_board_config_kernel h2_config[] = {
 	{ OMAP_TAG_USB,           &h2_usb_config },
 	{ OMAP_TAG_USB,           &h2_usb_config },
 	{ OMAP_TAG_MMC,           &h2_mmc_config },
 	{ OMAP_TAG_MMC,           &h2_mmc_config },
+	{ OMAP_TAG_UART,	&h2_uart_config },
+	{ OMAP_TAG_LCD,		&h2_lcd_config },
 };
 };
 
 
 static void __init h2_init(void)
 static void __init h2_init(void)
@@ -180,12 +189,12 @@ static void __init h2_init(void)
 	platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
 	platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
 	omap_board_config = h2_config;
 	omap_board_config = h2_config;
 	omap_board_config_size = ARRAY_SIZE(h2_config);
 	omap_board_config_size = ARRAY_SIZE(h2_config);
+	omap_serial_init();
 }
 }
 
 
 static void __init h2_map_io(void)
 static void __init h2_map_io(void)
 {
 {
 	omap_map_common_io();
 	omap_map_common_io();
-	omap_serial_init(h2_serial_ports);
 }
 }
 
 
 MACHINE_START(OMAP_H2, "TI-H2")
 MACHINE_START(OMAP_H2, "TI-H2")

+ 14 - 5
arch/arm/mach-omap1/board-h3.c

@@ -41,8 +41,6 @@
 
 
 extern int omap_gpio_init(void);
 extern int omap_gpio_init(void);
 
 
-static int __initdata h3_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
 static struct mtd_partition h3_partitions[] = {
 static struct mtd_partition h3_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	/* bootloader (U-Boot, etc) in first sector */
 	{
 	{
@@ -168,9 +166,20 @@ static struct omap_mmc_config h3_mmc_config __initdata = {
 	},
 	},
 };
 };
 
 
+static struct omap_uart_config h3_uart_config __initdata = {
+	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_lcd_config h3_lcd_config __initdata = {
+	.panel_name	= "h3",
+	.ctrl_name	= "internal",
+};
+
 static struct omap_board_config_kernel h3_config[] = {
 static struct omap_board_config_kernel h3_config[] = {
-	{ OMAP_TAG_USB,	 &h3_usb_config },
-	{ OMAP_TAG_MMC,  &h3_mmc_config },
+	{ OMAP_TAG_USB,		&h3_usb_config },
+	{ OMAP_TAG_MMC,		&h3_mmc_config },
+	{ OMAP_TAG_UART,	&h3_uart_config },
+	{ OMAP_TAG_LCD,		&h3_lcd_config },
 };
 };
 
 
 static void __init h3_init(void)
 static void __init h3_init(void)
@@ -180,6 +189,7 @@ static void __init h3_init(void)
 	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
 	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
 	omap_board_config = h3_config;
 	omap_board_config = h3_config;
 	omap_board_config_size = ARRAY_SIZE(h3_config);
 	omap_board_config_size = ARRAY_SIZE(h3_config);
+	omap_serial_init();
 }
 }
 
 
 static void __init h3_init_smc91x(void)
 static void __init h3_init_smc91x(void)
@@ -201,7 +211,6 @@ void h3_init_irq(void)
 static void __init h3_map_io(void)
 static void __init h3_map_io(void)
 {
 {
 	omap_map_common_io();
 	omap_map_common_io();
-	omap_serial_init(h3_serial_ports);
 }
 }
 
 
 MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
 MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")

+ 30 - 12
arch/arm/mach-omap1/board-innovator.c

@@ -36,8 +36,6 @@
 #include <asm/arch/usb.h>
 #include <asm/arch/usb.h>
 #include <asm/arch/common.h>
 #include <asm/arch/common.h>
 
 
-static int __initdata innovator_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
 static struct mtd_partition innovator_partitions[] = {
 static struct mtd_partition innovator_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	/* bootloader (U-Boot, etc) in first sector */
 	{
 	{
@@ -99,7 +97,7 @@ static struct platform_device innovator_flash_device = {
 	.resource	= &innovator_flash_resource,
 	.resource	= &innovator_flash_resource,
 };
 };
 
 
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 
 
 /* Only FPGA needs to be mapped here. All others are done with ioremap */
 /* Only FPGA needs to be mapped here. All others are done with ioremap */
 static struct map_desc innovator1510_io_desc[] __initdata = {
 static struct map_desc innovator1510_io_desc[] __initdata = {
@@ -136,7 +134,7 @@ static struct platform_device *innovator1510_devices[] __initdata = {
 	&innovator1510_smc91x_device,
 	&innovator1510_smc91x_device,
 };
 };
 
 
-#endif /* CONFIG_ARCH_OMAP1510 */
+#endif /* CONFIG_ARCH_OMAP15XX */
 
 
 #ifdef CONFIG_ARCH_OMAP16XX
 #ifdef CONFIG_ARCH_OMAP16XX
 
 
@@ -185,7 +183,7 @@ void innovator_init_irq(void)
 {
 {
 	omap_init_irq();
 	omap_init_irq();
 	omap_gpio_init();
 	omap_gpio_init();
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
 	if (cpu_is_omap1510()) {
 		omap1510_fpga_init_irq();
 		omap1510_fpga_init_irq();
 	}
 	}
@@ -193,7 +191,7 @@ void innovator_init_irq(void)
 	innovator_init_smc91x();
 	innovator_init_smc91x();
 }
 }
 
 
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 static struct omap_usb_config innovator1510_usb_config __initdata = {
 static struct omap_usb_config innovator1510_usb_config __initdata = {
 	/* for bundled non-standard host and peripheral cables */
 	/* for bundled non-standard host and peripheral cables */
 	.hmc_mode	= 4,
 	.hmc_mode	= 4,
@@ -205,6 +203,11 @@ static struct omap_usb_config innovator1510_usb_config __initdata = {
 	.register_dev	= 1,
 	.register_dev	= 1,
 	.pins[0]	= 2,
 	.pins[0]	= 2,
 };
 };
+
+static struct omap_lcd_config innovator1510_lcd_config __initdata = {
+	.panel_name	= "inn1510",
+	.ctrl_name	= "internal",
+};
 #endif
 #endif
 
 
 #ifdef CONFIG_ARCH_OMAP16XX
 #ifdef CONFIG_ARCH_OMAP16XX
@@ -222,6 +225,11 @@ static struct omap_usb_config h2_usb_config __initdata = {
 
 
 	.pins[1]	= 3,
 	.pins[1]	= 3,
 };
 };
+
+static struct omap_lcd_config innovator1610_lcd_config __initdata = {
+	.panel_name	= "inn1610",
+	.ctrl_name	= "internal",
+};
 #endif
 #endif
 
 
 static struct omap_mmc_config innovator_mmc_config __initdata = {
 static struct omap_mmc_config innovator_mmc_config __initdata = {
@@ -234,14 +242,20 @@ static struct omap_mmc_config innovator_mmc_config __initdata = {
 	},
 	},
 };
 };
 
 
+static struct omap_uart_config innovator_uart_config __initdata = {
+	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
 static struct omap_board_config_kernel innovator_config[] = {
 static struct omap_board_config_kernel innovator_config[] = {
 	{ OMAP_TAG_USB,         NULL },
 	{ OMAP_TAG_USB,         NULL },
+	{ OMAP_TAG_LCD,		NULL },
 	{ OMAP_TAG_MMC,		&innovator_mmc_config },
 	{ OMAP_TAG_MMC,		&innovator_mmc_config },
+	{ OMAP_TAG_UART,	&innovator_uart_config },
 };
 };
 
 
 static void __init innovator_init(void)
 static void __init innovator_init(void)
 {
 {
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
 	if (cpu_is_omap1510()) {
 		platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
 		platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
 	}
 	}
@@ -252,23 +266,28 @@ static void __init innovator_init(void)
 	}
 	}
 #endif
 #endif
 
 
-#ifdef CONFIG_ARCH_OMAP1510
-	if (cpu_is_omap1510())
+#ifdef CONFIG_ARCH_OMAP15XX
+	if (cpu_is_omap1510()) {
 		innovator_config[0].data = &innovator1510_usb_config;
 		innovator_config[0].data = &innovator1510_usb_config;
+		innovator_config[1].data = &innovator1510_lcd_config;
+	}
 #endif
 #endif
 #ifdef CONFIG_ARCH_OMAP16XX
 #ifdef CONFIG_ARCH_OMAP16XX
-	if (cpu_is_omap1610())
+	if (cpu_is_omap1610()) {
 		innovator_config[0].data = &h2_usb_config;
 		innovator_config[0].data = &h2_usb_config;
+		innovator_config[1].data = &innovator1610_lcd_config;
+	}
 #endif
 #endif
 	omap_board_config = innovator_config;
 	omap_board_config = innovator_config;
 	omap_board_config_size = ARRAY_SIZE(innovator_config);
 	omap_board_config_size = ARRAY_SIZE(innovator_config);
+	omap_serial_init();
 }
 }
 
 
 static void __init innovator_map_io(void)
 static void __init innovator_map_io(void)
 {
 {
 	omap_map_common_io();
 	omap_map_common_io();
 
 
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
 	if (cpu_is_omap1510()) {
 		iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc));
 		iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc));
 		udelay(10);	/* Delay needed for FPGA */
 		udelay(10);	/* Delay needed for FPGA */
@@ -280,7 +299,6 @@ static void __init innovator_map_io(void)
 		       fpga_read(OMAP1510_FPGA_BOARD_REV));
 		       fpga_read(OMAP1510_FPGA_BOARD_REV));
 	}
 	}
 #endif
 #endif
-	omap_serial_init(innovator_serial_ports);
 }
 }
 
 
 MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
 MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")

+ 12 - 3
arch/arm/mach-omap1/board-netstar.c

@@ -55,6 +55,14 @@ static struct platform_device *netstar_devices[] __initdata = {
 	&netstar_smc91x_device,
 	&netstar_smc91x_device,
 };
 };
 
 
+static struct omap_uart_config netstar_uart_config __initdata = {
+	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_board_config_kernel netstar_config[] = {
+	{ OMAP_TAG_UART,	&netstar_uart_config },
+};
+
 static void __init netstar_init_irq(void)
 static void __init netstar_init_irq(void)
 {
 {
 	omap_init_irq();
 	omap_init_irq();
@@ -92,14 +100,15 @@ static void __init netstar_init(void)
 	/* Switch off red LED */
 	/* Switch off red LED */
 	omap_writeb(0x00, OMAP_LPG1_PMR);	/* Disable clock */
 	omap_writeb(0x00, OMAP_LPG1_PMR);	/* Disable clock */
 	omap_writeb(0x80, OMAP_LPG1_LCR);
 	omap_writeb(0x80, OMAP_LPG1_LCR);
-}
 
 
-static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
+	omap_board_config = netstar_config;
+	omap_board_config_size = ARRAY_SIZE(netstar_config);
+	omap_serial_init();
+}
 
 
 static void __init netstar_map_io(void)
 static void __init netstar_map_io(void)
 {
 {
 	omap_map_common_io();
 	omap_map_common_io();
-	omap_serial_init(omap_serial_ports);
 }
 }
 
 
 #define MACHINE_PANICED		1
 #define MACHINE_PANICED		1

+ 13 - 4
arch/arm/mach-omap1/board-osk.c

@@ -46,8 +46,6 @@
 #include <asm/arch/tc.h>
 #include <asm/arch/tc.h>
 #include <asm/arch/common.h>
 #include <asm/arch/common.h>
 
 
-static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0};
-
 static struct mtd_partition osk_partitions[] = {
 static struct mtd_partition osk_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	/* bootloader (U-Boot, etc) in first sector */
 	{
 	{
@@ -155,7 +153,7 @@ static void __init osk_init_smc91x(void)
 	}
 	}
 
 
 	/* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */
 	/* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */
-	EMIFS_CCS(1) |= 0x2;
+	EMIFS_CCS(1) |= 0x3;
 }
 }
 
 
 static void __init osk_init_cf(void)
 static void __init osk_init_cf(void)
@@ -193,8 +191,19 @@ static struct omap_usb_config osk_usb_config __initdata = {
 	.pins[0]	= 2,
 	.pins[0]	= 2,
 };
 };
 
 
+static struct omap_uart_config osk_uart_config __initdata = {
+	.enabled_uarts = (1 << 0),
+};
+
+static struct omap_lcd_config osk_lcd_config __initdata = {
+	.panel_name	= "osk",
+	.ctrl_name	= "internal",
+};
+
 static struct omap_board_config_kernel osk_config[] = {
 static struct omap_board_config_kernel osk_config[] = {
 	{ OMAP_TAG_USB,           &osk_usb_config },
 	{ OMAP_TAG_USB,           &osk_usb_config },
+	{ OMAP_TAG_UART,		&osk_uart_config },
+	{ OMAP_TAG_LCD,			&osk_lcd_config },
 };
 };
 
 
 #ifdef	CONFIG_OMAP_OSK_MISTRAL
 #ifdef	CONFIG_OMAP_OSK_MISTRAL
@@ -254,13 +263,13 @@ static void __init osk_init(void)
 	omap_board_config_size = ARRAY_SIZE(osk_config);
 	omap_board_config_size = ARRAY_SIZE(osk_config);
 	USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
 	USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
 
 
+	omap_serial_init();
 	osk_mistral_init();
 	osk_mistral_init();
 }
 }
 
 
 static void __init osk_map_io(void)
 static void __init osk_map_io(void)
 {
 {
 	omap_map_common_io();
 	omap_map_common_io();
-	omap_serial_init(osk_serial_ports);
 }
 }
 
 
 MACHINE_START(OMAP_OSK, "TI-OSK")
 MACHINE_START(OMAP_OSK, "TI-OSK")

+ 87 - 0
arch/arm/mach-omap1/board-palmte.c

@@ -0,0 +1,87 @@
+/*
+ * linux/arch/arm/mach-omap1/board-palmte.c
+ *
+ * Modified from board-generic.c
+ *
+ * Support for the Palm Tungsten E PDA.
+ *
+ * Original version : Laurent Gonzalez
+ *
+ * Maintainters : http://palmtelinux.sf.net
+ *                palmtelinux-developpers@lists.sf.net
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/notifier.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/board.h>
+#include <asm/arch/common.h>
+#include <asm/hardware/clock.h>
+
+static void __init omap_generic_init_irq(void)
+{
+	omap_init_irq();
+}
+
+static struct omap_usb_config palmte_usb_config __initdata = {
+	.register_dev	= 1,
+	.hmc_mode	= 0,
+	.pins[0]	= 3,
+};
+
+static struct omap_mmc_config palmte_mmc_config __initdata = {
+	.mmc [0] = {
+		.enabled 	= 1,
+		.wire4		= 1,
+		.wp_pin		= OMAP_MPUIO(3),
+		.power_pin	= -1,
+		.switch_pin	= -1,
+	},
+};
+
+static struct omap_lcd_config palmte_lcd_config __initdata = {
+	.panel_name	= "palmte",
+	.ctrl_name	= "internal",
+};
+
+static struct omap_board_config_kernel palmte_config[] = {
+	{ OMAP_TAG_USB, &palmte_usb_config },
+	{ OMAP_TAG_MMC,	&palmte_mmc_config },
+	{ OMAP_TAG_LCD,	&palmte_lcd_config },
+};
+
+static void __init omap_generic_init(void)
+{
+	omap_board_config = palmte_config;
+	omap_board_config_size = ARRAY_SIZE(palmte_config);
+}
+
+static void __init omap_generic_map_io(void)
+{
+	omap_map_common_io();
+}
+
+MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= omap_generic_map_io,
+	.init_irq	= omap_generic_init_irq,
+	.init_machine	= omap_generic_init,
+	.timer		= &omap_timer,
+MACHINE_END

+ 19 - 4
arch/arm/mach-omap1/board-perseus2.c

@@ -29,6 +29,7 @@
 #include <asm/arch/mux.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/fpga.h>
 #include <asm/arch/fpga.h>
 #include <asm/arch/common.h>
 #include <asm/arch/common.h>
+#include <asm/arch/board.h>
 
 
 static struct resource smc91x_resources[] = {
 static struct resource smc91x_resources[] = {
 	[0] = {
 	[0] = {
@@ -43,8 +44,6 @@ static struct resource smc91x_resources[] = {
 	},
 	},
 };
 };
 
 
-static int __initdata p2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 0};
-
 static struct mtd_partition p2_partitions[] = {
 static struct mtd_partition p2_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	/* bootloader (U-Boot, etc) in first sector */
 	{
 	{
@@ -111,9 +110,27 @@ static struct platform_device *devices[] __initdata = {
 	&smc91x_device,
 	&smc91x_device,
 };
 };
 
 
+static struct omap_uart_config perseus2_uart_config __initdata = {
+	.enabled_uarts = ((1 << 0) | (1 << 1)),
+};
+
+static struct omap_lcd_config perseus2_lcd_config __initdata = {
+	.panel_name	= "p2",
+	.ctrl_name	= "internal",
+};
+
+static struct omap_board_config_kernel perseus2_config[] = {
+	{ OMAP_TAG_UART,	&perseus2_uart_config },
+	{ OMAP_TAG_LCD,		&perseus2_lcd_config },
+};
+
 static void __init omap_perseus2_init(void)
 static void __init omap_perseus2_init(void)
 {
 {
 	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
 	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	omap_board_config = perseus2_config;
+	omap_board_config_size = ARRAY_SIZE(perseus2_config);
+	omap_serial_init();
 }
 }
 
 
 static void __init perseus2_init_smc91x(void)
 static void __init perseus2_init_smc91x(void)
@@ -131,7 +148,6 @@ void omap_perseus2_init_irq(void)
 	omap_gpio_init();
 	omap_gpio_init();
 	perseus2_init_smc91x();
 	perseus2_init_smc91x();
 }
 }
-
 /* Only FPGA needs to be mapped here. All others are done with ioremap */
 /* Only FPGA needs to be mapped here. All others are done with ioremap */
 static struct map_desc omap_perseus2_io_desc[] __initdata = {
 static struct map_desc omap_perseus2_io_desc[] __initdata = {
 	{
 	{
@@ -179,7 +195,6 @@ static void __init omap_perseus2_map_io(void)
 	 * It is used as the Ethernet controller interrupt
 	 * It is used as the Ethernet controller interrupt
 	 */
 	 */
 	omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9);
 	omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9);
-	omap_serial_init(p2_serial_ports);
 }
 }
 
 
 MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
 MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")

+ 6 - 3
arch/arm/mach-omap1/board-voiceblue.c

@@ -150,9 +150,14 @@ static struct omap_mmc_config voiceblue_mmc_config __initdata = {
 	},
 	},
 };
 };
 
 
+static struct omap_uart_config voiceblue_uart_config __initdata = {
+	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
 static struct omap_board_config_kernel voiceblue_config[] = {
 static struct omap_board_config_kernel voiceblue_config[] = {
 	{ OMAP_TAG_USB, &voiceblue_usb_config },
 	{ OMAP_TAG_USB, &voiceblue_usb_config },
 	{ OMAP_TAG_MMC, &voiceblue_mmc_config },
 	{ OMAP_TAG_MMC, &voiceblue_mmc_config },
+	{ OMAP_TAG_UART,	&voiceblue_uart_config },
 };
 };
 
 
 static void __init voiceblue_init_irq(void)
 static void __init voiceblue_init_irq(void)
@@ -191,6 +196,7 @@ static void __init voiceblue_init(void)
 	platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
 	platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
 	omap_board_config = voiceblue_config;
 	omap_board_config = voiceblue_config;
 	omap_board_config_size = ARRAY_SIZE(voiceblue_config);
 	omap_board_config_size = ARRAY_SIZE(voiceblue_config);
+	omap_serial_init();
 
 
 	/* There is a good chance board is going up, so enable power LED
 	/* There is a good chance board is going up, so enable power LED
 	 * (it is connected through invertor) */
 	 * (it is connected through invertor) */
@@ -198,12 +204,9 @@ static void __init voiceblue_init(void)
 	omap_writeb(0x00, OMAP_LPG1_PMR);	/* Disable clock */
 	omap_writeb(0x00, OMAP_LPG1_PMR);	/* Disable clock */
 }
 }
 
 
-static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
 static void __init voiceblue_map_io(void)
 static void __init voiceblue_map_io(void)
 {
 {
 	omap_map_common_io();
 	omap_map_common_io();
-	omap_serial_init(omap_serial_ports);
 }
 }
 
 
 #define MACHINE_PANICED		1
 #define MACHINE_PANICED		1

+ 792 - 0
arch/arm/mach-omap1/clock.c

@@ -0,0 +1,792 @@
+/*
+ *  linux/arch/arm/mach-omap1/clock.c
+ *
+ *  Copyright (C) 2004 - 2005 Nokia corporation
+ *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ *  Modified to use omap shared clock framework by
+ *  Tony Lindgren <tony@atomide.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <asm/io.h>
+#include <asm/hardware/clock.h>
+
+#include <asm/arch/usb.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sram.h>
+
+#include "clock.h"
+
+__u32 arm_idlect1_mask;
+
+/*-------------------------------------------------------------------------
+ * Omap1 specific clock functions
+ *-------------------------------------------------------------------------*/
+
+static void omap1_watchdog_recalc(struct clk * clk)
+{
+	clk->rate = clk->parent->rate / 14;
+}
+
+static void omap1_uart_recalc(struct clk * clk)
+{
+	unsigned int val = omap_readl(clk->enable_reg);
+	if (val & clk->enable_bit)
+		clk->rate = 48000000;
+	else
+		clk->rate = 12000000;
+}
+
+static int omap1_clk_enable_dsp_domain(struct clk *clk)
+{
+	int retval;
+
+	retval = omap1_clk_use(&api_ck.clk);
+	if (!retval) {
+		retval = omap1_clk_enable(clk);
+		omap1_clk_unuse(&api_ck.clk);
+	}
+
+	return retval;
+}
+
+static void omap1_clk_disable_dsp_domain(struct clk *clk)
+{
+	if (omap1_clk_use(&api_ck.clk) == 0) {
+		omap1_clk_disable(clk);
+		omap1_clk_unuse(&api_ck.clk);
+	}
+}
+
+static int omap1_clk_enable_uart_functional(struct clk *clk)
+{
+	int ret;
+	struct uart_clk *uclk;
+
+	ret = omap1_clk_enable(clk);
+	if (ret == 0) {
+		/* Set smart idle acknowledgement mode */
+		uclk = (struct uart_clk *)clk;
+		omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8,
+			    uclk->sysc_addr);
+	}
+
+	return ret;
+}
+
+static void omap1_clk_disable_uart_functional(struct clk *clk)
+{
+	struct uart_clk *uclk;
+
+	/* Set force idle acknowledgement mode */
+	uclk = (struct uart_clk *)clk;
+	omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr);
+
+	omap1_clk_disable(clk);
+}
+
+static void omap1_clk_allow_idle(struct clk *clk)
+{
+	struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
+
+	if (!(clk->flags & CLOCK_IDLE_CONTROL))
+		return;
+
+	if (iclk->no_idle_count > 0 && !(--iclk->no_idle_count))
+		arm_idlect1_mask |= 1 << iclk->idlect_shift;
+}
+
+static void omap1_clk_deny_idle(struct clk *clk)
+{
+	struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
+
+	if (!(clk->flags & CLOCK_IDLE_CONTROL))
+		return;
+
+	if (iclk->no_idle_count++ == 0)
+		arm_idlect1_mask &= ~(1 << iclk->idlect_shift);
+}
+
+static __u16 verify_ckctl_value(__u16 newval)
+{
+	/* This function checks for following limitations set
+	 * by the hardware (all conditions must be true):
+	 * DSPMMU_CK == DSP_CK  or  DSPMMU_CK == DSP_CK/2
+	 * ARM_CK >= TC_CK
+	 * DSP_CK >= TC_CK
+	 * DSPMMU_CK >= TC_CK
+	 *
+	 * In addition following rules are enforced:
+	 * LCD_CK <= TC_CK
+	 * ARMPER_CK <= TC_CK
+	 *
+	 * However, maximum frequencies are not checked for!
+	 */
+	__u8 per_exp;
+	__u8 lcd_exp;
+	__u8 arm_exp;
+	__u8 dsp_exp;
+	__u8 tc_exp;
+	__u8 dspmmu_exp;
+
+	per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
+	lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
+	arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
+	dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
+	tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
+	dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
+
+	if (dspmmu_exp < dsp_exp)
+		dspmmu_exp = dsp_exp;
+	if (dspmmu_exp > dsp_exp+1)
+		dspmmu_exp = dsp_exp+1;
+	if (tc_exp < arm_exp)
+		tc_exp = arm_exp;
+	if (tc_exp < dspmmu_exp)
+		tc_exp = dspmmu_exp;
+	if (tc_exp > lcd_exp)
+		lcd_exp = tc_exp;
+	if (tc_exp > per_exp)
+		per_exp = tc_exp;
+
+	newval &= 0xf000;
+	newval |= per_exp << CKCTL_PERDIV_OFFSET;
+	newval |= lcd_exp << CKCTL_LCDDIV_OFFSET;
+	newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
+	newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
+	newval |= tc_exp << CKCTL_TCDIV_OFFSET;
+	newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
+
+	return newval;
+}
+
+static int calc_dsor_exp(struct clk *clk, unsigned long rate)
+{
+	/* Note: If target frequency is too low, this function will return 4,
+	 * which is invalid value. Caller must check for this value and act
+	 * accordingly.
+	 *
+	 * Note: This function does not check for following limitations set
+	 * by the hardware (all conditions must be true):
+	 * DSPMMU_CK == DSP_CK  or  DSPMMU_CK == DSP_CK/2
+	 * ARM_CK >= TC_CK
+	 * DSP_CK >= TC_CK
+	 * DSPMMU_CK >= TC_CK
+	 */
+	unsigned long realrate;
+	struct clk * parent;
+	unsigned  dsor_exp;
+
+	if (unlikely(!(clk->flags & RATE_CKCTL)))
+		return -EINVAL;
+
+	parent = clk->parent;
+	if (unlikely(parent == 0))
+		return -EIO;
+
+	realrate = parent->rate;
+	for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
+		if (realrate <= rate)
+			break;
+
+		realrate /= 2;
+	}
+
+	return dsor_exp;
+}
+
+static void omap1_ckctl_recalc(struct clk * clk)
+{
+	int dsor;
+
+	/* Calculate divisor encoded as 2-bit exponent */
+	dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
+
+	if (unlikely(clk->rate == clk->parent->rate / dsor))
+		return; /* No change, quick exit */
+	clk->rate = clk->parent->rate / dsor;
+
+	if (unlikely(clk->flags & RATE_PROPAGATES))
+		propagate_rate(clk);
+}
+
+static void omap1_ckctl_recalc_dsp_domain(struct clk * clk)
+{
+	int dsor;
+
+	/* Calculate divisor encoded as 2-bit exponent
+	 *
+	 * The clock control bits are in DSP domain,
+	 * so api_ck is needed for access.
+	 * Note that DSP_CKCTL virt addr = phys addr, so
+	 * we must use __raw_readw() instead of omap_readw().
+	 */
+	omap1_clk_use(&api_ck.clk);
+	dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
+	omap1_clk_unuse(&api_ck.clk);
+
+	if (unlikely(clk->rate == clk->parent->rate / dsor))
+		return; /* No change, quick exit */
+	clk->rate = clk->parent->rate / dsor;
+
+	if (unlikely(clk->flags & RATE_PROPAGATES))
+		propagate_rate(clk);
+}
+
+/* MPU virtual clock functions */
+static int omap1_select_table_rate(struct clk * clk, unsigned long rate)
+{
+	/* Find the highest supported frequency <= rate and switch to it */
+	struct mpu_rate * ptr;
+
+	if (clk != &virtual_ck_mpu)
+		return -EINVAL;
+
+	for (ptr = rate_table; ptr->rate; ptr++) {
+		if (ptr->xtal != ck_ref.rate)
+			continue;
+
+		/* DPLL1 cannot be reprogrammed without risking system crash */
+		if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate)
+			continue;
+
+		/* Can check only after xtal frequency check */
+		if (ptr->rate <= rate)
+			break;
+	}
+
+	if (!ptr->rate)
+		return -EINVAL;
+
+	/*
+	 * In most cases we should not need to reprogram DPLL.
+	 * Reprogramming the DPLL is tricky, it must be done from SRAM.
+	 */
+	omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
+
+	ck_dpll1.rate = ptr->pll_rate;
+	propagate_rate(&ck_dpll1);
+	return 0;
+}
+
+static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
+{
+	int  ret = -EINVAL;
+	int  dsor_exp;
+	__u16  regval;
+
+	if (clk->flags & RATE_CKCTL) {
+		dsor_exp = calc_dsor_exp(clk, rate);
+		if (dsor_exp > 3)
+			dsor_exp = -EINVAL;
+		if (dsor_exp < 0)
+			return dsor_exp;
+
+		regval = __raw_readw(DSP_CKCTL);
+		regval &= ~(3 << clk->rate_offset);
+		regval |= dsor_exp << clk->rate_offset;
+		__raw_writew(regval, DSP_CKCTL);
+		clk->rate = clk->parent->rate / (1 << dsor_exp);
+		ret = 0;
+	}
+
+	if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
+		propagate_rate(clk);
+
+	return ret;
+}
+
+static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate)
+{
+	/* Find the highest supported frequency <= rate */
+	struct mpu_rate * ptr;
+	long  highest_rate;
+
+	if (clk != &virtual_ck_mpu)
+		return -EINVAL;
+
+	highest_rate = -EINVAL;
+
+	for (ptr = rate_table; ptr->rate; ptr++) {
+		if (ptr->xtal != ck_ref.rate)
+			continue;
+
+		highest_rate = ptr->rate;
+
+		/* Can check only after xtal frequency check */
+		if (ptr->rate <= rate)
+			break;
+	}
+
+	return highest_rate;
+}
+
+static unsigned calc_ext_dsor(unsigned long rate)
+{
+	unsigned dsor;
+
+	/* MCLK and BCLK divisor selection is not linear:
+	 * freq = 96MHz / dsor
+	 *
+	 * RATIO_SEL range: dsor <-> RATIO_SEL
+	 * 0..6: (RATIO_SEL+2) <-> (dsor-2)
+	 * 6..48:  (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6)
+	 * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9
+	 * can not be used.
+	 */
+	for (dsor = 2; dsor < 96; ++dsor) {
+		if ((dsor & 1) && dsor > 8)
+		  	continue;
+		if (rate >= 96000000 / dsor)
+			break;
+	}
+	return dsor;
+}
+
+/* Only needed on 1510 */
+static int omap1_set_uart_rate(struct clk * clk, unsigned long rate)
+{
+	unsigned int val;
+
+	val = omap_readl(clk->enable_reg);
+	if (rate == 12000000)
+		val &= ~(1 << clk->enable_bit);
+	else if (rate == 48000000)
+		val |= (1 << clk->enable_bit);
+	else
+		return -EINVAL;
+	omap_writel(val, clk->enable_reg);
+	clk->rate = rate;
+
+	return 0;
+}
+
+/* External clock (MCLK & BCLK) functions */
+static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate)
+{
+	unsigned dsor;
+	__u16 ratio_bits;
+
+	dsor = calc_ext_dsor(rate);
+	clk->rate = 96000000 / dsor;
+	if (dsor > 8)
+		ratio_bits = ((dsor - 8) / 2 + 6) << 2;
+	else
+		ratio_bits = (dsor - 2) << 2;
+
+	ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd;
+	omap_writew(ratio_bits, clk->enable_reg);
+
+	return 0;
+}
+
+static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate)
+{
+	return 96000000 / calc_ext_dsor(rate);
+}
+
+static void omap1_init_ext_clk(struct clk * clk)
+{
+	unsigned dsor;
+	__u16 ratio_bits;
+
+	/* Determine current rate and ensure clock is based on 96MHz APLL */
+	ratio_bits = omap_readw(clk->enable_reg) & ~1;
+	omap_writew(ratio_bits, clk->enable_reg);
+
+	ratio_bits = (ratio_bits & 0xfc) >> 2;
+	if (ratio_bits > 6)
+		dsor = (ratio_bits - 6) * 2 + 8;
+	else
+		dsor = ratio_bits + 2;
+
+	clk-> rate = 96000000 / dsor;
+}
+
+static int omap1_clk_use(struct clk *clk)
+{
+	int ret = 0;
+	if (clk->usecount++ == 0) {
+		if (likely(clk->parent)) {
+			ret = omap1_clk_use(clk->parent);
+
+			if (unlikely(ret != 0)) {
+				clk->usecount--;
+				return ret;
+			}
+
+			if (clk->flags & CLOCK_NO_IDLE_PARENT)
+				if (!cpu_is_omap24xx())
+					omap1_clk_deny_idle(clk->parent);
+		}
+
+		ret = clk->enable(clk);
+
+		if (unlikely(ret != 0) && clk->parent) {
+			omap1_clk_unuse(clk->parent);
+			clk->usecount--;
+		}
+	}
+
+	return ret;
+}
+
+static void omap1_clk_unuse(struct clk *clk)
+{
+	if (clk->usecount > 0 && !(--clk->usecount)) {
+		clk->disable(clk);
+		if (likely(clk->parent)) {
+			omap1_clk_unuse(clk->parent);
+			if (clk->flags & CLOCK_NO_IDLE_PARENT)
+				if (!cpu_is_omap24xx())
+					omap1_clk_allow_idle(clk->parent);
+		}
+	}
+}
+
+static int omap1_clk_enable(struct clk *clk)
+{
+	__u16 regval16;
+	__u32 regval32;
+
+	if (clk->flags & ALWAYS_ENABLED)
+		return 0;
+
+	if (unlikely(clk->enable_reg == 0)) {
+		printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
+		       clk->name);
+		return 0;
+	}
+
+	if (clk->flags & ENABLE_REG_32BIT) {
+		if (clk->flags & VIRTUAL_IO_ADDRESS) {
+			regval32 = __raw_readl(clk->enable_reg);
+			regval32 |= (1 << clk->enable_bit);
+			__raw_writel(regval32, clk->enable_reg);
+		} else {
+			regval32 = omap_readl(clk->enable_reg);
+			regval32 |= (1 << clk->enable_bit);
+			omap_writel(regval32, clk->enable_reg);
+		}
+	} else {
+		if (clk->flags & VIRTUAL_IO_ADDRESS) {
+			regval16 = __raw_readw(clk->enable_reg);
+			regval16 |= (1 << clk->enable_bit);
+			__raw_writew(regval16, clk->enable_reg);
+		} else {
+			regval16 = omap_readw(clk->enable_reg);
+			regval16 |= (1 << clk->enable_bit);
+			omap_writew(regval16, clk->enable_reg);
+		}
+	}
+
+	return 0;
+}
+
+static void omap1_clk_disable(struct clk *clk)
+{
+	__u16 regval16;
+	__u32 regval32;
+
+	if (clk->enable_reg == 0)
+		return;
+
+	if (clk->flags & ENABLE_REG_32BIT) {
+		if (clk->flags & VIRTUAL_IO_ADDRESS) {
+			regval32 = __raw_readl(clk->enable_reg);
+			regval32 &= ~(1 << clk->enable_bit);
+			__raw_writel(regval32, clk->enable_reg);
+		} else {
+			regval32 = omap_readl(clk->enable_reg);
+			regval32 &= ~(1 << clk->enable_bit);
+			omap_writel(regval32, clk->enable_reg);
+		}
+	} else {
+		if (clk->flags & VIRTUAL_IO_ADDRESS) {
+			regval16 = __raw_readw(clk->enable_reg);
+			regval16 &= ~(1 << clk->enable_bit);
+			__raw_writew(regval16, clk->enable_reg);
+		} else {
+			regval16 = omap_readw(clk->enable_reg);
+			regval16 &= ~(1 << clk->enable_bit);
+			omap_writew(regval16, clk->enable_reg);
+		}
+	}
+}
+
+static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	int dsor_exp;
+
+	if (clk->flags & RATE_FIXED)
+		return clk->rate;
+
+	if (clk->flags & RATE_CKCTL) {
+		dsor_exp = calc_dsor_exp(clk, rate);
+		if (dsor_exp < 0)
+			return dsor_exp;
+		if (dsor_exp > 3)
+			dsor_exp = 3;
+		return clk->parent->rate / (1 << dsor_exp);
+	}
+
+	if(clk->round_rate != 0)
+		return clk->round_rate(clk, rate);
+
+	return clk->rate;
+}
+
+static int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int  ret = -EINVAL;
+	int  dsor_exp;
+	__u16  regval;
+
+	if (clk->set_rate)
+		ret = clk->set_rate(clk, rate);
+	else if (clk->flags & RATE_CKCTL) {
+		dsor_exp = calc_dsor_exp(clk, rate);
+		if (dsor_exp > 3)
+			dsor_exp = -EINVAL;
+		if (dsor_exp < 0)
+			return dsor_exp;
+
+		regval = omap_readw(ARM_CKCTL);
+		regval &= ~(3 << clk->rate_offset);
+		regval |= dsor_exp << clk->rate_offset;
+		regval = verify_ckctl_value(regval);
+		omap_writew(regval, ARM_CKCTL);
+		clk->rate = clk->parent->rate / (1 << dsor_exp);
+		ret = 0;
+	}
+
+	if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
+		propagate_rate(clk);
+
+	return ret;
+}
+
+/*-------------------------------------------------------------------------
+ * Omap1 clock reset and init functions
+ *-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+/*
+ * Resets some clocks that may be left on from bootloader,
+ * but leaves serial clocks on. See also omap_late_clk_reset().
+ */
+static inline void omap1_early_clk_reset(void)
+{
+	//omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
+}
+
+static int __init omap1_late_clk_reset(void)
+{
+	/* Turn off all unused clocks */
+	struct clk *p;
+	__u32 regval32;
+
+	/* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
+	regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4);
+	omap_writew(regval32, SOFT_REQ_REG);
+	omap_writew(0, SOFT_REQ_REG2);
+
+	list_for_each_entry(p, &clocks, node) {
+		if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) ||
+			p->enable_reg == 0)
+			continue;
+
+		/* Clocks in the DSP domain need api_ck. Just assume bootloader
+		 * has not enabled any DSP clocks */
+		if ((u32)p->enable_reg == DSP_IDLECT2) {
+			printk(KERN_INFO "Skipping reset check for DSP domain "
+			       "clock \"%s\"\n", p->name);
+			continue;
+		}
+
+		/* Is the clock already disabled? */
+		if (p->flags & ENABLE_REG_32BIT) {
+			if (p->flags & VIRTUAL_IO_ADDRESS)
+				regval32 = __raw_readl(p->enable_reg);
+			else
+				regval32 = omap_readl(p->enable_reg);
+		} else {
+			if (p->flags & VIRTUAL_IO_ADDRESS)
+				regval32 = __raw_readw(p->enable_reg);
+			else
+				regval32 = omap_readw(p->enable_reg);
+		}
+
+		if ((regval32 & (1 << p->enable_bit)) == 0)
+			continue;
+
+		/* FIXME: This clock seems to be necessary but no-one
+		 * has asked for its activation. */
+		if (p == &tc2_ck         // FIX: pm.c (SRAM), CCP, Camera
+		    || p == &ck_dpll1out.clk // FIX: SoSSI, SSR
+		    || p == &arm_gpio_ck // FIX: GPIO code for 1510
+		    ) {
+			printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
+			       p->name);
+			continue;
+		}
+
+		printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name);
+		p->disable(p);
+		printk(" done\n");
+	}
+
+	return 0;
+}
+late_initcall(omap1_late_clk_reset);
+
+#else
+#define omap1_early_clk_reset()	{}
+#endif
+
+static struct clk_functions omap1_clk_functions = {
+	.clk_use		= omap1_clk_use,
+	.clk_unuse		= omap1_clk_unuse,
+	.clk_round_rate		= omap1_clk_round_rate,
+	.clk_set_rate		= omap1_clk_set_rate,
+};
+
+int __init omap1_clk_init(void)
+{
+	struct clk ** clkp;
+	const struct omap_clock_config *info;
+	int crystal_type = 0; /* Default 12 MHz */
+
+	omap1_early_clk_reset();
+	clk_init(&omap1_clk_functions);
+
+	/* By default all idlect1 clocks are allowed to idle */
+	arm_idlect1_mask = ~0;
+
+	for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
+		if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
+			clk_register(*clkp);
+			continue;
+		}
+
+		if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
+			clk_register(*clkp);
+			continue;
+		}
+
+		if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) {
+			clk_register(*clkp);
+			continue;
+		}
+	}
+
+	info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
+	if (info != NULL) {
+		if (!cpu_is_omap1510())
+			crystal_type = info->system_clock_type;
+	}
+
+#if defined(CONFIG_ARCH_OMAP730)
+	ck_ref.rate = 13000000;
+#elif defined(CONFIG_ARCH_OMAP16XX)
+	if (crystal_type == 2)
+		ck_ref.rate = 19200000;
+#endif
+
+	printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n",
+	       omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),
+	       omap_readw(ARM_CKCTL));
+
+	/* We want to be in syncronous scalable mode */
+	omap_writew(0x1000, ARM_SYSST);
+
+#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
+	/* Use values set by bootloader. Determine PLL rate and recalculate
+	 * dependent clocks as if kernel had changed PLL or divisors.
+	 */
+	{
+		unsigned pll_ctl_val = omap_readw(DPLL_CTL);
+
+		ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */
+		if (pll_ctl_val & 0x10) {
+			/* PLL enabled, apply multiplier and divisor */
+			if (pll_ctl_val & 0xf80)
+				ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7;
+			ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1;
+		} else {
+			/* PLL disabled, apply bypass divisor */
+			switch (pll_ctl_val & 0xc) {
+			case 0:
+				break;
+			case 0x4:
+				ck_dpll1.rate /= 2;
+				break;
+			default:
+				ck_dpll1.rate /= 4;
+				break;
+			}
+		}
+	}
+	propagate_rate(&ck_dpll1);
+#else
+	/* Find the highest supported frequency and enable it */
+	if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
+		printk(KERN_ERR "System frequencies not set. Check your config.\n");
+		/* Guess sane values (60MHz) */
+		omap_writew(0x2290, DPLL_CTL);
+		omap_writew(0x1005, ARM_CKCTL);
+		ck_dpll1.rate = 60000000;
+		propagate_rate(&ck_dpll1);
+	}
+#endif
+	/* Cache rates for clocks connected to ck_ref (not dpll1) */
+	propagate_rate(&ck_ref);
+	printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
+		"%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
+	       ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
+	       ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
+	       arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
+
+#ifdef CONFIG_MACH_OMAP_PERSEUS2
+	/* Select slicer output as OMAP input clock */
+	omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
+#endif
+
+	/* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
+	omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
+
+	/* Put DSP/MPUI into reset until needed */
+	omap_writew(0, ARM_RSTCT1);
+	omap_writew(1, ARM_RSTCT2);
+	omap_writew(0x400, ARM_IDLECT1);
+
+	/*
+	 * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
+	 * of the ARM_IDLECT2 register must be set to zero. The power-on
+	 * default value of this bit is one.
+	 */
+	omap_writew(0x0000, ARM_IDLECT2);	/* Turn LCD clock off also */
+
+	/*
+	 * Only enable those clocks we will need, let the drivers
+	 * enable other clocks as necessary
+	 */
+	clk_use(&armper_ck.clk);
+	clk_use(&armxor_ck.clk);
+	clk_use(&armtim_ck.clk); /* This should be done by timer code */
+
+	if (cpu_is_omap1510())
+		clk_enable(&arm_gpio_ck);
+
+	return 0;
+}
+

+ 768 - 0
arch/arm/mach-omap1/clock.h

@@ -0,0 +1,768 @@
+/*
+ *  linux/arch/arm/mach-omap1/clock.h
+ *
+ *  Copyright (C) 2004 - 2005 Nokia corporation
+ *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H
+#define __ARCH_ARM_MACH_OMAP1_CLOCK_H
+
+static int omap1_clk_enable(struct clk * clk);
+static void omap1_clk_disable(struct clk * clk);
+static void omap1_ckctl_recalc(struct clk * clk);
+static void omap1_watchdog_recalc(struct clk * clk);
+static void omap1_ckctl_recalc_dsp_domain(struct clk * clk);
+static int omap1_clk_enable_dsp_domain(struct clk * clk);
+static int omap1_clk_set_rate_dsp_domain(struct clk * clk, unsigned long rate);
+static void omap1_clk_disable_dsp_domain(struct clk * clk);
+static int omap1_set_uart_rate(struct clk * clk, unsigned long rate);
+static void omap1_uart_recalc(struct clk * clk);
+static int omap1_clk_enable_uart_functional(struct clk * clk);
+static void omap1_clk_disable_uart_functional(struct clk * clk);
+static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate);
+static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate);
+static void omap1_init_ext_clk(struct clk * clk);
+static int omap1_select_table_rate(struct clk * clk, unsigned long rate);
+static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate);
+static int omap1_clk_use(struct clk *clk);
+static void omap1_clk_unuse(struct clk *clk);
+
+struct mpu_rate {
+	unsigned long		rate;
+	unsigned long		xtal;
+	unsigned long		pll_rate;
+	__u16			ckctl_val;
+	__u16			dpllctl_val;
+};
+
+struct uart_clk {
+	struct clk	clk;
+	unsigned long	sysc_addr;
+};
+
+/* Provide a method for preventing idling some ARM IDLECT clocks */
+struct arm_idlect1_clk {
+	struct clk	clk;
+	unsigned long	no_idle_count;
+	__u8		idlect_shift;
+};
+
+/* ARM_CKCTL bit shifts */
+#define CKCTL_PERDIV_OFFSET	0
+#define CKCTL_LCDDIV_OFFSET	2
+#define CKCTL_ARMDIV_OFFSET	4
+#define CKCTL_DSPDIV_OFFSET	6
+#define CKCTL_TCDIV_OFFSET	8
+#define CKCTL_DSPMMUDIV_OFFSET	10
+/*#define ARM_TIMXO		12*/
+#define EN_DSPCK		13
+/*#define ARM_INTHCK_SEL	14*/ /* Divide-by-2 for mpu inth_ck */
+/* DSP_CKCTL bit shifts */
+#define CKCTL_DSPPERDIV_OFFSET	0
+
+/* ARM_IDLECT2 bit shifts */
+#define EN_WDTCK	0
+#define EN_XORPCK	1
+#define EN_PERCK	2
+#define EN_LCDCK	3
+#define EN_LBCK		4 /* Not on 1610/1710 */
+/*#define EN_HSABCK	5*/
+#define EN_APICK	6
+#define EN_TIMCK	7
+#define DMACK_REQ	8
+#define EN_GPIOCK	9 /* Not on 1610/1710 */
+/*#define EN_LBFREECK	10*/
+#define EN_CKOUT_ARM	11
+
+/* ARM_IDLECT3 bit shifts */
+#define EN_OCPI_CK	0
+#define EN_TC1_CK	2
+#define EN_TC2_CK	4
+
+/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */
+#define EN_DSPTIMCK	5
+
+/* Various register defines for clock controls scattered around OMAP chip */
+#define USB_MCLK_EN_BIT		4	/* In ULPD_CLKC_CTRL */
+#define USB_HOST_HHC_UHOST_EN	9	/* In MOD_CONF_CTRL_0 */
+#define SWD_ULPD_PLL_CLK_REQ	1	/* In SWD_CLK_DIV_CTRL_SEL */
+#define COM_ULPD_PLL_CLK_REQ	1	/* In COM_CLK_DIV_CTRL_SEL */
+#define SWD_CLK_DIV_CTRL_SEL	0xfffe0874
+#define COM_CLK_DIV_CTRL_SEL	0xfffe0878
+#define SOFT_REQ_REG		0xfffe0834
+#define SOFT_REQ_REG2		0xfffe0880
+
+/*-------------------------------------------------------------------------
+ * Omap1 MPU rate table
+ *-------------------------------------------------------------------------*/
+static struct mpu_rate rate_table[] = {
+	/* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
+	 * NOTE: Comment order here is different from bits in CKCTL value:
+	 * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
+	 */
+#if defined(CONFIG_OMAP_ARM_216MHZ)
+	{ 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_195MHZ)
+	{ 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_192MHZ)
+	{ 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
+	{ 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
+	{  96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
+	{  48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/4/4/8/8/8 */
+	{  24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_182MHZ)
+	{ 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_168MHZ)
+	{ 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_150MHZ)
+	{ 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */
+#endif
+#if defined(CONFIG_OMAP_ARM_120MHZ)
+	{ 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
+#endif
+#if defined(CONFIG_OMAP_ARM_96MHZ)
+	{  96000000, 12000000,  96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */
+#endif
+#if defined(CONFIG_OMAP_ARM_60MHZ)
+	{  60000000, 12000000,  60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
+#endif
+#if defined(CONFIG_OMAP_ARM_30MHZ)
+	{  30000000, 12000000,  60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
+#endif
+	{ 0, 0, 0, 0, 0 },
+};
+
+/*-------------------------------------------------------------------------
+ * Omap1 clocks
+ *-------------------------------------------------------------------------*/
+
+static struct clk ck_ref = {
+	.name		= "ck_ref",
+	.rate		= 12000000,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  ALWAYS_ENABLED,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk ck_dpll1 = {
+	.name		= "ck_dpll1",
+	.parent		= &ck_ref,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_PROPAGATES | ALWAYS_ENABLED,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct arm_idlect1_clk ck_dpll1out = {
+	.clk = {
+	       	.name		= "ck_dpll1out",
+		.parent		= &ck_dpll1,
+		.flags		= CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL,
+		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.enable_bit	= EN_CKOUT_ARM,
+		.recalc		= &followparent_recalc,
+		.enable		= &omap1_clk_enable,
+		.disable	= &omap1_clk_disable,
+	},
+	.idlect_shift	= 12,
+};
+
+static struct clk arm_ck = {
+	.name		= "arm_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
+	.rate_offset	= CKCTL_ARMDIV_OFFSET,
+	.recalc		= &omap1_ckctl_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct arm_idlect1_clk armper_ck = {
+	.clk = {
+		.name		= "armper_ck",
+		.parent		= &ck_dpll1,
+		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+				  RATE_CKCTL | CLOCK_IDLE_CONTROL,
+		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.enable_bit	= EN_PERCK,
+		.rate_offset	= CKCTL_PERDIV_OFFSET,
+		.recalc		= &omap1_ckctl_recalc,
+		.enable		= &omap1_clk_enable,
+		.disable	= &omap1_clk_disable,
+	},
+	.idlect_shift	= 2,
+};
+
+static struct clk arm_gpio_ck = {
+	.name		= "arm_gpio_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP1510,
+	.enable_reg	= (void __iomem *)ARM_IDLECT2,
+	.enable_bit	= EN_GPIOCK,
+	.recalc		= &followparent_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct arm_idlect1_clk armxor_ck = {
+	.clk = {
+		.name		= "armxor_ck",
+		.parent		= &ck_ref,
+		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+				  CLOCK_IDLE_CONTROL,
+		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.enable_bit	= EN_XORPCK,
+		.recalc		= &followparent_recalc,
+		.enable		= &omap1_clk_enable,
+		.disable	= &omap1_clk_disable,
+	},
+	.idlect_shift	= 1,
+};
+
+static struct arm_idlect1_clk armtim_ck = {
+	.clk = {
+		.name		= "armtim_ck",
+		.parent		= &ck_ref,
+		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+				  CLOCK_IDLE_CONTROL,
+		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.enable_bit	= EN_TIMCK,
+		.recalc		= &followparent_recalc,
+		.enable		= &omap1_clk_enable,
+		.disable	= &omap1_clk_disable,
+	},
+	.idlect_shift	= 9,
+};
+
+static struct arm_idlect1_clk armwdt_ck = {
+	.clk = {
+		.name		= "armwdt_ck",
+		.parent		= &ck_ref,
+		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+				  CLOCK_IDLE_CONTROL,
+		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.enable_bit	= EN_WDTCK,
+		.recalc		= &omap1_watchdog_recalc,
+		.enable		= &omap1_clk_enable,
+		.disable	= &omap1_clk_disable,
+	},
+	.idlect_shift	= 0,
+};
+
+static struct clk arminth_ck16xx = {
+	.name		= "arminth_ck",
+	.parent		= &arm_ck,
+	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+	/* Note: On 16xx the frequency can be divided by 2 by programming
+	 * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
+	 *
+	 * 1510 version is in TC clocks.
+	 */
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk dsp_ck = {
+	.name		= "dsp_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_CKCTL,
+	.enable_reg	= (void __iomem *)ARM_CKCTL,
+	.enable_bit	= EN_DSPCK,
+	.rate_offset	= CKCTL_DSPDIV_OFFSET,
+	.recalc		= &omap1_ckctl_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk dspmmu_ck = {
+	.name		= "dspmmu_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_CKCTL | ALWAYS_ENABLED,
+	.rate_offset	= CKCTL_DSPMMUDIV_OFFSET,
+	.recalc		= &omap1_ckctl_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk dspper_ck = {
+	.name		= "dspper_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_CKCTL | VIRTUAL_IO_ADDRESS,
+	.enable_reg	= (void __iomem *)DSP_IDLECT2,
+	.enable_bit	= EN_PERCK,
+	.rate_offset	= CKCTL_PERDIV_OFFSET,
+	.recalc		= &omap1_ckctl_recalc_dsp_domain,
+	.set_rate	= &omap1_clk_set_rate_dsp_domain,
+	.enable		= &omap1_clk_enable_dsp_domain,
+	.disable	= &omap1_clk_disable_dsp_domain,
+};
+
+static struct clk dspxor_ck = {
+	.name		= "dspxor_ck",
+	.parent		= &ck_ref,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  VIRTUAL_IO_ADDRESS,
+	.enable_reg	= (void __iomem *)DSP_IDLECT2,
+	.enable_bit	= EN_XORPCK,
+	.recalc		= &followparent_recalc,
+	.enable		= &omap1_clk_enable_dsp_domain,
+	.disable	= &omap1_clk_disable_dsp_domain,
+};
+
+static struct clk dsptim_ck = {
+	.name		= "dsptim_ck",
+	.parent		= &ck_ref,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  VIRTUAL_IO_ADDRESS,
+	.enable_reg	= (void __iomem *)DSP_IDLECT2,
+	.enable_bit	= EN_DSPTIMCK,
+	.recalc		= &followparent_recalc,
+	.enable		= &omap1_clk_enable_dsp_domain,
+	.disable	= &omap1_clk_disable_dsp_domain,
+};
+
+/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */
+static struct arm_idlect1_clk tc_ck = {
+	.clk = {
+		.name		= "tc_ck",
+		.parent		= &ck_dpll1,
+		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+				  CLOCK_IN_OMAP730 | RATE_CKCTL |
+				  RATE_PROPAGATES | ALWAYS_ENABLED |
+				  CLOCK_IDLE_CONTROL,
+		.rate_offset	= CKCTL_TCDIV_OFFSET,
+		.recalc		= &omap1_ckctl_recalc,
+		.enable		= &omap1_clk_enable,
+		.disable	= &omap1_clk_disable,
+	},
+	.idlect_shift	= 6,
+};
+
+static struct clk arminth_ck1510 = {
+	.name		= "arminth_ck",
+	.parent		= &tc_ck.clk,
+	.flags		= CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+	/* Note: On 1510 the frequency follows TC_CK
+	 *
+	 * 16xx version is in MPU clocks.
+	 */
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk tipb_ck = {
+	/* No-idle controlled by "tc_ck" */
+	.name		= "tibp_ck",
+	.parent		= &tc_ck.clk,
+	.flags		= CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk l3_ocpi_ck = {
+	/* No-idle controlled by "tc_ck" */
+	.name		= "l3_ocpi_ck",
+	.parent		= &tc_ck.clk,
+	.flags		= CLOCK_IN_OMAP16XX,
+	.enable_reg	= (void __iomem *)ARM_IDLECT3,
+	.enable_bit	= EN_OCPI_CK,
+	.recalc		= &followparent_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk tc1_ck = {
+	.name		= "tc1_ck",
+	.parent		= &tc_ck.clk,
+	.flags		= CLOCK_IN_OMAP16XX,
+	.enable_reg	= (void __iomem *)ARM_IDLECT3,
+	.enable_bit	= EN_TC1_CK,
+	.recalc		= &followparent_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk tc2_ck = {
+	.name		= "tc2_ck",
+	.parent		= &tc_ck.clk,
+	.flags		= CLOCK_IN_OMAP16XX,
+	.enable_reg	= (void __iomem *)ARM_IDLECT3,
+	.enable_bit	= EN_TC2_CK,
+	.recalc		= &followparent_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk dma_ck = {
+	/* No-idle controlled by "tc_ck" */
+	.name		= "dma_ck",
+	.parent		= &tc_ck.clk,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk dma_lcdfree_ck = {
+	.name		= "dma_lcdfree_ck",
+	.parent		= &tc_ck.clk,
+	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct arm_idlect1_clk api_ck = {
+	.clk = {
+		.name		= "api_ck",
+		.parent		= &tc_ck.clk,
+		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+				  CLOCK_IDLE_CONTROL,
+		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.enable_bit	= EN_APICK,
+		.recalc		= &followparent_recalc,
+		.enable		= &omap1_clk_enable,
+		.disable	= &omap1_clk_disable,
+	},
+	.idlect_shift	= 8,
+};
+
+static struct arm_idlect1_clk lb_ck = {
+	.clk = {
+		.name		= "lb_ck",
+		.parent		= &tc_ck.clk,
+		.flags		= CLOCK_IN_OMAP1510 | CLOCK_IDLE_CONTROL,
+		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.enable_bit	= EN_LBCK,
+		.recalc		= &followparent_recalc,
+		.enable		= &omap1_clk_enable,
+		.disable	= &omap1_clk_disable,
+	},
+	.idlect_shift	= 4,
+};
+
+static struct clk rhea1_ck = {
+	.name		= "rhea1_ck",
+	.parent		= &tc_ck.clk,
+	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk rhea2_ck = {
+	.name		= "rhea2_ck",
+	.parent		= &tc_ck.clk,
+	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk lcd_ck_16xx = {
+	.name		= "lcd_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | RATE_CKCTL,
+	.enable_reg	= (void __iomem *)ARM_IDLECT2,
+	.enable_bit	= EN_LCDCK,
+	.rate_offset	= CKCTL_LCDDIV_OFFSET,
+	.recalc		= &omap1_ckctl_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct arm_idlect1_clk lcd_ck_1510 = {
+	.clk = {
+		.name		= "lcd_ck",
+		.parent		= &ck_dpll1,
+		.flags		= CLOCK_IN_OMAP1510 | RATE_CKCTL |
+				  CLOCK_IDLE_CONTROL,
+		.enable_reg	= (void __iomem *)ARM_IDLECT2,
+		.enable_bit	= EN_LCDCK,
+		.rate_offset	= CKCTL_LCDDIV_OFFSET,
+		.recalc		= &omap1_ckctl_recalc,
+		.enable		= &omap1_clk_enable,
+		.disable	= &omap1_clk_disable,
+	},
+	.idlect_shift	= 3,
+};
+
+static struct clk uart1_1510 = {
+	.name		= "uart1_ck",
+	/* Direct from ULPD, no real parent */
+	.parent		= &armper_ck.clk,
+	.rate		= 12000000,
+	.flags		= CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
+			  ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
+	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+	.enable_bit	= 29,	/* Chooses between 12MHz and 48MHz */
+	.set_rate	= &omap1_set_uart_rate,
+	.recalc		= &omap1_uart_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct uart_clk uart1_16xx = {
+	.clk	= {
+		.name		= "uart1_ck",
+		/* Direct from ULPD, no real parent */
+		.parent		= &armper_ck.clk,
+		.rate		= 48000000,
+		.flags		= CLOCK_IN_OMAP16XX | RATE_FIXED |
+				  ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+		.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+		.enable_bit	= 29,
+		.enable		= &omap1_clk_enable_uart_functional,
+		.disable	= &omap1_clk_disable_uart_functional,
+	},
+	.sysc_addr	= 0xfffb0054,
+};
+
+static struct clk uart2_ck = {
+	.name		= "uart2_ck",
+	/* Direct from ULPD, no real parent */
+	.parent		= &armper_ck.clk,
+	.rate		= 12000000,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  ENABLE_REG_32BIT | ALWAYS_ENABLED |
+			  CLOCK_NO_IDLE_PARENT,
+	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+	.enable_bit	= 30,	/* Chooses between 12MHz and 48MHz */
+	.set_rate	= &omap1_set_uart_rate,
+	.recalc		= &omap1_uart_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk uart3_1510 = {
+	.name		= "uart3_ck",
+	/* Direct from ULPD, no real parent */
+	.parent		= &armper_ck.clk,
+	.rate		= 12000000,
+	.flags		= CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT |
+			  ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
+	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+	.enable_bit	= 31,	/* Chooses between 12MHz and 48MHz */
+	.set_rate	= &omap1_set_uart_rate,
+	.recalc		= &omap1_uart_recalc,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct uart_clk uart3_16xx = {
+	.clk	= {
+		.name		= "uart3_ck",
+		/* Direct from ULPD, no real parent */
+		.parent		= &armper_ck.clk,
+		.rate		= 48000000,
+		.flags		= CLOCK_IN_OMAP16XX | RATE_FIXED |
+				  ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+		.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+		.enable_bit	= 31,
+		.enable		= &omap1_clk_enable_uart_functional,
+		.disable	= &omap1_clk_disable_uart_functional,
+	},
+	.sysc_addr	= 0xfffb9854,
+};
+
+static struct clk usb_clko = {	/* 6 MHz output on W4_USB_CLKO */
+	.name		= "usb_clko",
+	/* Direct from ULPD, no parent */
+	.rate		= 6000000,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= (void __iomem *)ULPD_CLOCK_CTRL,
+	.enable_bit	= USB_MCLK_EN_BIT,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk usb_hhc_ck1510 = {
+	.name		= "usb_hhc_ck",
+	/* Direct from ULPD, no parent */
+	.rate		= 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
+	.flags		= CLOCK_IN_OMAP1510 |
+			  RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+	.enable_bit	= USB_HOST_HHC_UHOST_EN,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk usb_hhc_ck16xx = {
+	.name		= "usb_hhc_ck",
+	/* Direct from ULPD, no parent */
+	.rate		= 48000000,
+	/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
+	.flags		= CLOCK_IN_OMAP16XX |
+			  RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= (void __iomem *)OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
+	.enable_bit	= 8 /* UHOST_EN */,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk usb_dc_ck = {
+	.name		= "usb_dc_ck",
+	/* Direct from ULPD, no parent */
+	.rate		= 48000000,
+	.flags		= CLOCK_IN_OMAP16XX | RATE_FIXED,
+	.enable_reg	= (void __iomem *)SOFT_REQ_REG,
+	.enable_bit	= 4,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk mclk_1510 = {
+	.name		= "mclk",
+	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+	.rate		= 12000000,
+	.flags		= CLOCK_IN_OMAP1510 | RATE_FIXED,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk mclk_16xx = {
+	.name		= "mclk",
+	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+	.flags		= CLOCK_IN_OMAP16XX,
+	.enable_reg	= (void __iomem *)COM_CLK_DIV_CTRL_SEL,
+	.enable_bit	= COM_ULPD_PLL_CLK_REQ,
+	.set_rate	= &omap1_set_ext_clk_rate,
+	.round_rate	= &omap1_round_ext_clk_rate,
+	.init		= &omap1_init_ext_clk,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk bclk_1510 = {
+	.name		= "bclk",
+	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+	.rate		= 12000000,
+	.flags		= CLOCK_IN_OMAP1510 | RATE_FIXED,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk bclk_16xx = {
+	.name		= "bclk",
+	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+	.flags		= CLOCK_IN_OMAP16XX,
+	.enable_reg	= (void __iomem *)SWD_CLK_DIV_CTRL_SEL,
+	.enable_bit	= SWD_ULPD_PLL_CLK_REQ,
+	.set_rate	= &omap1_set_ext_clk_rate,
+	.round_rate	= &omap1_round_ext_clk_rate,
+	.init		= &omap1_init_ext_clk,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk mmc1_ck = {
+	.name		= "mmc1_ck",
+	/* Functional clock is direct from ULPD, interface clock is ARMPER */
+	.parent		= &armper_ck.clk,
+	.rate		= 48000000,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+	.enable_bit	= 23,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk mmc2_ck = {
+	.name		= "mmc2_ck",
+	/* Functional clock is direct from ULPD, interface clock is ARMPER */
+	.parent		= &armper_ck.clk,
+	.rate		= 48000000,
+	.flags		= CLOCK_IN_OMAP16XX |
+			  RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+	.enable_reg	= (void __iomem *)MOD_CONF_CTRL_0,
+	.enable_bit	= 20,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk virtual_ck_mpu = {
+	.name		= "mpu",
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  VIRTUAL_CLOCK | ALWAYS_ENABLED,
+	.parent		= &arm_ck, /* Is smarter alias for */
+	.recalc		= &followparent_recalc,
+	.set_rate	= &omap1_select_table_rate,
+	.round_rate	= &omap1_round_to_table_rate,
+	.enable		= &omap1_clk_enable,
+	.disable	= &omap1_clk_disable,
+};
+
+static struct clk * onchip_clks[] = {
+	/* non-ULPD clocks */
+	&ck_ref,
+	&ck_dpll1,
+	/* CK_GEN1 clocks */
+	&ck_dpll1out.clk,
+	&arm_ck,
+	&armper_ck.clk,
+	&arm_gpio_ck,
+	&armxor_ck.clk,
+	&armtim_ck.clk,
+	&armwdt_ck.clk,
+	&arminth_ck1510,  &arminth_ck16xx,
+	/* CK_GEN2 clocks */
+	&dsp_ck,
+	&dspmmu_ck,
+	&dspper_ck,
+	&dspxor_ck,
+	&dsptim_ck,
+	/* CK_GEN3 clocks */
+	&tc_ck.clk,
+	&tipb_ck,
+	&l3_ocpi_ck,
+	&tc1_ck,
+	&tc2_ck,
+	&dma_ck,
+	&dma_lcdfree_ck,
+	&api_ck.clk,
+	&lb_ck.clk,
+	&rhea1_ck,
+	&rhea2_ck,
+	&lcd_ck_16xx,
+	&lcd_ck_1510.clk,
+	/* ULPD clocks */
+	&uart1_1510,
+	&uart1_16xx.clk,
+	&uart2_ck,
+	&uart3_1510,
+	&uart3_16xx.clk,
+	&usb_clko,
+	&usb_hhc_ck1510, &usb_hhc_ck16xx,
+	&usb_dc_ck,
+	&mclk_1510,  &mclk_16xx,
+	&bclk_1510,  &bclk_16xx,
+	&mmc1_ck,
+	&mmc2_ck,
+	/* Virtual clocks */
+	&virtual_ck_mpu,
+};
+
+#endif

+ 3 - 218
arch/arm/mach-omap1/devices.c

@@ -25,56 +25,7 @@
 #include <asm/arch/mux.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/gpio.h>
 
 
-
-static void omap_nop_release(struct device *dev)
-{
-        /* Nothing */
-}
-
-/*-------------------------------------------------------------------------*/
-
-#if	defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
-
-#define	OMAP_I2C_BASE		0xfffb3800
-
-static struct resource i2c_resources[] = {
-	{
-		.start		= OMAP_I2C_BASE,
-		.end		= OMAP_I2C_BASE + 0x3f,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= INT_I2C,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-/* DMA not used; works around erratum writing to non-empty i2c fifo */
-
-static struct platform_device omap_i2c_device = {
-        .name           = "i2c_omap",
-        .id             = -1,
-        .dev = {
-                .release        = omap_nop_release,
-        },
-	.num_resources	= ARRAY_SIZE(i2c_resources),
-	.resource	= i2c_resources,
-};
-
-static void omap_init_i2c(void)
-{
-	/* FIXME define and use a boot tag, in case of boards that
-	 * either don't wire up I2C, or chips that mux it differently...
-	 * it can include clocking and address info, maybe more.
-	 */
-	omap_cfg_reg(I2C_SCL);
-	omap_cfg_reg(I2C_SDA);
-
-	(void) platform_device_register(&omap_i2c_device);
-}
-#else
-static inline void omap_init_i2c(void) {}
-#endif
+extern void omap_nop_release(struct device *dev);
 
 
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
 
 
@@ -110,137 +61,6 @@ static inline void omap_init_irda(void) {}
 
 
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
 
 
-#if	defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
-
-#define	OMAP_MMC1_BASE		0xfffb7800
-#define	OMAP_MMC2_BASE		0xfffb7c00	/* omap16xx only */
-
-static struct omap_mmc_conf mmc1_conf;
-
-static u64 mmc1_dmamask = 0xffffffff;
-
-static struct resource mmc1_resources[] = {
-	{
-		.start		= IO_ADDRESS(OMAP_MMC1_BASE),
-		.end		= IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= INT_MMC,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mmc_omap_device1 = {
-	.name		= "mmci-omap",
-	.id		= 1,
-	.dev = {
-		.release	= omap_nop_release,
-		.dma_mask	= &mmc1_dmamask,
-		.platform_data	= &mmc1_conf,
-	},
-	.num_resources	= ARRAY_SIZE(mmc1_resources),
-	.resource	= mmc1_resources,
-};
-
-#ifdef	CONFIG_ARCH_OMAP16XX
-
-static struct omap_mmc_conf mmc2_conf;
-
-static u64 mmc2_dmamask = 0xffffffff;
-
-static struct resource mmc2_resources[] = {
-	{
-		.start		= IO_ADDRESS(OMAP_MMC2_BASE),
-		.end		= IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= INT_1610_MMC2,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mmc_omap_device2 = {
-	.name		= "mmci-omap",
-	.id		= 2,
-	.dev = {
-		.release	= omap_nop_release,
-		.dma_mask	= &mmc2_dmamask,
-		.platform_data	= &mmc2_conf,
-	},
-	.num_resources	= ARRAY_SIZE(mmc2_resources),
-	.resource	= mmc2_resources,
-};
-#endif
-
-static void __init omap_init_mmc(void)
-{
-	const struct omap_mmc_config	*mmc_conf;
-	const struct omap_mmc_conf	*mmc;
-
-	/* NOTE:  assumes MMC was never (wrongly) enabled */
-	mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
-	if (!mmc_conf)
-		return;
-
-	/* block 1 is always available and has just one pinout option */
-	mmc = &mmc_conf->mmc[0];
-	if (mmc->enabled) {
-		omap_cfg_reg(MMC_CMD);
-		omap_cfg_reg(MMC_CLK);
-		omap_cfg_reg(MMC_DAT0);
-		if (cpu_is_omap1710()) {
-	              omap_cfg_reg(M15_1710_MMC_CLKI);
-	              omap_cfg_reg(P19_1710_MMC_CMDDIR);
-	              omap_cfg_reg(P20_1710_MMC_DATDIR0);
-	        }
-		if (mmc->wire4) {
-			omap_cfg_reg(MMC_DAT1);
-			/* NOTE:  DAT2 can be on W10 (here) or M15 */
-			if (!mmc->nomux)
-				omap_cfg_reg(MMC_DAT2);
-			omap_cfg_reg(MMC_DAT3);
-		}
-		mmc1_conf = *mmc;
-		(void) platform_device_register(&mmc_omap_device1);
-	}
-
-#ifdef	CONFIG_ARCH_OMAP16XX
-	/* block 2 is on newer chips, and has many pinout options */
-	mmc = &mmc_conf->mmc[1];
-	if (mmc->enabled) {
-		if (!mmc->nomux) {
-			omap_cfg_reg(Y8_1610_MMC2_CMD);
-			omap_cfg_reg(Y10_1610_MMC2_CLK);
-			omap_cfg_reg(R18_1610_MMC2_CLKIN);
-			omap_cfg_reg(W8_1610_MMC2_DAT0);
-			if (mmc->wire4) {
-				omap_cfg_reg(V8_1610_MMC2_DAT1);
-				omap_cfg_reg(W15_1610_MMC2_DAT2);
-				omap_cfg_reg(R10_1610_MMC2_DAT3);
-			}
-
-			/* These are needed for the level shifter */
-			omap_cfg_reg(V9_1610_MMC2_CMDDIR);
-			omap_cfg_reg(V5_1610_MMC2_DATDIR0);
-			omap_cfg_reg(W19_1610_MMC2_DATDIR1);
-		}
-
-		/* Feedback clock must be set on OMAP-1710 MMC2 */
-		if (cpu_is_omap1710())
-			omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
-				     MOD_CONF_CTRL_1);
-		mmc2_conf = *mmc;
-		(void) platform_device_register(&mmc_omap_device2);
-	}
-#endif
-	return;
-}
-#else
-static inline void omap_init_mmc(void) {}
-#endif
-
 #if	defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC)
 #if	defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC)
 
 
 #define	OMAP_RTC_BASE		0xfffb4800
 #define	OMAP_RTC_BASE		0xfffb4800
@@ -279,38 +99,6 @@ static void omap_init_rtc(void)
 static inline void omap_init_rtc(void) {}
 static inline void omap_init_rtc(void) {}
 #endif
 #endif
 
 
-/*-------------------------------------------------------------------------*/
-
-#if	defined(CONFIG_OMAP16XX_WATCHDOG) || defined(CONFIG_OMAP16XX_WATCHDOG_MODULE)
-
-#define	OMAP_WDT_BASE		0xfffeb000
-
-static struct resource wdt_resources[] = {
-	{
-		.start		= OMAP_WDT_BASE,
-		.end		= OMAP_WDT_BASE + 0x4f,
-		.flags		= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device omap_wdt_device = {
-	.name	   = "omap1610_wdt",
-	.id	     = -1,
-	.dev = {
-		.release	= omap_nop_release,
-	},
-	.num_resources	= ARRAY_SIZE(wdt_resources),
-	.resource	= wdt_resources,
-};
-
-static void omap_init_wdt(void)
-{
-	(void) platform_device_register(&omap_wdt_device);
-}
-#else
-static inline void omap_init_wdt(void) {}
-#endif
-
 
 
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
 
 
@@ -334,18 +122,15 @@ static inline void omap_init_wdt(void) {}
  * may be handled by the boot loader, and drivers should expect it will
  * may be handled by the boot loader, and drivers should expect it will
  * normally have been done by the time they're probed.
  * normally have been done by the time they're probed.
  */
  */
-static int __init omap_init_devices(void)
+static int __init omap1_init_devices(void)
 {
 {
 	/* 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.
 	 */
 	 */
-	omap_init_i2c();
 	omap_init_irda();
 	omap_init_irda();
-	omap_init_mmc();
 	omap_init_rtc();
 	omap_init_rtc();
-	omap_init_wdt();
 
 
 	return 0;
 	return 0;
 }
 }
-arch_initcall(omap_init_devices);
+arch_initcall(omap1_init_devices);
 
 

+ 9 - 0
arch/arm/mach-omap1/id.c

@@ -18,6 +18,13 @@
 
 
 #include <asm/io.h>
 #include <asm/io.h>
 
 
+#define OMAP_DIE_ID_0		0xfffe1800
+#define OMAP_DIE_ID_1		0xfffe1804
+#define OMAP_PRODUCTION_ID_0	0xfffe2000
+#define OMAP_PRODUCTION_ID_1	0xfffe2004
+#define OMAP32_ID_0		0xfffed400
+#define OMAP32_ID_1		0xfffed404
+
 struct omap_id {
 struct omap_id {
 	u16	jtag_id;	/* Used to determine OMAP type */
 	u16	jtag_id;	/* Used to determine OMAP type */
 	u8	die_rev;	/* Processor revision */
 	u8	die_rev;	/* Processor revision */
@@ -27,6 +34,7 @@ struct omap_id {
 
 
 /* Register values to detect the OMAP version */
 /* Register values to detect the OMAP version */
 static struct omap_id omap_ids[] __initdata = {
 static struct omap_id omap_ids[] __initdata = {
+	{ .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000},
 	{ .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
 	{ .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
 	{ .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
 	{ .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
 	{ .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
 	{ .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
@@ -164,6 +172,7 @@ void __init omap_check_revision(void)
 	case 0x07:
 	case 0x07:
 		system_rev |= 0x07;
 		system_rev |= 0x07;
 		break;
 		break;
+	case 0x03:
 	case 0x15:
 	case 0x15:
 		system_rev |= 0x15;
 		system_rev |= 0x15;
 		break;
 		break;

+ 8 - 5
arch/arm/mach-omap1/io.c

@@ -15,9 +15,10 @@
 
 
 #include <asm/mach/map.h>
 #include <asm/mach/map.h>
 #include <asm/io.h>
 #include <asm/io.h>
+#include <asm/arch/mux.h>
 #include <asm/arch/tc.h>
 #include <asm/arch/tc.h>
 
 
-extern int clk_init(void);
+extern int omap1_clk_init(void);
 extern void omap_check_revision(void);
 extern void omap_check_revision(void);
 extern void omap_sram_init(void);
 extern void omap_sram_init(void);
 
 
@@ -50,7 +51,7 @@ static struct map_desc omap730_io_desc[] __initdata = {
 };
 };
 #endif
 #endif
 
 
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 static struct map_desc omap1510_io_desc[] __initdata = {
 static struct map_desc omap1510_io_desc[] __initdata = {
 	{
 	{
 		.virtual	= OMAP1510_DSP_BASE,
 		.virtual	= OMAP1510_DSP_BASE,
@@ -98,7 +99,7 @@ static void __init _omap_map_io(void)
 		iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc));
 		iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc));
 	}
 	}
 #endif
 #endif
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
 	if (cpu_is_omap1510()) {
 		iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
 		iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
 	}
 	}
@@ -119,7 +120,7 @@ static void __init _omap_map_io(void)
 
 
 	/* Must init clocks early to assure that timer interrupt works
 	/* Must init clocks early to assure that timer interrupt works
 	 */
 	 */
-	clk_init();
+	omap1_clk_init();
 }
 }
 
 
 /*
 /*
@@ -127,7 +128,9 @@ static void __init _omap_map_io(void)
  */
  */
 void __init omap_map_common_io(void)
 void __init omap_map_common_io(void)
 {
 {
-	if (!initialized)
+	if (!initialized) {
 		_omap_map_io();
 		_omap_map_io();
+		omap1_mux_init();
+	}
 }
 }
 
 

+ 17 - 6
arch/arm/mach-omap1/irq.c

@@ -47,6 +47,7 @@
 #include <asm/irq.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/gpio.h>
+#include <asm/arch/cpu.h>
 
 
 #include <asm/io.h>
 #include <asm/io.h>
 
 
@@ -147,11 +148,15 @@ static struct omap_irq_bank omap730_irq_banks[] = {
 };
 };
 #endif
 #endif
 
 
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 static struct omap_irq_bank omap1510_irq_banks[] = {
 static struct omap_irq_bank omap1510_irq_banks[] = {
 	{ .base_reg = OMAP_IH1_BASE, 		.trigger_map = 0xb3febfff },
 	{ .base_reg = OMAP_IH1_BASE, 		.trigger_map = 0xb3febfff },
 	{ .base_reg = OMAP_IH2_BASE, 		.trigger_map = 0xffbfffed },
 	{ .base_reg = OMAP_IH2_BASE, 		.trigger_map = 0xffbfffed },
 };
 };
+static struct omap_irq_bank omap310_irq_banks[] = {
+	{ .base_reg = OMAP_IH1_BASE, 		.trigger_map = 0xb3faefc3 },
+	{ .base_reg = OMAP_IH2_BASE, 		.trigger_map = 0x65b3c061 },
+};
 #endif
 #endif
 
 
 #if defined(CONFIG_ARCH_OMAP16XX)
 #if defined(CONFIG_ARCH_OMAP16XX)
@@ -181,11 +186,15 @@ void __init omap_init_irq(void)
 		irq_bank_count = ARRAY_SIZE(omap730_irq_banks);
 		irq_bank_count = ARRAY_SIZE(omap730_irq_banks);
 	}
 	}
 #endif
 #endif
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
 	if (cpu_is_omap1510()) {
 		irq_banks = omap1510_irq_banks;
 		irq_banks = omap1510_irq_banks;
 		irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
 		irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
 	}
 	}
+	if (cpu_is_omap310()) {
+		irq_banks = omap310_irq_banks;
+		irq_bank_count = ARRAY_SIZE(omap310_irq_banks);
+	}
 #endif
 #endif
 #if defined(CONFIG_ARCH_OMAP16XX)
 #if defined(CONFIG_ARCH_OMAP16XX)
 	if (cpu_is_omap16xx()) {
 	if (cpu_is_omap16xx()) {
@@ -226,9 +235,11 @@ void __init omap_init_irq(void)
 	}
 	}
 
 
 	/* Unmask level 2 handler */
 	/* Unmask level 2 handler */
-	if (cpu_is_omap730()) {
+
+	if (cpu_is_omap730())
 		omap_unmask_irq(INT_730_IH2_IRQ);
 		omap_unmask_irq(INT_730_IH2_IRQ);
-	} else {
-		omap_unmask_irq(INT_IH2_IRQ);
-	}
+	else if (cpu_is_omap1510())
+		omap_unmask_irq(INT_1510_IH2_IRQ);
+	else if (cpu_is_omap16xx())
+		omap_unmask_irq(INT_1610_IH2_IRQ);
 }
 }

+ 34 - 9
arch/arm/mach-omap1/leds-h2p2-debug.c

@@ -18,6 +18,7 @@
 #include <asm/hardware.h>
 #include <asm/hardware.h>
 #include <asm/leds.h>
 #include <asm/leds.h>
 #include <asm/system.h>
 #include <asm/system.h>
+#include <asm/mach-types.h>
 
 
 #include <asm/arch/fpga.h>
 #include <asm/arch/fpga.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/gpio.h>
@@ -63,14 +64,19 @@ void h2p2_dbg_leds_event(led_event_t evt)
 	case led_stop:
 	case led_stop:
 	case led_halted:
 	case led_halted:
 		/* all leds off during suspend or shutdown */
 		/* all leds off during suspend or shutdown */
-		omap_set_gpio_dataout(GPIO_TIMER, 0);
-		omap_set_gpio_dataout(GPIO_IDLE, 0);
+
+		if (! machine_is_omap_perseus2()) {
+			omap_set_gpio_dataout(GPIO_TIMER, 0);
+			omap_set_gpio_dataout(GPIO_IDLE, 0);
+		}
+
 		__raw_writew(~0, &fpga->leds);
 		__raw_writew(~0, &fpga->leds);
 		led_state &= ~LED_STATE_ENABLED;
 		led_state &= ~LED_STATE_ENABLED;
 		if (evt == led_halted) {
 		if (evt == led_halted) {
 			iounmap(fpga);
 			iounmap(fpga);
 			fpga = NULL;
 			fpga = NULL;
 		}
 		}
+
 		goto done;
 		goto done;
 
 
 	case led_claim:
 	case led_claim:
@@ -85,18 +91,37 @@ void h2p2_dbg_leds_event(led_event_t evt)
 #ifdef CONFIG_LEDS_TIMER
 #ifdef CONFIG_LEDS_TIMER
 	case led_timer:
 	case led_timer:
 		led_state ^= LED_TIMER_ON;
 		led_state ^= LED_TIMER_ON;
-		omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON);
-		goto done;
+
+		if (machine_is_omap_perseus2())
+			hw_led_state ^= H2P2_DBG_FPGA_P2_LED_TIMER;
+		else {
+			omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON);
+			goto done;
+		}
+
+		break;
 #endif
 #endif
 
 
 #ifdef CONFIG_LEDS_CPU
 #ifdef CONFIG_LEDS_CPU
 	case led_idle_start:
 	case led_idle_start:
-		omap_set_gpio_dataout(GPIO_IDLE, 1);
-		goto done;
+		if (machine_is_omap_perseus2())
+			hw_led_state |= H2P2_DBG_FPGA_P2_LED_IDLE;
+		else {
+			omap_set_gpio_dataout(GPIO_IDLE, 1);
+			goto done;
+		}
+
+		break;
 
 
 	case led_idle_end:
 	case led_idle_end:
-		omap_set_gpio_dataout(GPIO_IDLE, 0);
-		goto done;
+		if (machine_is_omap_perseus2())
+			hw_led_state &= ~H2P2_DBG_FPGA_P2_LED_IDLE;
+		else {
+			omap_set_gpio_dataout(GPIO_IDLE, 0);
+			goto done;
+		}
+
+		break;
 #endif
 #endif
 
 
 	case led_green_on:
 	case led_green_on:
@@ -135,7 +160,7 @@ void h2p2_dbg_leds_event(led_event_t evt)
 	/*
 	/*
 	 *  Actually burn the LEDs
 	 *  Actually burn the LEDs
 	 */
 	 */
-	if (led_state & LED_STATE_CLAIMED)
+	if (led_state & LED_STATE_ENABLED)
 		__raw_writew(~hw_led_state, &fpga->leds);
 		__raw_writew(~hw_led_state, &fpga->leds);
 
 
 done:
 done:

+ 0 - 1
arch/arm/mach-omap1/leds.c

@@ -33,7 +33,6 @@ omap_leds_init(void)
 
 
 	if (machine_is_omap_h2()
 	if (machine_is_omap_h2()
 			|| machine_is_omap_h3()
 			|| machine_is_omap_h3()
-			|| machine_is_omap_perseus2()
 #ifdef	CONFIG_OMAP_OSK_MISTRAL
 #ifdef	CONFIG_OMAP_OSK_MISTRAL
 			|| machine_is_omap_osk()
 			|| machine_is_omap_osk()
 #endif
 #endif

+ 289 - 0
arch/arm/mach-omap1/mux.c

@@ -0,0 +1,289 @@
+/*
+ * linux/arch/arm/mach-omap1/mux.c
+ *
+ * OMAP1 pin multiplexing configurations
+ *
+ * Copyright (C) 2003 - 2005 Nokia Corporation
+ *
+ * Written by Tony Lindgren <tony.lindgren@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/arch/mux.h>
+
+#ifdef CONFIG_OMAP_MUX
+
+#ifdef CONFIG_ARCH_OMAP730
+struct pin_config __initdata_or_module omap730_pins[] = {
+MUX_CFG_730("E2_730_KBR0",	12,   21,    0,	  0,   20,   1,	  NA,	 0,  0)
+MUX_CFG_730("J7_730_KBR1",	12,   25,    0,	  0,   24,   1,	  NA,	 0,  0)
+MUX_CFG_730("E1_730_KBR2",	12,   29,    0,	  0,   28,   1,	  NA,	 0,  0)
+MUX_CFG_730("F3_730_KBR3",	13,    1,    0,	  0,   0,    1,	  NA,	 0,  0)
+MUX_CFG_730("D2_730_KBR4",	13,    5,    0,	  0,   4,    1,	  NA,	 0,  0)
+MUX_CFG_730("C2_730_KBC0",	13,    9,    0,	  0,	8,   1,	  NA,	 0,  0)
+MUX_CFG_730("D3_730_KBC1",	13,   13,    0,	  0,   12,   1,	  NA,	 0,  0)
+MUX_CFG_730("E4_730_KBC2",	13,   17,    0,	  0,   16,   1,	  NA,	 0,  0)
+MUX_CFG_730("F4_730_KBC3",	13,   21,    0,	  0,   20,   1,	  NA,	 0,  0)
+MUX_CFG_730("E3_730_KBC4",	13,   25,    0,	  0,   24,   1,	  NA,	 0,  0)
+};
+#endif
+
+#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
+struct pin_config __initdata_or_module omap1xxx_pins[] = {
+/*
+ *	 description		mux  mode   mux	 pull pull  pull  pu_pd	 pu  dbg
+ *				reg  offset mode reg  bit   ena	  reg
+ */
+MUX_CFG("UART1_TX",		 9,   21,    1,	  2,   3,   0,	 NA,	 0,  0)
+MUX_CFG("UART1_RTS",		 9,   12,    1,	  2,   0,   0,	 NA,	 0,  0)
+
+/* UART2 (COM_UART_GATING), conflicts with USB2 */
+MUX_CFG("UART2_TX",		 C,   27,    1,	  3,   3,   0,	 NA,	 0,  0)
+MUX_CFG("UART2_RX",		 C,   18,    0,	  3,   1,   1,	 NA,	 0,  0)
+MUX_CFG("UART2_CTS",		 C,   21,    0,	  3,   1,   1,	 NA,	 0,  0)
+MUX_CFG("UART2_RTS",		 C,   24,    1,	  3,   2,   0,	 NA,	 0,  0)
+
+/* UART3 (GIGA_UART_GATING) */
+MUX_CFG("UART3_TX",		 6,    0,    1,	  0,  30,   0,	 NA,	 0,  0)
+MUX_CFG("UART3_RX",		 6,    3,    0,	  0,  31,   1,	 NA,	 0,  0)
+MUX_CFG("UART3_CTS",		 5,   12,    2,	  0,  24,   0,	 NA,	 0,  0)
+MUX_CFG("UART3_RTS",		 5,   15,    2,	  0,  25,   0,	 NA,	 0,  0)
+MUX_CFG("UART3_CLKREQ",		 9,   27,    0,	  2,   5,   0,	 NA,	 0,  0)
+MUX_CFG("UART3_BCLK",		 A,    0,    0,	  2,   6,   0,	 NA,	 0,  0)
+MUX_CFG("Y15_1610_UART3_RTS",	 A,    0,    1,	  2,   6,   0,	 NA,	 0,  0)
+
+/* PWT & PWL, conflicts with UART3 */
+MUX_CFG("PWT",		 	 6,    0,    2,	  0,  30,   0,	 NA,	 0,  0)
+MUX_CFG("PWL",		 	 6,    3,    1,	  0,  31,   1,	 NA,	 0,  0)
+
+/* USB internal master generic */
+MUX_CFG("R18_USB_VBUS",		 7,    9,    2,	  1,  11,   0,	 NA,	 0,  1)
+MUX_CFG("R18_1510_USB_GPIO0",	 7,    9,    0,	  1,  11,   1,	 NA,	 0,  1)
+/* works around erratum:  W4_USB_PUEN and W4_USB_PUDIS are switched! */
+MUX_CFG("W4_USB_PUEN",		 D,    3,    3,	  3,   5,   1,	 NA,	 0,  1)
+MUX_CFG("W4_USB_CLKO",		 D,    3,    1,	  3,   5,   0,	 NA,	 0,  1)
+MUX_CFG("W4_USB_HIGHZ",		 D,    3,    4,	  3,   5,   0,	  3,	 0,  1)
+MUX_CFG("W4_GPIO58",		 D,    3,    7,	  3,   5,   0,	  3,	 0,  1)
+
+/* USB1 master */
+MUX_CFG("USB1_SUSP",		 8,   27,    2,	  1,  27,   0,	 NA,	 0,  1)
+MUX_CFG("USB1_SE0",		 9,    0,    2,	  1,  28,   0,	 NA,	 0,  1)
+MUX_CFG("W13_1610_USB1_SE0",	 9,    0,    4,	  1,  28,   0,	 NA,	 0,  1)
+MUX_CFG("USB1_TXEN",		 9,    3,    2,	  1,  29,   0,	 NA,	 0,  1)
+MUX_CFG("USB1_TXD",		 9,   24,    1,	  2,   4,   0,	 NA,	 0,  1)
+MUX_CFG("USB1_VP",		 A,    3,    1,	  2,   7,   0,	 NA,	 0,  1)
+MUX_CFG("USB1_VM",		 A,    6,    1,	  2,   8,   0,	 NA,	 0,  1)
+MUX_CFG("USB1_RCV",		 A,    9,    1,	  2,   9,   0,	 NA,	 0,  1)
+MUX_CFG("USB1_SPEED",		 A,   12,    2,	  2,  10,   0,	 NA,	 0,  1)
+MUX_CFG("R13_1610_USB1_SPEED",	 A,   12,    5,	  2,  10,   0,	 NA,	 0,  1)
+MUX_CFG("R13_1710_USB1_SEO",	 A,   12,    5,   2,  10,   0,   NA,     0,  1)
+
+/* USB2 master */
+MUX_CFG("USB2_SUSP",		 B,    3,    1,	  2,  17,   0,	 NA,	 0,  1)
+MUX_CFG("USB2_VP",		 B,    6,    1,	  2,  18,   0,	 NA,	 0,  1)
+MUX_CFG("USB2_TXEN",		 B,    9,    1,	  2,  19,   0,	 NA,	 0,  1)
+MUX_CFG("USB2_VM",		 C,   18,    1,	  3,   0,   0,	 NA,	 0,  1)
+MUX_CFG("USB2_RCV",		 C,   21,    1,	  3,   1,   0,	 NA,	 0,  1)
+MUX_CFG("USB2_SE0",		 C,   24,    2,	  3,   2,   0,	 NA,	 0,  1)
+MUX_CFG("USB2_TXD",		 C,   27,    2,	  3,   3,   0,	 NA,	 0,  1)
+
+/* OMAP-1510 GPIO */
+MUX_CFG("R18_1510_GPIO0",	 7,    9,    0,   1,  11,   1,    0,     0,  1)
+MUX_CFG("R19_1510_GPIO1",	 7,    6,    0,   1,  10,   1,    0,     0,  1)
+MUX_CFG("M14_1510_GPIO2",	 7,    3,    0,   1,   9,   1,    0,     0,  1)
+
+/* OMAP1610 GPIO */
+MUX_CFG("P18_1610_GPIO3",	 7,    0,    0,   1,   8,   0,   NA,     0,  1)
+MUX_CFG("Y15_1610_GPIO17",	 A,    0,    7,   2,   6,   0,   NA,     0,  1)
+
+/* OMAP-1710 GPIO */
+MUX_CFG("R18_1710_GPIO0",        7,    9,    0,   1,  11,   1,    1,     1,  1)
+MUX_CFG("V2_1710_GPIO10",        F,   27,    1,   4,   3,   1,    4,     1,  1)
+MUX_CFG("N21_1710_GPIO14",       6,    9,    0,   1,   1,   1,    1,     1,  1)
+MUX_CFG("W15_1710_GPIO40",       9,   27,    7,   2,   5,   1,    2,     1,  1)
+
+/* MPUIO */
+MUX_CFG("MPUIO2",		 7,   18,    0,	  1,  14,   1,	 NA,	 0,  1)
+MUX_CFG("N15_1610_MPUIO2",	 7,   18,    0,	  1,  14,   1,	  1,	 0,  1)
+MUX_CFG("MPUIO4",		 7,   15,    0,	  1,  13,   1,	 NA,	 0,  1)
+MUX_CFG("MPUIO5",		 7,   12,    0,	  1,  12,   1,	 NA,	 0,  1)
+
+MUX_CFG("T20_1610_MPUIO5",	 7,   12,    0,	  1,  12,   0,	  3,	 0,  1)
+MUX_CFG("W11_1610_MPUIO6",	10,   15,    2,	  3,   8,   0,	  3,	 0,  1)
+MUX_CFG("V10_1610_MPUIO7",	 A,   24,    2,	  2,  14,   0,	  2,	 0,  1)
+MUX_CFG("W11_1610_MPUIO9",	10,   15,    1,	  3,   8,   0,	  3,	 0,  1)
+MUX_CFG("V10_1610_MPUIO10",	 A,   24,    1,	  2,  14,   0,	  2,	 0,  1)
+MUX_CFG("W10_1610_MPUIO11",	 A,   18,    2,	  2,  11,   0,	  2,	 0,  1)
+MUX_CFG("E20_1610_MPUIO13",	 3,   21,    1,	  0,   7,   0,	  0,	 0,  1)
+MUX_CFG("U20_1610_MPUIO14",	 9,    6,    6,	  0,  30,   0,	  0,	 0,  1)
+MUX_CFG("E19_1610_MPUIO15",	 3,   18,    1,	  0,   6,   0,	  0,	 0,  1)
+
+/* MCBSP2 */
+MUX_CFG("MCBSP2_CLKR",		 C,    6,    0,	  2,  27,   1,	 NA,	 0,  1)
+MUX_CFG("MCBSP2_CLKX",		 C,    9,    0,	  2,  29,   1,	 NA,	 0,  1)
+MUX_CFG("MCBSP2_DR",		 C,    0,    0,	  2,  26,   1,	 NA,	 0,  1)
+MUX_CFG("MCBSP2_DX",		 C,   15,    0,	  2,  31,   1,	 NA,	 0,  1)
+MUX_CFG("MCBSP2_FSR",		 C,   12,    0,	  2,  30,   1,	 NA,	 0,  1)
+MUX_CFG("MCBSP2_FSX",		 C,    3,    0,	  2,  27,   1,	 NA,	 0,  1)
+
+/* MCBSP3 NOTE: Mode must 1 for clock */
+MUX_CFG("MCBSP3_CLKX",		 9,    3,    1,	  1,  29,   0,	 NA,	 0,  1)
+
+/* Misc ballouts */
+MUX_CFG("BALLOUT_V8_ARMIO3",	 B,   18,    0,	  2,  25,   1,	 NA,	 0,  1)
+MUX_CFG("N20_HDQ",	       6,   18,    1,   1,   4,   0,    1,     4,  0)
+
+/* OMAP-1610 MMC2 */
+MUX_CFG("W8_1610_MMC2_DAT0",	 B,   21,    6,	  2,  23,   1,	  2,	 1,  1)
+MUX_CFG("V8_1610_MMC2_DAT1",	 B,   27,    6,	  2,  25,   1,	  2,	 1,  1)
+MUX_CFG("W15_1610_MMC2_DAT2",	 9,   12,    6,	  2,   5,   1,	  2,	 1,  1)
+MUX_CFG("R10_1610_MMC2_DAT3",	 B,   18,    6,	  2,  22,   1,	  2,	 1,  1)
+MUX_CFG("Y10_1610_MMC2_CLK",	 B,    3,    6,	  2,  17,   0,	  2,	 0,  1)
+MUX_CFG("Y8_1610_MMC2_CMD",	 B,   24,    6,	  2,  24,   1,	  2,	 1,  1)
+MUX_CFG("V9_1610_MMC2_CMDDIR",	 B,   12,    6,	  2,  20,   0,	  2,	 1,  1)
+MUX_CFG("V5_1610_MMC2_DATDIR0",	 B,   15,    6,	  2,  21,   0,	  2,	 1,  1)
+MUX_CFG("W19_1610_MMC2_DATDIR1", 8,   15,    6,	  1,  23,   0,	  1,	 1,  1)
+MUX_CFG("R18_1610_MMC2_CLKIN",	 7,    9,    6,	  1,  11,   0,	  1,	11,  1)
+
+/* OMAP-1610 External Trace Interface */
+MUX_CFG("M19_1610_ETM_PSTAT0",	 5,   27,    1,	  0,  29,   0,	  0,	 0,  1)
+MUX_CFG("L15_1610_ETM_PSTAT1",	 5,   24,    1,	  0,  28,   0,	  0,	 0,  1)
+MUX_CFG("L18_1610_ETM_PSTAT2",	 5,   21,    1,	  0,  27,   0,	  0,	 0,  1)
+MUX_CFG("L19_1610_ETM_D0",	 5,   18,    1,	  0,  26,   0,	  0,	 0,  1)
+MUX_CFG("J19_1610_ETM_D6",	 5,    0,    1,	  0,  20,   0,	  0,	 0,  1)
+MUX_CFG("J18_1610_ETM_D7",	 5,   27,    1,	  0,  19,   0,	  0,	 0,  1)
+
+/* OMAP16XX GPIO */
+MUX_CFG("P20_1610_GPIO4",	 6,   27,    0,	  1,   7,   0,	  1,	 1,  1)
+MUX_CFG("V9_1610_GPIO7",	 B,   12,    1,	  2,  20,   0,	  2,	 1,  1)
+MUX_CFG("W8_1610_GPIO9",	 B,   21,    0,	  2,  23,   0,	  2,	 1,  1)
+MUX_CFG("N20_1610_GPIO11",       6,   18,    0,   1,   4,   0,    1,     1,  1)
+MUX_CFG("N19_1610_GPIO13",	 6,   12,    0,	  1,   2,   0,	  1,	 1,  1)
+MUX_CFG("P10_1610_GPIO22",	 C,    0,    7,	  2,  26,   0,	  2,	 1,  1)
+MUX_CFG("V5_1610_GPIO24",	 B,   15,    7,	  2,  21,   0,	  2,	 1,  1)
+MUX_CFG("AA20_1610_GPIO_41",	 9,    9,    7,	  1,  31,   0,	  1,	 1,  1)
+MUX_CFG("W19_1610_GPIO48",	 8,   15,    7,   1,  23,   1,    1,     0,  1)
+MUX_CFG("M7_1610_GPIO62",	10,    0,    0,   4,  24,   0,    4,     0,  1)
+MUX_CFG("V14_16XX_GPIO37",	 9,   18,    7,	  2,   2,   0,	  2,	 2,  0)
+MUX_CFG("R9_16XX_GPIO18",	 C,   18,    7,   3,   0,   0,    3,     0,  0)
+MUX_CFG("L14_16XX_GPIO49",	 6,    3,    7,   0,  31,   0,    0,    31,  0)
+
+/* OMAP-1610 uWire */
+MUX_CFG("V19_1610_UWIRE_SCLK",	 8,    6,    0,	  1,  20,   0,	  1,	 1,  1)
+MUX_CFG("U18_1610_UWIRE_SDI",	 8,    0,    0,	  1,  18,   0,	  1,	 1,  1)
+MUX_CFG("W21_1610_UWIRE_SDO",	 8,    3,    0,	  1,  19,   0,	  1,	 1,  1)
+MUX_CFG("N14_1610_UWIRE_CS0",	 8,    9,    1,	  1,  21,   0,	  1,	 1,  1)
+MUX_CFG("P15_1610_UWIRE_CS3",	 8,   12,    1,	  1,  22,   0,	  1,	 1,  1)
+MUX_CFG("N15_1610_UWIRE_CS1",	 7,   18,    2,	  1,  14,   0,	 NA,	 0,  1)
+
+/* OMAP-1610 Flash */
+MUX_CFG("L3_1610_FLASH_CS2B_OE",10,    6,    1,	 NA,   0,   0,	 NA,	 0,  1)
+MUX_CFG("M8_1610_FLASH_CS2B_WE",10,    3,    1,	 NA,   0,   0,	 NA,	 0,  1)
+
+/* First MMC interface, same on 1510, 1610 and 1710 */
+MUX_CFG("MMC_CMD",		 A,   27,    0,	  2,  15,   1,	  2,	 1,  1)
+MUX_CFG("MMC_DAT1",		 A,   24,    0,	  2,  14,   1,	  2,	 1,  1)
+MUX_CFG("MMC_DAT2",		 A,   18,    0,	  2,  12,   1,	  2,	 1,  1)
+MUX_CFG("MMC_DAT0",		 B,    0,    0,	  2,  16,   1,	  2,	 1,  1)
+MUX_CFG("MMC_CLK",		 A,   21,    0,	 NA,   0,   0,	 NA,	 0,  1)
+MUX_CFG("MMC_DAT3",		10,   15,    0,	  3,   8,   1,	  3,	 1,  1)
+MUX_CFG("M15_1710_MMC_CLKI",	 6,   21,    2,   0,   0,   0,   NA,     0,  1)
+MUX_CFG("P19_1710_MMC_CMDDIR",	 6,   24,    6,   0,   0,   0,   NA,     0,  1)
+MUX_CFG("P20_1710_MMC_DATDIR0",	 6,   27,    5,   0,   0,   0,   NA,     0,  1)
+
+/* OMAP-1610 USB0 alternate configuration */
+MUX_CFG("W9_USB0_TXEN",		 B,   9,     5,	  2,  19,   0,	  2,	 0,  1)
+MUX_CFG("AA9_USB0_VP",		 B,   6,     5,	  2,  18,   0,	  2,	 0,  1)
+MUX_CFG("Y5_USB0_RCV",		 C,  21,     5,	  3,   1,   0,	  1,	 0,  1)
+MUX_CFG("R9_USB0_VM",		 C,  18,     5,	  3,   0,   0,	  3,	 0,  1)
+MUX_CFG("V6_USB0_TXD",		 C,  27,     5,	  3,   3,   0,	  3,	 0,  1)
+MUX_CFG("W5_USB0_SE0",		 C,  24,     5,	  3,   2,   0,	  3,	 0,  1)
+MUX_CFG("V9_USB0_SPEED",	 B,  12,     5,	  2,  20,   0,	  2,	 0,  1)
+MUX_CFG("Y10_USB0_SUSP",	 B,   3,     5,	  2,  17,   0,	  2,	 0,  1)
+
+/* USB2 interface */
+MUX_CFG("W9_USB2_TXEN",		 B,   9,     1,	 NA,   0,   0,	 NA,	 0,  1)
+MUX_CFG("AA9_USB2_VP",		 B,   6,     1,	 NA,   0,   0,	 NA,	 0,  1)
+MUX_CFG("Y5_USB2_RCV",		 C,  21,     1,	 NA,   0,   0,	 NA,	 0,  1)
+MUX_CFG("R9_USB2_VM",		 C,  18,     1,	 NA,   0,   0,	 NA,	 0,  1)
+MUX_CFG("V6_USB2_TXD",		 C,  27,     2,	 NA,   0,   0,	 NA,	 0,  1)
+MUX_CFG("W5_USB2_SE0",		 C,  24,     2,	 NA,   0,   0,	 NA,	 0,  1)
+
+/* 16XX UART */
+MUX_CFG("R13_1610_UART1_TX",	 A,  12,     6,	  2,  10,   0,	  2,	10,  1)
+MUX_CFG("V14_16XX_UART1_RX",	 9,  18,     0,	  2,   2,   0,	  2,	 2,  1)
+MUX_CFG("R14_1610_UART1_CTS",	 9,  15,     0,	  2,   1,   0,	  2,	 1,  1)
+MUX_CFG("AA15_1610_UART1_RTS",	 9,  12,     1,	  2,   0,   0,	  2,	 0,  1)
+MUX_CFG("R9_16XX_UART2_RX",	 C,  18,     0,   3,   0,   0,    3,     0,  1)
+MUX_CFG("L14_16XX_UART3_RX",	 6,   3,     0,   0,  31,   0,    0,    31,  1)
+
+/* I2C interface */
+MUX_CFG("I2C_SCL",		 7,  24,     0,	 NA,   0,   0,	 NA,	 0,  0)
+MUX_CFG("I2C_SDA",		 7,  27,     0,	 NA,   0,   0,	 NA,	 0,  0)
+
+/* Keypad */
+MUX_CFG("F18_1610_KBC0",	 3,  15,     0,	  0,   5,   1,	  0,	 0,  0)
+MUX_CFG("D20_1610_KBC1",	 3,  12,     0,	  0,   4,   1,	  0,	 0,  0)
+MUX_CFG("D19_1610_KBC2",	 3,   9,     0,	  0,   3,   1,	  0,	 0,  0)
+MUX_CFG("E18_1610_KBC3",	 3,   6,     0,	  0,   2,   1,	  0,	 0,  0)
+MUX_CFG("C21_1610_KBC4",	 3,   3,     0,	  0,   1,   1,	  0,	 0,  0)
+MUX_CFG("G18_1610_KBR0",	 4,   0,     0,	  0,   10,  1,	  0,	 1,  0)
+MUX_CFG("F19_1610_KBR1",	 3,   27,    0,	  0,   9,   1,	  0,	 1,  0)
+MUX_CFG("H14_1610_KBR2",	 3,   24,    0,	  0,   8,   1,	  0,	 1,  0)
+MUX_CFG("E20_1610_KBR3",	 3,   21,    0,	  0,   7,   1,	  0,	 1,  0)
+MUX_CFG("E19_1610_KBR4",	 3,   18,    0,	  0,   6,   1,	  0,	 1,  0)
+MUX_CFG("N19_1610_KBR5",	 6,  12,     1,	  1,   2,   1,	  1,	 1,  0)
+
+/* Power management */
+MUX_CFG("T20_1610_LOW_PWR",	 7,   12,    1,	  NA,   0,   0,   NA,	 0,  0)
+
+/* MCLK Settings */
+MUX_CFG("V5_1710_MCLK_ON",	 B,   15,    0,	  NA,   0,   0,   NA,	 0,  0)
+MUX_CFG("V5_1710_MCLK_OFF",	 B,   15,    6,	  NA,   0,   0,   NA,	 0,  0)
+MUX_CFG("R10_1610_MCLK_ON",	 B,   18,    0,	  NA,  22,   0,	  NA,	 1,  0)
+MUX_CFG("R10_1610_MCLK_OFF",	 B,   18,    6,	  2,   22,   1,	  2,	 1,  1)
+
+/* CompactFlash controller, conflicts with MMC1 */
+MUX_CFG("P11_1610_CF_CD2",	 A,   27,    3,	  2,   15,   1,	  2,	 1,  1)
+MUX_CFG("R11_1610_CF_IOIS16",	 B,    0,    3,	  2,   16,   1,	  2,	 1,  1)
+MUX_CFG("V10_1610_CF_IREQ",	 A,   24,    3,	  2,   14,   0,	  2,	 0,  1)
+MUX_CFG("W10_1610_CF_RESET",	 A,   18,    3,	  2,   12,   1,	  2,	 1,  1)
+MUX_CFG("W11_1610_CF_CD1",	10,   15,    3,	  3,    8,   1,	  3,	 1,  1)
+};
+#endif	/* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */
+
+int __init omap1_mux_init(void)
+{
+
+#ifdef CONFIG_ARCH_OMAP730
+	omap_mux_register(omap730_pins, ARRAY_SIZE(omap730_pins));
+#endif
+
+#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
+	omap_mux_register(omap1xxx_pins, ARRAY_SIZE(omap1xxx_pins));
+#endif
+
+	return 0;
+}
+
+#endif

+ 7 - 2
arch/arm/mach-omap1/serial.c

@@ -109,9 +109,10 @@ static struct platform_device serial_device = {
  * By default UART2 does not work on Innovator-1510 if you have
  * By default UART2 does not work on Innovator-1510 if you have
  * USB OHCI enabled. To use UART2, you must disable USB2 first.
  * USB OHCI enabled. To use UART2, you must disable USB2 first.
  */
  */
-void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
+void __init omap_serial_init(void)
 {
 {
 	int i;
 	int i;
+	const struct omap_uart_config *info;
 
 
 	if (cpu_is_omap730()) {
 	if (cpu_is_omap730()) {
 		serial_platform_data[0].regshift = 0;
 		serial_platform_data[0].regshift = 0;
@@ -126,10 +127,14 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
 		serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
 		serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
 	}
 	}
 
 
+	info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
+	if (info == NULL)
+		return;
+
 	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
 	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
 		unsigned char reg;
 		unsigned char reg;
 
 
-		if (ports[i] == 0) {
+		if (!((1 << i) & info->enabled_uarts)) {
 			serial_platform_data[i].membase = NULL;
 			serial_platform_data[i].membase = NULL;
 			serial_platform_data[i].mapbase = 0;
 			serial_platform_data[i].mapbase = 0;
 			continue;
 			continue;

+ 2 - 2
arch/arm/mach-omap1/time.c

@@ -226,8 +226,8 @@ unsigned long long sched_clock(void)
 
 
 #ifdef CONFIG_OMAP_32K_TIMER
 #ifdef CONFIG_OMAP_32K_TIMER
 
 
-#ifdef CONFIG_ARCH_OMAP1510
-#error OMAP 32KHz timer does not currently work on 1510!
+#ifdef CONFIG_ARCH_OMAP15XX
+#error OMAP 32KHz timer does not currently work on 15XX!
 #endif
 #endif
 
 
 /*
 /*

+ 22 - 0
arch/arm/mach-omap2/Kconfig

@@ -0,0 +1,22 @@
+comment "OMAP Core Type"
+	depends on ARCH_OMAP2
+
+config ARCH_OMAP24XX
+	bool "OMAP24xx Based System"
+	depends on ARCH_OMAP2
+
+config ARCH_OMAP2420
+	bool "OMAP2420 support"
+	depends on ARCH_OMAP24XX
+
+comment "OMAP Board Type"
+	depends on ARCH_OMAP2
+
+config MACH_OMAP_GENERIC
+	bool "Generic OMAP board"
+	depends on ARCH_OMAP2 && ARCH_OMAP24XX
+
+config MACH_OMAP_H4
+	bool "OMAP 2420 H4 board"
+	depends on ARCH_OMAP2 && ARCH_OMAP24XX
+

+ 13 - 0
arch/arm/mach-omap2/Makefile

@@ -0,0 +1,13 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := irq.o id.o io.o sram-fn.o clock.o mux.o devices.o serial.o
+
+obj-$(CONFIG_OMAP_MPU_TIMER)		+= timer-gp.o
+
+# Specific board support
+obj-$(CONFIG_MACH_OMAP_GENERIC)		+= board-generic.o
+obj-$(CONFIG_MACH_OMAP_H4)		+= board-h4.o
+

+ 3 - 0
arch/arm/mach-omap2/Makefile.boot

@@ -0,0 +1,3 @@
+  zreladdr-y		:= 0x80008000
+params_phys-y		:= 0x80000100
+initrd_phys-y		:= 0x80800000

+ 80 - 0
arch/arm/mach-omap2/board-generic.c

@@ -0,0 +1,80 @@
+/*
+ * linux/arch/arm/mach-omap/omap2/board-generic.c
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * Modified from mach-omap/omap1/board-generic.c
+ *
+ * Code for generic OMAP2 board. Should work on many OMAP2 systems where
+ * the bootloader passes the board-specific data to the kernel.
+ * Do not put any board specific code to this file; create a new machine
+ * type if you need custom low-level initializations.
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/board.h>
+#include <asm/arch/common.h>
+
+static void __init omap_generic_init_irq(void)
+{
+	omap_init_irq();
+}
+
+static struct omap_uart_config generic_uart_config __initdata = {
+	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_mmc_config generic_mmc_config __initdata = {
+	.mmc [0] = {
+		.enabled 	= 0,
+		.wire4		= 0,
+		.wp_pin		= -1,
+		.power_pin	= -1,
+		.switch_pin	= -1,
+	},
+};
+
+static struct omap_board_config_kernel generic_config[] = {
+	{ OMAP_TAG_UART,	&generic_uart_config },
+	{ OMAP_TAG_MMC,		&generic_mmc_config },
+};
+
+static void __init omap_generic_init(void)
+{
+	omap_board_config = generic_config;
+	omap_board_config_size = ARRAY_SIZE(generic_config);
+	omap_serial_init();
+}
+
+static void __init omap_generic_map_io(void)
+{
+	omap_map_common_io();
+}
+
+MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
+	/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
+	.phys_ram	= 0x80000000,
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= omap_generic_map_io,
+	.init_irq	= omap_generic_init_irq,
+	.init_machine	= omap_generic_init,
+	.timer		= &omap_timer,
+MACHINE_END

+ 197 - 0
arch/arm/mach-omap2/board-h4.c

@@ -0,0 +1,197 @@
+/*
+ * linux/arch/arm/mach-omap/omap2/board-h4.c
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * Modified from mach-omap/omap1/board-generic.c
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/delay.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/board.h>
+#include <asm/arch/common.h>
+#include <asm/arch/prcm.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+
+static struct mtd_partition h4_partitions[] = {
+	/* bootloader (U-Boot, etc) in first sector */
+	{
+	      .name		= "bootloader",
+	      .offset		= 0,
+	      .size		= SZ_128K,
+	      .mask_flags	= MTD_WRITEABLE, /* force read-only */
+	},
+	/* bootloader params in the next sector */
+	{
+	      .name		= "params",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_128K,
+	      .mask_flags	= 0,
+	},
+	/* kernel */
+	{
+	      .name		= "kernel",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_2M,
+	      .mask_flags	= 0
+	},
+	/* file system */
+	{
+	      .name		= "filesystem",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= MTDPART_SIZ_FULL,
+	      .mask_flags	= 0
+	}
+};
+
+static struct flash_platform_data h4_flash_data = {
+	.map_name	= "cfi_probe",
+	.width		= 2,
+	.parts		= h4_partitions,
+	.nr_parts	= ARRAY_SIZE(h4_partitions),
+};
+
+static struct resource h4_flash_resource = {
+	.start		= H4_CS0_BASE,
+	.end		= H4_CS0_BASE + SZ_64M - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device h4_flash_device = {
+	.name		= "omapflash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &h4_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &h4_flash_resource,
+};
+
+static struct resource h4_smc91x_resources[] = {
+	[0] = {
+		.start  = OMAP24XX_ETHR_START,          /* Physical */
+		.end    = OMAP24XX_ETHR_START + 0xf,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
+		.end    = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device h4_smc91x_device = {
+	.name		= "smc91x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(h4_smc91x_resources),
+	.resource	= h4_smc91x_resources,
+};
+
+static struct platform_device *h4_devices[] __initdata = {
+	&h4_smc91x_device,
+	&h4_flash_device,
+};
+
+static inline void __init h4_init_smc91x(void)
+{
+	/* Make sure CS1 timings are correct */
+	GPMC_CONFIG1_1 = 0x00011200;
+	GPMC_CONFIG2_1 = 0x001f1f01;
+	GPMC_CONFIG3_1 = 0x00080803;
+	GPMC_CONFIG4_1 = 0x1c091c09;
+	GPMC_CONFIG5_1 = 0x041f1f1f;
+	GPMC_CONFIG6_1 = 0x000004c4;
+	GPMC_CONFIG7_1 = 0x00000f40 | (0x08000000 >> 24);
+	udelay(100);
+
+	omap_cfg_reg(M15_24XX_GPIO92);
+	if (omap_request_gpio(OMAP24XX_ETHR_GPIO_IRQ) < 0) {
+		printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
+			OMAP24XX_ETHR_GPIO_IRQ);
+		return;
+	}
+	omap_set_gpio_direction(OMAP24XX_ETHR_GPIO_IRQ, 1);
+}
+
+static void __init omap_h4_init_irq(void)
+{
+	omap_init_irq();
+	omap_gpio_init();
+	h4_init_smc91x();
+}
+
+static struct omap_uart_config h4_uart_config __initdata = {
+	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_mmc_config h4_mmc_config __initdata = {
+	.mmc [0] = {
+		.enabled	= 1,
+		.wire4		= 1,
+		.wp_pin		= -1,
+		.power_pin	= -1,
+		.switch_pin	= -1,
+	},
+};
+
+static struct omap_lcd_config h4_lcd_config __initdata = {
+	.panel_name	= "h4",
+	.ctrl_name	= "internal",
+};
+
+static struct omap_board_config_kernel h4_config[] = {
+	{ OMAP_TAG_UART,	&h4_uart_config },
+	{ OMAP_TAG_MMC,		&h4_mmc_config },
+	{ OMAP_TAG_LCD,		&h4_lcd_config },
+};
+
+static void __init omap_h4_init(void)
+{
+	/*
+	 * Make sure the serial ports are muxed on at this point.
+	 * You have to mux them off in device drivers later on
+	 * if not needed.
+	 */
+	platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
+	omap_board_config = h4_config;
+	omap_board_config_size = ARRAY_SIZE(h4_config);
+	omap_serial_init();
+}
+
+static void __init omap_h4_map_io(void)
+{
+	omap_map_common_io();
+}
+
+MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
+	/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
+	.phys_ram	= 0x80000000,
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= omap_h4_map_io,
+	.init_irq	= omap_h4_init_irq,
+	.init_machine	= omap_h4_init,
+	.timer		= &omap_timer,
+MACHINE_END

+ 1129 - 0
arch/arm/mach-omap2/clock.c

@@ -0,0 +1,1129 @@
+/*
+ *  linux/arch/arm/mach-omap2/clock.c
+ *
+ *  Copyright (C) 2005 Texas Instruments Inc.
+ *  Richard Woodruff <r-woodruff2@ti.com>
+ *  Created for OMAP2.
+ *
+ *  Cleaned up and modified to use omap shared clock framework by
+ *  Tony Lindgren <tony@atomide.com>
+ *
+ *  Based on omap1 clock.c, Copyright (C) 2004 - 2005 Nokia corporation
+ *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+
+#include <asm/hardware/clock.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sram.h>
+#include <asm/arch/prcm.h>
+
+#include "clock.h"
+
+//#define DOWN_VARIABLE_DPLL 1			/* Experimental */
+
+static struct prcm_config *curr_prcm_set;
+static struct memory_timings mem_timings;
+static u32 curr_perf_level = PRCM_FULL_SPEED;
+
+/*-------------------------------------------------------------------------
+ * Omap2 specific clock functions
+ *-------------------------------------------------------------------------*/
+
+/* Recalculate SYST_CLK */
+static void omap2_sys_clk_recalc(struct clk * clk)
+{
+	u32 div = PRCM_CLKSRC_CTRL;
+	div &= (1 << 7) | (1 << 6);	/* Test if ext clk divided by 1 or 2 */
+	div >>= clk->rate_offset;
+	clk->rate = (clk->parent->rate / div);
+	propagate_rate(clk);
+}
+
+static u32 omap2_get_dpll_rate(struct clk * tclk)
+{
+	int dpll_clk, dpll_mult, dpll_div, amult;
+
+	dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff;	/* 10 bits */
+	dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f;	/* 4 bits */
+	dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1);
+	amult = CM_CLKSEL2_PLL & 0x3;
+	dpll_clk *= amult;
+
+	return dpll_clk;
+}
+
+static void omap2_followparent_recalc(struct clk *clk)
+{
+	followparent_recalc(clk);
+}
+
+static void omap2_propagate_rate(struct clk * clk)
+{
+	if (!(clk->flags & RATE_FIXED))
+		clk->rate = clk->parent->rate;
+
+	propagate_rate(clk);
+}
+
+/* Enable an APLL if off */
+static void omap2_clk_fixed_enable(struct clk *clk)
+{
+	u32 cval, i=0;
+
+	if (clk->enable_bit == 0xff)			/* Parent will do it */
+		return;
+
+	cval = CM_CLKEN_PLL;
+
+	if ((cval & (0x3 << clk->enable_bit)) == (0x3 << clk->enable_bit))
+		return;
+
+	cval &= ~(0x3 << clk->enable_bit);
+	cval |= (0x3 << clk->enable_bit);
+	CM_CLKEN_PLL = cval;
+
+	if (clk == &apll96_ck)
+		cval = (1 << 8);
+	else if (clk == &apll54_ck)
+		cval = (1 << 6);
+
+	while (!CM_IDLEST_CKGEN & cval) {		/* Wait for lock */
+		++i;
+		udelay(1);
+		if (i == 100000)
+			break;
+	}
+}
+
+/* Enables clock without considering parent dependencies or use count
+ * REVISIT: Maybe change this to use clk->enable like on omap1?
+ */
+static int omap2_clk_enable(struct clk * clk)
+{
+	u32 regval32;
+
+	if (clk->flags & ALWAYS_ENABLED)
+		return 0;
+
+	if (unlikely(clk->enable_reg == 0)) {
+		printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
+		       clk->name);
+		return 0;
+	}
+
+	if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) {
+		omap2_clk_fixed_enable(clk);
+		return 0;
+	}
+
+	regval32 = __raw_readl(clk->enable_reg);
+	regval32 |= (1 << clk->enable_bit);
+	__raw_writel(regval32, clk->enable_reg);
+
+	return 0;
+}
+
+/* Stop APLL */
+static void omap2_clk_fixed_disable(struct clk *clk)
+{
+	u32 cval;
+
+	if(clk->enable_bit == 0xff)		/* let parent off do it */
+		return;
+
+	cval = CM_CLKEN_PLL;
+	cval &= ~(0x3 << clk->enable_bit);
+	CM_CLKEN_PLL = cval;
+}
+
+/* Disables clock without considering parent dependencies or use count */
+static void omap2_clk_disable(struct clk *clk)
+{
+	u32 regval32;
+
+	if (clk->enable_reg == 0)
+		return;
+
+	if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) {
+		omap2_clk_fixed_disable(clk);
+		return;
+	}
+
+	regval32 = __raw_readl(clk->enable_reg);
+	regval32 &= ~(1 << clk->enable_bit);
+	__raw_writel(regval32, clk->enable_reg);
+}
+
+static int omap2_clk_use(struct clk *clk)
+{
+	int ret = 0;
+
+	if (clk->usecount++ == 0) {
+		if (likely((u32)clk->parent))
+			ret = omap2_clk_use(clk->parent);
+
+		if (unlikely(ret != 0)) {
+			clk->usecount--;
+			return ret;
+		}
+
+		ret = omap2_clk_enable(clk);
+
+		if (unlikely(ret != 0) && clk->parent) {
+			omap2_clk_unuse(clk->parent);
+			clk->usecount--;
+		}
+	}
+
+	return ret;
+}
+
+static void omap2_clk_unuse(struct clk *clk)
+{
+	if (clk->usecount > 0 && !(--clk->usecount)) {
+		omap2_clk_disable(clk);
+		if (likely((u32)clk->parent))
+			omap2_clk_unuse(clk->parent);
+	}
+}
+
+/*
+ * Uses the current prcm set to tell if a rate is valid.
+ * You can go slower, but not faster within a given rate set.
+ */
+static u32 omap2_dpll_round_rate(unsigned long target_rate)
+{
+	u32 high, low;
+
+	if ((CM_CLKSEL2_PLL & 0x3) == 1) {	/* DPLL clockout */
+		high = curr_prcm_set->dpll_speed * 2;
+		low = curr_prcm_set->dpll_speed;
+	} else {				/* DPLL clockout x 2 */
+		high = curr_prcm_set->dpll_speed;
+		low = curr_prcm_set->dpll_speed / 2;
+	}
+
+#ifdef DOWN_VARIABLE_DPLL
+	if (target_rate > high)
+		return high;
+	else
+		return target_rate;
+#else
+	if (target_rate > low)
+		return high;
+	else
+		return low;
+#endif
+
+}
+
+/*
+ * Used for clocks that are part of CLKSEL_xyz governed clocks.
+ * REVISIT: Maybe change to use clk->enable() functions like on omap1?
+ */
+static void omap2_clksel_recalc(struct clk * clk)
+{
+	u32 fixed = 0, div = 0;
+
+	if (clk == &dpll_ck) {
+		clk->rate = omap2_get_dpll_rate(clk);
+		fixed = 1;
+		div = 0;
+	}
+
+	if (clk == &iva1_mpu_int_ifck) {
+		div = 2;
+		fixed = 1;
+	}
+
+	if ((clk == &dss1_fck) && ((CM_CLKSEL1_CORE & (0x1f << 8)) == 0)) {
+		clk->rate = sys_ck.rate;
+		return;
+	}
+
+	if (!fixed) {
+		div = omap2_clksel_get_divisor(clk);
+		if (div == 0)
+			return;
+	}
+
+	if (div != 0) {
+		if (unlikely(clk->rate == clk->parent->rate / div))
+			return;
+		clk->rate = clk->parent->rate / div;
+	}
+
+	if (unlikely(clk->flags & RATE_PROPAGATES))
+		propagate_rate(clk);
+}
+
+/*
+ * Finds best divider value in an array based on the source and target
+ * rates. The divider array must be sorted with smallest divider first.
+ */
+static inline u32 omap2_divider_from_table(u32 size, u32 *div_array,
+					   u32 src_rate, u32 tgt_rate)
+{
+	int i, test_rate;
+
+	if (div_array == NULL)
+		return ~1;
+
+	for (i=0; i < size; i++) {
+		test_rate = src_rate / *div_array;
+		if (test_rate <= tgt_rate)
+			return *div_array;
+		++div_array;
+	}
+
+	return ~0;	/* No acceptable divider */
+}
+
+/*
+ * Find divisor for the given clock and target rate.
+ *
+ * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
+ * they are only settable as part of virtual_prcm set.
+ */
+static u32 omap2_clksel_round_rate(struct clk *tclk, u32 target_rate,
+	u32 *new_div)
+{
+	u32 gfx_div[] = {2, 3, 4};
+	u32 sysclkout_div[] = {1, 2, 4, 8, 16};
+	u32 dss1_div[] = {1, 2, 3, 4, 5, 6, 8, 9, 12, 16};
+	u32 vylnq_div[] = {1, 2, 3, 4, 6, 8, 9, 12, 16, 18};
+	u32 best_div = ~0, asize = 0;
+	u32 *div_array = NULL;
+
+	switch (tclk->flags & SRC_RATE_SEL_MASK) {
+	case CM_GFX_SEL1:
+		asize = 3;
+		div_array = gfx_div;
+		break;
+	case CM_PLL_SEL1:
+		return omap2_dpll_round_rate(target_rate);
+	case CM_SYSCLKOUT_SEL1:
+		asize = 5;
+		div_array = sysclkout_div;
+		break;
+	case CM_CORE_SEL1:
+		if(tclk == &dss1_fck){
+			if(tclk->parent == &core_ck){
+				asize = 10;
+				div_array = dss1_div;
+			} else {
+				*new_div = 0; /* fixed clk */
+				return(tclk->parent->rate);
+			}
+		} else if((tclk == &vlynq_fck) && cpu_is_omap2420()){
+			if(tclk->parent == &core_ck){
+				asize = 10;
+				div_array = vylnq_div;
+			} else {
+				*new_div = 0; /* fixed clk */
+				return(tclk->parent->rate);
+			}
+		}
+		break;
+	}
+
+	best_div = omap2_divider_from_table(asize, div_array,
+	 tclk->parent->rate, target_rate);
+	if (best_div == ~0){
+		*new_div = 1;
+		return best_div; /* signal error */
+	}
+
+	*new_div = best_div;
+	return (tclk->parent->rate / best_div);
+}
+
+/* Given a clock and a rate apply a clock specific rounding function */
+static long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	u32 new_div = 0;
+	int valid_rate;
+
+	if (clk->flags & RATE_FIXED)
+		return clk->rate;
+
+	if (clk->flags & RATE_CKCTL) {
+		valid_rate = omap2_clksel_round_rate(clk, rate, &new_div);
+		return valid_rate;
+	}
+
+	if (clk->round_rate != 0)
+		return clk->round_rate(clk, rate);
+
+	return clk->rate;
+}
+
+/*
+ * Check the DLL lock state, and return tue if running in unlock mode.
+ * This is needed to compenste for the shifted DLL value in unlock mode.
+ */
+static u32 omap2_dll_force_needed(void)
+{
+	u32 dll_state = SDRC_DLLA_CTRL;		/* dlla and dllb are a set */
+
+	if ((dll_state & (1 << 2)) == (1 << 2))
+		return 1;
+	else
+		return 0;
+}
+
+static void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
+{
+	unsigned long dll_cnt;
+	u32 fast_dll = 0;
+
+	mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
+
+	/* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
+	 * In the case of 2422, its ok to use CS1 instead of CS0.
+	 */
+
+#if 0	/* FIXME: Enable after 24xx cpu detection works */
+	ctype = get_cpu_type();
+	if (cpu_is_omap2422())
+		mem_timings.base_cs = 1;
+	else
+#endif
+		mem_timings.base_cs = 0;
+
+	if (mem_timings.m_type != M_DDR)
+		return;
+
+	/* With DDR we need to determine the low frequency DLL value */
+	if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
+		mem_timings.dll_mode = M_UNLOCK;
+	else
+		mem_timings.dll_mode = M_LOCK;
+
+	if (mem_timings.base_cs == 0) {
+		fast_dll = SDRC_DLLA_CTRL;
+		dll_cnt = SDRC_DLLA_STATUS & 0xff00;
+	} else {
+		fast_dll = SDRC_DLLB_CTRL;
+		dll_cnt = SDRC_DLLB_STATUS & 0xff00;
+	}
+	if (force_lock_to_unlock_mode) {
+		fast_dll &= ~0xff00;
+		fast_dll |= dll_cnt;		/* Current lock mode */
+	}
+	mem_timings.fast_dll_ctrl = fast_dll;
+
+	/* No disruptions, DDR will be offline & C-ABI not followed */
+	omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
+			    mem_timings.fast_dll_ctrl,
+			    mem_timings.base_cs,
+			    force_lock_to_unlock_mode);
+	mem_timings.slow_dll_ctrl &= 0xff00;	/* Keep lock value */
+
+	/* Turn status into unlock ctrl */
+	mem_timings.slow_dll_ctrl |=
+		((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
+
+	/* 90 degree phase for anything below 133Mhz */
+	mem_timings.slow_dll_ctrl |= (1 << 1);
+}
+
+static u32 omap2_reprogram_sdrc(u32 level, u32 force)
+{
+	u32 prev = curr_perf_level, flags;
+
+	if ((curr_perf_level == level) && !force)
+		return prev;
+
+	if (level == PRCM_HALF_SPEED) {
+		local_irq_save(flags);
+		PRCM_VOLTSETUP = 0xffff;
+		omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED,
+					  mem_timings.slow_dll_ctrl,
+					  mem_timings.m_type);
+		curr_perf_level = PRCM_HALF_SPEED;
+		local_irq_restore(flags);
+	}
+	if (level == PRCM_FULL_SPEED) {
+		local_irq_save(flags);
+		PRCM_VOLTSETUP = 0xffff;
+		omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED,
+					  mem_timings.fast_dll_ctrl,
+					  mem_timings.m_type);
+		curr_perf_level = PRCM_FULL_SPEED;
+		local_irq_restore(flags);
+	}
+
+	return prev;
+}
+
+static int omap2_reprogram_dpll(struct clk * clk, unsigned long rate)
+{
+	u32 flags, cur_rate, low, mult, div, valid_rate, done_rate;
+	u32 bypass = 0;
+	struct prcm_config tmpset;
+	int ret = -EINVAL;
+
+	local_irq_save(flags);
+	cur_rate = omap2_get_dpll_rate(&dpll_ck);
+	mult = CM_CLKSEL2_PLL & 0x3;
+
+	if ((rate == (cur_rate / 2)) && (mult == 2)) {
+		omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1);
+	} else if ((rate == (cur_rate * 2)) && (mult == 1)) {
+		omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
+	} else if (rate != cur_rate) {
+		valid_rate = omap2_dpll_round_rate(rate);
+		if (valid_rate != rate)
+			goto dpll_exit;
+
+		if ((CM_CLKSEL2_PLL & 0x3) == 1)
+			low = curr_prcm_set->dpll_speed;
+		else
+			low = curr_prcm_set->dpll_speed / 2;
+
+		tmpset.cm_clksel1_pll = CM_CLKSEL1_PLL;
+		tmpset.cm_clksel1_pll &= ~(0x3FFF << 8);
+		div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
+		tmpset.cm_clksel2_pll = CM_CLKSEL2_PLL;
+		tmpset.cm_clksel2_pll &= ~0x3;
+		if (rate > low) {
+			tmpset.cm_clksel2_pll |= 0x2;
+			mult = ((rate / 2) / 1000000);
+			done_rate = PRCM_FULL_SPEED;
+		} else {
+			tmpset.cm_clksel2_pll |= 0x1;
+			mult = (rate / 1000000);
+			done_rate = PRCM_HALF_SPEED;
+		}
+		tmpset.cm_clksel1_pll |= ((div << 8) | (mult << 12));
+
+		/* Worst case */
+		tmpset.base_sdrc_rfr = V24XX_SDRC_RFR_CTRL_BYPASS;
+
+		if (rate == curr_prcm_set->xtal_speed)	/* If asking for 1-1 */
+			bypass = 1;
+
+		omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); /* For init_mem */
+
+		/* Force dll lock mode */
+		omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
+			       bypass);
+
+		/* Errata: ret dll entry state */
+		omap2_init_memory_params(omap2_dll_force_needed());
+		omap2_reprogram_sdrc(done_rate, 0);
+	}
+	omap2_clksel_recalc(&dpll_ck);
+	ret = 0;
+
+dpll_exit:
+	local_irq_restore(flags);
+	return(ret);
+}
+
+/* Just return the MPU speed */
+static void omap2_mpu_recalc(struct clk * clk)
+{
+	clk->rate = curr_prcm_set->mpu_speed;
+}
+
+/*
+ * Look for a rate equal or less than the target rate given a configuration set.
+ *
+ * What's not entirely clear is "which" field represents the key field.
+ * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
+ * just uses the ARM rates.
+ */
+static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate)
+{
+	struct prcm_config * ptr;
+	long highest_rate;
+
+	if (clk != &virt_prcm_set)
+		return -EINVAL;
+
+	highest_rate = -EINVAL;
+
+	for (ptr = rate_table; ptr->mpu_speed; ptr++) {
+		if (ptr->xtal_speed != sys_ck.rate)
+			continue;
+
+		highest_rate = ptr->mpu_speed;
+
+		/* Can check only after xtal frequency check */
+		if (ptr->mpu_speed <= rate)
+			break;
+	}
+	return highest_rate;
+}
+
+/*
+ * omap2_convert_field_to_div() - turn field value into integer divider
+ */
+static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val)
+{
+	u32 i;
+	u32 clkout_array[] = {1, 2, 4, 8, 16};
+
+	if ((div_sel & SRC_RATE_SEL_MASK) == CM_SYSCLKOUT_SEL1) {
+		for (i = 0; i < 5; i++) {
+			if (field_val == i)
+				return clkout_array[i];
+		}
+		return ~0;
+	} else
+		return field_val;
+}
+
+/*
+ * Returns the CLKSEL divider register value
+ * REVISIT: This should be cleaned up to work nicely with void __iomem *
+ */
+static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask,
+			    struct clk *clk)
+{
+	int ret = ~0;
+	u32 reg_val, div_off;
+	u32 div_addr = 0;
+	u32 mask = ~0;
+
+	div_off = clk->rate_offset;
+
+	switch ((*div_sel & SRC_RATE_SEL_MASK)) {
+	case CM_MPU_SEL1:
+		div_addr = (u32)&CM_CLKSEL_MPU;
+		mask = 0x1f;
+		break;
+	case CM_DSP_SEL1:
+		div_addr = (u32)&CM_CLKSEL_DSP;
+		if (cpu_is_omap2420()) {
+			if ((div_off == 0) || (div_off == 8))
+				mask = 0x1f;
+			else if (div_off == 5)
+				mask = 0x3;
+		} else if (cpu_is_omap2430()) {
+			if (div_off == 0)
+				mask = 0x1f;
+			else if (div_off == 5)
+				mask = 0x3;
+		}
+		break;
+	case CM_GFX_SEL1:
+		div_addr = (u32)&CM_CLKSEL_GFX;
+		if (div_off == 0)
+			mask = 0x7;
+		break;
+	case CM_MODEM_SEL1:
+		div_addr = (u32)&CM_CLKSEL_MDM;
+		if (div_off == 0)
+			mask = 0xf;
+		break;
+	case CM_SYSCLKOUT_SEL1:
+		div_addr = (u32)&PRCM_CLKOUT_CTRL;
+		if ((div_off == 3) || (div_off = 11))
+			mask= 0x3;
+		break;
+	case CM_CORE_SEL1:
+		div_addr = (u32)&CM_CLKSEL1_CORE;
+		switch (div_off) {
+		case 0:					/* l3 */
+		case 8:					/* dss1 */
+		case 15:				/* vylnc-2420 */
+		case 20:				/* ssi */
+			mask = 0x1f; break;
+		case 5:					/* l4 */
+			mask = 0x3; break;
+		case 13:				/* dss2 */
+			mask = 0x1; break;
+		case 25:				/* usb */
+			mask = 0xf; break;
+		}
+	}
+
+	*field_mask = mask;
+
+	if (unlikely(mask == ~0))
+		div_addr = 0;
+
+	*div_sel = div_addr;
+
+	if (unlikely(div_addr == 0))
+		return ret;
+
+	/* Isolate field */
+	reg_val = __raw_readl((void __iomem *)div_addr) & (mask << div_off);
+
+	/* Normalize back to divider value */
+	reg_val >>= div_off;
+
+	return reg_val;
+}
+
+/*
+ * Return divider to be applied to parent clock.
+ * Return 0 on error.
+ */
+static u32 omap2_clksel_get_divisor(struct clk *clk)
+{
+	int ret = 0;
+	u32 div, div_sel, div_off, field_mask, field_val;
+
+	/* isolate control register */
+	div_sel = (SRC_RATE_SEL_MASK & clk->flags);
+
+	div_off = clk->rate_offset;
+	field_val = omap2_get_clksel(&div_sel, &field_mask, clk);
+	if (div_sel == 0)
+		return ret;
+
+	div_sel = (SRC_RATE_SEL_MASK & clk->flags);
+	div = omap2_clksel_to_divisor(div_sel, field_val);
+
+	return div;
+}
+
+/* Set the clock rate for a clock source */
+static int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
+
+{
+	int ret = -EINVAL;
+	void __iomem * reg;
+	u32 div_sel, div_off, field_mask, field_val, reg_val, validrate;
+	u32 new_div = 0;
+
+	if (!(clk->flags & CONFIG_PARTICIPANT) && (clk->flags & RATE_CKCTL)) {
+		if (clk == &dpll_ck)
+			return omap2_reprogram_dpll(clk, rate);
+
+		/* Isolate control register */
+		div_sel = (SRC_RATE_SEL_MASK & clk->flags);
+		div_off = clk->src_offset;
+
+		validrate = omap2_clksel_round_rate(clk, rate, &new_div);
+		if(validrate != rate)
+			return(ret);
+
+		field_val = omap2_get_clksel(&div_sel, &field_mask, clk);
+		if (div_sel == 0)
+			return ret;
+
+		if(clk->flags & CM_SYSCLKOUT_SEL1){
+			switch(new_div){
+			case 16: field_val = 4; break;
+			case 8:  field_val = 3; break;
+			case 4:  field_val = 2; break;
+			case 2:  field_val = 1; break;
+			case 1:  field_val = 0; break;
+			}
+		}
+		else
+			field_val = new_div;
+
+		reg = (void __iomem *)div_sel;
+
+		reg_val = __raw_readl(reg);
+		reg_val &= ~(field_mask << div_off);
+		reg_val |= (field_val << div_off);
+
+		__raw_writel(reg_val, reg);
+		clk->rate = clk->parent->rate / field_val;
+
+		if (clk->flags & DELAYED_APP)
+			__raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
+		ret = 0;
+	} else if (clk->set_rate != 0)
+		ret = clk->set_rate(clk, rate);
+
+	if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
+		propagate_rate(clk);
+
+	return ret;
+}
+
+/* Converts encoded control register address into a full address */
+static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset,
+			       struct clk *src_clk, u32 *field_mask)
+{
+	u32 val = ~0, src_reg_addr = 0, mask = 0;
+
+	/* Find target control register.*/
+	switch ((*type_to_addr & SRC_RATE_SEL_MASK)) {
+	case CM_CORE_SEL1:
+		src_reg_addr = (u32)&CM_CLKSEL1_CORE;
+		if (reg_offset == 13) {			/* DSS2_fclk */
+			mask = 0x1;
+			if (src_clk == &sys_ck)
+				val = 0;
+			if (src_clk == &func_48m_ck)
+				val = 1;
+		} else if (reg_offset == 8) {		/* DSS1_fclk */
+			mask = 0x1f;
+			if (src_clk == &sys_ck)
+				val = 0;
+			else if (src_clk == &core_ck)	/* divided clock */
+				val = 0x10;		/* rate needs fixing */
+		} else if ((reg_offset == 15) && cpu_is_omap2420()){ /*vlnyq*/
+			mask = 0x1F;
+			if(src_clk == &func_96m_ck)
+				val = 0;
+			else if (src_clk == &core_ck)
+				val = 0x10;
+		}
+		break;
+	case CM_CORE_SEL2:
+		src_reg_addr = (u32)&CM_CLKSEL2_CORE;
+		mask = 0x3;
+		if (src_clk == &func_32k_ck)
+			val = 0x0;
+		if (src_clk == &sys_ck)
+			val = 0x1;
+		if (src_clk == &alt_ck)
+			val = 0x2;
+		break;
+	case CM_WKUP_SEL1:
+		src_reg_addr = (u32)&CM_CLKSEL2_CORE;
+		mask = 0x3;
+		if (src_clk == &func_32k_ck)
+			val = 0x0;
+		if (src_clk == &sys_ck)
+			val = 0x1;
+		if (src_clk == &alt_ck)
+			val = 0x2;
+		break;
+	case CM_PLL_SEL1:
+		src_reg_addr = (u32)&CM_CLKSEL1_PLL;
+		mask = 0x1;
+		if (reg_offset == 0x3) {
+			if (src_clk == &apll96_ck)
+				val = 0;
+			if (src_clk == &alt_ck)
+				val = 1;
+		}
+		else if (reg_offset == 0x5) {
+			if (src_clk == &apll54_ck)
+				val = 0;
+			if (src_clk == &alt_ck)
+				val = 1;
+		}
+		break;
+	case CM_PLL_SEL2:
+		src_reg_addr = (u32)&CM_CLKSEL2_PLL;
+		mask = 0x3;
+		if (src_clk == &func_32k_ck)
+			val = 0x0;
+		if (src_clk == &dpll_ck)
+			val = 0x2;
+		break;
+	case CM_SYSCLKOUT_SEL1:
+		src_reg_addr = (u32)&PRCM_CLKOUT_CTRL;
+		mask = 0x3;
+		if (src_clk == &dpll_ck)
+			val = 0;
+		if (src_clk == &sys_ck)
+			val = 1;
+		if (src_clk == &func_54m_ck)
+			val = 2;
+		if (src_clk == &func_96m_ck)
+			val = 3;
+		break;
+	}
+
+	if (val == ~0)			/* Catch errors in offset */
+		*type_to_addr = 0;
+	else
+		*type_to_addr = src_reg_addr;
+	*field_mask = mask;
+
+	return val;
+}
+
+static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
+{
+	void __iomem * reg;
+	u32 src_sel, src_off, field_val, field_mask, reg_val, rate;
+	int ret = -EINVAL;
+
+	if (unlikely(clk->flags & CONFIG_PARTICIPANT))
+		return ret;
+
+	if (clk->flags & SRC_SEL_MASK) {	/* On-chip SEL collection */
+		src_sel = (SRC_RATE_SEL_MASK & clk->flags);
+		src_off = clk->src_offset;
+
+		if (src_sel == 0)
+			goto set_parent_error;
+
+		field_val = omap2_get_src_field(&src_sel, src_off, new_parent,
+						&field_mask);
+
+		reg = (void __iomem *)src_sel;
+
+		if (clk->usecount > 0)
+			omap2_clk_disable(clk);
+
+		/* Set new source value (previous dividers if any in effect) */
+		reg_val = __raw_readl(reg) & ~(field_mask << src_off);
+		reg_val |= (field_val << src_off);
+		__raw_writel(reg_val, reg);
+
+		if (clk->flags & DELAYED_APP)
+			__raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
+
+		if (clk->usecount > 0)
+			omap2_clk_enable(clk);
+
+		clk->parent = new_parent;
+
+		/* SRC_RATE_SEL_MASK clocks follow their parents rates.*/
+		if ((new_parent == &core_ck) && (clk == &dss1_fck))
+			clk->rate = new_parent->rate / 0x10;
+		else
+			clk->rate = new_parent->rate;
+
+		if (unlikely(clk->flags & RATE_PROPAGATES))
+			propagate_rate(clk);
+
+		return 0;
+	} else {
+		clk->parent = new_parent;
+		rate = new_parent->rate;
+		omap2_clk_set_rate(clk, rate);
+		ret = 0;
+	}
+
+ set_parent_error:
+	return ret;
+}
+
+/* Sets basic clocks based on the specified rate */
+static int omap2_select_table_rate(struct clk * clk, unsigned long rate)
+{
+	u32 flags, cur_rate, done_rate, bypass = 0;
+	u8 cpu_mask = 0;
+	struct prcm_config *prcm;
+	unsigned long found_speed = 0;
+
+	if (clk != &virt_prcm_set)
+		return -EINVAL;
+
+	/* FIXME: Change cpu_is_omap2420() to cpu_is_omap242x() */
+	if (cpu_is_omap2420())
+		cpu_mask = RATE_IN_242X;
+	else if (cpu_is_omap2430())
+		cpu_mask = RATE_IN_243X;
+
+	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+		if (!(prcm->flags & cpu_mask))
+			continue;
+
+		if (prcm->xtal_speed != sys_ck.rate)
+			continue;
+
+		if (prcm->mpu_speed <= rate) {
+			found_speed = prcm->mpu_speed;
+			break;
+		}
+	}
+
+	if (!found_speed) {
+		printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
+	 rate / 1000000);
+		return -EINVAL;
+	}
+
+	curr_prcm_set = prcm;
+	cur_rate = omap2_get_dpll_rate(&dpll_ck);
+
+	if (prcm->dpll_speed == cur_rate / 2) {
+		omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1);
+	} else if (prcm->dpll_speed == cur_rate * 2) {
+		omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
+	} else if (prcm->dpll_speed != cur_rate) {
+		local_irq_save(flags);
+
+		if (prcm->dpll_speed == prcm->xtal_speed)
+			bypass = 1;
+
+		if ((prcm->cm_clksel2_pll & 0x3) == 2)
+			done_rate = PRCM_FULL_SPEED;
+		else
+			done_rate = PRCM_HALF_SPEED;
+
+		/* MPU divider */
+		CM_CLKSEL_MPU = prcm->cm_clksel_mpu;
+
+		/* dsp + iva1 div(2420), iva2.1(2430) */
+		CM_CLKSEL_DSP = prcm->cm_clksel_dsp;
+
+		CM_CLKSEL_GFX = prcm->cm_clksel_gfx;
+
+		/* Major subsystem dividers */
+		CM_CLKSEL1_CORE = prcm->cm_clksel1_core;
+		if (cpu_is_omap2430())
+			CM_CLKSEL_MDM = prcm->cm_clksel_mdm;
+
+		/* x2 to enter init_mem */
+		omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
+
+		omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
+			       bypass);
+
+		omap2_init_memory_params(omap2_dll_force_needed());
+		omap2_reprogram_sdrc(done_rate, 0);
+
+		local_irq_restore(flags);
+	}
+	omap2_clksel_recalc(&dpll_ck);
+
+	return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Omap2 clock reset and init functions
+ *-------------------------------------------------------------------------*/
+
+static struct clk_functions omap2_clk_functions = {
+	.clk_enable		= omap2_clk_enable,
+	.clk_disable		= omap2_clk_disable,
+	.clk_use		= omap2_clk_use,
+	.clk_unuse		= omap2_clk_unuse,
+	.clk_round_rate		= omap2_clk_round_rate,
+	.clk_set_rate		= omap2_clk_set_rate,
+	.clk_set_parent		= omap2_clk_set_parent,
+};
+
+static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys)
+{
+	u32 div, aplls, sclk = 13000000;
+
+	aplls = CM_CLKSEL1_PLL;
+	aplls &= ((1 << 23) | (1 << 24) | (1 << 25));
+	aplls >>= 23;			/* Isolate field, 0,2,3 */
+
+	if (aplls == 0)
+		sclk = 19200000;
+	else if (aplls == 2)
+		sclk = 13000000;
+	else if (aplls == 3)
+		sclk = 12000000;
+
+	div = PRCM_CLKSRC_CTRL;
+	div &= ((1 << 7) | (1 << 6));
+	div >>= sys->rate_offset;
+
+	osc->rate = sclk * div;
+	sys->rate = sclk;
+}
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+static void __init omap2_disable_unused_clocks(void)
+{
+	struct clk *ck;
+	u32 regval32;
+
+	list_for_each_entry(ck, &clocks, node) {
+		if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) ||
+			ck->enable_reg == 0)
+			continue;
+
+		regval32 = __raw_readl(ck->enable_reg);
+		if ((regval32 & (1 << ck->enable_bit)) == 0)
+			continue;
+
+		printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name);
+		omap2_clk_disable(ck);
+	}
+}
+late_initcall(omap2_disable_unused_clocks);
+#endif
+
+/*
+ * Switch the MPU rate if specified on cmdline.
+ * We cannot do this early until cmdline is parsed.
+ */
+static int __init omap2_clk_arch_init(void)
+{
+	if (!mpurate)
+		return -EINVAL;
+
+	if (omap2_select_table_rate(&virt_prcm_set, mpurate))
+		printk(KERN_ERR "Could not find matching MPU rate\n");
+
+	propagate_rate(&osc_ck);		/* update main root fast */
+	propagate_rate(&func_32k_ck);		/* update main root slow */
+
+	printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL/MPU): "
+	       "%ld.%01ld/%ld/%ld MHz\n",
+	       (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
+	       (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
+
+	return 0;
+}
+arch_initcall(omap2_clk_arch_init);
+
+int __init omap2_clk_init(void)
+{
+	struct prcm_config *prcm;
+	struct clk ** clkp;
+	u32 clkrate;
+
+	clk_init(&omap2_clk_functions);
+	omap2_get_crystal_rate(&osc_ck, &sys_ck);
+
+	for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
+	     clkp++) {
+
+		if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) {
+			clk_register(*clkp);
+			continue;
+		}
+
+		if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) {
+			clk_register(*clkp);
+			continue;
+		}
+	}
+
+	/* Check the MPU rate set by bootloader */
+	clkrate = omap2_get_dpll_rate(&dpll_ck);
+	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+		if (prcm->xtal_speed != sys_ck.rate)
+			continue;
+		if (prcm->dpll_speed <= clkrate)
+			 break;
+	}
+	curr_prcm_set = prcm;
+
+	propagate_rate(&osc_ck);		/* update main root fast */
+	propagate_rate(&func_32k_ck);		/* update main root slow */
+
+	printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): "
+	       "%ld.%01ld/%ld/%ld MHz\n",
+	       (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
+	       (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
+
+	/*
+	 * Only enable those clocks we will need, let the drivers
+	 * enable other clocks as necessary
+	 */
+	clk_use(&sync_32k_ick);
+	clk_use(&omapctrl_ick);
+	if (cpu_is_omap2430())
+		clk_use(&sdrc_ick);
+
+	return 0;
+}

+ 2103 - 0
arch/arm/mach-omap2/clock.h

@@ -0,0 +1,2103 @@
+/*
+ *  linux/arch/arm/mach-omap24xx/clock.h
+ *
+ *  Copyright (C) 2005 Texas Instruments Inc.
+ *  Richard Woodruff <r-woodruff2@ti.com>
+ *  Created for OMAP2.
+ *
+ *  Copyright (C) 2004 Nokia corporation
+ *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK_H
+
+static void omap2_sys_clk_recalc(struct clk * clk);
+static void omap2_clksel_recalc(struct clk * clk);
+static void omap2_followparent_recalc(struct clk * clk);
+static void omap2_propagate_rate(struct clk * clk);
+static void omap2_mpu_recalc(struct clk * clk);
+static int omap2_select_table_rate(struct clk * clk, unsigned long rate);
+static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate);
+static void omap2_clk_unuse(struct clk *clk);
+static void omap2_sys_clk_recalc(struct clk * clk);
+static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val);
+static u32 omap2_clksel_get_divisor(struct clk *clk);
+
+
+#define RATE_IN_242X	(1 << 0)
+#define RATE_IN_243X	(1 << 1)
+
+/* Memory timings */
+#define M_DDR		1
+#define M_LOCK_CTRL	(1 << 2)
+#define M_UNLOCK	0
+#define M_LOCK		1
+
+struct memory_timings {
+	u32 m_type;		/* ddr = 1, sdr = 0 */
+	u32 dll_mode;		/* use lock mode = 1, unlock mode = 0 */
+	u32 slow_dll_ctrl;	/* unlock mode, dll value for slow speed */
+	u32 fast_dll_ctrl;	/* unlock mode, dll value for fast speed */
+	u32 base_cs;		/* base chip select to use for calculations */
+};
+
+/* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
+ * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP
+ * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM
+ */
+struct prcm_config {
+	unsigned long xtal_speed;	/* crystal rate */
+	unsigned long dpll_speed;	/* dpll: out*xtal*M/(N-1)table_recalc */
+	unsigned long mpu_speed;	/* speed of MPU */
+	unsigned long cm_clksel_mpu;	/* mpu divider */
+	unsigned long cm_clksel_dsp;	/* dsp+iva1 div(2420), iva2.1(2430) */
+	unsigned long cm_clksel_gfx;	/* gfx dividers */
+	unsigned long cm_clksel1_core;	/* major subsystem dividers */
+	unsigned long cm_clksel1_pll;	/* m,n */
+	unsigned long cm_clksel2_pll;	/* dpllx1 or x2 out */
+	unsigned long cm_clksel_mdm;	/* modem dividers 2430 only */
+	unsigned long base_sdrc_rfr;	/* base refresh timing for a set */
+	unsigned char flags;
+};
+
+/* Mask for clksel which support parent settign in set_rate */
+#define SRC_SEL_MASK (CM_CORE_SEL1 | CM_CORE_SEL2 | CM_WKUP_SEL1 | \
+			CM_PLL_SEL1 | CM_PLL_SEL2 | CM_SYSCLKOUT_SEL1)
+
+/* Mask for clksel regs which support rate operations */
+#define SRC_RATE_SEL_MASK (CM_MPU_SEL1 | CM_DSP_SEL1 | CM_GFX_SEL1 | \
+			CM_MODEM_SEL1 | CM_CORE_SEL1 | CM_CORE_SEL2 | \
+			CM_WKUP_SEL1 | CM_PLL_SEL1 | CM_PLL_SEL2 | \
+			CM_SYSCLKOUT_SEL1)
+
+/*
+ * The OMAP2 processor can be run at several discrete 'PRCM configurations'.
+ * These configurations are characterized by voltage and speed for clocks.
+ * The device is only validated for certain combinations. One way to express
+ * these combinations is via the 'ratio's' which the clocks operate with
+ * respect to each other. These ratio sets are for a given voltage/DPLL
+ * setting. All configurations can be described by a DPLL setting and a ratio
+ * There are 3 ratio sets for the 2430 and X ratio sets for 2420.
+ *
+ * 2430 differs from 2420 in that there are no more phase synchronizers used.
+ * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs
+ * 2430 (iva2.1, NOdsp, mdm)
+ */
+
+/* Core fields for cm_clksel, not ratio governed */
+#define RX_CLKSEL_DSS1			(0x10 << 8)
+#define RX_CLKSEL_DSS2			(0x0 << 13)
+#define RX_CLKSEL_SSI			(0x5 << 20)
+
+/*-------------------------------------------------------------------------
+ * Voltage/DPLL ratios
+ *-------------------------------------------------------------------------*/
+
+/* 2430 Ratio's, 2430-Ratio Config 1 */
+#define R1_CLKSEL_L3			(4 << 0)
+#define R1_CLKSEL_L4			(2 << 5)
+#define R1_CLKSEL_USB			(4 << 25)
+#define R1_CM_CLKSEL1_CORE_VAL		R1_CLKSEL_USB | RX_CLKSEL_SSI | \
+					RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+					R1_CLKSEL_L4 | R1_CLKSEL_L3
+#define R1_CLKSEL_MPU			(2 << 0)
+#define R1_CM_CLKSEL_MPU_VAL		R1_CLKSEL_MPU
+#define R1_CLKSEL_DSP			(2 << 0)
+#define R1_CLKSEL_DSP_IF		(2 << 5)
+#define R1_CM_CLKSEL_DSP_VAL		R1_CLKSEL_DSP | R1_CLKSEL_DSP_IF
+#define R1_CLKSEL_GFX			(2 << 0)
+#define R1_CM_CLKSEL_GFX_VAL		R1_CLKSEL_GFX
+#define R1_CLKSEL_MDM			(4 << 0)
+#define R1_CM_CLKSEL_MDM_VAL		R1_CLKSEL_MDM
+
+/* 2430-Ratio Config 2 */
+#define R2_CLKSEL_L3			(6 << 0)
+#define R2_CLKSEL_L4			(2 << 5)
+#define R2_CLKSEL_USB			(2 << 25)
+#define R2_CM_CLKSEL1_CORE_VAL		R2_CLKSEL_USB | RX_CLKSEL_SSI | \
+					RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+					R2_CLKSEL_L4 | R2_CLKSEL_L3
+#define R2_CLKSEL_MPU			(2 << 0)
+#define R2_CM_CLKSEL_MPU_VAL		R2_CLKSEL_MPU
+#define R2_CLKSEL_DSP			(2 << 0)
+#define R2_CLKSEL_DSP_IF		(3 << 5)
+#define R2_CM_CLKSEL_DSP_VAL		R2_CLKSEL_DSP | R2_CLKSEL_DSP_IF
+#define R2_CLKSEL_GFX			(2 << 0)
+#define R2_CM_CLKSEL_GFX_VAL		R2_CLKSEL_GFX
+#define R2_CLKSEL_MDM			(6 << 0)
+#define R2_CM_CLKSEL_MDM_VAL		R2_CLKSEL_MDM
+
+/* 2430-Ratio Bootm (BYPASS) */
+#define RB_CLKSEL_L3			(1 << 0)
+#define RB_CLKSEL_L4			(1 << 5)
+#define RB_CLKSEL_USB			(1 << 25)
+#define RB_CM_CLKSEL1_CORE_VAL		RB_CLKSEL_USB | RX_CLKSEL_SSI | \
+					RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+					RB_CLKSEL_L4 | RB_CLKSEL_L3
+#define RB_CLKSEL_MPU			(1 << 0)
+#define RB_CM_CLKSEL_MPU_VAL		RB_CLKSEL_MPU
+#define RB_CLKSEL_DSP			(1 << 0)
+#define RB_CLKSEL_DSP_IF		(1 << 5)
+#define RB_CM_CLKSEL_DSP_VAL		RB_CLKSEL_DSP | RB_CLKSEL_DSP_IF
+#define RB_CLKSEL_GFX			(1 << 0)
+#define RB_CM_CLKSEL_GFX_VAL		RB_CLKSEL_GFX
+#define RB_CLKSEL_MDM			(1 << 0)
+#define RB_CM_CLKSEL_MDM_VAL		RB_CLKSEL_MDM
+
+/* 2420 Ratio Equivalents */
+#define RXX_CLKSEL_VLYNQ		(0x12 << 15)
+#define RXX_CLKSEL_SSI			(0x8 << 20)
+
+/* 2420-PRCM III 532MHz core */
+#define RIII_CLKSEL_L3			(4 << 0)	/* 133MHz */
+#define RIII_CLKSEL_L4			(2 << 5)	/* 66.5MHz */
+#define RIII_CLKSEL_USB			(4 << 25)	/* 33.25MHz */
+#define RIII_CM_CLKSEL1_CORE_VAL	RIII_CLKSEL_USB | RXX_CLKSEL_SSI | \
+					RXX_CLKSEL_VLYNQ | RX_CLKSEL_DSS2 | \
+					RX_CLKSEL_DSS1 | RIII_CLKSEL_L4 | \
+					RIII_CLKSEL_L3
+#define RIII_CLKSEL_MPU			(2 << 0)	/* 266MHz */
+#define RIII_CM_CLKSEL_MPU_VAL		RIII_CLKSEL_MPU
+#define RIII_CLKSEL_DSP			(3 << 0)	/* c5x - 177.3MHz */
+#define RIII_CLKSEL_DSP_IF		(2 << 5)	/* c5x - 88.67MHz */
+#define RIII_SYNC_DSP			(1 << 7)	/* Enable sync */
+#define RIII_CLKSEL_IVA			(6 << 8)	/* iva1 - 88.67MHz */
+#define RIII_SYNC_IVA			(1 << 13)	/* Enable sync */
+#define RIII_CM_CLKSEL_DSP_VAL		RIII_SYNC_IVA | RIII_CLKSEL_IVA | \
+					RIII_SYNC_DSP | RIII_CLKSEL_DSP_IF | \
+					RIII_CLKSEL_DSP
+#define RIII_CLKSEL_GFX			(2 << 0)	/* 66.5MHz */
+#define RIII_CM_CLKSEL_GFX_VAL		RIII_CLKSEL_GFX
+
+/* 2420-PRCM II 600MHz core */
+#define RII_CLKSEL_L3			(6 << 0)	/* 100MHz */
+#define RII_CLKSEL_L4			(2 << 5)	/* 50MHz */
+#define RII_CLKSEL_USB			(2 << 25)	/* 50MHz */
+#define RII_CM_CLKSEL1_CORE_VAL		RII_CLKSEL_USB | \
+					RXX_CLKSEL_SSI | RXX_CLKSEL_VLYNQ | \
+					RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+					RII_CLKSEL_L4 | RII_CLKSEL_L3
+#define RII_CLKSEL_MPU			(2 << 0)	/* 300MHz */
+#define RII_CM_CLKSEL_MPU_VAL		RII_CLKSEL_MPU
+#define RII_CLKSEL_DSP			(3 << 0)	/* c5x - 200MHz */
+#define RII_CLKSEL_DSP_IF		(2 << 5)	/* c5x - 100MHz */
+#define RII_SYNC_DSP			(0 << 7)	/* Bypass sync */
+#define RII_CLKSEL_IVA			(6 << 8)	/* iva1 - 200MHz */
+#define RII_SYNC_IVA			(0 << 13)	/* Bypass sync */
+#define RII_CM_CLKSEL_DSP_VAL		RII_SYNC_IVA | RII_CLKSEL_IVA | \
+					RII_SYNC_DSP | RII_CLKSEL_DSP_IF | \
+					RII_CLKSEL_DSP
+#define RII_CLKSEL_GFX			(2 << 0)	/* 50MHz */
+#define RII_CM_CLKSEL_GFX_VAL		RII_CLKSEL_GFX
+
+/* 2420-PRCM VII (boot) */
+#define RVII_CLKSEL_L3			(1 << 0)
+#define RVII_CLKSEL_L4			(1 << 5)
+#define RVII_CLKSEL_DSS1		(1 << 8)
+#define RVII_CLKSEL_DSS2		(0 << 13)
+#define RVII_CLKSEL_VLYNQ		(1 << 15)
+#define RVII_CLKSEL_SSI			(1 << 20)
+#define RVII_CLKSEL_USB			(1 << 25)
+
+#define RVII_CM_CLKSEL1_CORE_VAL	RVII_CLKSEL_USB | RVII_CLKSEL_SSI | \
+					RVII_CLKSEL_VLYNQ | RVII_CLKSEL_DSS2 | \
+					RVII_CLKSEL_DSS1 | RVII_CLKSEL_L4 | RVII_CLKSEL_L3
+
+#define RVII_CLKSEL_MPU			(1 << 0) /* all divide by 1 */
+#define RVII_CM_CLKSEL_MPU_VAL		RVII_CLKSEL_MPU
+
+#define RVII_CLKSEL_DSP			(1 << 0)
+#define RVII_CLKSEL_DSP_IF		(1 << 5)
+#define RVII_SYNC_DSP			(0 << 7)
+#define RVII_CLKSEL_IVA			(1 << 8)
+#define RVII_SYNC_IVA			(0 << 13)
+#define RVII_CM_CLKSEL_DSP_VAL		RVII_SYNC_IVA | RVII_CLKSEL_IVA | RVII_SYNC_DSP | \
+					RVII_CLKSEL_DSP_IF | RVII_CLKSEL_DSP
+
+#define RVII_CLKSEL_GFX			(1 << 0)
+#define RVII_CM_CLKSEL_GFX_VAL		RVII_CLKSEL_GFX
+
+/*-------------------------------------------------------------------------
+ * 2430 Target modes: Along with each configuration the CPU has several
+ * modes which goes along with them. Modes mainly are the addition of
+ * describe DPLL combinations to go along with a ratio.
+ *-------------------------------------------------------------------------*/
+
+/* Hardware governed */
+#define MX_48M_SRC			(0 << 3)
+#define MX_54M_SRC			(0 << 5)
+#define MX_APLLS_CLIKIN_12		(3 << 23)
+#define MX_APLLS_CLIKIN_13		(2 << 23)
+#define MX_APLLS_CLIKIN_19_2		(0 << 23)
+
+/*
+ * 2430 - standalone, 2*ref*M/(n+1), M/N is for exactness not relock speed
+ * #2	(ratio1) baseport-target
+ * #5a	(ratio1) baseport-target, target DPLL = 266*2 = 532MHz
+ */
+#define M5A_DPLL_MULT_12		(133 << 12)
+#define M5A_DPLL_DIV_12			(5 << 8)
+#define M5A_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | \
+					M5A_DPLL_DIV_12 | M5A_DPLL_MULT_12 | \
+					MX_APLLS_CLIKIN_12
+#define M5A_DPLL_MULT_13		(266 << 12)
+#define M5A_DPLL_DIV_13			(12 << 8)
+#define M5A_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | \
+					M5A_DPLL_DIV_13 | M5A_DPLL_MULT_13 | \
+					MX_APLLS_CLIKIN_13
+#define M5A_DPLL_MULT_19		(180 << 12)
+#define M5A_DPLL_DIV_19			(12 << 8)
+#define M5A_CM_CLKSEL1_PLL_19_VAL	MX_48M_SRC | MX_54M_SRC | \
+					M5A_DPLL_DIV_19 | M5A_DPLL_MULT_19 | \
+					MX_APLLS_CLIKIN_19_2
+/* #5b	(ratio1) target DPLL = 200*2 = 400MHz */
+#define M5B_DPLL_MULT_12		(50 << 12)
+#define M5B_DPLL_DIV_12			(2 << 8)
+#define M5B_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | \
+					M5B_DPLL_DIV_12 | M5B_DPLL_MULT_12 | \
+					MX_APLLS_CLIKIN_12
+#define M5B_DPLL_MULT_13		(200 << 12)
+#define M5B_DPLL_DIV_13			(12 << 8)
+
+#define M5B_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | \
+					M5B_DPLL_DIV_13 | M5B_DPLL_MULT_13 | \
+					MX_APLLS_CLIKIN_13
+#define M5B_DPLL_MULT_19		(125 << 12)
+#define M5B_DPLL_DIV_19			(31 << 8)
+#define M5B_CM_CLKSEL1_PLL_19_VAL	MX_48M_SRC | MX_54M_SRC | \
+					M5B_DPLL_DIV_19 | M5B_DPLL_MULT_19 | \
+					MX_APLLS_CLIKIN_19_2
+/*
+ * #4	(ratio2)
+ * #3	(ratio2) baseport-target, target DPLL = 330*2 = 660MHz
+ */
+#define M3_DPLL_MULT_12			(55 << 12)
+#define M3_DPLL_DIV_12			(1 << 8)
+#define M3_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | \
+					M3_DPLL_DIV_12 | M3_DPLL_MULT_12 | \
+					MX_APLLS_CLIKIN_12
+#define M3_DPLL_MULT_13			(330 << 12)
+#define M3_DPLL_DIV_13			(12 << 8)
+#define M3_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | \
+					M3_DPLL_DIV_13 | M3_DPLL_MULT_13 | \
+					MX_APLLS_CLIKIN_13
+#define M3_DPLL_MULT_19			(275 << 12)
+#define M3_DPLL_DIV_19			(15 << 8)
+#define M3_CM_CLKSEL1_PLL_19_VAL	MX_48M_SRC | MX_54M_SRC | \
+					M3_DPLL_DIV_19 | M3_DPLL_MULT_19 | \
+					MX_APLLS_CLIKIN_19_2
+/* boot (boot) */
+#define MB_DPLL_MULT			(1 << 12)
+#define MB_DPLL_DIV			(0 << 8)
+#define MB_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\
+					MB_DPLL_MULT | MX_APLLS_CLIKIN_12
+
+#define MB_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\
+					MB_DPLL_MULT | MX_APLLS_CLIKIN_13
+
+#define MB_CM_CLKSEL1_PLL_19_VAL	MX_48M_SRC | MX_54M_SRC | MB_DPLL_DIV |\
+					MB_DPLL_MULT | MX_APLLS_CLIKIN_19
+
+/*
+ * 2430 - chassis (sedna)
+ * 165 (ratio1) same as above #2
+ * 150 (ratio1)
+ * 133 (ratio2) same as above #4
+ * 110 (ratio2) same as above #3
+ * 104 (ratio2)
+ * boot (boot)
+ */
+
+/*
+ * 2420 Equivalent - mode registers
+ * PRCM II , target DPLL = 2*300MHz = 600MHz
+ */
+#define MII_DPLL_MULT_12		(50 << 12)
+#define MII_DPLL_DIV_12			(1 << 8)
+#define MII_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | \
+					MII_DPLL_DIV_12 | MII_DPLL_MULT_12 | \
+					MX_APLLS_CLIKIN_12
+#define MII_DPLL_MULT_13		(300 << 12)
+#define MII_DPLL_DIV_13			(12 << 8)
+#define MII_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | \
+					MII_DPLL_DIV_13 | MII_DPLL_MULT_13 | \
+					MX_APLLS_CLIKIN_13
+
+/* PRCM III target DPLL = 2*266 = 532MHz*/
+#define MIII_DPLL_MULT_12		(133 << 12)
+#define MIII_DPLL_DIV_12		(5 << 8)
+#define MIII_CM_CLKSEL1_PLL_12_VAL	MX_48M_SRC | MX_54M_SRC | \
+					MIII_DPLL_DIV_12 | MIII_DPLL_MULT_12 | \
+					MX_APLLS_CLIKIN_12
+#define MIII_DPLL_MULT_13		(266 << 12)
+#define MIII_DPLL_DIV_13		(12 << 8)
+#define MIII_CM_CLKSEL1_PLL_13_VAL	MX_48M_SRC | MX_54M_SRC | \
+					MIII_DPLL_DIV_13 | MIII_DPLL_MULT_13 | \
+					MX_APLLS_CLIKIN_13
+
+/* PRCM VII (boot bypass) */
+#define MVII_CM_CLKSEL1_PLL_12_VAL	MB_CM_CLKSEL1_PLL_12_VAL
+#define MVII_CM_CLKSEL1_PLL_13_VAL	MB_CM_CLKSEL1_PLL_13_VAL
+
+/* High and low operation value */
+#define MX_CLKSEL2_PLL_2x_VAL		(2 << 0)
+#define MX_CLKSEL2_PLL_1x_VAL		(1 << 0)
+
+/*
+ * These represent optimal values for common parts, it won't work for all.
+ * As long as you scale down, most parameters are still work, they just
+ * become sub-optimal. The RFR value goes in the oppisite direction. If you
+ * don't adjust it down as your clock period increases the refresh interval
+ * will not be met. Setting all parameters for complete worst case may work,
+ * but may cut memory performance by 2x. Due to errata the DLLs need to be
+ * unlocked and their value needs run time calibration.	A dynamic call is
+ * need for that as no single right value exists acorss production samples.
+ *
+ * Only the FULL speed values are given. Current code is such that rate
+ * changes must be made at DPLLoutx2. The actual value adjustment for low
+ * frequency operation will be handled by omap_set_performance()
+ *
+ * By having the boot loader boot up in the fastest L4 speed available likely
+ * will result in something which you can switch between.
+ */
+#define V24XX_SDRC_RFR_CTRL_133MHz	(0x0003de00 | 1)
+#define V24XX_SDRC_RFR_CTRL_100MHz	(0x0002da01 | 1)
+#define V24XX_SDRC_RFR_CTRL_110MHz	(0x0002da01 | 1) /* Need to calc */
+#define V24XX_SDRC_RFR_CTRL_BYPASS	(0x00005000 | 1) /* Need to calc */
+
+/* MPU speed defines */
+#define S12M	12000000
+#define S13M	13000000
+#define S19M	19200000
+#define S26M	26000000
+#define S100M	100000000
+#define S133M	133000000
+#define S150M	150000000
+#define S165M	165000000
+#define S200M	200000000
+#define S266M	266000000
+#define S300M	300000000
+#define S330M	330000000
+#define S400M	400000000
+#define S532M	532000000
+#define S600M	600000000
+#define S660M	660000000
+
+/*-------------------------------------------------------------------------
+ * Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
+ * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,
+ * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL,
+ * CM_CLKSEL2_PLL, CM_CLKSEL_MDM
+ *
+ * Filling in table based on H4 boards and 2430-SDPs variants available.
+ * There are quite a few more rates combinations which could be defined.
+ *
+ * When multiple values are defiend the start up will try and choose the
+ * fastest one. If a 'fast' value is defined, then automatically, the /2
+ * one should be included as it can be used.	Generally having more that
+ * one fast set does not make sense, as static timings need to be changed
+ * to change the set.	 The exception is the bypass setting which is
+ * availble for low power bypass.
+ *
+ * Note: This table needs to be sorted, fastest to slowest.
+ *-------------------------------------------------------------------------*/
+static struct prcm_config rate_table[] = {
+	/* PRCM II - FAST */
+	{S12M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL,		/* 300MHz ARM */
+		RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+		RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz,
+		RATE_IN_242X},
+
+	{S13M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL,		/* 300MHz ARM */
+		RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+		RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz,
+		RATE_IN_242X},
+
+	/* PRCM III - FAST */
+	{S12M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL,		/* 266MHz ARM */
+		RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+		RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz,
+		RATE_IN_242X},
+
+	{S13M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL,		/* 266MHz ARM */
+		RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+		RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz,
+		RATE_IN_242X},
+
+	/* PRCM II - SLOW */
+	{S12M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL,		/* 150MHz ARM */
+		RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+		RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz,
+		RATE_IN_242X},
+
+	{S13M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL,		/* 150MHz ARM */
+		RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+		RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_100MHz,
+		RATE_IN_242X},
+
+	/* PRCM III - SLOW */
+	{S12M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL,		/* 133MHz ARM */
+		RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+		RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz,
+		RATE_IN_242X},
+
+	{S13M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL,		/* 133MHz ARM */
+		RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+		RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_133MHz,
+		RATE_IN_242X},
+
+	/* PRCM-VII (boot-bypass) */
+	{S12M, S12M, S12M, RVII_CM_CLKSEL_MPU_VAL,		/* 12MHz ARM*/
+		RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL,
+		RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_12_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_BYPASS,
+		RATE_IN_242X},
+
+	/* PRCM-VII (boot-bypass) */
+	{S13M, S13M, S13M, RVII_CM_CLKSEL_MPU_VAL,		/* 13MHz ARM */
+		RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL,
+		RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, 0, V24XX_SDRC_RFR_CTRL_BYPASS,
+		RATE_IN_242X},
+
+	/* PRCM #3 - ratio2 (ES2) - FAST */
+	{S13M, S660M, S330M, R2_CM_CLKSEL_MPU_VAL,		/* 330MHz ARM */
+		R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL,
+		R2_CM_CLKSEL1_CORE_VAL, M3_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, R2_CM_CLKSEL_MDM_VAL,
+		V24XX_SDRC_RFR_CTRL_110MHz,
+		RATE_IN_243X},
+
+	/* PRCM #5a - ratio1 - FAST */
+	{S13M, S532M, S266M, R1_CM_CLKSEL_MPU_VAL,		/* 266MHz ARM */
+		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+		R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
+		V24XX_SDRC_RFR_CTRL_133MHz,
+		RATE_IN_243X},
+
+	/* PRCM #5b - ratio1 - FAST */
+	{S13M, S400M, S200M, R1_CM_CLKSEL_MPU_VAL,		/* 200MHz ARM */
+		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+		R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
+		V24XX_SDRC_RFR_CTRL_100MHz,
+		RATE_IN_243X},
+
+	/* PRCM #3 - ratio2 (ES2) - SLOW */
+	{S13M, S330M, S165M, R2_CM_CLKSEL_MPU_VAL,		/* 165MHz ARM */
+		R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL,
+		R2_CM_CLKSEL1_CORE_VAL, M3_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_1x_VAL, R2_CM_CLKSEL_MDM_VAL,
+		V24XX_SDRC_RFR_CTRL_110MHz,
+		RATE_IN_243X},
+
+	/* PRCM #5a - ratio1 - SLOW */
+	{S13M, S266M, S133M, R1_CM_CLKSEL_MPU_VAL,		/* 133MHz ARM */
+		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+		R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
+		V24XX_SDRC_RFR_CTRL_133MHz,
+		RATE_IN_243X},
+
+	/* PRCM #5b - ratio1 - SLOW*/
+	{S13M, S200M, S100M, R1_CM_CLKSEL_MPU_VAL,		/* 100MHz ARM */
+		R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+		R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
+		V24XX_SDRC_RFR_CTRL_100MHz,
+		RATE_IN_243X},
+
+	/* PRCM-boot/bypass */
+	{S13M, S13M, S13M, RB_CM_CLKSEL_MPU_VAL,		/* 13Mhz */
+		RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL,
+		RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_13_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL,
+		V24XX_SDRC_RFR_CTRL_BYPASS,
+		RATE_IN_243X},
+
+	/* PRCM-boot/bypass */
+	{S12M, S12M, S12M, RB_CM_CLKSEL_MPU_VAL,		/* 12Mhz */
+		RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL,
+		RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_12_VAL,
+		MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL,
+		V24XX_SDRC_RFR_CTRL_BYPASS,
+		RATE_IN_243X},
+
+	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+};
+
+/*-------------------------------------------------------------------------
+ * 24xx clock tree.
+ *
+ * NOTE:In many cases here we are assigning a 'default' parent.	In many
+ *	cases the parent is selectable.	The get/set parent calls will also
+ *	switch sources.
+ *
+ *	Many some clocks say always_enabled, but they can be auto idled for
+ *	power savings. They will always be available upon clock request.
+ *
+ *	Several sources are given initial rates which may be wrong, this will
+ *	be fixed up in the init func.
+ *
+ *	Things are broadly separated below by clock domains. It is
+ *	noteworthy that most periferals have dependencies on multiple clock
+ *	domains. Many get their interface clocks from the L4 domain, but get
+ *	functional clocks from fixed sources or other core domain derived
+ *	clocks.
+ *-------------------------------------------------------------------------*/
+
+/* Base external input clocks */
+static struct clk func_32k_ck = {
+	.name		= "func_32k_ck",
+	.rate		= 32000,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_FIXED | ALWAYS_ENABLED,
+};
+
+/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
+static struct clk osc_ck = {		/* (*12, *13, 19.2, *26, 38.4)MHz */
+	.name		= "osc_ck",
+	.rate		= 26000000,		/* fixed up in clock init */
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+};
+
+/* With out modem likely 12MHz, with modem likely 13MHz */
+static struct clk sys_ck = {		/* (*12, *13, 19.2, 26, 38.4)MHz */
+	.name		= "sys_ck",		/* ~ ref_clk also */
+	.parent		= &osc_ck,
+	.rate		= 13000000,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+	.rate_offset	= 6, /* sysclkdiv 1 or 2, already handled or no boot */
+	.recalc		= &omap2_sys_clk_recalc,
+};
+
+static struct clk alt_ck = {		/* Typical 54M or 48M, may not exist */
+	.name		= "alt_ck",
+	.rate		= 54000000,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+	.recalc		= &omap2_propagate_rate,
+};
+
+/*
+ * Analog domain root source clocks
+ */
+
+/* dpll_ck, is broken out in to special cases through clksel */
+static struct clk dpll_ck = {
+	.name		= "dpll_ck",
+	.parent		= &sys_ck,		/* Can be func_32k also */
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_PROPAGATES | RATE_CKCTL | CM_PLL_SEL1,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk apll96_ck = {
+	.name		= "apll96_ck",
+	.parent		= &sys_ck,
+	.rate		= 96000000,
+	.flags		= CLOCK_IN_OMAP242X |CLOCK_IN_OMAP243X |
+				RATE_FIXED | RATE_PROPAGATES,
+	.enable_reg	= (void __iomem *)&CM_CLKEN_PLL,
+	.enable_bit	= 0x2,
+	.recalc		= &omap2_propagate_rate,
+};
+
+static struct clk apll54_ck = {
+	.name		= "apll54_ck",
+	.parent		= &sys_ck,
+	.rate		= 54000000,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_FIXED | RATE_PROPAGATES,
+	.enable_reg	= (void __iomem *)&CM_CLKEN_PLL,
+	.enable_bit	= 0x6,
+	.recalc		= &omap2_propagate_rate,
+};
+
+/*
+ * PRCM digital base sources
+ */
+static struct clk func_54m_ck = {
+	.name		= "func_54m_ck",
+	.parent		= &apll54_ck,	/* can also be alt_clk */
+	.rate		= 54000000,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_FIXED | CM_PLL_SEL1 | RATE_PROPAGATES,
+	.src_offset	= 5,
+	.enable_reg	= (void __iomem *)&CM_CLKEN_PLL,
+	.enable_bit	= 0xff,
+	.recalc		= &omap2_propagate_rate,
+};
+
+static struct clk core_ck = {
+	.name		= "core_ck",
+	.parent		= &dpll_ck,		/* can also be 32k */
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				ALWAYS_ENABLED | RATE_PROPAGATES,
+	.recalc		= &omap2_propagate_rate,
+};
+
+static struct clk sleep_ck = {		/* sys_clk or 32k */
+	.name		= "sleep_ck",
+	.parent		= &func_32k_ck,
+	.rate		= 32000,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.recalc		= &omap2_propagate_rate,
+};
+
+static struct clk func_96m_ck = {
+	.name		= "func_96m_ck",
+	.parent		= &apll96_ck,
+	.rate		= 96000000,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_FIXED | RATE_PROPAGATES,
+	.enable_reg	= (void __iomem *)&CM_CLKEN_PLL,
+	.enable_bit	= 0xff,
+	.recalc		= &omap2_propagate_rate,
+};
+
+static struct clk func_48m_ck = {
+	.name		= "func_48m_ck",
+	.parent		= &apll96_ck,	 /* 96M or Alt */
+	.rate		= 48000000,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_FIXED | CM_PLL_SEL1 | RATE_PROPAGATES,
+	.src_offset	= 3,
+	.enable_reg	= (void __iomem *)&CM_CLKEN_PLL,
+	.enable_bit	= 0xff,
+	.recalc		= &omap2_propagate_rate,
+};
+
+static struct clk func_12m_ck = {
+	.name		= "func_12m_ck",
+	.parent		= &func_48m_ck,
+	.rate		= 12000000,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_FIXED | RATE_PROPAGATES,
+	.recalc		= &omap2_propagate_rate,
+	.enable_reg	= (void __iomem *)&CM_CLKEN_PLL,
+	.enable_bit	= 0xff,
+};
+
+/* Secure timer, only available in secure mode */
+static struct clk wdt1_osc_ck = {
+	.name		= "ck_wdt1_osc",
+	.parent		= &osc_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk sys_clkout = {
+	.name		= "sys_clkout",
+	.parent		= &func_54m_ck,
+	.rate		= 54000000,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				CM_SYSCLKOUT_SEL1 | RATE_CKCTL,
+	.src_offset	= 0,
+	.enable_reg	= (void __iomem *)&PRCM_CLKOUT_CTRL,
+	.enable_bit	= 7,
+	.rate_offset	= 3,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* In 2430, new in 2420 ES2 */
+static struct clk sys_clkout2 = {
+	.name		= "sys_clkout2",
+	.parent		= &func_54m_ck,
+	.rate		= 54000000,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				CM_SYSCLKOUT_SEL1 | RATE_CKCTL,
+	.src_offset	= 8,
+	.enable_reg	= (void __iomem *)&PRCM_CLKOUT_CTRL,
+	.enable_bit	= 15,
+	.rate_offset	= 11,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * MPU clock domain
+ *	Clocks:
+ *		MPU_FCLK, MPU_ICLK
+ *		INT_M_FCLK, INT_M_I_CLK
+ *
+ * - Individual clocks are hardware managed.
+ * - Base divider comes from: CM_CLKSEL_MPU
+ *
+ */
+static struct clk mpu_ck = {	/* Control cpu */
+	.name		= "mpu_ck",
+	.parent		= &core_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_CKCTL |
+				ALWAYS_ENABLED | CM_MPU_SEL1 | DELAYED_APP |
+				CONFIG_PARTICIPANT | RATE_PROPAGATES,
+	.rate_offset	= 0,	/* bits 0-4 */
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * DSP (2430-IVA2.1) (2420-UMA+IVA1) clock domain
+ * Clocks:
+ *	2430: IVA2.1_FCLK, IVA2.1_ICLK
+ *	2420: UMA_FCLK, UMA_ICLK, IVA_MPU, IVA_COP
+ */
+static struct clk iva2_1_fck = {
+	.name		= "iva2_1_fck",
+	.parent		= &core_ck,
+	.flags		= CLOCK_IN_OMAP243X | RATE_CKCTL | CM_DSP_SEL1 |
+				DELAYED_APP | RATE_PROPAGATES |
+				CONFIG_PARTICIPANT,
+	.rate_offset	= 0,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN_DSP,
+	.enable_bit	= 0,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk iva2_1_ick = {
+	.name		= "iva2_1_ick",
+	.parent		= &iva2_1_fck,
+	.flags		= CLOCK_IN_OMAP243X | RATE_CKCTL | CM_DSP_SEL1 |
+				DELAYED_APP | CONFIG_PARTICIPANT,
+	.rate_offset	= 5,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * Won't be too specific here. The core clock comes into this block
+ * it is divided then tee'ed. One branch goes directly to xyz enable
+ * controls. The other branch gets further divided by 2 then possibly
+ * routed into a synchronizer and out of clocks abc.
+ */
+static struct clk dsp_fck = {
+	.name		= "dsp_fck",
+	.parent		= &core_ck,
+	.flags		= CLOCK_IN_OMAP242X | RATE_CKCTL | CM_DSP_SEL1 |
+			DELAYED_APP | CONFIG_PARTICIPANT | RATE_PROPAGATES,
+	.rate_offset	= 0,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN_DSP,
+	.enable_bit	= 0,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk dsp_ick = {
+	.name		= "dsp_ick",	 /* apparently ipi and isp */
+	.parent		= &dsp_fck,
+	.flags		= CLOCK_IN_OMAP242X | RATE_CKCTL | CM_DSP_SEL1 |
+				DELAYED_APP | CONFIG_PARTICIPANT,
+	.rate_offset = 5,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN_DSP,
+	.enable_bit	= 1,		/* for ipi */
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk iva1_ifck = {
+	.name		= "iva1_ifck",
+	.parent		= &core_ck,
+	.flags		= CLOCK_IN_OMAP242X | CM_DSP_SEL1 | RATE_CKCTL |
+			CONFIG_PARTICIPANT | RATE_PROPAGATES | DELAYED_APP,
+	.rate_offset= 8,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN_DSP,
+	.enable_bit	= 10,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/* IVA1 mpu/int/i/f clocks are /2 of parent */
+static struct clk iva1_mpu_int_ifck = {
+	.name		= "iva1_mpu_int_ifck",
+	.parent		= &iva1_ifck,
+	.flags		= CLOCK_IN_OMAP242X | RATE_CKCTL | CM_DSP_SEL1,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN_DSP,
+	.enable_bit	= 8,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * L3 clock domain
+ * L3 clocks are used for both interface and functional clocks to
+ * multiple entities. Some of these clocks are completely managed
+ * by hardware, and some others allow software control. Hardware
+ * managed ones general are based on directly CLK_REQ signals and
+ * various auto idle settings. The functional spec sets many of these
+ * as 'tie-high' for their enables.
+ *
+ * I-CLOCKS:
+ *	L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA
+ *	CAM, HS-USB.
+ * F-CLOCK
+ *	SSI.
+ *
+ * GPMC memories and SDRC have timing and clock sensitive registers which
+ * may very well need notification when the clock changes. Currently for low
+ * operating points, these are taken care of in sleep.S.
+ */
+static struct clk core_l3_ck = {	/* Used for ick and fck, interconnect */
+	.name		= "core_l3_ck",
+	.parent		= &core_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_CKCTL | ALWAYS_ENABLED | CM_CORE_SEL1 |
+				DELAYED_APP | CONFIG_PARTICIPANT |
+				RATE_PROPAGATES,
+	.rate_offset	= 0,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk usb_l4_ick = {	/* FS-USB interface clock */
+	.name		= "usb_l4_ick",
+	.parent		= &core_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP |
+				CONFIG_PARTICIPANT,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN2_CORE,
+	.enable_bit	= 0,
+	.rate_offset = 25,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * SSI is in L3 management domain, its direct parent is core not l3,
+ * many core power domain entities are grouped into the L3 clock
+ * domain.
+ * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_CLIK
+ *
+ * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
+ */
+static struct clk ssi_ssr_sst_fck = {
+	.name		= "ssi_fck",
+	.parent		= &core_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,	/* bit 1 */
+	.enable_bit	= 1,
+	.rate_offset = 20,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+/*
+ * GFX clock domain
+ *	Clocks:
+ * GFX_FCLK, GFX_ICLK
+ * GFX_CG1(2d), GFX_CG2(3d)
+ *
+ * GFX_FCLK runs from L3, and is divided by (1,2,3,4)
+ * The 2d and 3d clocks run at a hardware determined
+ * divided value of fclk.
+ *
+ */
+static struct clk gfx_3d_fck = {
+	.name		= "gfx_3d_fck",
+	.parent		= &core_l3_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_CKCTL | CM_GFX_SEL1,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN_GFX,
+	.enable_bit	= 2,
+	.rate_offset= 0,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gfx_2d_fck = {
+	.name		= "gfx_2d_fck",
+	.parent		= &core_l3_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_CKCTL | CM_GFX_SEL1,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN_GFX,
+	.enable_bit	= 1,
+	.rate_offset= 0,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk gfx_ick = {
+	.name		= "gfx_ick",		/* From l3 */
+	.parent		= &core_l3_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_CKCTL,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN_GFX,	/* bit 0 */
+	.enable_bit	= 0,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+/*
+ * Modem clock domain (2430)
+ *	CLOCKS:
+ *		MDM_OSC_CLK
+ *		MDM_ICLK
+ */
+static struct clk mdm_ick = {		/* used both as a ick and fck */
+	.name		= "mdm_ick",
+	.parent		= &core_ck,
+	.flags		= CLOCK_IN_OMAP243X | RATE_CKCTL | CM_MODEM_SEL1 |
+				DELAYED_APP | CONFIG_PARTICIPANT,
+	.rate_offset	= 0,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN_MDM,
+	.enable_bit	= 0,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk mdm_osc_ck = {
+	.name		= "mdm_osc_ck",
+	.rate		= 26000000,
+	.parent		= &osc_ck,
+	.flags		= CLOCK_IN_OMAP243X | RATE_FIXED,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN_MDM,
+	.enable_bit	= 1,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+/*
+ * L4 clock management domain
+ *
+ * This domain contains lots of interface clocks from the L4 interface, some
+ * functional clocks.	Fixed APLL functional source clocks are managed in
+ * this domain.
+ */
+static struct clk l4_ck = {		/* used both as an ick and fck */
+	.name		= "l4_ck",
+	.parent		= &core_l3_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_CKCTL | ALWAYS_ENABLED | CM_CORE_SEL1 |
+				DELAYED_APP | RATE_PROPAGATES,
+	.rate_offset	= 5,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk ssi_l4_ick = {
+	.name		= "ssi_l4_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_CKCTL,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN2_CORE,	/* bit 1 */
+	.enable_bit	= 1,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+/*
+ * DSS clock domain
+ * CLOCKs:
+ * DSS_L4_ICLK, DSS_L3_ICLK,
+ * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK
+ *
+ * DSS is both initiator and target.
+ */
+static struct clk dss_ick = {		/* Enables both L3,L4 ICLK's */
+	.name		= "dss_ick",
+	.parent		= &l4_ck,	/* really both l3 and l4 */
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | RATE_CKCTL,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 0,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk dss1_fck = {
+	.name		= "dss1_fck",
+	.parent		= &core_ck,		/* Core or sys */
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 0,
+	.rate_offset	= 8,
+	.src_offset	= 8,
+	.recalc		= &omap2_clksel_recalc,
+};
+
+static struct clk dss2_fck = {		/* Alt clk used in power management */
+	.name		= "dss2_fck",
+	.parent		= &sys_ck,		/* fixed at sys_ck or 48MHz */
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_CKCTL | CM_CORE_SEL1 | RATE_FIXED,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 1,
+	.src_offset	= 13,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk dss_54m_fck = {	/* Alt clk used in power management */
+	.name		= "dss_54m_fck",	/* 54m tv clk */
+	.parent		= &func_54m_ck,
+	.rate		= 54000000,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				RATE_FIXED | RATE_PROPAGATES,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 2,
+	.recalc		= &omap2_propagate_rate,
+};
+
+/*
+ * CORE power domain ICLK & FCLK defines.
+ * Many of the these can have more than one possible parent. Entries
+ * here will likely have an L4 interface parent, and may have multiple
+ * functional clock parents.
+ */
+static struct clk gpt1_ick = {
+	.name		= "gpt1_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN_WKUP,	/* Bit4 */
+	.enable_bit	= 0,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt1_fck = {
+	.name		= "gpt1_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				CM_WKUP_SEL1,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN_WKUP,
+	.enable_bit	= 0,
+	.src_offset	= 0,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt2_ick = {
+	.name		= "gpt2_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,	/* bit4 */
+	.enable_bit	= 0,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt2_fck = {
+	.name		= "gpt2_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				CM_CORE_SEL2,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 4,
+	.src_offset	= 2,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt3_ick = {
+	.name		= "gpt3_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,	/* Bit5 */
+	.enable_bit	= 5,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt3_fck = {
+	.name		= "gpt3_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				CM_CORE_SEL2,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 5,
+	.src_offset	= 4,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt4_ick = {
+	.name		= "gpt4_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,	/* Bit6 */
+	.enable_bit	= 6,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt4_fck = {
+	.name		= "gpt4_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				CM_CORE_SEL2,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 6,
+	.src_offset	= 6,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt5_ick = {
+	.name		= "gpt5_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,	 /* Bit7 */
+	.enable_bit	= 7,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt5_fck = {
+	.name		= "gpt5_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				CM_CORE_SEL2,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 7,
+	.src_offset	= 8,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt6_ick = {
+	.name		= "gpt6_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_bit	= 8,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,	 /* bit8 */
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt6_fck = {
+	.name		= "gpt6_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				CM_CORE_SEL2,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 8,
+	.src_offset	= 10,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt7_ick = {
+	.name		= "gpt7_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,	 /* bit9 */
+	.enable_bit	= 9,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt7_fck = {
+	.name		= "gpt7_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				CM_CORE_SEL2,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 9,
+	.src_offset	= 12,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt8_ick = {
+	.name		= "gpt8_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,	 /* bit10 */
+	.enable_bit	= 10,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt8_fck = {
+	.name		= "gpt8_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				CM_CORE_SEL2,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 10,
+	.src_offset	= 14,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt9_ick = {
+	.name		= "gpt9_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 11,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt9_fck = {
+	.name		= "gpt9_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+					CM_CORE_SEL2,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 11,
+	.src_offset	= 16,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt10_ick = {
+	.name		= "gpt10_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 12,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt10_fck = {
+	.name		= "gpt10_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+					CM_CORE_SEL2,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 12,
+	.src_offset	= 18,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt11_ick = {
+	.name		= "gpt11_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 13,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt11_fck = {
+	.name		= "gpt11_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+					CM_CORE_SEL2,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 13,
+	.src_offset	= 20,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt12_ick = {
+	.name		= "gpt12_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,	 /* bit14 */
+	.enable_bit	= 14,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpt12_fck = {
+	.name		= "gpt12_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+					CM_CORE_SEL2,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 14,
+	.src_offset	= 22,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp1_ick = {
+	.name		= "mcbsp1_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_bit	= 15,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,	 /* bit16 */
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp1_fck = {
+	.name		= "mcbsp1_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_bit	= 15,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp2_ick = {
+	.name		= "mcbsp2_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_bit	= 16,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp2_fck = {
+	.name		= "mcbsp2_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_bit	= 16,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp3_ick = {
+	.name		= "mcbsp3_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN2_CORE,
+	.enable_bit	= 3,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp3_fck = {
+	.name		= "mcbsp3_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,
+	.enable_bit	= 3,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp4_ick = {
+	.name		= "mcbsp4_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN2_CORE,
+	.enable_bit	= 4,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp4_fck = {
+	.name		= "mcbsp4_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,
+	.enable_bit	= 4,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp5_ick = {
+	.name		= "mcbsp5_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN2_CORE,
+	.enable_bit	= 5,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcbsp5_fck = {
+	.name		= "mcbsp5_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,
+	.enable_bit	= 5,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcspi1_ick = {
+	.name		= "mcspi1_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 17,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcspi1_fck = {
+	.name		= "mcspi1_fck",
+	.parent		= &func_48m_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 17,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcspi2_ick = {
+	.name		= "mcspi2_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 18,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcspi2_fck = {
+	.name		= "mcspi2_fck",
+	.parent		= &func_48m_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 18,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcspi3_ick = {
+	.name		= "mcspi3_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN2_CORE,
+	.enable_bit	= 9,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mcspi3_fck = {
+	.name		= "mcspi3_fck",
+	.parent		= &func_48m_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,
+	.enable_bit	= 9,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk uart1_ick = {
+	.name		= "uart1_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 21,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk uart1_fck = {
+	.name		= "uart1_fck",
+	.parent		= &func_48m_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 21,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk uart2_ick = {
+	.name		= "uart2_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 22,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk uart2_fck = {
+	.name		= "uart2_fck",
+	.parent		= &func_48m_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 22,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk uart3_ick = {
+	.name		= "uart3_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN2_CORE,
+	.enable_bit	= 2,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk uart3_fck = {
+	.name		= "uart3_fck",
+	.parent		= &func_48m_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,
+	.enable_bit	= 2,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpios_ick = {
+	.name		= "gpios_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN_WKUP,
+	.enable_bit	= 2,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpios_fck = {
+	.name		= "gpios_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN_WKUP,
+	.enable_bit	= 2,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mpu_wdt_ick = {
+	.name		= "mpu_wdt_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN_WKUP,
+	.enable_bit	= 3,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mpu_wdt_fck = {
+	.name		= "mpu_wdt_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN_WKUP,
+	.enable_bit	= 3,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk sync_32k_ick = {
+	.name		= "sync_32k_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN_WKUP,
+	.enable_bit	= 1,
+	.recalc		= &omap2_followparent_recalc,
+};
+static struct clk wdt1_ick = {
+	.name		= "wdt1_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN_WKUP,
+	.enable_bit	= 4,
+	.recalc		= &omap2_followparent_recalc,
+};
+static struct clk omapctrl_ick = {
+	.name		= "omapctrl_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN_WKUP,
+	.enable_bit	= 5,
+	.recalc		= &omap2_followparent_recalc,
+};
+static struct clk icr_ick = {
+	.name		= "icr_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN_WKUP,
+	.enable_bit	= 6,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk cam_ick = {
+	.name		= "cam_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 31,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk cam_fck = {
+	.name		= "cam_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 31,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mailboxes_ick = {
+	.name		= "mailboxes_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 30,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk wdt4_ick = {
+	.name		= "wdt4_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 29,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk wdt4_fck = {
+	.name		= "wdt4_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 29,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk wdt3_ick = {
+	.name		= "wdt3_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 28,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk wdt3_fck = {
+	.name		= "wdt3_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 28,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mspro_ick = {
+	.name		= "mspro_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 27,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mspro_fck = {
+	.name		= "mspro_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 27,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mmc_ick = {
+	.name		= "mmc_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 26,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mmc_fck = {
+	.name		= "mmc_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 26,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk fac_ick = {
+	.name		= "fac_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 25,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk fac_fck = {
+	.name		= "fac_fck",
+	.parent		= &func_12m_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 25,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk eac_ick = {
+	.name		= "eac_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 24,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk eac_fck = {
+	.name		= "eac_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 24,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk hdq_ick = {
+	.name		= "hdq_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 23,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk hdq_fck = {
+	.name		= "hdq_fck",
+	.parent		= &func_12m_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 23,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk i2c2_ick = {
+	.name		= "i2c2_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 20,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk i2c2_fck = {
+	.name		= "i2c2_fck",
+	.parent		= &func_12m_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 20,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk i2chs2_fck = {
+	.name		= "i2chs2_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,
+	.enable_bit	= 20,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk i2c1_ick = {
+	.name		= "i2c1_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 19,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk i2c1_fck = {
+	.name		= "i2c1_fck",
+	.parent		= &func_12m_ck,
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 19,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk i2chs1_fck = {
+	.name		= "i2chs1_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,
+	.enable_bit	= 19,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk vlynq_ick = {
+	.name		= "vlynq_ick",
+	.parent		= &core_l3_ck,
+	.flags		= CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN1_CORE,
+	.enable_bit	= 3,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk vlynq_fck = {
+	.name		= "vlynq_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP242X  | RATE_CKCTL | CM_CORE_SEL1 | DELAYED_APP,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN1_CORE,
+	.enable_bit	= 3,
+	.src_offset	= 15,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk sdrc_ick = {
+	.name		= "sdrc_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN3_CORE,
+	.enable_bit	= 2,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk des_ick = {
+	.name		= "des_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN4_CORE,
+	.enable_bit	= 0,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk sha_ick = {
+	.name		= "sha_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN4_CORE,
+	.enable_bit	= 1,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk rng_ick = {
+	.name		= "rng_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN4_CORE,
+	.enable_bit	= 2,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk aes_ick = {
+	.name		= "aes_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN4_CORE,
+	.enable_bit	= 3,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk pka_ick = {
+	.name		= "pka_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN4_CORE,
+	.enable_bit	= 4,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk usb_fck = {
+	.name		= "usb_fck",
+	.parent		= &func_48m_ck,
+	.flags		= CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,
+	.enable_bit	= 0,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk usbhs_ick = {
+	.name		= "usbhs_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN2_CORE,
+	.enable_bit	= 6,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mmchs1_ick = {
+	.name		= "mmchs1_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN2_CORE,
+	.enable_bit	= 7,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mmchs1_fck = {
+	.name		= "mmchs1_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,
+	.enable_bit	= 7,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mmchs2_ick = {
+	.name		= "mmchs2_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN2_CORE,
+	.enable_bit	= 8,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mmchs2_fck = {
+	.name		= "mmchs2_fck",
+	.parent		= &func_96m_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,
+	.enable_bit	= 8,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpio5_ick = {
+	.name		= "gpio5_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN2_CORE,
+	.enable_bit	= 10,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk gpio5_fck = {
+	.name		= "gpio5_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,
+	.enable_bit	= 10,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mdm_intc_ick = {
+	.name		= "mdm_intc_ick",
+	.parent		= &l4_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_ICLKEN2_CORE,
+	.enable_bit	= 11,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mmchsdb1_fck = {
+	.name		= "mmchsdb1_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,
+	.enable_bit	= 16,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+static struct clk mmchsdb2_fck = {
+	.name		= "mmchsdb2_fck",
+	.parent		= &func_32k_ck,
+	.flags		= CLOCK_IN_OMAP243X,
+	.enable_reg	= (void __iomem *)&CM_FCLKEN2_CORE,
+	.enable_bit	= 17,
+	.recalc		= &omap2_followparent_recalc,
+};
+
+/*
+ * This clock is a composite clock which does entire set changes then
+ * forces a rebalance. It keys on the MPU speed, but it really could
+ * be any key speed part of a set in the rate table.
+ *
+ * to really change a set, you need memory table sets which get changed
+ * in sram, pre-notifiers & post notifiers, changing the top set, without
+ * having low level display recalc's won't work... this is why dpm notifiers
+ * work, isr's off, walk a list of clocks already _off_ and not messing with
+ * the bus.
+ *
+ * This clock should have no parent. It embodies the entire upper level
+ * active set. A parent will mess up some of the init also.
+ */
+static struct clk virt_prcm_set = {
+	.name		= "virt_prcm_set",
+	.flags		= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+				VIRTUAL_CLOCK | ALWAYS_ENABLED | DELAYED_APP,
+	.parent		= &mpu_ck,	/* Indexed by mpu speed, no parent */
+	.recalc		= &omap2_mpu_recalc,	/* sets are keyed on mpu rate */
+	.set_rate	= &omap2_select_table_rate,
+	.round_rate	= &omap2_round_to_table_rate,
+};
+
+static struct clk *onchip_clks[] = {
+	/* external root sources */
+	&func_32k_ck,
+	&osc_ck,
+	&sys_ck,
+	&alt_ck,
+	/* internal analog sources */
+	&dpll_ck,
+	&apll96_ck,
+	&apll54_ck,
+	/* internal prcm root sources */
+	&func_54m_ck,
+	&core_ck,
+	&sleep_ck,
+	&func_96m_ck,
+	&func_48m_ck,
+	&func_12m_ck,
+	&wdt1_osc_ck,
+	&sys_clkout,
+	&sys_clkout2,
+	/* mpu domain clocks */
+	&mpu_ck,
+	/* dsp domain clocks */
+	&iva2_1_fck,		/* 2430 */
+	&iva2_1_ick,
+	&dsp_ick,		/* 2420 */
+	&dsp_fck,
+	&iva1_ifck,
+	&iva1_mpu_int_ifck,
+	/* GFX domain clocks */
+	&gfx_3d_fck,
+	&gfx_2d_fck,
+	&gfx_ick,
+	/* Modem domain clocks */
+	&mdm_ick,
+	&mdm_osc_ck,
+	/* DSS domain clocks */
+	&dss_ick,
+	&dss1_fck,
+	&dss2_fck,
+	&dss_54m_fck,
+	/* L3 domain clocks */
+	&core_l3_ck,
+	&ssi_ssr_sst_fck,
+	&usb_l4_ick,
+	/* L4 domain clocks */
+	&l4_ck,			/* used as both core_l4 and wu_l4 */
+	&ssi_l4_ick,
+	/* virtual meta-group clock */
+	&virt_prcm_set,
+	/* general l4 interface ck, multi-parent functional clk */
+	&gpt1_ick,
+	&gpt1_fck,
+	&gpt2_ick,
+	&gpt2_fck,
+	&gpt3_ick,
+	&gpt3_fck,
+	&gpt4_ick,
+	&gpt4_fck,
+	&gpt5_ick,
+	&gpt5_fck,
+	&gpt6_ick,
+	&gpt6_fck,
+	&gpt7_ick,
+	&gpt7_fck,
+	&gpt8_ick,
+	&gpt8_fck,
+	&gpt9_ick,
+	&gpt9_fck,
+	&gpt10_ick,
+	&gpt10_fck,
+	&gpt11_ick,
+	&gpt11_fck,
+	&gpt12_ick,
+	&gpt12_fck,
+	&mcbsp1_ick,
+	&mcbsp1_fck,
+	&mcbsp2_ick,
+	&mcbsp2_fck,
+	&mcbsp3_ick,
+	&mcbsp3_fck,
+	&mcbsp4_ick,
+	&mcbsp4_fck,
+	&mcbsp5_ick,
+	&mcbsp5_fck,
+	&mcspi1_ick,
+	&mcspi1_fck,
+	&mcspi2_ick,
+	&mcspi2_fck,
+	&mcspi3_ick,
+	&mcspi3_fck,
+	&uart1_ick,
+	&uart1_fck,
+	&uart2_ick,
+	&uart2_fck,
+	&uart3_ick,
+	&uart3_fck,
+	&gpios_ick,
+	&gpios_fck,
+	&mpu_wdt_ick,
+	&mpu_wdt_fck,
+	&sync_32k_ick,
+	&wdt1_ick,
+	&omapctrl_ick,
+	&icr_ick,
+	&cam_fck,
+	&cam_ick,
+	&mailboxes_ick,
+	&wdt4_ick,
+	&wdt4_fck,
+	&wdt3_ick,
+	&wdt3_fck,
+	&mspro_ick,
+	&mspro_fck,
+	&mmc_ick,
+	&mmc_fck,
+	&fac_ick,
+	&fac_fck,
+	&eac_ick,
+	&eac_fck,
+	&hdq_ick,
+	&hdq_fck,
+	&i2c1_ick,
+	&i2c1_fck,
+	&i2chs1_fck,
+	&i2c2_ick,
+	&i2c2_fck,
+	&i2chs2_fck,
+	&vlynq_ick,
+	&vlynq_fck,
+	&sdrc_ick,
+	&des_ick,
+	&sha_ick,
+	&rng_ick,
+	&aes_ick,
+	&pka_ick,
+	&usb_fck,
+	&usbhs_ick,
+	&mmchs1_ick,
+	&mmchs1_fck,
+	&mmchs2_ick,
+	&mmchs2_fck,
+	&gpio5_ick,
+	&gpio5_fck,
+	&mdm_intc_ick,
+	&mmchsdb1_fck,
+	&mmchsdb2_fck,
+};
+
+#endif

+ 89 - 0
arch/arm/mach-omap2/devices.c

@@ -0,0 +1,89 @@
+/*
+ * linux/arch/arm/mach-omap2/devices.c
+ *
+ * OMAP2 platform device setup/initialization
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/tc.h>
+#include <asm/arch/board.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/gpio.h>
+
+extern void omap_nop_release(struct device *dev);
+
+/*-------------------------------------------------------------------------*/
+
+#if 	defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
+
+#define OMAP2_I2C_BASE2		0x48072000
+#define OMAP2_I2C_INT2		57
+
+static struct resource i2c_resources2[] = {
+	{
+		.start		= OMAP2_I2C_BASE2,
+		.end		= OMAP2_I2C_BASE2 + 0x3f,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP2_I2C_INT2,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device omap_i2c_device2 = {
+        .name           = "i2c_omap",
+        .id             = 2,
+        .dev = {
+                .release        = omap_nop_release,
+        },
+	.num_resources	= ARRAY_SIZE(i2c_resources2),
+	.resource	= i2c_resources2,
+};
+
+/* See also arch/arm/plat-omap/devices.c for first I2C on 24xx */
+static void omap_init_i2c(void)
+{
+	/* REVISIT: Second I2C not in use on H4? */
+	if (machine_is_omap_h4())
+		return;
+
+	omap_cfg_reg(J15_24XX_I2C2_SCL);
+	omap_cfg_reg(H19_24XX_I2C2_SDA);
+	(void) platform_device_register(&omap_i2c_device2);
+}
+
+#else
+
+static void omap_init_i2c(void) {}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static int __init omap2_init_devices(void)
+{
+	/* please keep these calls, and their implementations above,
+	 * in alphabetical order so they're easier to sort through.
+	 */
+	omap_init_i2c();
+
+	return 0;
+}
+arch_initcall(omap2_init_devices);
+

+ 124 - 0
arch/arm/mach-omap2/id.c

@@ -0,0 +1,124 @@
+/*
+ * linux/arch/arm/mach-omap2/id.c
+ *
+ * OMAP2 CPU identification code
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+
+#define OMAP24XX_TAP_BASE	io_p2v(0x48014000)
+
+#define OMAP_TAP_IDCODE		0x0204
+#define OMAP_TAP_PROD_ID	0x0208
+
+#define OMAP_TAP_DIE_ID_0	0x0218
+#define OMAP_TAP_DIE_ID_1	0x021C
+#define OMAP_TAP_DIE_ID_2	0x0220
+#define OMAP_TAP_DIE_ID_3	0x0224
+
+/* system_rev fields for OMAP2 processors:
+ *   CPU id bits     [31:16],
+ *   CPU device type [15:12], (unprg,normal,POP)
+ *   CPU revision    [11:08]
+ *   CPU class bits  [07:00]
+ */
+
+struct omap_id {
+	u16	hawkeye;	/* Silicon type (Hawkeye id) */
+	u8	dev;		/* Device type from production_id reg */
+	u32	type;		/* combined type id copied to system_rev */
+};
+
+/* Register values to detect the OMAP version */
+static struct omap_id omap_ids[] __initdata = {
+	{ .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200000 },
+	{ .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201000 },
+	{ .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202000 },
+	{ .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220000 },
+	{ .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230000 },
+	{ .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 },
+};
+
+static u32 __init read_tap_reg(int reg)
+{
+	return __raw_readl(OMAP24XX_TAP_BASE + reg);
+}
+
+void __init omap2_check_revision(void)
+{
+	int i, j;
+	u32 idcode;
+	u32 prod_id;
+	u16 hawkeye;
+	u8  dev_type;
+	u8  rev;
+
+	idcode = read_tap_reg(OMAP_TAP_IDCODE);
+	prod_id = read_tap_reg(OMAP_TAP_PROD_ID);
+	hawkeye = (idcode >> 12) & 0xffff;
+	rev = (idcode >> 28) & 0x0f;
+	dev_type = (prod_id >> 16) & 0x0f;
+
+#ifdef DEBUG
+	printk(KERN_DEBUG "OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
+		idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
+	printk(KERN_DEBUG "OMAP_TAP_DIE_ID_0: 0x%08x\n",
+		read_tap_reg(OMAP_TAP_DIE_ID_0));
+	printk(KERN_DEBUG "OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
+		read_tap_reg(OMAP_TAP_DIE_ID_1),
+	       (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf);
+	printk(KERN_DEBUG "OMAP_TAP_DIE_ID_2: 0x%08x\n",
+		read_tap_reg(OMAP_TAP_DIE_ID_2));
+	printk(KERN_DEBUG "OMAP_TAP_DIE_ID_3: 0x%08x\n",
+		read_tap_reg(OMAP_TAP_DIE_ID_3));
+	printk(KERN_DEBUG "OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
+		prod_id, dev_type);
+#endif
+
+	/* Check hawkeye ids */
+	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+		if (hawkeye == omap_ids[i].hawkeye)
+			break;
+	}
+
+	if (i == ARRAY_SIZE(omap_ids)) {
+		printk(KERN_ERR "Unknown OMAP CPU id\n");
+		return;
+	}
+
+	for (j = i; j < ARRAY_SIZE(omap_ids); j++) {
+		if (dev_type == omap_ids[j].dev)
+			break;
+	}
+
+	if (j == ARRAY_SIZE(omap_ids)) {
+		printk(KERN_ERR "Unknown OMAP device type. "
+				"Handling it as OMAP%04x\n",
+				omap_ids[i].type >> 16);
+		j = i;
+	}
+	system_rev = omap_ids[j].type;
+
+	system_rev |= rev << 8;
+
+	/* Add the cpu class info (24xx) */
+	system_rev |= 0x24;
+
+	pr_info("OMAP%04x", system_rev >> 16);
+	if ((system_rev >> 8) & 0x0f)
+		printk("%x", (system_rev >> 8) & 0x0f);
+	printk("\n");
+}
+

+ 53 - 0
arch/arm/mach-omap2/io.c

@@ -0,0 +1,53 @@
+/*
+ * linux/arch/arm/mach-omap2/io.c
+ *
+ * OMAP2 I/O mapping code
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+#include <asm/io.h>
+#include <asm/arch/mux.h>
+
+extern void omap_sram_init(void);
+extern int omap2_clk_init(void);
+extern void omap2_check_revision(void);
+
+/*
+ * The machine specific code may provide the extra mapping besides the
+ * default mapping provided here.
+ */
+static struct map_desc omap2_io_desc[] __initdata = {
+	{
+		.virtual	= L3_24XX_VIRT,
+		.pfn		= __phys_to_pfn(L3_24XX_PHYS),
+		.length		= L3_24XX_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= L4_24XX_VIRT,
+		.pfn		= __phys_to_pfn(L4_24XX_PHYS),
+		.length		= L4_24XX_SIZE,
+		.type		= MT_DEVICE
+	}
+};
+
+void __init omap_map_common_io(void)
+{
+	iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc));
+	omap2_check_revision();
+	omap_sram_init();
+	omap2_mux_init();
+	omap2_clk_init();
+}

+ 149 - 0
arch/arm/mach-omap2/irq.c

@@ -0,0 +1,149 @@
+/*
+ * linux/arch/arm/mach-omap/omap2/irq.c
+ *
+ * Interrupt handler for OMAP2 boards.
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/interrupt.h>
+#include <asm/hardware.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#define INTC_REVISION	0x0000
+#define INTC_SYSCONFIG	0x0010
+#define INTC_SYSSTATUS	0x0014
+#define INTC_CONTROL	0x0048
+#define INTC_MIR_CLEAR0	0x0088
+#define INTC_MIR_SET0	0x008c
+
+/*
+ * OMAP2 has a number of different interrupt controllers, each interrupt
+ * controller is identified as its own "bank". Register definitions are
+ * fairly consistent for each bank, but not all registers are implemented
+ * for each bank.. when in doubt, consult the TRM.
+ */
+static struct omap_irq_bank {
+	unsigned long base_reg;
+	unsigned int nr_irqs;
+} __attribute__ ((aligned(4))) irq_banks[] = {
+	{
+		/* MPU INTC */
+		.base_reg	= OMAP24XX_IC_BASE,
+		.nr_irqs	= 96,
+	}, {
+		/* XXX: DSP INTC */
+
+#if 0
+	/*
+	 * Commented out for now until we fix the IVA clocking
+	 */
+#ifdef CONFIG_ARCH_OMAP2420
+	}, {
+		/* IVA INTC (2420 only) */
+		.base_reg	= OMAP24XX_IVA_INTC_BASE,
+		.nr_irqs	= 16,	/* Actually 32, but only 16 are used */
+#endif
+#endif
+	}
+};
+
+/* XXX: FIQ and additional INTC support (only MPU at the moment) */
+static void omap_ack_irq(unsigned int irq)
+{
+	omap_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL);
+}
+
+static void omap_mask_irq(unsigned int irq)
+{
+	int offset = (irq >> 5) << 5;
+
+	if (irq >= 64) {
+		irq %= 64;
+	} else if (irq >= 32) {
+		irq %= 32;
+	}
+
+	omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset);
+}
+
+static void omap_unmask_irq(unsigned int irq)
+{
+	int offset = (irq >> 5) << 5;
+
+	if (irq >= 64) {
+		irq %= 64;
+	} else if (irq >= 32) {
+		irq %= 32;
+	}
+
+	omap_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset);
+}
+
+static void omap_mask_ack_irq(unsigned int irq)
+{
+	omap_mask_irq(irq);
+	omap_ack_irq(irq);
+}
+
+static struct irqchip omap_irq_chip = {
+	.ack	= omap_mask_ack_irq,
+	.mask	= omap_mask_irq,
+	.unmask	= omap_unmask_irq,
+};
+
+static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
+{
+	unsigned long tmp;
+
+	tmp = omap_readl(bank->base_reg + INTC_REVISION) & 0xff;
+	printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx "
+			 "(revision %ld.%ld) with %d interrupts\n",
+			 bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs);
+
+	tmp = omap_readl(bank->base_reg + INTC_SYSCONFIG);
+	tmp |= 1 << 1;	/* soft reset */
+	omap_writel(tmp, bank->base_reg + INTC_SYSCONFIG);
+
+	while (!(omap_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1))
+		/* Wait for reset to complete */;
+}
+
+void __init omap_init_irq(void)
+{
+	unsigned long nr_irqs = 0;
+	unsigned int nr_banks = 0;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
+		struct omap_irq_bank *bank = irq_banks + i;
+
+		/* XXX */
+		if (!bank->base_reg)
+			continue;
+
+		omap_irq_bank_init_one(bank);
+
+		nr_irqs += bank->nr_irqs;
+		nr_banks++;
+	}
+
+	printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n",
+	       nr_irqs, nr_banks, nr_banks > 1 ? "s" : "");
+
+	for (i = 0; i < nr_irqs; i++) {
+		set_irq_chip(i, &omap_irq_chip);
+		set_irq_handler(i, do_level_IRQ);
+		set_irq_flags(i, IRQF_VALID);
+	}
+}
+

+ 65 - 0
arch/arm/mach-omap2/mux.c

@@ -0,0 +1,65 @@
+/*
+ * linux/arch/arm/mach-omap2/mux.c
+ *
+ * OMAP1 pin multiplexing configurations
+ *
+ * Copyright (C) 2003 - 2005 Nokia Corporation
+ *
+ * Written by Tony Lindgren <tony.lindgren@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/arch/mux.h>
+
+#ifdef CONFIG_OMAP_MUX
+
+/* NOTE: See mux.h for the enumeration */
+
+struct pin_config __initdata_or_module omap24xx_pins[] = {
+/*
+ *	description			mux	mux	pull	pull	debug
+ *					offset	mode	ena	type
+ */
+
+/* 24xx I2C */
+MUX_CFG_24XX("M19_24XX_I2C1_SCL",	0x111,	0,	0,	0,	1)
+MUX_CFG_24XX("L15_24XX_I2C1_SDA",	0x112,	0,	0,	0,	1)
+MUX_CFG_24XX("J15_24XX_I2C2_SCL",	0x113,	0,	0,	0,	1)
+MUX_CFG_24XX("H19_24XX_I2C2_SDA",	0x114,	0,	0,	0,	1)
+
+/* Menelaus interrupt */
+MUX_CFG_24XX("W19_24XX_SYS_NIRQ",	0x12c,	0,	1,	1,	1)
+
+/* 24xx GPIO */
+MUX_CFG_24XX("Y20_24XX_GPIO60",		0x12c,	3,	0,	0,	1)
+MUX_CFG_24XX("M15_24XX_GPIO92",		0x10a,	3,	0,	0,	1)
+
+};
+
+int __init omap2_mux_init(void)
+{
+	omap_mux_register(omap24xx_pins, ARRAY_SIZE(omap24xx_pins));
+	return 0;
+}
+
+#endif

+ 419 - 0
arch/arm/mach-omap2/prcm.h

@@ -0,0 +1,419 @@
+/*
+ * prcm.h - Access definations for use in OMAP24XX clock and power management
+ *
+ * Copyright (C) 2005 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARM_ARCH_DPM_PRCM_H
+#define __ASM_ARM_ARCH_DPM_PRCM_H
+
+/* SET_PERFORMANCE_LEVEL PARAMETERS */
+#define PRCM_HALF_SPEED 1
+#define PRCM_FULL_SPEED 2
+
+#ifndef __ASSEMBLER__
+
+#define PRCM_REG32(offset)	__REG32(OMAP24XX_PRCM_BASE + (offset))
+
+#define PRCM_REVISION		PRCM_REG32(0x000)
+#define PRCM_SYSCONFIG		PRCM_REG32(0x010)
+#define PRCM_IRQSTATUS_MPU	PRCM_REG32(0x018)
+#define PRCM_IRQENABLE_MPU	PRCM_REG32(0x01C)
+#define PRCM_VOLTCTRL		PRCM_REG32(0x050)
+#define PRCM_VOLTST		PRCM_REG32(0x054)
+#define PRCM_CLKSRC_CTRL	PRCM_REG32(0x060)
+#define PRCM_CLKOUT_CTRL	PRCM_REG32(0x070)
+#define PRCM_CLKEMUL_CTRL	PRCM_REG32(0x078)
+#define PRCM_CLKCFG_CTRL	PRCM_REG32(0x080)
+#define PRCM_CLKCFG_STATUS	PRCM_REG32(0x084)
+#define PRCM_VOLTSETUP		PRCM_REG32(0x090)
+#define PRCM_CLKSSETUP		PRCM_REG32(0x094)
+#define PRCM_POLCTRL		PRCM_REG32(0x098)
+
+/* GENERAL PURPOSE */
+#define GENERAL_PURPOSE1	PRCM_REG32(0x0B0)
+#define GENERAL_PURPOSE2	PRCM_REG32(0x0B4)
+#define GENERAL_PURPOSE3	PRCM_REG32(0x0B8)
+#define GENERAL_PURPOSE4	PRCM_REG32(0x0BC)
+#define GENERAL_PURPOSE5	PRCM_REG32(0x0C0)
+#define GENERAL_PURPOSE6	PRCM_REG32(0x0C4)
+#define GENERAL_PURPOSE7	PRCM_REG32(0x0C8)
+#define GENERAL_PURPOSE8	PRCM_REG32(0x0CC)
+#define GENERAL_PURPOSE9	PRCM_REG32(0x0D0)
+#define GENERAL_PURPOSE10	PRCM_REG32(0x0D4)
+#define GENERAL_PURPOSE11	PRCM_REG32(0x0D8)
+#define GENERAL_PURPOSE12	PRCM_REG32(0x0DC)
+#define GENERAL_PURPOSE13	PRCM_REG32(0x0E0)
+#define GENERAL_PURPOSE14	PRCM_REG32(0x0E4)
+#define GENERAL_PURPOSE15	PRCM_REG32(0x0E8)
+#define GENERAL_PURPOSE16	PRCM_REG32(0x0EC)
+#define GENERAL_PURPOSE17	PRCM_REG32(0x0F0)
+#define GENERAL_PURPOSE18	PRCM_REG32(0x0F4)
+#define GENERAL_PURPOSE19	PRCM_REG32(0x0F8)
+#define GENERAL_PURPOSE20	PRCM_REG32(0x0FC)
+
+/* MPU */
+#define CM_CLKSEL_MPU		PRCM_REG32(0x140)
+#define CM_CLKSTCTRL_MPU	PRCM_REG32(0x148)
+#define RM_RSTST_MPU		PRCM_REG32(0x158)
+#define PM_WKDEP_MPU		PRCM_REG32(0x1C8)
+#define PM_EVGENCTRL_MPU	PRCM_REG32(0x1D4)
+#define PM_EVEGENONTIM_MPU	PRCM_REG32(0x1D8)
+#define PM_EVEGENOFFTIM_MPU	PRCM_REG32(0x1DC)
+#define PM_PWSTCTRL_MPU		PRCM_REG32(0x1E0)
+#define PM_PWSTST_MPU		PRCM_REG32(0x1E4)
+
+/* CORE */
+#define CM_FCLKEN1_CORE		PRCM_REG32(0x200)
+#define CM_FCLKEN2_CORE		PRCM_REG32(0x204)
+#define CM_FCLKEN3_CORE		PRCM_REG32(0x208)
+#define CM_ICLKEN1_CORE		PRCM_REG32(0x210)
+#define CM_ICLKEN2_CORE		PRCM_REG32(0x214)
+#define CM_ICLKEN3_CORE		PRCM_REG32(0x218)
+#define CM_ICLKEN4_CORE		PRCM_REG32(0x21C)
+#define CM_IDLEST1_CORE		PRCM_REG32(0x220)
+#define CM_IDLEST2_CORE		PRCM_REG32(0x224)
+#define CM_IDLEST3_CORE		PRCM_REG32(0x228)
+#define CM_IDLEST4_CORE		PRCM_REG32(0x22C)
+#define CM_AUTOIDLE1_CORE	PRCM_REG32(0x230)
+#define CM_AUTOIDLE2_CORE	PRCM_REG32(0x234)
+#define CM_AUTOIDLE3_CORE	PRCM_REG32(0x238)
+#define CM_AUTOIDLE4_CORE	PRCM_REG32(0x23C)
+#define CM_CLKSEL1_CORE		PRCM_REG32(0x240)
+#define CM_CLKSEL2_CORE		PRCM_REG32(0x244)
+#define CM_CLKSTCTRL_CORE	PRCM_REG32(0x248)
+#define PM_WKEN1_CORE		PRCM_REG32(0x2A0)
+#define PM_WKEN2_CORE		PRCM_REG32(0x2A4)
+#define PM_WKST1_CORE		PRCM_REG32(0x2B0)
+#define PM_WKST2_CORE		PRCM_REG32(0x2B4)
+#define PM_WKDEP_CORE		PRCM_REG32(0x2C8)
+#define PM_PWSTCTRL_CORE	PRCM_REG32(0x2E0)
+#define PM_PWSTST_CORE		PRCM_REG32(0x2E4)
+
+/* GFX */
+#define CM_FCLKEN_GFX		PRCM_REG32(0x300)
+#define CM_ICLKEN_GFX		PRCM_REG32(0x310)
+#define CM_IDLEST_GFX		PRCM_REG32(0x320)
+#define CM_CLKSEL_GFX		PRCM_REG32(0x340)
+#define CM_CLKSTCTRL_GFX	PRCM_REG32(0x348)
+#define RM_RSTCTRL_GFX		PRCM_REG32(0x350)
+#define RM_RSTST_GFX		PRCM_REG32(0x358)
+#define PM_WKDEP_GFX		PRCM_REG32(0x3C8)
+#define PM_PWSTCTRL_GFX		PRCM_REG32(0x3E0)
+#define PM_PWSTST_GFX		PRCM_REG32(0x3E4)
+
+/* WAKE-UP */
+#define CM_FCLKEN_WKUP		PRCM_REG32(0x400)
+#define CM_ICLKEN_WKUP		PRCM_REG32(0x410)
+#define CM_IDLEST_WKUP		PRCM_REG32(0x420)
+#define CM_AUTOIDLE_WKUP	PRCM_REG32(0x430)
+#define CM_CLKSEL_WKUP		PRCM_REG32(0x440)
+#define RM_RSTCTRL_WKUP		PRCM_REG32(0x450)
+#define RM_RSTTIME_WKUP		PRCM_REG32(0x454)
+#define RM_RSTST_WKUP		PRCM_REG32(0x458)
+#define PM_WKEN_WKUP		PRCM_REG32(0x4A0)
+#define PM_WKST_WKUP		PRCM_REG32(0x4B0)
+
+/* CLOCKS */
+#define CM_CLKEN_PLL		PRCM_REG32(0x500)
+#define CM_IDLEST_CKGEN		PRCM_REG32(0x520)
+#define CM_AUTOIDLE_PLL		PRCM_REG32(0x530)
+#define CM_CLKSEL1_PLL		PRCM_REG32(0x540)
+#define CM_CLKSEL2_PLL		PRCM_REG32(0x544)
+
+/* DSP */
+#define CM_FCLKEN_DSP		PRCM_REG32(0x800)
+#define CM_ICLKEN_DSP		PRCM_REG32(0x810)
+#define CM_IDLEST_DSP		PRCM_REG32(0x820)
+#define CM_AUTOIDLE_DSP		PRCM_REG32(0x830)
+#define CM_CLKSEL_DSP		PRCM_REG32(0x840)
+#define CM_CLKSTCTRL_DSP	PRCM_REG32(0x848)
+#define RM_RSTCTRL_DSP		PRCM_REG32(0x850)
+#define RM_RSTST_DSP		PRCM_REG32(0x858)
+#define PM_WKEN_DSP		PRCM_REG32(0x8A0)
+#define PM_WKDEP_DSP		PRCM_REG32(0x8C8)
+#define PM_PWSTCTRL_DSP		PRCM_REG32(0x8E0)
+#define PM_PWSTST_DSP		PRCM_REG32(0x8E4)
+#define PRCM_IRQSTATUS_DSP	PRCM_REG32(0x8F0)
+#define PRCM_IRQENABLE_DSP	PRCM_REG32(0x8F4)
+
+/* IVA */
+#define PRCM_IRQSTATUS_IVA	PRCM_REG32(0x8F8)
+#define PRCM_IRQENABLE_IVA	PRCM_REG32(0x8FC)
+
+/* Modem on 2430 */
+#define CM_FCLKEN_MDM		PRCM_REG32(0xC00)
+#define CM_ICLKEN_MDM		PRCM_REG32(0xC10)
+#define CM_IDLEST_MDM		PRCM_REG32(0xC20)
+#define CM_CLKSEL_MDM		PRCM_REG32(0xC40)
+
+/* FIXME: Move to header for 2430 */
+#define DISP_BASE		(OMAP24XX_L4_IO_BASE+0x50000)
+#define DISP_REG32(offset)	__REG32(DISP_BASE + (offset))
+
+#define GPMC_BASE		(OMAP24XX_GPMC_BASE)
+#define GPMC_REG32(offset)	__REG32(GPMC_BASE + (offset))
+
+#define GPT1_BASE		(OMAP24XX_GPT1)
+#define GPT1_REG32(offset)	__REG32(GPT1_BASE + (offset))
+
+/* Misc sysconfig */
+#define DISPC_SYSCONFIG		DISP_REG32(0x410)
+#define SPI_BASE		(OMAP24XX_L4_IO_BASE+0x98000)
+#define MCSPI1_SYSCONFIG	__REG32(SPI_BASE + 0x10)
+#define MCSPI2_SYSCONFIG	__REG32(SPI_BASE+0x2000 + 0x10)
+
+//#define DSP_MMU_SYSCONFIG	0x5A000010
+#define CAMERA_MMU_SYSCONFIG	__REG32(DISP_BASE+0x2C10)
+//#define IVA_MMU_SYSCONFIG	0x5D000010
+//#define DSP_DMA_SYSCONFIG	0x00FCC02C
+#define CAMERA_DMA_SYSCONFIG	__REG32(DISP_BASE+0x282C)
+#define SYSTEM_DMA_SYSCONFIG	__REG32(DISP_BASE+0x602C)
+#define GPMC_SYSCONFIG		GPMC_REG32(0x010)
+#define MAILBOXES_SYSCONFIG	__REG32(OMAP24XX_L4_IO_BASE+0x94010)
+#define UART1_SYSCONFIG		__REG32(OMAP24XX_L4_IO_BASE+0x6A054)
+#define UART2_SYSCONFIG		__REG32(OMAP24XX_L4_IO_BASE+0x6C054)
+#define UART3_SYSCONFIG		__REG32(OMAP24XX_L4_IO_BASE+0x6E054)
+//#define IVA_SYSCONFIG		0x5C060010
+#define SDRC_SYSCONFIG		__REG32(OMAP24XX_SDRC_BASE+0x10)
+#define SMS_SYSCONFIG		__REG32(OMAP24XX_SMS_BASE+0x10)
+#define SSI_SYSCONFIG		__REG32(DISP_BASE+0x8010)
+//#define VLYNQ_SYSCONFIG	0x67FFFE10
+
+/* rkw - good cannidates for PM_ to start what nm was trying */
+#define OMAP24XX_GPT2		(OMAP24XX_L4_IO_BASE+0x2A000)
+#define OMAP24XX_GPT3		(OMAP24XX_L4_IO_BASE+0x78000)
+#define OMAP24XX_GPT4		(OMAP24XX_L4_IO_BASE+0x7A000)
+#define OMAP24XX_GPT5		(OMAP24XX_L4_IO_BASE+0x7C000)
+#define OMAP24XX_GPT6		(OMAP24XX_L4_IO_BASE+0x7E000)
+#define OMAP24XX_GPT7		(OMAP24XX_L4_IO_BASE+0x80000)
+#define OMAP24XX_GPT8		(OMAP24XX_L4_IO_BASE+0x82000)
+#define OMAP24XX_GPT9		(OMAP24XX_L4_IO_BASE+0x84000)
+#define OMAP24XX_GPT10		(OMAP24XX_L4_IO_BASE+0x86000)
+#define OMAP24XX_GPT11		(OMAP24XX_L4_IO_BASE+0x88000)
+#define OMAP24XX_GPT12		(OMAP24XX_L4_IO_BASE+0x8A000)
+
+#define GPTIMER1_SYSCONFIG	GPT1_REG32(0x010)
+#define GPTIMER2_SYSCONFIG	__REG32(OMAP24XX_GPT2 + 0x10)
+#define GPTIMER3_SYSCONFIG	__REG32(OMAP24XX_GPT3 + 0x10)
+#define GPTIMER4_SYSCONFIG	__REG32(OMAP24XX_GPT4 + 0x10)
+#define GPTIMER5_SYSCONFIG	__REG32(OMAP24XX_GPT5 + 0x10)
+#define GPTIMER6_SYSCONFIG	__REG32(OMAP24XX_GPT6 + 0x10)
+#define GPTIMER7_SYSCONFIG	__REG32(OMAP24XX_GPT7 + 0x10)
+#define GPTIMER8_SYSCONFIG	__REG32(OMAP24XX_GPT8 + 0x10)
+#define GPTIMER9_SYSCONFIG	__REG32(OMAP24XX_GPT9 + 0x10)
+#define GPTIMER10_SYSCONFIG	__REG32(OMAP24XX_GPT10 + 0x10)
+#define GPTIMER11_SYSCONFIG	__REG32(OMAP24XX_GPT11 + 0x10)
+#define GPTIMER12_SYSCONFIG	__REG32(OMAP24XX_GPT12 + 0x10)
+
+#define GPIOX_BASE(X)		(OMAP24XX_GPIO_BASE+(0x2000*((X)-1)))
+
+#define GPIO1_SYSCONFIG		__REG32((GPIOX_BASE(1)+0x10))
+#define GPIO2_SYSCONFIG		__REG32((GPIOX_BASE(2)+0x10))
+#define GPIO3_SYSCONFIG		__REG32((GPIOX_BASE(3)+0x10))
+#define GPIO4_SYSCONFIG		__REG32((GPIOX_BASE(4)+0x10))
+
+/* GP TIMER 1 */
+#define GPTIMER1_TISTAT		GPT1_REG32(0x014)
+#define GPTIMER1_TISR		GPT1_REG32(0x018)
+#define GPTIMER1_TIER		GPT1_REG32(0x01C)
+#define GPTIMER1_TWER		GPT1_REG32(0x020)
+#define GPTIMER1_TCLR		GPT1_REG32(0x024)
+#define GPTIMER1_TCRR		GPT1_REG32(0x028)
+#define GPTIMER1_TLDR		GPT1_REG32(0x02C)
+#define GPTIMER1_TTGR		GPT1_REG32(0x030)
+#define GPTIMER1_TWPS		GPT1_REG32(0x034)
+#define GPTIMER1_TMAR		GPT1_REG32(0x038)
+#define GPTIMER1_TCAR1		GPT1_REG32(0x03C)
+#define GPTIMER1_TSICR		GPT1_REG32(0x040)
+#define GPTIMER1_TCAR2		GPT1_REG32(0x044)
+
+/* rkw -- base fix up please... */
+#define GPTIMER3_TISR		__REG32(OMAP24XX_L4_IO_BASE+0x78018)
+
+/* SDRC */
+#define SDRC_DLLA_CTRL		__REG32(OMAP24XX_SDRC_BASE+0x060)
+#define SDRC_DLLA_STATUS	__REG32(OMAP24XX_SDRC_BASE+0x064)
+#define SDRC_DLLB_CTRL		__REG32(OMAP24XX_SDRC_BASE+0x068)
+#define SDRC_DLLB_STATUS	__REG32(OMAP24XX_SDRC_BASE+0x06C)
+#define SDRC_POWER		__REG32(OMAP24XX_SDRC_BASE+0x070)
+#define SDRC_MR_0		__REG32(OMAP24XX_SDRC_BASE+0x084)
+
+/* GPIO 1 */
+#define GPIO1_BASE		GPIOX_BASE(1)
+#define GPIO1_REG32(offset)	__REG32(GPIO1_BASE + (offset))
+#define GPIO1_IRQENABLE1	GPIO1_REG32(0x01C)
+#define GPIO1_IRQSTATUS1	GPIO1_REG32(0x018)
+#define GPIO1_IRQENABLE2	GPIO1_REG32(0x02C)
+#define GPIO1_IRQSTATUS2	GPIO1_REG32(0x028)
+#define GPIO1_WAKEUPENABLE	GPIO1_REG32(0x020)
+#define GPIO1_RISINGDETECT	GPIO1_REG32(0x048)
+#define GPIO1_DATAIN		GPIO1_REG32(0x038)
+#define GPIO1_OE		GPIO1_REG32(0x034)
+#define GPIO1_DATAOUT		GPIO1_REG32(0x03C)
+
+/* GPIO2 */
+#define GPIO2_BASE		GPIOX_BASE(2)
+#define GPIO2_REG32(offset)	__REG32(GPIO2_BASE + (offset))
+#define GPIO2_IRQENABLE1	GPIO2_REG32(0x01C)
+#define GPIO2_IRQSTATUS1	GPIO2_REG32(0x018)
+#define GPIO2_IRQENABLE2	GPIO2_REG32(0x02C)
+#define GPIO2_IRQSTATUS2	GPIO2_REG32(0x028)
+#define GPIO2_WAKEUPENABLE	GPIO2_REG32(0x020)
+#define GPIO2_RISINGDETECT	GPIO2_REG32(0x048)
+#define GPIO2_DATAIN		GPIO2_REG32(0x038)
+#define GPIO2_OE		GPIO2_REG32(0x034)
+#define GPIO2_DATAOUT		GPIO2_REG32(0x03C)
+
+/* GPIO 3 */
+#define GPIO3_BASE		GPIOX_BASE(3)
+#define GPIO3_REG32(offset)	__REG32(GPIO3_BASE + (offset))
+#define GPIO3_IRQENABLE1	GPIO3_REG32(0x01C)
+#define GPIO3_IRQSTATUS1	GPIO3_REG32(0x018)
+#define GPIO3_IRQENABLE2	GPIO3_REG32(0x02C)
+#define GPIO3_IRQSTATUS2	GPIO3_REG32(0x028)
+#define GPIO3_WAKEUPENABLE	GPIO3_REG32(0x020)
+#define GPIO3_RISINGDETECT	GPIO3_REG32(0x048)
+#define GPIO3_FALLINGDETECT	GPIO3_REG32(0x04C)
+#define GPIO3_DATAIN		GPIO3_REG32(0x038)
+#define GPIO3_OE		GPIO3_REG32(0x034)
+#define GPIO3_DATAOUT		GPIO3_REG32(0x03C)
+#define GPIO3_DEBOUNCENABLE	GPIO3_REG32(0x050)
+#define GPIO3_DEBOUNCINGTIME	GPIO3_REG32(0x054)
+
+/* GPIO 4 */
+#define GPIO4_BASE		GPIOX_BASE(4)
+#define GPIO4_REG32(offset)	__REG32(GPIO4_BASE + (offset))
+#define GPIO4_IRQENABLE1	GPIO4_REG32(0x01C)
+#define GPIO4_IRQSTATUS1	GPIO4_REG32(0x018)
+#define GPIO4_IRQENABLE2	GPIO4_REG32(0x02C)
+#define GPIO4_IRQSTATUS2	GPIO4_REG32(0x028)
+#define GPIO4_WAKEUPENABLE	GPIO4_REG32(0x020)
+#define GPIO4_RISINGDETECT	GPIO4_REG32(0x048)
+#define GPIO4_FALLINGDETECT	GPIO4_REG32(0x04C)
+#define GPIO4_DATAIN		GPIO4_REG32(0x038)
+#define GPIO4_OE		GPIO4_REG32(0x034)
+#define GPIO4_DATAOUT		GPIO4_REG32(0x03C)
+#define GPIO4_DEBOUNCENABLE	GPIO4_REG32(0x050)
+#define GPIO4_DEBOUNCINGTIME	GPIO4_REG32(0x054)
+
+
+/* IO CONFIG */
+#define CONTROL_BASE		(OMAP24XX_CTRL_BASE)
+#define CONTROL_REG32(offset)	__REG32(CONTROL_BASE + (offset))
+
+#define CONTROL_PADCONF_SPI1_NCS2	CONTROL_REG32(0x104)
+#define CONTROL_PADCONF_SYS_XTALOUT	CONTROL_REG32(0x134)
+#define CONTROL_PADCONF_UART1_RX	CONTROL_REG32(0x0C8)
+#define CONTROL_PADCONF_MCBSP1_DX	CONTROL_REG32(0x10C)
+#define CONTROL_PADCONF_GPMC_NCS4	CONTROL_REG32(0x090)
+#define CONTROL_PADCONF_DSS_D5		CONTROL_REG32(0x0B8)
+#define CONTROL_PADCONF_DSS_D9		CONTROL_REG32(0x0BC)
+#define CONTROL_PADCONF_DSS_D13		CONTROL_REG32(0x0C0)
+#define CONTROL_PADCONF_DSS_VSYNC	CONTROL_REG32(0x0CC)
+
+/* CONTROL */
+#define CONTROL_DEVCONF		CONTROL_REG32(0x274)
+
+/* INTERRUPT CONTROLLER */
+#define INTC_BASE		(OMAP24XX_L4_IO_BASE+0xfe000)
+#define INTC_REG32(offset)	__REG32(INTC_BASE + (offset))
+
+#define INTC1_U_BASE		INTC_REG32(0x000)
+#define INTC_MIR0		INTC_REG32(0x084)
+#define INTC_MIR_SET0		INTC_REG32(0x08C)
+#define INTC_MIR_CLEAR0		INTC_REG32(0x088)
+#define INTC_ISR_CLEAR0		INTC_REG32(0x094)
+#define INTC_MIR1		INTC_REG32(0x0A4)
+#define INTC_MIR_SET1		INTC_REG32(0x0AC)
+#define INTC_MIR_CLEAR1		INTC_REG32(0x0A8)
+#define INTC_ISR_CLEAR1		INTC_REG32(0x0B4)
+#define INTC_MIR2		INTC_REG32(0x0C4)
+#define INTC_MIR_SET2		INTC_REG32(0x0CC)
+#define INTC_MIR_CLEAR2		INTC_REG32(0x0C8)
+#define INTC_ISR_CLEAR2		INTC_REG32(0x0D4)
+#define INTC_SIR_IRQ		INTC_REG32(0x040)
+#define INTC_CONTROL		INTC_REG32(0x048)
+#define INTC_ILR11		INTC_REG32(0x12C)
+#define INTC_ILR32		INTC_REG32(0x180)
+#define INTC_ILR37		INTC_REG32(0x194)
+#define INTC_SYSCONFIG		INTC_REG32(0x010)
+
+/* RAM FIREWALL */
+#define RAMFW_BASE		(0x68005000)
+#define RAMFW_REG32(offset)	__REG32(RAMFW_BASE + (offset))
+
+#define RAMFW_REQINFOPERM0	RAMFW_REG32(0x048)
+#define RAMFW_READPERM0		RAMFW_REG32(0x050)
+#define RAMFW_WRITEPERM0	RAMFW_REG32(0x058)
+
+/* GPMC CS1 FPGA ON USER INTERFACE MODULE */
+//#define DEBUG_BOARD_LED_REGISTER 0x04000014
+
+/* GPMC CS0 */
+#define GPMC_CONFIG1_0		GPMC_REG32(0x060)
+#define GPMC_CONFIG2_0		GPMC_REG32(0x064)
+#define GPMC_CONFIG3_0		GPMC_REG32(0x068)
+#define GPMC_CONFIG4_0		GPMC_REG32(0x06C)
+#define GPMC_CONFIG5_0		GPMC_REG32(0x070)
+#define GPMC_CONFIG6_0		GPMC_REG32(0x074)
+#define GPMC_CONFIG7_0		GPMC_REG32(0x078)
+
+/* DSS */
+#define DSS_CONTROL		DISP_REG32(0x040)
+#define DISPC_CONTROL		DISP_REG32(0x440)
+#define DISPC_SYSSTATUS		DISP_REG32(0x414)
+#define DISPC_IRQSTATUS		DISP_REG32(0x418)
+#define DISPC_IRQENABLE		DISP_REG32(0x41C)
+#define DISPC_CONFIG		DISP_REG32(0x444)
+#define DISPC_DEFAULT_COLOR0	DISP_REG32(0x44C)
+#define DISPC_DEFAULT_COLOR1	DISP_REG32(0x450)
+#define DISPC_TRANS_COLOR0	DISP_REG32(0x454)
+#define DISPC_TRANS_COLOR1	DISP_REG32(0x458)
+#define DISPC_LINE_NUMBER	DISP_REG32(0x460)
+#define DISPC_TIMING_H		DISP_REG32(0x464)
+#define DISPC_TIMING_V		DISP_REG32(0x468)
+#define DISPC_POL_FREQ		DISP_REG32(0x46C)
+#define DISPC_DIVISOR		DISP_REG32(0x470)
+#define DISPC_SIZE_DIG		DISP_REG32(0x478)
+#define DISPC_SIZE_LCD		DISP_REG32(0x47C)
+#define DISPC_GFX_BA0		DISP_REG32(0x480)
+#define DISPC_GFX_BA1		DISP_REG32(0x484)
+#define DISPC_GFX_POSITION	DISP_REG32(0x488)
+#define DISPC_GFX_SIZE		DISP_REG32(0x48C)
+#define DISPC_GFX_ATTRIBUTES	DISP_REG32(0x4A0)
+#define DISPC_GFX_FIFO_THRESHOLD	DISP_REG32(0x4A4)
+#define DISPC_GFX_ROW_INC	DISP_REG32(0x4AC)
+#define DISPC_GFX_PIXEL_INC	DISP_REG32(0x4B0)
+#define DISPC_GFX_WINDOW_SKIP	DISP_REG32(0x4B4)
+#define DISPC_GFX_TABLE_BA	DISP_REG32(0x4B8)
+#define DISPC_DATA_CYCLE1	DISP_REG32(0x5D4)
+#define DISPC_DATA_CYCLE2	DISP_REG32(0x5D8)
+#define DISPC_DATA_CYCLE3	DISP_REG32(0x5DC)
+
+/* Wake up define for board */
+#define GPIO97			(1 << 1)
+#define GPIO88			(1 << 24)
+
+#endif /* __ASSEMBLER__ */
+
+#endif
+
+
+
+
+

+ 180 - 0
arch/arm/mach-omap2/serial.c

@@ -0,0 +1,180 @@
+/*
+ * arch/arm/mach-omap/omap2/serial.c
+ *
+ * OMAP2 serial support.
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * Based off of arch/arm/mach-omap/omap1/serial.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+
+#include <asm/io.h>
+#include <asm/hardware/clock.h>
+
+#include <asm/arch/common.h>
+#include <asm/arch/board.h>
+
+static struct clk * uart1_ick = NULL;
+static struct clk * uart1_fck = NULL;
+static struct clk * uart2_ick = NULL;
+static struct clk * uart2_fck = NULL;
+static struct clk * uart3_ick = NULL;
+static struct clk * uart3_fck = NULL;
+
+static struct plat_serial8250_port serial_platform_data[] = {
+	{
+		.membase	= (char *)IO_ADDRESS(OMAP_UART1_BASE),
+		.mapbase	= (unsigned long)OMAP_UART1_BASE,
+		.irq		= 72,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= OMAP16XX_BASE_BAUD * 16,
+	}, {
+		.membase	= (char *)IO_ADDRESS(OMAP_UART2_BASE),
+		.mapbase	= (unsigned long)OMAP_UART2_BASE,
+		.irq		= 73,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= OMAP16XX_BASE_BAUD * 16,
+	}, {
+		.membase	= (char *)IO_ADDRESS(OMAP_UART3_BASE),
+		.mapbase	= (unsigned long)OMAP_UART3_BASE,
+		.irq		= 74,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= OMAP16XX_BASE_BAUD * 16,
+	}, {
+		.flags		= 0
+	}
+};
+
+static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
+					   int offset)
+{
+	offset <<= up->regshift;
+	return (unsigned int)__raw_readb(up->membase + offset);
+}
+
+static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
+				    int value)
+{
+	offset <<= p->regshift;
+	__raw_writeb(value, (unsigned long)(p->membase + offset));
+}
+
+/*
+ * Internal UARTs need to be initialized for the 8250 autoconfig to work
+ * properly. Note that the TX watermark initialization may not be needed
+ * once the 8250.c watermark handling code is merged.
+ */
+static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
+{
+	serial_write_reg(p, UART_OMAP_MDR1, 0x07);
+	serial_write_reg(p, UART_OMAP_SCR, 0x08);
+	serial_write_reg(p, UART_OMAP_MDR1, 0x00);
+	serial_write_reg(p, UART_OMAP_SYSC, 0x01);
+}
+
+void __init omap_serial_init()
+{
+	int i;
+	const struct omap_uart_config *info;
+
+	/*
+	 * Make sure the serial ports are muxed on at this point.
+	 * You have to mux them off in device drivers later on
+	 * if not needed.
+	 */
+
+	info = omap_get_config(OMAP_TAG_UART,
+			       struct omap_uart_config);
+
+	if (info == NULL)
+		return;
+
+	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+		struct plat_serial8250_port *p = serial_platform_data + i;
+
+		if (!(info->enabled_uarts & (1 << i))) {
+			p->membase = 0;
+			p->mapbase = 0;
+			continue;
+		}
+
+		switch (i) {
+		case 0:
+			uart1_ick = clk_get(NULL, "uart1_ick");
+			if (IS_ERR(uart1_ick))
+				printk("Could not get uart1_ick\n");
+			else {
+				clk_use(uart1_ick);
+			}
+
+			uart1_fck = clk_get(NULL, "uart1_fck");
+			if (IS_ERR(uart1_fck))
+				printk("Could not get uart1_fck\n");
+			else {
+				clk_use(uart1_fck);
+			}
+			break;
+		case 1:
+			uart2_ick = clk_get(NULL, "uart2_ick");
+			if (IS_ERR(uart2_ick))
+				printk("Could not get uart2_ick\n");
+			else {
+				clk_use(uart2_ick);
+			}
+
+			uart2_fck = clk_get(NULL, "uart2_fck");
+			if (IS_ERR(uart2_fck))
+				printk("Could not get uart2_fck\n");
+			else {
+				clk_use(uart2_fck);
+			}
+			break;
+		case 2:
+			uart3_ick = clk_get(NULL, "uart3_ick");
+			if (IS_ERR(uart3_ick))
+				printk("Could not get uart3_ick\n");
+			else {
+				clk_use(uart3_ick);
+			}
+
+			uart3_fck = clk_get(NULL, "uart3_fck");
+			if (IS_ERR(uart3_fck))
+				printk("Could not get uart3_fck\n");
+			else {
+				clk_use(uart3_fck);
+			}
+			break;
+		}
+
+		omap_serial_reset(p);
+	}
+}
+
+static struct platform_device serial_device = {
+	.name			= "serial8250",
+	.id			= 0,
+	.dev			= {
+		.platform_data	= serial_platform_data,
+	},
+};
+
+static int __init omap_init(void)
+{
+	return platform_device_register(&serial_device);
+}
+arch_initcall(omap_init);

+ 333 - 0
arch/arm/mach-omap2/sram-fn.S

@@ -0,0 +1,333 @@
+/*
+ * linux/arch/arm/mach-omap1/sram.S
+ *
+ * Omap2 specific functions that need to be run in internal SRAM
+ *
+ * (C) Copyright 2004
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/arch/io.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/prcm.h>
+
+#define TIMER_32KSYNCT_CR_V	IO_ADDRESS(OMAP24XX_32KSYNCT_BASE + 0x010)
+
+#define CM_CLKSEL2_PLL_V	IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x544)
+#define PRCM_VOLTCTRL_V		IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x050)
+#define PRCM_CLKCFG_CTRL_V	IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x080)
+#define CM_CLKEN_PLL_V		IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x500)
+#define CM_IDLEST_CKGEN_V	IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x520)
+#define CM_CLKSEL1_PLL_V	IO_ADDRESS(OMAP24XX_PRCM_BASE + 0x540)
+
+#define SDRC_DLLA_CTRL_V	IO_ADDRESS(OMAP24XX_SDRC_BASE + 0x060)
+#define SDRC_RFR_CTRL_V		IO_ADDRESS(OMAP24XX_SDRC_BASE + 0x0a4)
+
+	.text
+
+ENTRY(sram_ddr_init)
+	stmfd	sp!, {r0 - r12, lr}	@ save registers on stack
+
+	mov	r12, r2			@ capture CS1 vs CS0
+	mov	r8, r3			@ capture force parameter
+
+	/* frequency shift down */
+	ldr	r2, cm_clksel2_pll	@ get address of dpllout reg
+	mov	r3, #0x1		@ value for 1x operation
+	str	r3, [r2]		@ go to L1-freq operation
+
+	/* voltage shift down */
+	mov r9, #0x1			@ set up for L1 voltage call
+	bl voltage_shift		@ go drop voltage
+
+	/* dll lock mode */
+	ldr	r11, sdrc_dlla_ctrl	@ addr of dlla ctrl
+	ldr	r10, [r11]		@ get current val
+	cmp	r12, #0x1		@ cs1 base (2422 es2.05/1)
+	addeq	r11, r11, #0x8		@ if cs1 base, move to DLLB
+	mvn	r9, #0x4		@ mask to get clear bit2
+	and	r10, r10, r9		@ clear bit2 for lock mode.
+	orr	r10, r10, #0x8		@ make sure DLL on (es2 bit pos)
+	orr	r10, r10, #0x2		@ 90 degree phase for all below 133Mhz
+	str	r10, [r11]		@ commit to DLLA_CTRL
+	bl	i_dll_wait		@ wait for dll to lock
+
+	/* get dll value */
+	add	r11, r11, #0x4		@ get addr of status reg
+	ldr	r10, [r11]		@ get locked value
+
+	/* voltage shift up */
+	mov r9, #0x0			@ shift back to L0-voltage
+	bl voltage_shift		@ go raise voltage
+
+	/* frequency shift up */
+	mov	r3, #0x2		@ value for 2x operation
+	str	r3, [r2]		@ go to L0-freq operation
+
+	/* reset entry mode for dllctrl */
+	sub	r11, r11, #0x4		@ move from status to ctrl
+	cmp	r12, #0x1		@ normalize if cs1 based
+	subeq	r11, r11, #0x8		@ possibly back to DLLA
+	cmp	r8, #0x1		@ if forced unlock exit
+	orreq	r1, r1, #0x4		@ make sure exit with unlocked value
+	str	r1, [r11]		@ restore DLLA_CTRL high value
+	add	r11, r11, #0x8		@ move to DLLB_CTRL addr
+	str	r1, [r11]		@ set value DLLB_CTRL
+	bl	i_dll_wait		@ wait for possible lock
+
+	/* set up for return, DDR should be good */
+	str r10, [r0]			@ write dll_status and return counter
+	ldmfd	sp!, {r0 - r12, pc}	@ restore regs and return
+
+	/* ensure the DLL has relocked */
+i_dll_wait:
+	mov	r4, #0x800		@ delay DLL relock, min 0x400 L3 clocks
+i_dll_delay:
+	subs	r4, r4, #0x1
+	bne	i_dll_delay
+	mov	pc, lr
+
+	/*
+	 * shift up or down voltage, use R9 as input to tell level.
+	 * wait for it to finish, use 32k sync counter, 1tick=31uS.
+	 */
+voltage_shift:
+	ldr	r4, prcm_voltctrl	@ get addr of volt ctrl.
+	ldr	r5, [r4]		@ get value.
+	ldr	r6, prcm_mask_val	@ get value of mask
+	and	r5, r5, r6		@ apply mask to clear bits
+	orr	r5, r5, r9		@ bulld value for L0/L1-volt operation.
+	str	r5, [r4]		@ set up for change.
+	mov	r3, #0x4000		@ get val for force
+	orr	r5, r5, r3		@ build value for force
+	str	r5, [r4]		@ Force transition to L1
+
+	ldr	r3, timer_32ksynct_cr	@ get addr of counter
+	ldr	r5, [r3]		@ get value
+	add	r5, r5, #0x3		@ give it at most 93uS
+volt_delay:
+	ldr	r7, [r3]		@ get timer value
+	cmp	r5, r7			@ time up?
+	bhi	volt_delay		@ not yet->branch
+	mov	pc, lr			@ back to caller.
+
+/* relative load constants */
+cm_clksel2_pll:
+	.word CM_CLKSEL2_PLL_V
+sdrc_dlla_ctrl:
+	.word SDRC_DLLA_CTRL_V
+prcm_voltctrl:
+	.word PRCM_VOLTCTRL_V
+prcm_mask_val:
+	.word 0xFFFF3FFC
+timer_32ksynct_cr:
+	.word TIMER_32KSYNCT_CR_V
+ENTRY(sram_ddr_init_sz)
+	.word	. - sram_ddr_init
+
+/*
+ * Reprograms memory timings.
+ * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
+ * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
+ */
+ENTRY(sram_reprogram_sdrc)
+	stmfd	sp!, {r0 - r10, lr}	@ save registers on stack
+	mov	r3, #0x0		@ clear for mrc call
+	mcr	p15, 0, r3, c7, c10, 4	@ memory barrier, finish ARM SDR/DDR
+	nop
+	nop
+	ldr	r6, ddr_sdrc_rfr_ctrl	@ get addr of refresh reg
+	ldr	r5, [r6]		@ get value
+	mov	r5, r5, lsr #8		@ isolate rfr field and drop burst
+
+	cmp	r0, #0x1		@ going to half speed?
+	movne	r9, #0x0		@ if up set flag up for pre up, hi volt
+
+	blne	voltage_shift_c		@ adjust voltage
+
+	cmp	r0, #0x1		@ going to half speed (post branch link)
+	moveq	r5, r5, lsr #1		@ divide by 2 if to half
+	movne	r5, r5, lsl #1		@ mult by 2 if to full
+	mov	r5, r5, lsl #8		@ put rfr field back into place
+	add	r5, r5, #0x1		@ turn on burst of 1
+	ldr	r4, ddr_cm_clksel2_pll	@ get address of out reg
+	ldr	r3, [r4]		@ get curr value
+	orr	r3, r3, #0x3
+	bic	r3, r3, #0x3		@ clear lower bits
+	orr	r3, r3, r0		@ new state value
+	str	r3, [r4]		@ set new state (pll/x, x=1 or 2)
+	nop
+	nop
+
+	moveq	r9, #0x1		@ if speed down, post down, drop volt
+	bleq	voltage_shift_c
+
+	mcr	p15, 0, r3, c7, c10, 4	@ memory barrier
+	str	r5, [r6]		@ set new RFR_1 value
+	add	r6, r6, #0x30		@ get RFR_2 addr
+	str	r5, [r6]		@ set RFR_2
+	nop
+	cmp	r2, #0x1		@ (SDR or DDR) do we need to adjust DLL
+	bne	freq_out		@ leave if SDR, no DLL function
+
+	/* With DDR, we need to take care of the DLL for the frequency change */
+	ldr	r2, ddr_sdrc_dlla_ctrl	@ addr of dlla ctrl
+	str	r1, [r2]		@ write out new SDRC_DLLA_CTRL
+	add	r2, r2, #0x8		@ addr to SDRC_DLLB_CTRL
+	str	r1, [r2]		@ commit to SDRC_DLLB_CTRL
+	mov	r1, #0x2000		@ wait DLL relock, min 0x400 L3 clocks
+dll_wait:
+	subs	r1, r1, #0x1
+	bne	dll_wait
+freq_out:
+	ldmfd	sp!, {r0 - r10, pc}	@ restore regs and return
+
+    /*
+     * shift up or down voltage, use R9 as input to tell level.
+     *	wait for it to finish, use 32k sync counter, 1tick=31uS.
+     */
+voltage_shift_c:
+	ldr	r10, ddr_prcm_voltctrl	@ get addr of volt ctrl
+	ldr	r8, [r10]		@ get value
+	ldr	r7, ddr_prcm_mask_val	@ get value of mask
+	and	r8, r8, r7		@ apply mask to clear bits
+	orr	r8, r8, r9		@ bulld value for L0/L1-volt operation.
+	str	r8, [r10]		@ set up for change.
+	mov	r7, #0x4000		@ get val for force
+	orr	r8, r8, r7		@ build value for force
+	str	r8, [r10]		@ Force transition to L1
+
+	ldr	r10, ddr_timer_32ksynct	@ get addr of counter
+	ldr	r8, [r10]		@ get value
+	add	r8, r8, #0x2		@ give it at most 62uS (min 31+)
+volt_delay_c:
+	ldr	r7, [r10]		@ get timer value
+	cmp	r8, r7			@ time up?
+	bhi	volt_delay_c		@ not yet->branch
+	mov	pc, lr			@ back to caller
+
+ddr_cm_clksel2_pll:
+	.word CM_CLKSEL2_PLL_V
+ddr_sdrc_dlla_ctrl:
+	.word SDRC_DLLA_CTRL_V
+ddr_sdrc_rfr_ctrl:
+	.word SDRC_RFR_CTRL_V
+ddr_prcm_voltctrl:
+	.word PRCM_VOLTCTRL_V
+ddr_prcm_mask_val:
+	.word 0xFFFF3FFC
+ddr_timer_32ksynct:
+	.word TIMER_32KSYNCT_CR_V
+
+ENTRY(sram_reprogram_sdrc_sz)
+	.word	. - sram_reprogram_sdrc
+
+/*
+ * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
+ */
+ENTRY(sram_set_prcm)
+	stmfd	sp!, {r0-r12, lr}	@ regs to stack
+	adr	r4, pbegin		@ addr of preload start
+	adr	r8, pend		@ addr of preload end
+	mcrr	p15, 1, r8, r4, c12	@ preload into icache
+pbegin:
+	/* move into fast relock bypass */
+	ldr	r8, pll_ctl		@ get addr
+	ldr	r5, [r8]		@ get val
+	mvn	r6, #0x3		@ clear mask
+	and	r5, r5, r6		@ clear field
+	orr	r7, r5, #0x2		@ fast relock val
+	str	r7, [r8]		@ go to fast relock
+	ldr	r4, pll_stat		@ addr of stat
+block:
+	/* wait for bypass */
+	ldr	r8, [r4]		@ stat value
+	and	r8, r8, #0x3		@ mask for stat
+	cmp	r8, #0x1		@ there yet
+	bne	block			@ loop if not
+
+	/* set new dpll dividers _after_ in bypass */
+	ldr	r4, pll_div		@ get addr
+	str	r0, [r4]		@ set dpll ctrl val
+
+	ldr	r4, set_config		@ get addr
+	mov	r8, #1			@ valid cfg msk
+	str	r8, [r4]		@ make dividers take
+
+	mov	r4, #100		@ dead spin a bit
+wait_a_bit:
+	subs	r4, r4, #1		@ dec loop
+	bne	wait_a_bit		@ delay done?
+
+	/* check if staying in bypass */
+	cmp	r2, #0x1		@ stay in bypass?
+	beq	pend			@ jump over dpll relock
+
+	/* relock DPLL with new vals */
+	ldr	r5, pll_stat		@ get addr
+	ldr	r4, pll_ctl		@ get addr
+	orr	r8, r7, #0x3		@ val for lock dpll
+	str	r8, [r4]		@ set val
+	mov	r0, #1000		@ dead spin a bit
+wait_more:
+	subs	r0, r0, #1		@ dec loop
+	bne	wait_more		@ delay done?
+wait_lock:
+	ldr	r8, [r5]		@ get lock val
+	and	r8, r8, #3		@ isolate field
+	cmp	r8, #2			@ locked?
+	bne	wait_lock		@ wait if not
+pend:
+	/* update memory timings & briefly lock dll */
+	ldr	r4, sdrc_rfr		@ get addr
+	str	r1, [r4]		@ update refresh timing
+	ldr	r11, dlla_ctrl		@ get addr of DLLA ctrl
+	ldr	r10, [r11]		@ get current val
+	mvn	r9, #0x4		@ mask to get clear bit2
+	and	r10, r10, r9		@ clear bit2 for lock mode
+	orr	r10, r10, #0x8		@ make sure DLL on (es2 bit pos)
+	str	r10, [r11]		@ commit to DLLA_CTRL
+	add	r11, r11, #0x8		@ move to dllb
+	str	r10, [r11]		@ hit DLLB also
+
+	mov	r4, #0x800		@ relock time (min 0x400 L3 clocks)
+wait_dll_lock:
+	subs	r4, r4, #0x1
+	bne	wait_dll_lock
+	nop
+	ldmfd	sp!, {r0-r12, pc}	@ restore regs and return
+
+set_config:
+	.word PRCM_CLKCFG_CTRL_V
+pll_ctl:
+	.word CM_CLKEN_PLL_V
+pll_stat:
+	.word CM_IDLEST_CKGEN_V
+pll_div:
+	.word CM_CLKSEL1_PLL_V
+sdrc_rfr:
+	.word SDRC_RFR_CTRL_V
+dlla_ctrl:
+	.word SDRC_DLLA_CTRL_V
+
+ENTRY(sram_set_prcm_sz)
+	.word	. - sram_set_prcm

+ 126 - 0
arch/arm/mach-omap2/timer-gp.c

@@ -0,0 +1,126 @@
+/*
+ * linux/arch/arm/mach-omap2/timer-gp.c
+ *
+ * OMAP2 GP timer support.
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *         Juha Yrjölä <juha.yrjola@nokia.com>
+ *
+ * Some parts based off of TI's 24xx code:
+ *
+ *   Copyright (C) 2004 Texas Instruments, Inc.
+ *
+ * Roughly modelled after the OMAP1 MPU timer code.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <asm/mach/time.h>
+#include <asm/delay.h>
+#include <asm/io.h>
+#include <asm/hardware/clock.h>
+
+#define OMAP2_GP_TIMER1_BASE	0x48028000
+#define OMAP2_GP_TIMER2_BASE	0x4802a000
+#define OMAP2_GP_TIMER3_BASE	0x48078000
+#define OMAP2_GP_TIMER4_BASE	0x4807a000
+
+#define GP_TIMER_TIDR		0x00
+#define GP_TIMER_TISR		0x18
+#define GP_TIMER_TIER		0x1c
+#define GP_TIMER_TCLR		0x24
+#define GP_TIMER_TCRR		0x28
+#define GP_TIMER_TLDR		0x2c
+#define GP_TIMER_TSICR		0x40
+
+#define OS_TIMER_NR		1  /* GP timer 2 */
+
+static unsigned long timer_base[] = {
+	IO_ADDRESS(OMAP2_GP_TIMER1_BASE),
+	IO_ADDRESS(OMAP2_GP_TIMER2_BASE),
+	IO_ADDRESS(OMAP2_GP_TIMER3_BASE),
+	IO_ADDRESS(OMAP2_GP_TIMER4_BASE),
+};
+
+static inline unsigned int timer_read_reg(int nr, unsigned int reg)
+{
+	return __raw_readl(timer_base[nr] + reg);
+}
+
+static inline void timer_write_reg(int nr, unsigned int reg, unsigned int val)
+{
+	__raw_writel(val, timer_base[nr] + reg);
+}
+
+/* Note that we always enable the clock prescale divider bit */
+static inline void omap2_gp_timer_start(int nr, unsigned long load_val)
+{
+	unsigned int tmp;
+
+	tmp = 0xffffffff - load_val;
+
+	timer_write_reg(nr, GP_TIMER_TLDR, tmp);
+	timer_write_reg(nr, GP_TIMER_TCRR, tmp);
+	timer_write_reg(nr, GP_TIMER_TIER, 1 << 1);
+	timer_write_reg(nr, GP_TIMER_TCLR, (1 << 5) | (1 << 1) | 1);
+}
+
+static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id,
+					    struct pt_regs *regs)
+{
+	write_seqlock(&xtime_lock);
+
+	timer_write_reg(OS_TIMER_NR, GP_TIMER_TISR, 1 << 1);
+	timer_tick(regs);
+
+	write_sequnlock(&xtime_lock);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction omap2_gp_timer_irq = {
+	.name		= "gp timer",
+	.flags		= SA_INTERRUPT,
+	.handler	= omap2_gp_timer_interrupt,
+};
+
+static void __init omap2_gp_timer_init(void)
+{
+	struct clk * sys_ck;
+	u32 tick_period = 120000;
+	u32 l;
+
+	/* Reset clock and prescale value */
+	timer_write_reg(OS_TIMER_NR, GP_TIMER_TCLR, 0);
+
+	sys_ck = clk_get(NULL, "sys_ck");
+	if (IS_ERR(sys_ck))
+		printk(KERN_ERR "Could not get sys_ck\n");
+	else {
+		clk_use(sys_ck);
+		tick_period = clk_get_rate(sys_ck) / 100;
+		clk_put(sys_ck);
+	}
+
+	tick_period /= 2;	/* Minimum prescale divider is 2 */
+	tick_period -= 1;
+
+	l = timer_read_reg(OS_TIMER_NR, GP_TIMER_TIDR);
+	printk(KERN_INFO "OMAP2 GP timer (HW version %d.%d)\n",
+	       (l >> 4) & 0x0f, l & 0x0f);
+
+	setup_irq(38, &omap2_gp_timer_irq);
+
+	omap2_gp_timer_start(OS_TIMER_NR, tick_period);
+}
+
+struct sys_timer omap_timer = {
+	.init	= omap2_gp_timer_init,
+};
+

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

@@ -60,6 +60,7 @@ config MACH_CORGI
 	bool "Enable Sharp SL-C700 (Corgi) Support"
 	bool "Enable Sharp SL-C700 (Corgi) Support"
 	depends PXA_SHARPSL_25x
 	depends PXA_SHARPSL_25x
 	select PXA_SHARP_C7xx
 	select PXA_SHARP_C7xx
+	select PXA_SSP
 
 
 config MACH_SHEPHERD
 config MACH_SHEPHERD
 	bool "Enable Sharp SL-C750 (Shepherd) Support"
 	bool "Enable Sharp SL-C750 (Shepherd) Support"
@@ -102,12 +103,18 @@ config IWMMXT
 
 
 config PXA_SHARP_C7xx
 config PXA_SHARP_C7xx
 	bool
 	bool
+	select PXA_SSP
 	help
 	help
 	  Enable support for all Sharp C7xx models
 	  Enable support for all Sharp C7xx models
 
 
 config PXA_SHARP_Cxx00
 config PXA_SHARP_Cxx00
 	bool
 	bool
+	select PXA_SSP
 	help
 	help
 	  Enable common support for Sharp Cxx00 models
 	  Enable common support for Sharp Cxx00 models
 
 
+config PXA_SSP
+	tristate
+	help
+	  Enable support for PXA2xx SSP ports
 endif
 endif

+ 3 - 2
arch/arm/mach-pxa/Makefile

@@ -11,8 +11,8 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
 obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
 obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
 obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
 obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
 obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
 obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
-obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o corgi_lcd.o ssp.o
-obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o corgi_ssp.o corgi_lcd.o ssp.o
+obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o corgi_lcd.o
+obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o corgi_ssp.o corgi_lcd.o
 obj-$(CONFIG_MACH_POODLE)	+= poodle.o
 obj-$(CONFIG_MACH_POODLE)	+= poodle.o
 obj-$(CONFIG_MACH_TOSA)         += tosa.o
 obj-$(CONFIG_MACH_TOSA)         += tosa.o
 
 
@@ -26,6 +26,7 @@ obj-$(CONFIG_LEDS) += $(led-y)
 
 
 # Misc features
 # Misc features
 obj-$(CONFIG_PM) += pm.o sleep.o
 obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_PXA_SSP) += ssp.o
 
 
 ifeq ($(CONFIG_PXA27x),y)
 ifeq ($(CONFIG_PXA27x),y)
 obj-$(CONFIG_PM) += standby.o
 obj-$(CONFIG_PM) += standby.o

+ 10 - 9
arch/arm/mach-pxa/corgi_ssp.c

@@ -191,7 +191,7 @@ void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo)
 	ssp_machinfo = machinfo;
 	ssp_machinfo = machinfo;
 }
 }
 
 
-static int __init corgi_ssp_probe(struct device *dev)
+static int __init corgi_ssp_probe(struct platform_device *dev)
 {
 {
 	int ret;
 	int ret;
 
 
@@ -203,7 +203,7 @@ static int __init corgi_ssp_probe(struct device *dev)
 	GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846);  /* output */
 	GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846);  /* output */
 	GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);   /* High - Disable ADS7846*/
 	GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);   /* High - Disable ADS7846*/
 
 
-	ret = ssp_init(&corgi_ssp_dev,ssp_machinfo->port);
+	ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0);
 
 
 	if (ret)
 	if (ret)
 		printk(KERN_ERR "Unable to register SSP handler!\n");
 		printk(KERN_ERR "Unable to register SSP handler!\n");
@@ -216,13 +216,13 @@ static int __init corgi_ssp_probe(struct device *dev)
 	return ret;
 	return ret;
 }
 }
 
 
-static int corgi_ssp_remove(struct device *dev)
+static int corgi_ssp_remove(struct platform_device *dev)
 {
 {
 	ssp_exit(&corgi_ssp_dev);
 	ssp_exit(&corgi_ssp_dev);
 	return 0;
 	return 0;
 }
 }
 
 
-static int corgi_ssp_suspend(struct device *dev, pm_message_t state)
+static int corgi_ssp_suspend(struct platform_device *dev, pm_message_t state)
 {
 {
 	ssp_flush(&corgi_ssp_dev);
 	ssp_flush(&corgi_ssp_dev);
 	ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
 	ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
@@ -230,7 +230,7 @@ static int corgi_ssp_suspend(struct device *dev, pm_message_t state)
 	return 0;
 	return 0;
 }
 }
 
 
-static int corgi_ssp_resume(struct device *dev)
+static int corgi_ssp_resume(struct platform_device *dev)
 {
 {
 	GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
 	GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
 	GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
 	GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
@@ -241,18 +241,19 @@ static int corgi_ssp_resume(struct device *dev)
 	return 0;
 	return 0;
 }
 }
 
 
-static struct device_driver corgissp_driver = {
-	.name		= "corgi-ssp",
-	.bus		= &platform_bus_type,
+static struct platform_driver corgissp_driver = {
 	.probe		= corgi_ssp_probe,
 	.probe		= corgi_ssp_probe,
 	.remove		= corgi_ssp_remove,
 	.remove		= corgi_ssp_remove,
 	.suspend	= corgi_ssp_suspend,
 	.suspend	= corgi_ssp_suspend,
 	.resume		= corgi_ssp_resume,
 	.resume		= corgi_ssp_resume,
+	.driver		= {
+		.name	= "corgi-ssp",
+	},
 };
 };
 
 
 int __init corgi_ssp_init(void)
 int __init corgi_ssp_init(void)
 {
 {
-	return driver_register(&corgissp_driver);
+	return platform_driver_register(&corgissp_driver);
 }
 }
 
 
 arch_initcall(corgi_ssp_init);
 arch_initcall(corgi_ssp_init);

+ 87 - 0
arch/arm/mach-pxa/sharpsl.h

@@ -32,3 +32,90 @@ void corgi_put_hsync(void);
 void spitz_put_hsync(void);
 void spitz_put_hsync(void);
 void corgi_wait_hsync(void);
 void corgi_wait_hsync(void);
 void spitz_wait_hsync(void);
 void spitz_wait_hsync(void);
+
+/*
+ * SharpSL Battery/PM Driver
+ */
+
+struct sharpsl_charger_machinfo {
+	void (*init)(void);
+	int gpio_acin;
+	int gpio_batfull;
+	int gpio_batlock;
+	int gpio_fatal;
+	int (*status_acin)(void);
+	void (*discharge)(int);
+	void (*discharge1)(int);
+	void (*charge)(int);
+	void (*chargeled)(int);
+	void (*measure_temp)(int);
+	void (*presuspend)(void);
+	void (*postsuspend)(void);
+	unsigned long (*charger_wakeup)(void);
+	int (*should_wakeup)(unsigned int resume_on_alarm);
+	int bat_levels;
+	struct battery_thresh *bat_levels_noac;
+	struct battery_thresh *bat_levels_acin;
+	int status_high_acin;
+	int status_low_acin;
+	int status_high_noac;
+	int status_low_noac;
+};
+
+struct battery_thresh {
+	int voltage;
+	int percentage;
+};
+
+struct battery_stat {
+	int ac_status;         /* APM AC Present/Not Present */
+	int mainbat_status;    /* APM Main Battery Status */
+	int mainbat_percent;   /* Main Battery Percentage Charge */
+	int mainbat_voltage;   /* Main Battery Voltage */
+};
+
+struct sharpsl_pm_status {
+	struct device *dev;
+	struct timer_list ac_timer;
+	struct timer_list chrg_full_timer;
+
+	int charge_mode;
+#define CHRG_ERROR    (-1)
+#define CHRG_OFF      (0)
+#define CHRG_ON       (1)
+#define CHRG_DONE     (2)
+
+	unsigned int flags;
+#define SHARPSL_SUSPENDED       (1 << 0)  /* Device is Suspended */
+#define SHARPSL_ALARM_ACTIVE    (1 << 1)  /* Alarm is for charging event (not user) */
+#define SHARPSL_BL_LIMIT        (1 << 2)  /* Backlight Intensity Limited */
+#define SHARPSL_APM_QUEUED      (1 << 3)  /* APM Event Queued */
+#define SHARPSL_DO_OFFLINE_CHRG (1 << 4)  /* Trigger the offline charger */
+
+	int full_count;
+	unsigned long charge_start_time;
+	struct sharpsl_charger_machinfo *machinfo;
+	struct battery_stat battstat;
+};
+
+extern struct sharpsl_pm_status sharpsl_pm;
+extern struct battery_thresh spitz_battery_levels_acin[];
+extern struct battery_thresh spitz_battery_levels_noac[];
+
+#define READ_GPIO_BIT(x)    (GPLR(x) & GPIO_bit(x))
+
+#define SHARPSL_LED_ERROR  2
+#define SHARPSL_LED_ON     1
+#define SHARPSL_LED_OFF    0
+
+#define CHARGE_ON()         sharpsl_pm.machinfo->charge(1)
+#define CHARGE_OFF()        sharpsl_pm.machinfo->charge(0)
+#define CHARGE_LED_ON()     sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ON)
+#define CHARGE_LED_OFF()    sharpsl_pm.machinfo->chargeled(SHARPSL_LED_OFF)
+#define CHARGE_LED_ERR()    sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR)
+#define DISCHARGE_ON()      sharpsl_pm.machinfo->discharge(1)
+#define DISCHARGE_OFF()     sharpsl_pm.machinfo->discharge(0)
+#define STATUS_AC_IN        sharpsl_pm.machinfo->status_acin()
+#define STATUS_BATT_LOCKED  READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock)
+#define STATUS_CHRG_FULL    READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull)
+#define STATUS_FATAL        READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal)

+ 992 - 0
arch/arm/mach-pxa/sharpsl_pm.c

@@ -0,0 +1,992 @@
+/*
+ * Battery and Power Management code for the Sharp SL-C7xx and SL-Cxx00
+ * series of PDAs
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * Based on code written by Sharp for 2.4 kernels
+ *
+ * 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.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/apm_bios.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/hardware/scoop.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/apm.h>
+
+#include <asm/arch/pm.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/sharpsl.h>
+#include "sharpsl.h"
+
+/*
+ * Constants
+ */
+#define SHARPSL_CHARGE_ON_TIME_INTERVAL        (msecs_to_jiffies(1*60*1000))  /* 1 min */
+#define SHARPSL_CHARGE_FINISH_TIME             (msecs_to_jiffies(10*60*1000)) /* 10 min */
+#define SHARPSL_BATCHK_TIME                    (msecs_to_jiffies(15*1000))    /* 15 sec */
+#define SHARPSL_BATCHK_TIME_SUSPEND            (60*10)                        /* 10 min */
+#define SHARPSL_WAIT_CO_TIME                   15  /* 15 sec */
+#define SHARPSL_WAIT_DISCHARGE_ON              100 /* 100 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP   10  /* 10 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT   10  /* 10 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD  10  /* 10 msec */
+#define SHARPSL_CHARGE_WAIT_TIME               15  /* 15 msec */
+#define SHARPSL_CHARGE_CO_CHECK_TIME           5   /* 5 msec */
+#define SHARPSL_CHARGE_RETRY_CNT               1   /* eqv. 10 min */
+
+#define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
+#define SHARPSL_CHARGE_ON_TEMP         0xe0  /* 2.9V */
+#define SHARPSL_CHARGE_ON_JKVAD_HIGH   0x9b  /* 6V */
+#define SHARPSL_CHARGE_ON_JKVAD_LOW    0x34  /* 2V */
+#define SHARPSL_FATAL_ACIN_VOLT        182   /* 3.45V */
+#define SHARPSL_FATAL_NOACIN_VOLT      170   /* 3.40V */
+
+struct battery_thresh spitz_battery_levels_acin[] = {
+	{ 213, 100},
+	{ 212,  98},
+	{ 211,  95},
+	{ 210,  93},
+	{ 209,  90},
+	{ 208,  88},
+	{ 207,  85},
+	{ 206,  83},
+	{ 205,  80},
+	{ 204,  78},
+	{ 203,  75},
+	{ 202,  73},
+	{ 201,  70},
+	{ 200,  68},
+	{ 199,  65},
+	{ 198,  63},
+	{ 197,  60},
+	{ 196,  58},
+	{ 195,  55},
+	{ 194,  53},
+	{ 193,  50},
+	{ 192,  48},
+	{ 192,  45},
+	{ 191,  43},
+	{ 191,  40},
+	{ 190,  38},
+	{ 190,  35},
+	{ 189,  33},
+	{ 188,  30},
+	{ 187,  28},
+	{ 186,  25},
+	{ 185,  23},
+	{ 184,  20},
+	{ 183,  18},
+	{ 182,  15},
+	{ 181,  13},
+	{ 180,  10},
+	{ 179,   8},
+	{ 178,   5},
+	{   0,   0},
+};
+
+struct battery_thresh  spitz_battery_levels_noac[] = {
+	{ 213, 100},
+	{ 212,  98},
+	{ 211,  95},
+	{ 210,  93},
+	{ 209,  90},
+	{ 208,  88},
+	{ 207,  85},
+	{ 206,  83},
+	{ 205,  80},
+	{ 204,  78},
+	{ 203,  75},
+	{ 202,  73},
+	{ 201,  70},
+	{ 200,  68},
+	{ 199,  65},
+	{ 198,  63},
+	{ 197,  60},
+	{ 196,  58},
+	{ 195,  55},
+	{ 194,  53},
+	{ 193,  50},
+	{ 192,  48},
+	{ 191,  45},
+	{ 190,  43},
+	{ 189,  40},
+	{ 188,  38},
+	{ 187,  35},
+	{ 186,  33},
+	{ 185,  30},
+	{ 184,  28},
+	{ 183,  25},
+	{ 182,  23},
+	{ 181,  20},
+	{ 180,  18},
+	{ 179,  15},
+	{ 178,  13},
+	{ 177,  10},
+	{ 176,   8},
+	{ 175,   5},
+	{   0,   0},
+};
+
+/* MAX1111 Commands */
+#define MAXCTRL_PD0      1u << 0
+#define MAXCTRL_PD1      1u << 1
+#define MAXCTRL_SGL      1u << 2
+#define MAXCTRL_UNI      1u << 3
+#define MAXCTRL_SEL_SH   4
+#define MAXCTRL_STR      1u << 7
+
+/* MAX1111 Channel Definitions */
+#define BATT_AD    4u
+#define BATT_THM   2u
+#define JK_VAD     6u
+
+
+/*
+ * Prototypes
+ */
+static int sharpsl_read_MainBattery(void);
+static int sharpsl_off_charge_battery(void);
+static int sharpsl_check_battery(int mode);
+static int sharpsl_ac_check(void);
+static int sharpsl_fatal_check(void);
+static int sharpsl_average_value(int ad);
+static void sharpsl_average_clear(void);
+static void sharpsl_charge_toggle(void *private_);
+static void sharpsl_battery_thread(void *private_);
+
+
+/*
+ * Variables
+ */
+struct sharpsl_pm_status sharpsl_pm;
+DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL);
+DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL);
+
+
+static int get_percentage(int voltage)
+{
+	int i = sharpsl_pm.machinfo->bat_levels - 1;
+	struct battery_thresh *thresh;
+
+	if (sharpsl_pm.charge_mode == CHRG_ON)
+		thresh=sharpsl_pm.machinfo->bat_levels_acin;
+	else
+		thresh=sharpsl_pm.machinfo->bat_levels_noac;
+
+	while (i > 0 && (voltage > thresh[i].voltage))
+		i--;
+
+	return thresh[i].percentage;
+}
+
+static int get_apm_status(int voltage)
+{
+	int low_thresh, high_thresh;
+
+	if (sharpsl_pm.charge_mode == CHRG_ON) {
+		high_thresh = sharpsl_pm.machinfo->status_high_acin;
+		low_thresh = sharpsl_pm.machinfo->status_low_acin;
+	} else {
+		high_thresh = sharpsl_pm.machinfo->status_high_noac;
+		low_thresh = sharpsl_pm.machinfo->status_low_noac;
+	}
+
+	if (voltage >= high_thresh)
+		return APM_BATTERY_STATUS_HIGH;
+	if (voltage >= low_thresh)
+		return APM_BATTERY_STATUS_LOW;
+	return APM_BATTERY_STATUS_CRITICAL;
+}
+
+void sharpsl_battery_kick(void)
+{
+	schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125));
+}
+EXPORT_SYMBOL(sharpsl_battery_kick);
+
+
+static void sharpsl_battery_thread(void *private_)
+{
+	int voltage, percent, apm_status, i = 0;
+
+	if (!sharpsl_pm.machinfo)
+		return;
+
+	sharpsl_pm.battstat.ac_status = (!(STATUS_AC_IN) ? APM_AC_OFFLINE : APM_AC_ONLINE);
+
+	/* Corgi cannot confirm when battery fully charged so periodically kick! */
+	if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON)
+			&& time_after(jiffies, sharpsl_pm.charge_start_time +  SHARPSL_CHARGE_ON_TIME_INTERVAL))
+		schedule_work(&toggle_charger);
+
+	while(1) {
+		voltage = sharpsl_read_MainBattery();
+		if (voltage > 0) break;
+		if (i++ > 5) {
+			voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
+			dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n");
+			break;
+		}
+	}
+
+	voltage = sharpsl_average_value(voltage);
+	apm_status = get_apm_status(voltage);
+	percent = get_percentage(voltage);
+
+	/* At low battery voltages, the voltage has a tendency to start
+           creeping back up so we try to avoid this here */
+	if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) ||  percent <= sharpsl_pm.battstat.mainbat_percent) {
+		sharpsl_pm.battstat.mainbat_voltage = voltage;
+		sharpsl_pm.battstat.mainbat_status = apm_status;
+		sharpsl_pm.battstat.mainbat_percent = percent;
+	}
+
+	dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %d\n", voltage,
+			sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies);
+
+	/* If battery is low. limit backlight intensity to save power. */
+	if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
+			&& ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) ||
+			(sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) {
+		if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) {
+			corgibl_limit_intensity(1);
+			sharpsl_pm.flags |= SHARPSL_BL_LIMIT;
+		}
+	} else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) {
+		corgibl_limit_intensity(0);
+		sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT;
+	}
+
+	/* Suspend if critical battery level */
+	if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
+			&& (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL)
+			&& !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) {
+		sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
+		dev_err(sharpsl_pm.dev, "Fatal Off\n");
+		apm_queue_event(APM_CRITICAL_SUSPEND);
+	}
+
+	schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME);
+}
+
+static void sharpsl_charge_on(void)
+{
+	dev_dbg(sharpsl_pm.dev, "Turning Charger On\n");
+
+	sharpsl_pm.full_count = 0;
+	sharpsl_pm.charge_mode = CHRG_ON;
+	schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250));
+	schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500));
+}
+
+static void sharpsl_charge_off(void)
+{
+	dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n");
+
+	CHARGE_OFF();
+	CHARGE_LED_OFF();
+	sharpsl_pm.charge_mode = CHRG_OFF;
+
+	schedule_work(&sharpsl_bat);
+}
+
+static void sharpsl_charge_error(void)
+{
+	CHARGE_LED_ERR();
+	CHARGE_OFF();
+	sharpsl_pm.charge_mode = CHRG_ERROR;
+}
+
+static void sharpsl_charge_toggle(void *private_)
+{
+	dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
+
+	if (STATUS_AC_IN == 0) {
+		sharpsl_charge_off();
+		return;
+	} else if ((sharpsl_check_battery(1) < 0) || (sharpsl_ac_check() < 0)) {
+		sharpsl_charge_error();
+		return;
+	}
+
+	CHARGE_LED_ON();
+	CHARGE_OFF();
+	mdelay(SHARPSL_CHARGE_WAIT_TIME);
+	CHARGE_ON();
+
+	sharpsl_pm.charge_start_time = jiffies;
+}
+
+static void sharpsl_ac_timer(unsigned long data)
+{
+	int acin = STATUS_AC_IN;
+
+	dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
+
+	sharpsl_average_clear();
+	if (acin && (sharpsl_pm.charge_mode != CHRG_ON))
+		sharpsl_charge_on();
+	else if (sharpsl_pm.charge_mode == CHRG_ON)
+		sharpsl_charge_off();
+
+	schedule_work(&sharpsl_bat);
+}
+
+
+static irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp)
+{
+	/* Delay the event slightly to debounce */
+	/* Must be a smaller delay than the chrg_full_isr below */
+	mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
+
+	return IRQ_HANDLED;
+}
+
+static void sharpsl_chrg_full_timer(unsigned long data)
+{
+	dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies);
+
+	sharpsl_pm.full_count++;
+
+	if (STATUS_AC_IN == 0) {
+		dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
+		if (sharpsl_pm.charge_mode == CHRG_ON)
+			sharpsl_charge_off();
+	} else if (sharpsl_pm.full_count < 2) {
+		dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n");
+		schedule_work(&toggle_charger);
+	} else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) {
+		dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n");
+		schedule_work(&toggle_charger);
+	} else {
+		sharpsl_charge_off();
+		sharpsl_pm.charge_mode = CHRG_DONE;
+		dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n");
+	}
+}
+
+/* Charging Finished Interrupt (Not present on Corgi) */
+/* Can trigger at the same time as an AC staus change so
+   delay until after that has been processed */
+static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp)
+{
+	if (sharpsl_pm.flags & SHARPSL_SUSPENDED)
+		return IRQ_HANDLED;
+
+	/* delay until after any ac interrupt */
+	mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500));
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp)
+{
+	int is_fatal = 0;
+
+	if (STATUS_BATT_LOCKED == 0) {
+		dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
+		is_fatal = 1;
+	}
+
+	if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL == 0)) {
+		dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
+		is_fatal = 1;
+	}
+
+	if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) {
+		sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
+		apm_queue_event(APM_CRITICAL_SUSPEND);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Maintain an average of the last 10 readings
+ */
+#define SHARPSL_CNV_VALUE_NUM    10
+static int sharpsl_ad_index;
+
+static void sharpsl_average_clear(void)
+{
+	sharpsl_ad_index = 0;
+}
+
+static int sharpsl_average_value(int ad)
+{
+	int i, ad_val = 0;
+	static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1];
+
+	if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) {
+		sharpsl_ad_index = 0;
+		return ad;
+	}
+
+	sharpsl_ad[sharpsl_ad_index] = ad;
+	sharpsl_ad_index++;
+	if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) {
+		for (i=0; i < (SHARPSL_CNV_VALUE_NUM-1); i++)
+			sharpsl_ad[i] = sharpsl_ad[i+1];
+		sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1;
+	}
+	for (i=0; i < sharpsl_ad_index; i++)
+		ad_val += sharpsl_ad[i];
+
+	return (ad_val / sharpsl_ad_index);
+}
+
+
+/*
+ * Read MAX1111 ADC
+ */
+static int read_max1111(int channel)
+{
+	return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
+			| MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
+}
+
+static int sharpsl_read_MainBattery(void)
+{
+	return read_max1111(BATT_AD);
+}
+
+static int sharpsl_read_Temp(void)
+{
+	int temp;
+
+	sharpsl_pm.machinfo->measure_temp(1);
+
+	mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
+	temp = read_max1111(BATT_THM);
+
+	sharpsl_pm.machinfo->measure_temp(0);
+
+	return temp;
+}
+
+static int sharpsl_read_jkvad(void)
+{
+	return read_max1111(JK_VAD);
+}
+
+/*
+ * Take an array of 5 integers, remove the maximum and minimum values
+ * and return the average.
+ */
+static int get_select_val(int *val)
+{
+	int i, j, k, temp, sum = 0;
+
+	/* Find MAX val */
+	temp = val[0];
+	j=0;
+	for (i=1; i<5; i++) {
+		if (temp < val[i]) {
+			temp = val[i];
+			j = i;
+		}
+	}
+
+	/* Find MIN val */
+	temp = val[4];
+	k=4;
+	for (i=3; i>=0; i--) {
+		if (temp > val[i]) {
+			temp = val[i];
+			k = i;
+		}
+	}
+
+	for (i=0; i<5; i++)
+		if (i != j && i != k )
+			sum += val[i];
+
+	dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]);
+
+	return (sum/3);
+}
+
+/*  mode 0 - Check temperature and voltage
+ *       1 - Check temperature only */
+static int sharpsl_check_battery(int mode)
+{
+	int val, i, buff[5];
+
+	/* Check battery temperature */
+	for (i=0; i<5; i++) {
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
+		buff[i] = sharpsl_read_Temp();
+	}
+
+	val = get_select_val(buff);
+
+	dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
+	if (val > SHARPSL_CHARGE_ON_TEMP)
+		return -1;
+	if (mode == 1)
+		return 0;
+
+	/* disable charge, enable discharge */
+	CHARGE_OFF();
+	DISCHARGE_ON();
+	mdelay(SHARPSL_WAIT_DISCHARGE_ON);
+
+	if (sharpsl_pm.machinfo->discharge1)
+		sharpsl_pm.machinfo->discharge1(1);
+
+	/* Check battery voltage */
+	for (i=0; i<5; i++) {
+		buff[i] = sharpsl_read_MainBattery();
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
+	}
+
+	if (sharpsl_pm.machinfo->discharge1)
+		sharpsl_pm.machinfo->discharge1(0);
+
+	DISCHARGE_OFF();
+
+	val = get_select_val(buff);
+	dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val);
+
+	if (val < SHARPSL_CHARGE_ON_VOLT)
+		return -1;
+
+	return 0;
+}
+
+static int sharpsl_ac_check(void)
+{
+	int temp, i, buff[5];
+
+	for (i=0; i<5; i++) {
+		buff[i] = sharpsl_read_jkvad();
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD);
+	}
+
+	temp = get_select_val(buff);
+	dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
+
+	if ((temp > SHARPSL_CHARGE_ON_JKVAD_HIGH) || (temp < SHARPSL_CHARGE_ON_JKVAD_LOW)) {
+		dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int sharpsl_pm_suspend(struct device *dev, pm_message_t state)
+{
+	sharpsl_pm.flags |= SHARPSL_SUSPENDED;
+	flush_scheduled_work();
+
+	if (sharpsl_pm.charge_mode == CHRG_ON)
+		sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
+	else
+		sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
+
+	return 0;
+}
+
+static int sharpsl_pm_resume(struct device *dev)
+{
+	/* Clear the reset source indicators as they break the bootloader upon reboot */
+	RCSR = 0x0f;
+	sharpsl_average_clear();
+	sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED;
+	sharpsl_pm.flags &= ~SHARPSL_SUSPENDED;
+
+	return 0;
+}
+
+static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
+{
+	dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR);
+
+	dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
+	/* not charging and AC-IN! */
+
+	if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN != 0)) {
+		dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
+		sharpsl_pm.charge_mode = CHRG_OFF;
+		sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
+		sharpsl_off_charge_battery();
+	}
+
+	sharpsl_pm.machinfo->presuspend();
+
+	PEDR = 0xffffffff; /* clear it */
+
+	sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE;
+	if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) {
+		RTSR &= RTSR_ALE;
+		RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND;
+		dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR);
+		sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE;
+	} else if (alarm_enable) {
+		RTSR &= RTSR_ALE;
+		RTAR = alarm_time;
+		dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR);
+	} else {
+		dev_dbg(sharpsl_pm.dev, "No alarms set.\n");
+	}
+
+	pxa_pm_enter(state);
+
+	sharpsl_pm.machinfo->postsuspend();
+
+	dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR);
+}
+
+static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
+{
+	if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) )
+	{
+		if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) {
+			dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n");
+			corgi_goto_sleep(alarm_time, alarm_enable, state);
+			return 1;
+		}
+		if(sharpsl_off_charge_battery()) {
+			dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n");
+			corgi_goto_sleep(alarm_time, alarm_enable, state);
+			return 1;
+		}
+		dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
+	}
+
+	if ((STATUS_BATT_LOCKED == 0) || (sharpsl_fatal_check() < 0) )
+	{
+		dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
+		corgi_goto_sleep(alarm_time, alarm_enable, state);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int corgi_pxa_pm_enter(suspend_state_t state)
+{
+	unsigned long alarm_time = RTAR;
+	unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0);
+
+	dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n");
+
+	corgi_goto_sleep(alarm_time, alarm_status, state);
+
+	while (corgi_enter_suspend(alarm_time,alarm_status,state))
+		{}
+
+	dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n");
+
+	return 0;
+}
+#endif
+
+
+/*
+ * Check for fatal battery errors
+ * Fatal returns -1
+ */
+static int sharpsl_fatal_check(void)
+{
+	int buff[5], temp, i, acin;
+
+	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
+
+	/* Check AC-Adapter */
+	acin = STATUS_AC_IN;
+
+	if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
+		CHARGE_OFF();
+		udelay(100);
+		DISCHARGE_ON();	/* enable discharge */
+		mdelay(SHARPSL_WAIT_DISCHARGE_ON);
+	}
+
+	if (sharpsl_pm.machinfo->discharge1)
+		sharpsl_pm.machinfo->discharge1(1);
+
+	/* Check battery : check inserting battery ? */
+	for (i=0; i<5; i++) {
+		buff[i] = sharpsl_read_MainBattery();
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
+	}
+
+	if (sharpsl_pm.machinfo->discharge1)
+		sharpsl_pm.machinfo->discharge1(0);
+
+	if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
+		udelay(100);
+		CHARGE_ON();
+		DISCHARGE_OFF();
+	}
+
+	temp = get_select_val(buff);
+	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_MainBattery());
+
+	if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) ||
+			(!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT)))
+		return -1;
+	return 0;
+}
+
+static int sharpsl_off_charge_error(void)
+{
+	dev_err(sharpsl_pm.dev, "Offline Charger: Error occured.\n");
+	CHARGE_OFF();
+	CHARGE_LED_ERR();
+	sharpsl_pm.charge_mode = CHRG_ERROR;
+	return 1;
+}
+
+/*
+ * Charging Control while suspended
+ * Return 1 - go straight to sleep
+ * Return 0 - sleep or wakeup depending on other factors
+ */
+static int sharpsl_off_charge_battery(void)
+{
+	int time;
+
+	dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode);
+
+	if (sharpsl_pm.charge_mode == CHRG_OFF) {
+		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
+
+		/* AC Check */
+		if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery(1) < 0))
+			return sharpsl_off_charge_error();
+
+		/* Start Charging */
+		CHARGE_LED_ON();
+		CHARGE_OFF();
+		mdelay(SHARPSL_CHARGE_WAIT_TIME);
+		CHARGE_ON();
+
+		sharpsl_pm.charge_mode = CHRG_ON;
+		sharpsl_pm.full_count = 0;
+
+		return 1;
+	} else if (sharpsl_pm.charge_mode != CHRG_ON) {
+		return 1;
+	}
+
+	if (sharpsl_pm.full_count == 0) {
+		int time;
+
+		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
+
+		if (sharpsl_check_battery(0) < 0)
+			return sharpsl_off_charge_error();
+
+		CHARGE_OFF();
+		mdelay(SHARPSL_CHARGE_WAIT_TIME);
+		CHARGE_ON();
+		sharpsl_pm.charge_mode = CHRG_ON;
+
+		mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
+
+		time = RCNR;
+		while(1) {
+			/* Check if any wakeup event had occured */
+			if (sharpsl_pm.machinfo->charger_wakeup() != 0)
+				return 0;
+			/* Check for timeout */
+			if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
+				return 1;
+			if (STATUS_CHRG_FULL) {
+				dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n");
+	   			sharpsl_pm.full_count++;
+				CHARGE_OFF();
+				mdelay(SHARPSL_CHARGE_WAIT_TIME);
+				CHARGE_ON();
+				return 1;
+			}
+		}
+	}
+
+	dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n");
+
+	mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
+
+	time = RCNR;
+	while(1) {
+		/* Check if any wakeup event had occured */
+		if (sharpsl_pm.machinfo->charger_wakeup() != 0)
+			return 0;
+		/* Check for timeout */
+		if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) {
+			if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) {
+				dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n");
+				sharpsl_pm.full_count = 0;
+			}
+			sharpsl_pm.full_count++;
+			return 1;
+		}
+		if (STATUS_CHRG_FULL) {
+			dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
+			CHARGE_LED_OFF();
+			CHARGE_OFF();
+			sharpsl_pm.charge_mode = CHRG_DONE;
+			return 1;
+		}
+	}
+}
+
+
+static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent);
+}
+
+static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage);
+}
+
+static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);
+static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL);
+
+extern void (*apm_get_power_status)(struct apm_power_info *);
+
+static void sharpsl_apm_get_power_status(struct apm_power_info *info)
+{
+	info->ac_line_status = sharpsl_pm.battstat.ac_status;
+
+	if (sharpsl_pm.charge_mode == CHRG_ON)
+		info->battery_status = APM_BATTERY_STATUS_CHARGING;
+	else
+		info->battery_status = sharpsl_pm.battstat.mainbat_status;
+
+	info->battery_flag = (1 << info->battery_status);
+	info->battery_life = sharpsl_pm.battstat.mainbat_percent;
+}
+
+static struct pm_ops sharpsl_pm_ops = {
+	.pm_disk_mode	= PM_DISK_FIRMWARE,
+	.prepare	= pxa_pm_prepare,
+	.enter		= corgi_pxa_pm_enter,
+	.finish		= pxa_pm_finish,
+};
+
+static int __init sharpsl_pm_probe(struct device *dev)
+{
+	if (!dev->platform_data)
+		return -EINVAL;
+
+	sharpsl_pm.dev = dev;
+	sharpsl_pm.machinfo = dev->platform_data;
+	sharpsl_pm.charge_mode = CHRG_OFF;
+	sharpsl_pm.flags = 0;
+
+	sharpsl_pm.machinfo->init();
+
+	init_timer(&sharpsl_pm.ac_timer);
+	sharpsl_pm.ac_timer.function = sharpsl_ac_timer;
+
+	init_timer(&sharpsl_pm.chrg_full_timer);
+	sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
+
+	pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN);
+	pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN);
+	pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN);
+
+	/* Register interrupt handlers */
+	if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, SA_INTERRUPT, "AC Input Detect", sharpsl_ac_isr)) {
+		dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin));
+	}
+	else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin),IRQT_BOTHEDGE);
+
+	if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, SA_INTERRUPT, "Battery Cover", sharpsl_fatal_isr)) {
+		dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock));
+	}
+	else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock),IRQT_FALLING);
+
+	if (sharpsl_pm.machinfo->gpio_fatal) {
+		if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, SA_INTERRUPT, "Fatal Battery", sharpsl_fatal_isr)) {
+			dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal));
+		}
+		else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal),IRQT_FALLING);
+	}
+
+	if (!machine_is_corgi())
+	{
+		/* Register interrupt handler. */
+		if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, SA_INTERRUPT, "CO", sharpsl_chrg_full_isr)) {
+			dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull));
+		}
+		else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING);
+	}
+
+	device_create_file(dev, &dev_attr_battery_percentage);
+	device_create_file(dev, &dev_attr_battery_voltage);
+
+	apm_get_power_status = sharpsl_apm_get_power_status;
+
+	pm_set_ops(&sharpsl_pm_ops);
+
+	mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
+
+	return 0;
+}
+
+static int sharpsl_pm_remove(struct device *dev)
+{
+	pm_set_ops(NULL);
+
+	device_remove_file(dev, &dev_attr_battery_percentage);
+	device_remove_file(dev, &dev_attr_battery_voltage);
+
+	free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
+	free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
+
+	if (sharpsl_pm.machinfo->gpio_fatal)
+		free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr);
+
+	if (!machine_is_corgi())
+		free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr);
+
+	del_timer_sync(&sharpsl_pm.chrg_full_timer);
+	del_timer_sync(&sharpsl_pm.ac_timer);
+
+	return 0;
+}
+
+static struct device_driver sharpsl_pm_driver = {
+	.name		= "sharpsl-pm",
+	.bus		= &platform_bus_type,
+	.probe		= sharpsl_pm_probe,
+	.remove		= sharpsl_pm_remove,
+	.suspend	= sharpsl_pm_suspend,
+	.resume		= sharpsl_pm_resume,
+};
+
+static int __devinit sharpsl_pm_init(void)
+{
+	return driver_register(&sharpsl_pm_driver);
+}
+
+static void sharpsl_pm_exit(void)
+{
+ 	driver_unregister(&sharpsl_pm_driver);
+}
+
+late_initcall(sharpsl_pm_init);
+module_exit(sharpsl_pm_exit);

+ 40 - 88
arch/arm/mach-pxa/ssp.c

@@ -19,6 +19,8 @@
  *   22nd Aug 2003 Initial version.
  *   22nd Aug 2003 Initial version.
  *   20th Dec 2004 Added ssp_config for changing port config without
  *   20th Dec 2004 Added ssp_config for changing port config without
  *                 closing the port.
  *                 closing the port.
+ *    4th Aug 2005 Added option to disable irq handler registration and
+ *                 cleaned up irq and clock detection.
  */
  */
 
 
 #include <linux/module.h>
 #include <linux/module.h>
@@ -37,6 +39,26 @@
 
 
 #define PXA_SSP_PORTS 	3
 #define PXA_SSP_PORTS 	3
 
 
+struct ssp_info_ {
+	int irq;
+	u32 clock;
+};
+
+/*
+ * SSP port clock and IRQ settings
+ */
+static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
+#if defined (CONFIG_PXA27x)
+	{IRQ_SSP,	CKEN23_SSP1},
+	{IRQ_SSP2,	CKEN3_SSP2},
+	{IRQ_SSP3,	CKEN4_SSP3},
+#else
+	{IRQ_SSP,	CKEN3_SSP},
+	{IRQ_NSSP,	CKEN9_NSSP},
+	{IRQ_ASSP,	CKEN10_ASSP},
+#endif
+};
+
 static DECLARE_MUTEX(sem);
 static DECLARE_MUTEX(sem);
 static int use_count[PXA_SSP_PORTS] = {0, 0, 0};
 static int use_count[PXA_SSP_PORTS] = {0, 0, 0};
 
 
@@ -210,9 +232,9 @@ int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 spee
  *   %-EBUSY	if the resources are already in use
  *   %-EBUSY	if the resources are already in use
  *   %0		on success
  *   %0		on success
  */
  */
-int ssp_init(struct ssp_dev *dev, u32 port)
+int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags)
 {
 {
-	int ret, irq;
+	int ret;
 
 
 	if (port > PXA_SSP_PORTS || port == 0)
 	if (port > PXA_SSP_PORTS || port == 0)
 		return -ENODEV;
 		return -ENODEV;
@@ -229,61 +251,20 @@ int ssp_init(struct ssp_dev *dev, u32 port)
 		up(&sem);
 		up(&sem);
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
-
-	switch (port) {
-		case 1:
-			irq = IRQ_SSP;
-			break;
-#if defined (CONFIG_PXA27x)
-		case 2:
-			irq = IRQ_SSP2;
-			break;
-		case 3:
-			irq = IRQ_SSP3;
-			break;
-#else
-		case 2:
-			irq = IRQ_NSSP;
-			break;
-		case 3:
-			irq = IRQ_ASSP;
-			break;
-#endif
-		default:
-			return -ENODEV;
-	}
-
 	dev->port = port;
 	dev->port = port;
 
 
-	ret = request_irq(irq, ssp_interrupt, 0, "SSP", dev);
-	if (ret)
-		goto out_region;
+	/* do we need to get irq */
+	if (!(init_flags & SSP_NO_IRQ)) {
+		ret = request_irq(ssp_info[port-1].irq, ssp_interrupt,
+				0, "SSP", dev);
+	    	if (ret)
+			goto out_region;
+	    	dev->irq = ssp_info[port-1].irq;
+	} else
+		dev->irq = 0;
 
 
 	/* turn on SSP port clock */
 	/* turn on SSP port clock */
-	switch (dev->port) {
-#if defined (CONFIG_PXA27x)
-		case 1:
-			pxa_set_cken(CKEN23_SSP1, 1);
-			break;
-		case 2:
-			pxa_set_cken(CKEN3_SSP2, 1);
-			break;
-		case 3:
-			pxa_set_cken(CKEN4_SSP3, 1);
-			break;
-#else
-		case 1:
-			pxa_set_cken(CKEN3_SSP, 1);
-			break;
-		case 2:
-			pxa_set_cken(CKEN9_NSSP, 1);
-			break;
-		case 3:
-			pxa_set_cken(CKEN10_ASSP, 1);
-			break;
-#endif
-	}
-
+	pxa_set_cken(ssp_info[port-1].clock, 1);
 	up(&sem);
 	up(&sem);
 	return 0;
 	return 0;
 
 
@@ -301,46 +282,17 @@ out_region:
  */
  */
 void ssp_exit(struct ssp_dev *dev)
 void ssp_exit(struct ssp_dev *dev)
 {
 {
-	int irq;
-
 	down(&sem);
 	down(&sem);
 	SSCR0_P(dev->port) &= ~SSCR0_SSE;
 	SSCR0_P(dev->port) &= ~SSCR0_SSE;
 
 
-	/* find irq, save power and turn off SSP port clock */
-	switch (dev->port) {
-#if defined (CONFIG_PXA27x)
-		case 1:
-			irq = IRQ_SSP;
-			pxa_set_cken(CKEN23_SSP1, 0);
-			break;
-		case 2:
-			irq = IRQ_SSP2;
-			pxa_set_cken(CKEN3_SSP2, 0);
-			break;
-		case 3:
-			irq = IRQ_SSP3;
-			pxa_set_cken(CKEN4_SSP3, 0);
-			break;
-#else
-		case 1:
-			irq = IRQ_SSP;
-			pxa_set_cken(CKEN3_SSP, 0);
-			break;
-		case 2:
-			irq = IRQ_NSSP;
-			pxa_set_cken(CKEN9_NSSP, 0);
-			break;
-		case 3:
-			irq = IRQ_ASSP;
-			pxa_set_cken(CKEN10_ASSP, 0);
-			break;
-#endif
-		default:
-			printk(KERN_WARNING "SSP: tried to close invalid port\n");
-			return;
+    	if (dev->port > PXA_SSP_PORTS || dev->port == 0) {
+		printk(KERN_WARNING "SSP: tried to close invalid port\n");
+		return;
 	}
 	}
 
 
-	free_irq(irq, dev);
+	pxa_set_cken(ssp_info[dev->port-1].clock, 0);
+	if (dev->irq)
+		free_irq(dev->irq, dev);
 	release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c);
 	release_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c);
 	use_count[dev->port - 1]--;
 	use_count[dev->port - 1]--;
 	up(&sem);
 	up(&sem);

+ 16 - 15
arch/arm/mach-sa1100/neponset.c

@@ -137,7 +137,7 @@ static struct sa1100_port_fns neponset_port_fns __initdata = {
 	.get_mctrl	= neponset_get_mctrl,
 	.get_mctrl	= neponset_get_mctrl,
 };
 };
 
 
-static int neponset_probe(struct device *dev)
+static int neponset_probe(struct platform_device *dev)
 {
 {
 	sa1100_register_uart_fns(&neponset_port_fns);
 	sa1100_register_uart_fns(&neponset_port_fns);
 
 
@@ -178,27 +178,27 @@ static int neponset_probe(struct device *dev)
 /*
 /*
  * LDM power management.
  * LDM power management.
  */
  */
-static int neponset_suspend(struct device *dev, pm_message_t state)
+static int neponset_suspend(struct platform_device *dev, pm_message_t state)
 {
 {
 	/*
 	/*
 	 * Save state.
 	 * Save state.
 	 */
 	 */
-	if (!dev->power.saved_state)
-		dev->power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
-	if (!dev->power.saved_state)
+	if (!dev->dev.power.saved_state)
+		dev->dev.power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
+	if (!dev->dev.power.saved_state)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	*(unsigned int *)dev->power.saved_state = NCR_0;
+	*(unsigned int *)dev->dev.power.saved_state = NCR_0;
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int neponset_resume(struct device *dev)
+static int neponset_resume(struct platform_device *dev)
 {
 {
-	if (dev->power.saved_state) {
-		NCR_0 = *(unsigned int *)dev->power.saved_state;
-		kfree(dev->power.saved_state);
-		dev->power.saved_state = NULL;
+	if (dev->dev.power.saved_state) {
+		NCR_0 = *(unsigned int *)dev->dev.power.saved_state;
+		kfree(dev->dev.power.saved_state);
+		dev->dev.power.saved_state = NULL;
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -209,12 +209,13 @@ static int neponset_resume(struct device *dev)
 #define neponset_resume  NULL
 #define neponset_resume  NULL
 #endif
 #endif
 
 
-static struct device_driver neponset_device_driver = {
-	.name		= "neponset",
-	.bus		= &platform_bus_type,
+static struct platform_driver neponset_device_driver = {
 	.probe		= neponset_probe,
 	.probe		= neponset_probe,
 	.suspend	= neponset_suspend,
 	.suspend	= neponset_suspend,
 	.resume		= neponset_resume,
 	.resume		= neponset_resume,
+	.driver		= {
+		.name	= "neponset",
+	},
 };
 };
 
 
 static struct resource neponset_resources[] = {
 static struct resource neponset_resources[] = {
@@ -293,7 +294,7 @@ static struct platform_device *devices[] __initdata = {
 
 
 static int __init neponset_init(void)
 static int __init neponset_init(void)
 {
 {
-	driver_register(&neponset_device_driver);
+	platform_driver_register(&neponset_device_driver);
 
 
 	/*
 	/*
 	 * The Neponset is only present on the Assabet machine type.
 	 * The Neponset is only present on the Assabet machine type.

+ 3 - 3
arch/arm/mm/Kconfig

@@ -102,8 +102,8 @@ config CPU_ARM922T
 # ARM925T
 # ARM925T
 config CPU_ARM925T
 config CPU_ARM925T
  	bool "Support ARM925T processor" if ARCH_OMAP1
  	bool "Support ARM925T processor" if ARCH_OMAP1
- 	depends on ARCH_OMAP1510
- 	default y if ARCH_OMAP1510
+ 	depends on ARCH_OMAP15XX
+ 	default y if ARCH_OMAP15XX
 	select CPU_32v4
 	select CPU_32v4
 	select CPU_ABRT_EV4T
 	select CPU_ABRT_EV4T
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_V4WT
@@ -242,7 +242,7 @@ config CPU_XSCALE
 # ARMv6
 # ARMv6
 config CPU_V6
 config CPU_V6
 	bool "Support ARM V6 processor"
 	bool "Support ARM V6 processor"
-	depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB
+	depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2
 	select CPU_32v6
 	select CPU_32v6
 	select CPU_ABRT_EV6
 	select CPU_ABRT_EV6
 	select CPU_CACHE_V6
 	select CPU_CACHE_V6

+ 1 - 1
arch/arm/plat-omap/Makefile

@@ -3,7 +3,7 @@
 #
 #
 
 
 # Common support
 # Common support
-obj-y := common.o sram.o sram-fn.o clock.o dma.o mux.o gpio.o mcbsp.o usb.o
+obj-y := common.o sram.o sram-fn.o clock.o devices.o dma.o mux.o gpio.o mcbsp.o usb.o
 obj-m :=
 obj-m :=
 obj-n :=
 obj-n :=
 obj-  :=
 obj-  :=

文件差异内容过多而无法显示
+ 117 - 988
arch/arm/plat-omap/clock.c


+ 0 - 120
arch/arm/plat-omap/clock.h

@@ -1,120 +0,0 @@
-/*
- *  linux/arch/arm/plat-omap/clock.h
- *
- *  Copyright (C) 2004 Nokia corporation
- *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
- *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ARCH_ARM_OMAP_CLOCK_H
-#define __ARCH_ARM_OMAP_CLOCK_H
-
-struct module;
-
-struct clk {
-	struct list_head	node;
-	struct module		*owner;
-	const char		*name;
-	struct clk		*parent;
-	unsigned long		rate;
-	__s8			usecount;
-	__u16			flags;
-	__u32			enable_reg;
-	__u8			enable_bit;
-	__u8			rate_offset;
-	void			(*recalc)(struct clk *);
-	int			(*set_rate)(struct clk *, unsigned long);
-	long			(*round_rate)(struct clk *, unsigned long);
-	void			(*init)(struct clk *);
-};
-
-
-struct mpu_rate {
-	unsigned long		rate;
-	unsigned long		xtal;
-	unsigned long		pll_rate;
-	__u16			ckctl_val;
-	__u16			dpllctl_val;
-};
-
-
-/* Clock flags */
-#define RATE_CKCTL		1
-#define RATE_FIXED		2
-#define RATE_PROPAGATES		4
-#define VIRTUAL_CLOCK		8
-#define ALWAYS_ENABLED		16
-#define ENABLE_REG_32BIT	32
-#define CLOCK_IN_OMAP16XX	64
-#define CLOCK_IN_OMAP1510	128
-#define CLOCK_IN_OMAP730	256
-#define DSP_DOMAIN_CLOCK	512
-#define VIRTUAL_IO_ADDRESS	1024
-
-/* ARM_CKCTL bit shifts */
-#define CKCTL_PERDIV_OFFSET	0
-#define CKCTL_LCDDIV_OFFSET	2
-#define CKCTL_ARMDIV_OFFSET	4
-#define CKCTL_DSPDIV_OFFSET	6
-#define CKCTL_TCDIV_OFFSET	8
-#define CKCTL_DSPMMUDIV_OFFSET	10
-/*#define ARM_TIMXO		12*/
-#define EN_DSPCK		13
-/*#define ARM_INTHCK_SEL	14*/ /* Divide-by-2 for mpu inth_ck */
-/* DSP_CKCTL bit shifts */
-#define CKCTL_DSPPERDIV_OFFSET	0
-
-/* ARM_IDLECT1 bit shifts */
-/*#define IDLWDT_ARM	0*/
-/*#define IDLXORP_ARM	1*/
-/*#define IDLPER_ARM	2*/
-/*#define IDLLCD_ARM	3*/
-/*#define IDLLB_ARM	4*/
-/*#define IDLHSAB_ARM	5*/
-/*#define IDLIF_ARM	6*/
-/*#define IDLDPLL_ARM	7*/
-/*#define IDLAPI_ARM	8*/
-/*#define IDLTIM_ARM	9*/
-/*#define SETARM_IDLE	11*/
-
-/* ARM_IDLECT2 bit shifts */
-#define EN_WDTCK	0
-#define EN_XORPCK	1
-#define EN_PERCK	2
-#define EN_LCDCK	3
-#define EN_LBCK		4 /* Not on 1610/1710 */
-/*#define EN_HSABCK	5*/
-#define EN_APICK	6
-#define EN_TIMCK	7
-#define DMACK_REQ	8
-#define EN_GPIOCK	9 /* Not on 1610/1710 */
-/*#define EN_LBFREECK	10*/
-#define EN_CKOUT_ARM	11
-
-/* ARM_IDLECT3 bit shifts */
-#define EN_OCPI_CK	0
-#define EN_TC1_CK	2
-#define EN_TC2_CK	4
-
-/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */
-#define EN_DSPTIMCK	5
-
-/* Various register defines for clock controls scattered around OMAP chip */
-#define USB_MCLK_EN_BIT		4	/* In ULPD_CLKC_CTRL */
-#define USB_HOST_HHC_UHOST_EN	9	/* In MOD_CONF_CTRL_0 */
-#define SWD_ULPD_PLL_CLK_REQ	1	/* In SWD_CLK_DIV_CTRL_SEL */
-#define COM_ULPD_PLL_CLK_REQ	1	/* In COM_CLK_DIV_CTRL_SEL */
-#define SWD_CLK_DIV_CTRL_SEL	0xfffe0874
-#define COM_CLK_DIV_CTRL_SEL	0xfffe0878
-#define SOFT_REQ_REG		0xfffe0834
-#define SOFT_REQ_REG2		0xfffe0880
-
-int clk_register(struct clk *clk);
-void clk_unregister(struct clk *clk);
-int clk_init(void);
-
-#endif

+ 37 - 13
arch/arm/plat-omap/common.c

@@ -31,7 +31,7 @@
 #include <asm/arch/mux.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/fpga.h>
 #include <asm/arch/fpga.h>
 
 
-#include "clock.h"
+#include <asm/arch/clock.h>
 
 
 #define NO_LENGTH_CHECK 0xffffffff
 #define NO_LENGTH_CHECK 0xffffffff
 
 
@@ -117,19 +117,43 @@ EXPORT_SYMBOL(omap_get_var_config);
 
 
 static int __init omap_add_serial_console(void)
 static int __init omap_add_serial_console(void)
 {
 {
-	const struct omap_serial_console_config *info;
-
-	info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
-			       struct omap_serial_console_config);
-	if (info != NULL && info->console_uart) {
-		static char speed[11], *opt = NULL;
+	const struct omap_serial_console_config *con_info;
+	const struct omap_uart_config *uart_info;
+	static char speed[11], *opt = NULL;
+	int line, i, uart_idx;
+
+	uart_info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
+	con_info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
+					struct omap_serial_console_config);
+	if (uart_info == NULL || con_info == NULL)
+		return 0;
+
+	if (con_info->console_uart == 0)
+		return 0;
+
+	if (con_info->console_speed) {
+		snprintf(speed, sizeof(speed), "%u", con_info->console_speed);
+		opt = speed;
+	}
 
 
-		if (info->console_speed) {
-			snprintf(speed, sizeof(speed), "%u", info->console_speed);
-			opt = speed;
-		}
-		return add_preferred_console("ttyS", info->console_uart - 1, opt);
+	uart_idx = con_info->console_uart - 1;
+	if (uart_idx >= OMAP_MAX_NR_PORTS) {
+		printk(KERN_INFO "Console: external UART#%d. "
+			"Not adding it as console this time.\n",
+			uart_idx + 1);
+		return 0;
+	}
+	if (!(uart_info->enabled_uarts & (1 << uart_idx))) {
+		printk(KERN_ERR "Console: Selected UART#%d is "
+			"not enabled for this platform\n",
+			uart_idx + 1);
+		return -1;
+	}
+	line = 0;
+	for (i = 0; i < uart_idx; i++) {
+		if (uart_info->enabled_uarts & (1 << i))
+			line++;
 	}
 	}
-	return 0;
+	return add_preferred_console("ttyS", line, opt);
 }
 }
 console_initcall(omap_add_serial_console);
 console_initcall(omap_add_serial_console);

+ 381 - 0
arch/arm/plat-omap/devices.c

@@ -0,0 +1,381 @@
+/*
+ * linux/arch/arm/plat-omap/devices.c
+ *
+ * Common platform device setup/initialization for OMAP1 and OMAP2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/tc.h>
+#include <asm/arch/board.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/gpio.h>
+
+
+void omap_nop_release(struct device *dev)
+{
+        /* Nothing */
+}
+
+/*-------------------------------------------------------------------------*/
+
+#if 	defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
+
+#define	OMAP1_I2C_BASE		0xfffb3800
+#define OMAP2_I2C_BASE1		0x48070000
+#define OMAP_I2C_SIZE		0x3f
+#define OMAP1_I2C_INT		INT_I2C
+#define OMAP2_I2C_INT1		56
+
+static struct resource i2c_resources1[] = {
+	{
+		.start		= 0,
+		.end		= 0,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= 0,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+/* DMA not used; works around erratum writing to non-empty i2c fifo */
+
+static struct platform_device omap_i2c_device1 = {
+        .name           = "i2c_omap",
+        .id             = 1,
+        .dev = {
+                .release        = omap_nop_release,
+        },
+	.num_resources	= ARRAY_SIZE(i2c_resources1),
+	.resource	= i2c_resources1,
+};
+
+/* See also arch/arm/mach-omap2/devices.c for second I2C on 24xx */
+static void omap_init_i2c(void)
+{
+	if (cpu_is_omap24xx()) {
+		i2c_resources1[0].start = OMAP2_I2C_BASE1;
+		i2c_resources1[0].end = OMAP2_I2C_BASE1 + OMAP_I2C_SIZE;
+		i2c_resources1[1].start = OMAP2_I2C_INT1;
+	} else {
+		i2c_resources1[0].start = OMAP1_I2C_BASE;
+		i2c_resources1[0].end = OMAP1_I2C_BASE + OMAP_I2C_SIZE;
+		i2c_resources1[1].start = OMAP1_I2C_INT;
+	}
+
+	/* FIXME define and use a boot tag, in case of boards that
+	 * either don't wire up I2C, or chips that mux it differently...
+	 * it can include clocking and address info, maybe more.
+	 */
+	if (cpu_is_omap24xx()) {
+		omap_cfg_reg(M19_24XX_I2C1_SCL);
+		omap_cfg_reg(L15_24XX_I2C1_SDA);
+	} else {
+		omap_cfg_reg(I2C_SCL);
+		omap_cfg_reg(I2C_SDA);
+	}
+
+	(void) platform_device_register(&omap_i2c_device1);
+}
+
+#else
+static inline void omap_init_i2c(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if	defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+#ifdef CONFIG_ARCH_OMAP24XX
+#define	OMAP_MMC1_BASE		0x4809c000
+#define OMAP_MMC1_INT		83
+#else
+#define	OMAP_MMC1_BASE		0xfffb7800
+#define OMAP_MMC1_INT		INT_MMC
+#endif
+#define	OMAP_MMC2_BASE		0xfffb7c00	/* omap16xx only */
+
+static struct omap_mmc_conf mmc1_conf;
+
+static u64 mmc1_dmamask = 0xffffffff;
+
+static struct resource mmc1_resources[] = {
+	{
+		.start		= IO_ADDRESS(OMAP_MMC1_BASE),
+		.end		= IO_ADDRESS(OMAP_MMC1_BASE) + 0x7f,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= OMAP_MMC1_INT,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device mmc_omap_device1 = {
+	.name		= "mmci-omap",
+	.id		= 1,
+	.dev = {
+		.release	= omap_nop_release,
+		.dma_mask	= &mmc1_dmamask,
+		.platform_data	= &mmc1_conf,
+	},
+	.num_resources	= ARRAY_SIZE(mmc1_resources),
+	.resource	= mmc1_resources,
+};
+
+#ifdef	CONFIG_ARCH_OMAP16XX
+
+static struct omap_mmc_conf mmc2_conf;
+
+static u64 mmc2_dmamask = 0xffffffff;
+
+static struct resource mmc2_resources[] = {
+	{
+		.start		= IO_ADDRESS(OMAP_MMC2_BASE),
+		.end		= IO_ADDRESS(OMAP_MMC2_BASE) + 0x7f,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= INT_1610_MMC2,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device mmc_omap_device2 = {
+	.name		= "mmci-omap",
+	.id		= 2,
+	.dev = {
+		.release	= omap_nop_release,
+		.dma_mask	= &mmc2_dmamask,
+		.platform_data	= &mmc2_conf,
+	},
+	.num_resources	= ARRAY_SIZE(mmc2_resources),
+	.resource	= mmc2_resources,
+};
+#endif
+
+static void __init omap_init_mmc(void)
+{
+	const struct omap_mmc_config	*mmc_conf;
+	const struct omap_mmc_conf	*mmc;
+
+	/* NOTE:  assumes MMC was never (wrongly) enabled */
+	mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
+	if (!mmc_conf)
+		return;
+
+	/* block 1 is always available and has just one pinout option */
+	mmc = &mmc_conf->mmc[0];
+	if (mmc->enabled) {
+		if (!cpu_is_omap24xx()) {
+			omap_cfg_reg(MMC_CMD);
+			omap_cfg_reg(MMC_CLK);
+			omap_cfg_reg(MMC_DAT0);
+			if (cpu_is_omap1710()) {
+				omap_cfg_reg(M15_1710_MMC_CLKI);
+				omap_cfg_reg(P19_1710_MMC_CMDDIR);
+				omap_cfg_reg(P20_1710_MMC_DATDIR0);
+			}
+		}
+		if (mmc->wire4) {
+			if (!cpu_is_omap24xx()) {
+				omap_cfg_reg(MMC_DAT1);
+				/* NOTE:  DAT2 can be on W10 (here) or M15 */
+				if (!mmc->nomux)
+					omap_cfg_reg(MMC_DAT2);
+				omap_cfg_reg(MMC_DAT3);
+			}
+		}
+		mmc1_conf = *mmc;
+		(void) platform_device_register(&mmc_omap_device1);
+	}
+
+#ifdef	CONFIG_ARCH_OMAP16XX
+	/* block 2 is on newer chips, and has many pinout options */
+	mmc = &mmc_conf->mmc[1];
+	if (mmc->enabled) {
+		if (!mmc->nomux) {
+			omap_cfg_reg(Y8_1610_MMC2_CMD);
+			omap_cfg_reg(Y10_1610_MMC2_CLK);
+			omap_cfg_reg(R18_1610_MMC2_CLKIN);
+			omap_cfg_reg(W8_1610_MMC2_DAT0);
+			if (mmc->wire4) {
+				omap_cfg_reg(V8_1610_MMC2_DAT1);
+				omap_cfg_reg(W15_1610_MMC2_DAT2);
+				omap_cfg_reg(R10_1610_MMC2_DAT3);
+			}
+
+			/* These are needed for the level shifter */
+			omap_cfg_reg(V9_1610_MMC2_CMDDIR);
+			omap_cfg_reg(V5_1610_MMC2_DATDIR0);
+			omap_cfg_reg(W19_1610_MMC2_DATDIR1);
+		}
+
+		/* Feedback clock must be set on OMAP-1710 MMC2 */
+		if (cpu_is_omap1710())
+			omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
+				     MOD_CONF_CTRL_1);
+		mmc2_conf = *mmc;
+		(void) platform_device_register(&mmc_omap_device2);
+	}
+#endif
+	return;
+}
+#else
+static inline void omap_init_mmc(void) {}
+#endif
+
+#if	defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
+
+#ifdef CONFIG_ARCH_OMAP24XX
+#define	OMAP_WDT_BASE		0x48022000
+#else
+#define	OMAP_WDT_BASE		0xfffeb000
+#endif
+
+static struct resource wdt_resources[] = {
+	{
+		.start		= OMAP_WDT_BASE,
+		.end		= OMAP_WDT_BASE + 0x4f,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device omap_wdt_device = {
+	.name	   = "omap_wdt",
+	.id	     = -1,
+	.dev = {
+		.release	= omap_nop_release,
+	},
+	.num_resources	= ARRAY_SIZE(wdt_resources),
+	.resource	= wdt_resources,
+};
+
+static void omap_init_wdt(void)
+{
+	(void) platform_device_register(&omap_wdt_device);
+}
+#else
+static inline void omap_init_wdt(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if	defined(CONFIG_OMAP_RNG) || defined(CONFIG_OMAP_RNG_MODULE)
+
+#ifdef CONFIG_ARCH_OMAP24XX
+#define	OMAP_RNG_BASE		0x480A0000
+#else
+#define	OMAP_RNG_BASE		0xfffe5000
+#endif
+
+static struct resource rng_resources[] = {
+	{
+		.start		= OMAP_RNG_BASE,
+		.end		= OMAP_RNG_BASE + 0x4f,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device omap_rng_device = {
+	.name	   = "omap_rng",
+	.id	     = -1,
+	.dev = {
+		.release	= omap_nop_release,
+	},
+	.num_resources	= ARRAY_SIZE(rng_resources),
+	.resource	= rng_resources,
+};
+
+static void omap_init_rng(void)
+{
+	(void) platform_device_register(&omap_rng_device);
+}
+#else
+static inline void omap_init_rng(void) {}
+#endif
+
+#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
+
+static struct omap_lcd_config omap_fb_conf;
+
+static u64 omap_fb_dma_mask = ~(u32)0;
+
+static struct platform_device omap_fb_device = {
+	.name		= "omapfb",
+	.id		= -1,
+	.dev = {
+		.release		= omap_nop_release,
+		.dma_mask		= &omap_fb_dma_mask,
+		.coherent_dma_mask	= ~(u32)0,
+		.platform_data		= &omap_fb_conf,
+	},
+	.num_resources = 0,
+};
+
+static inline void omap_init_fb(void)
+{
+	const struct omap_lcd_config *conf;
+
+	conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
+	if (conf != NULL)
+		omap_fb_conf = *conf;
+	platform_device_register(&omap_fb_device);
+}
+
+#else
+
+static inline void omap_init_fb(void) {}
+
+#endif
+
+/*
+ * This gets called after board-specific INIT_MACHINE, and initializes most
+ * on-chip peripherals accessible on this board (except for few like USB):
+ *
+ *  (a) Does any "standard config" pin muxing needed.  Board-specific
+ *	code will have muxed GPIO pins and done "nonstandard" setup;
+ *	that code could live in the boot loader.
+ *  (b) Populating board-specific platform_data with the data drivers
+ *	rely on to handle wiring variations.
+ *  (c) Creating platform devices as meaningful on this board and
+ *	with this kernel configuration.
+ *
+ * Claiming GPIOs, and setting their direction and initial values, is the
+ * responsibility of the device drivers.  So is responding to probe().
+ *
+ * Board-specific knowlege like creating devices or pin setup is to be
+ * kept out of drivers as much as possible.  In particular, pin setup
+ * may be handled by the boot loader, and drivers should expect it will
+ * normally have been done by the time they're probed.
+ */
+static int __init omap_init_devices(void)
+{
+	/* please keep these calls, and their implementations above,
+	 * in alphabetical order so they're easier to sort through.
+	 */
+	omap_init_fb();
+	omap_init_i2c();
+	omap_init_mmc();
+	omap_init_wdt();
+	omap_init_rng();
+
+	return 0;
+}
+arch_initcall(omap_init_devices);
+

文件差异内容过多而无法显示
+ 541 - 224
arch/arm/plat-omap/dma.c


+ 27 - 13
arch/arm/plat-omap/gpio.c

@@ -140,7 +140,7 @@ static struct gpio_bank gpio_bank_1610[5] = {
 };
 };
 #endif
 #endif
 
 
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 static struct gpio_bank gpio_bank_1510[2] = {
 static struct gpio_bank gpio_bank_1510[2] = {
 	{ OMAP_MPUIO_BASE,    INT_MPUIO,      IH_MPUIO_BASE, METHOD_MPUIO },
 	{ OMAP_MPUIO_BASE,    INT_MPUIO,      IH_MPUIO_BASE, METHOD_MPUIO },
 	{ OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE,  METHOD_GPIO_1510 }
 	{ OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE,  METHOD_GPIO_1510 }
@@ -173,7 +173,7 @@ static int gpio_bank_count;
 
 
 static inline struct gpio_bank *get_gpio_bank(int gpio)
 static inline struct gpio_bank *get_gpio_bank(int gpio)
 {
 {
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
 	if (cpu_is_omap1510()) {
 		if (OMAP_GPIO_IS_MPUIO(gpio))
 		if (OMAP_GPIO_IS_MPUIO(gpio))
 			return &gpio_bank[0];
 			return &gpio_bank[0];
@@ -222,7 +222,7 @@ static inline int gpio_valid(int gpio)
 			return -1;
 			return -1;
 		return 0;
 		return 0;
 	}
 	}
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510() && gpio < 16)
 	if (cpu_is_omap1510() && gpio < 16)
 		return 0;
 		return 0;
 #endif
 #endif
@@ -654,7 +654,7 @@ int omap_request_gpio(int gpio)
 	/* Set trigger to none. You need to enable the trigger after request_irq */
 	/* Set trigger to none. You need to enable the trigger after request_irq */
 	_set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE);
 	_set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE);
 
 
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 	if (bank->method == METHOD_GPIO_1510) {
 	if (bank->method == METHOD_GPIO_1510) {
 		void __iomem *reg;
 		void __iomem *reg;
 
 
@@ -739,7 +739,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
 	bank = (struct gpio_bank *) desc->data;
 	bank = (struct gpio_bank *) desc->data;
 	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;
-#ifdef CONFIG_ARCH_OMAP1510
+#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;
 #endif
 #endif
@@ -774,7 +774,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
 			d = irq_desc + gpio_irq;
 			d = irq_desc + gpio_irq;
 			desc_handle_irq(gpio_irq, d, regs);
 			desc_handle_irq(gpio_irq, d, regs);
 		}
 		}
-        }
+	}
 }
 }
 
 
 static void gpio_ack_irq(unsigned int irq)
 static void gpio_ack_irq(unsigned int irq)
@@ -837,8 +837,9 @@ static struct irqchip mpuio_irq_chip = {
 	.unmask = mpuio_unmask_irq
 	.unmask = mpuio_unmask_irq
 };
 };
 
 
-static int initialized = 0;
-static struct clk * gpio_ck = NULL;
+static int initialized;
+static struct clk * gpio_ick;
+static struct clk * gpio_fck;
 
 
 static int __init _omap_gpio_init(void)
 static int __init _omap_gpio_init(void)
 {
 {
@@ -848,14 +849,26 @@ static int __init _omap_gpio_init(void)
 	initialized = 1;
 	initialized = 1;
 
 
 	if (cpu_is_omap1510()) {
 	if (cpu_is_omap1510()) {
-		gpio_ck = clk_get(NULL, "arm_gpio_ck");
-		if (IS_ERR(gpio_ck))
+		gpio_ick = clk_get(NULL, "arm_gpio_ck");
+		if (IS_ERR(gpio_ick))
 			printk("Could not get arm_gpio_ck\n");
 			printk("Could not get arm_gpio_ck\n");
 		else
 		else
-			clk_use(gpio_ck);
+			clk_use(gpio_ick);
+	}
+	if (cpu_is_omap24xx()) {
+		gpio_ick = clk_get(NULL, "gpios_ick");
+		if (IS_ERR(gpio_ick))
+			printk("Could not get gpios_ick\n");
+		else
+			clk_use(gpio_ick);
+		gpio_fck = clk_get(NULL, "gpios_fck");
+		if (IS_ERR(gpio_ick))
+			printk("Could not get gpios_fck\n");
+		else
+			clk_use(gpio_fck);
 	}
 	}
 
 
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
 	if (cpu_is_omap1510()) {
 		printk(KERN_INFO "OMAP1510 GPIO hardware\n");
 		printk(KERN_INFO "OMAP1510 GPIO hardware\n");
 		gpio_bank_count = 2;
 		gpio_bank_count = 2;
@@ -901,7 +914,7 @@ static int __init _omap_gpio_init(void)
 		if (bank->method == METHOD_MPUIO) {
 		if (bank->method == METHOD_MPUIO) {
 			omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
 			omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
 		}
 		}
-#ifdef CONFIG_ARCH_OMAP1510
+#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);
 			__raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
 			__raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
@@ -1038,6 +1051,7 @@ static struct sys_device omap_gpio_device = {
 
 
 /*
 /*
  * This may get called early from board specific init
  * This may get called early from board specific init
+ * for boards that have interrupts routed via FPGA.
  */
  */
 int omap_gpio_init(void)
 int omap_gpio_init(void)
 {
 {

+ 14 - 8
arch/arm/plat-omap/mcbsp.c

@@ -491,17 +491,20 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
 	omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
 	omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
 				     OMAP_DMA_DATA_TYPE_S16,
 				     OMAP_DMA_DATA_TYPE_S16,
 				     length >> 1, 1,
 				     length >> 1, 1,
-				     OMAP_DMA_SYNC_ELEMENT);
+				     OMAP_DMA_SYNC_ELEMENT,
+				     0, 0);
 
 
 	omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
 	omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
 				 OMAP_DMA_PORT_TIPB,
 				 OMAP_DMA_PORT_TIPB,
 				 OMAP_DMA_AMODE_CONSTANT,
 				 OMAP_DMA_AMODE_CONSTANT,
-				 mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1);
+				 mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1,
+				 0, 0);
 
 
 	omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
 	omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
 				OMAP_DMA_PORT_EMIFF,
 				OMAP_DMA_PORT_EMIFF,
 				OMAP_DMA_AMODE_POST_INC,
 				OMAP_DMA_AMODE_POST_INC,
-				buffer);
+				buffer,
+				0, 0);
 
 
 	omap_start_dma(mcbsp[id].dma_tx_lch);
 	omap_start_dma(mcbsp[id].dma_tx_lch);
 	wait_for_completion(&(mcbsp[id].tx_dma_completion));
 	wait_for_completion(&(mcbsp[id].tx_dma_completion));
@@ -531,17 +534,20 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
 	omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
 	omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
 				     OMAP_DMA_DATA_TYPE_S16,
 				     OMAP_DMA_DATA_TYPE_S16,
 				     length >> 1, 1,
 				     length >> 1, 1,
-				     OMAP_DMA_SYNC_ELEMENT);
+				     OMAP_DMA_SYNC_ELEMENT,
+				     0, 0);
 
 
 	omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
 	omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
 				OMAP_DMA_PORT_TIPB,
 				OMAP_DMA_PORT_TIPB,
 				OMAP_DMA_AMODE_CONSTANT,
 				OMAP_DMA_AMODE_CONSTANT,
-				mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1);
+				mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1,
+				0, 0);
 
 
 	omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
 	omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
 				 OMAP_DMA_PORT_EMIFF,
 				 OMAP_DMA_PORT_EMIFF,
 				 OMAP_DMA_AMODE_POST_INC,
 				 OMAP_DMA_AMODE_POST_INC,
-				 buffer);
+				 buffer,
+				 0, 0);
 
 
 	omap_start_dma(mcbsp[id].dma_rx_lch);
 	omap_start_dma(mcbsp[id].dma_rx_lch);
 	wait_for_completion(&(mcbsp[id].rx_dma_completion));
 	wait_for_completion(&(mcbsp[id].rx_dma_completion));
@@ -643,7 +649,7 @@ static const struct omap_mcbsp_info mcbsp_730[] = {
 };
 };
 #endif
 #endif
 
 
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 static const struct omap_mcbsp_info mcbsp_1510[] = {
 static const struct omap_mcbsp_info mcbsp_1510[] = {
 	[0] = { .virt_base = OMAP1510_MCBSP1_BASE,
 	[0] = { .virt_base = OMAP1510_MCBSP1_BASE,
 		.dma_rx_sync = OMAP_DMA_MCBSP1_RX,
 		.dma_rx_sync = OMAP_DMA_MCBSP1_RX,
@@ -712,7 +718,7 @@ static int __init omap_mcbsp_init(void)
 		mcbsp_count = ARRAY_SIZE(mcbsp_730);
 		mcbsp_count = ARRAY_SIZE(mcbsp_730);
 	}
 	}
 #endif
 #endif
-#ifdef CONFIG_ARCH_OMAP1510
+#ifdef CONFIG_ARCH_OMAP15XX
 	if (cpu_is_omap1510()) {
 	if (cpu_is_omap1510()) {
 		mcbsp_info = mcbsp_1510;
 		mcbsp_info = mcbsp_1510;
 		mcbsp_count = ARRAY_SIZE(mcbsp_1510);
 		mcbsp_count = ARRAY_SIZE(mcbsp_1510);

+ 51 - 14
arch/arm/plat-omap/mux.c

@@ -3,7 +3,7 @@
  *
  *
  * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h
  * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h
  *
  *
- * Copyright (C) 2003 Nokia Corporation
+ * Copyright (C) 2003 - 2005 Nokia Corporation
  *
  *
  * Written by Tony Lindgren <tony.lindgren@nokia.com>
  * Written by Tony Lindgren <tony.lindgren@nokia.com>
  *
  *
@@ -25,38 +25,74 @@
 #include <linux/config.h>
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <asm/system.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
-
-#define __MUX_C__
 #include <asm/arch/mux.h>
 #include <asm/arch/mux.h>
 
 
 #ifdef CONFIG_OMAP_MUX
 #ifdef CONFIG_OMAP_MUX
 
 
+#define OMAP24XX_L4_BASE	0x48000000
+#define OMAP24XX_PULL_ENA	(1 << 3)
+#define OMAP24XX_PULL_UP	(1 << 4)
+
+static struct pin_config * pin_table;
+static unsigned long pin_table_sz;
+
+extern struct pin_config * omap730_pins;
+extern struct pin_config * omap1xxx_pins;
+extern struct pin_config * omap24xx_pins;
+
+int __init omap_mux_register(struct pin_config * pins, unsigned long size)
+{
+	pin_table = pins;
+	pin_table_sz = size;
+
+	return 0;
+}
+
 /*
 /*
  * Sets the Omap MUX and PULL_DWN registers based on the table
  * Sets the Omap MUX and PULL_DWN registers based on the table
  */
  */
-int __init_or_module
-omap_cfg_reg(const reg_cfg_t reg_cfg)
+int __init_or_module omap_cfg_reg(const unsigned long index)
 {
 {
 	static DEFINE_SPINLOCK(mux_spin_lock);
 	static DEFINE_SPINLOCK(mux_spin_lock);
 
 
 	unsigned long flags;
 	unsigned long flags;
-	reg_cfg_set *cfg;
+	struct pin_config *cfg;
 	unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0,
 	unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0,
 		pull_orig = 0, pull = 0;
 		pull_orig = 0, pull = 0;
 	unsigned int mask, warn = 0;
 	unsigned int mask, warn = 0;
 
 
-	if (cpu_is_omap7xx())
-		return 0;
+	if (!pin_table)
+		BUG();
 
 
-	if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) {
-		printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg);
-		return -EINVAL;
+	if (index >= pin_table_sz) {
+		printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
+		       index, pin_table_sz);
+		dump_stack();
+		return -ENODEV;
 	}
 	}
 
 
-	cfg = (reg_cfg_set *)&reg_cfg_table[reg_cfg];
+	cfg = (struct pin_config *)&pin_table[index];
+	if (cpu_is_omap24xx()) {
+		u8 reg = 0;
+
+		reg |= cfg->mask & 0x7;
+		if (cfg->pull_val)
+			reg |= OMAP24XX_PULL_ENA;
+		if(cfg->pu_pd_val)
+			reg |= OMAP24XX_PULL_UP;
+#ifdef CONFIG_OMAP_MUX_DEBUG
+		printk("Muxing %s (0x%08x): 0x%02x -> 0x%02x\n",
+		       cfg->name, OMAP24XX_L4_BASE + cfg->mux_reg,
+		       omap_readb(OMAP24XX_L4_BASE + cfg->mux_reg), reg);
+#endif
+		omap_writeb(reg, OMAP24XX_L4_BASE + cfg->mux_reg);
+
+		return 0;
+	}
 
 
 	/* Check the mux register in question */
 	/* Check the mux register in question */
 	if (cfg->mux_reg) {
 	if (cfg->mux_reg) {
@@ -157,7 +193,8 @@ omap_cfg_reg(const reg_cfg_t reg_cfg)
 	return 0;
 	return 0;
 #endif
 #endif
 }
 }
-
 EXPORT_SYMBOL(omap_cfg_reg);
 EXPORT_SYMBOL(omap_cfg_reg);
-
+#else
+#define omap_mux_init() do {} while(0)
+#define omap_cfg_reg(x)	do {} while(0)
 #endif	/* CONFIG_OMAP_MUX */
 #endif	/* CONFIG_OMAP_MUX */

+ 82 - 21
arch/arm/plat-omap/pm.c

@@ -54,11 +54,12 @@
 #include <asm/arch/tps65010.h>
 #include <asm/arch/tps65010.h>
 #include <asm/arch/dsp_common.h>
 #include <asm/arch/dsp_common.h>
 
 
-#include "clock.h"
-#include "sram.h"
+#include <asm/arch/clock.h>
+#include <asm/arch/sram.h>
 
 
 static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
 static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
 static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
 static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
+static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
 static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
 static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
 static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
 static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
 
 
@@ -120,8 +121,8 @@ void omap_pm_idle(void)
  */
  */
 static void omap_pm_wakeup_setup(void)
 static void omap_pm_wakeup_setup(void)
 {
 {
-	u32 level1_wake = OMAP_IRQ_BIT(INT_IH2_IRQ);
-	u32 level2_wake = OMAP_IRQ_BIT(INT_UART2) | OMAP_IRQ_BIT(INT_KEYBOARD);
+	u32 level1_wake = 0;
+	u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
 
 
 	/*
 	/*
 	 * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
 	 * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
@@ -129,19 +130,29 @@ static void omap_pm_wakeup_setup(void)
 	 * drivers must still separately call omap_set_gpio_wakeup() to
 	 * drivers must still separately call omap_set_gpio_wakeup() to
 	 * wake up to a GPIO interrupt.
 	 * wake up to a GPIO interrupt.
 	 */
 	 */
-	if (cpu_is_omap1510() || cpu_is_omap16xx())
-		level1_wake |= OMAP_IRQ_BIT(INT_GPIO_BANK1);
-	else if (cpu_is_omap730())
-		level1_wake |= OMAP_IRQ_BIT(INT_730_GPIO_BANK1);
+	if (cpu_is_omap730())
+		level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
+			OMAP_IRQ_BIT(INT_730_IH2_IRQ);
+	else if (cpu_is_omap1510())
+		level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
+			OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
+	else if (cpu_is_omap16xx())
+		level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
+			OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
 
 
 	omap_writel(~level1_wake, OMAP_IH1_MIR);
 	omap_writel(~level1_wake, OMAP_IH1_MIR);
 
 
-	if (cpu_is_omap1510())
+	if (cpu_is_omap730()) {
+		omap_writel(~level2_wake, OMAP_IH2_0_MIR);
+		omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) | OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)), OMAP_IH2_1_MIR);
+	} else if (cpu_is_omap1510()) {
+		level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
 		omap_writel(~level2_wake,  OMAP_IH2_MIR);
 		omap_writel(~level2_wake,  OMAP_IH2_MIR);
-
-	/* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
-	if (cpu_is_omap16xx()) {
+	} else if (cpu_is_omap16xx()) {
+		level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
 		omap_writel(~level2_wake, OMAP_IH2_0_MIR);
 		omap_writel(~level2_wake, OMAP_IH2_0_MIR);
+
+		/* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
 		omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR);
 		omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR);
 		omap_writel(~0x0, OMAP_IH2_2_MIR);
 		omap_writel(~0x0, OMAP_IH2_2_MIR);
 		omap_writel(~0x0, OMAP_IH2_3_MIR);
 		omap_writel(~0x0, OMAP_IH2_3_MIR);
@@ -185,7 +196,17 @@ void omap_pm_suspend(void)
  	 * Save interrupt, MPUI, ARM and UPLD control registers.
  	 * Save interrupt, MPUI, ARM and UPLD control registers.
 	 */
 	 */
 
 
-	if (cpu_is_omap1510()) {
+	if (cpu_is_omap730()) {
+		MPUI730_SAVE(OMAP_IH1_MIR);
+		MPUI730_SAVE(OMAP_IH2_0_MIR);
+		MPUI730_SAVE(OMAP_IH2_1_MIR);
+		MPUI730_SAVE(MPUI_CTRL);
+		MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI730_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI730_SAVE(EMIFS_CONFIG);
+		MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
+
+	} else if (cpu_is_omap1510()) {
 		MPUI1510_SAVE(OMAP_IH1_MIR);
 		MPUI1510_SAVE(OMAP_IH1_MIR);
 		MPUI1510_SAVE(OMAP_IH2_MIR);
 		MPUI1510_SAVE(OMAP_IH2_MIR);
 		MPUI1510_SAVE(MPUI_CTRL);
 		MPUI1510_SAVE(MPUI_CTRL);
@@ -280,7 +301,13 @@ void omap_pm_suspend(void)
 	ULPD_RESTORE(ULPD_CLOCK_CTRL);
 	ULPD_RESTORE(ULPD_CLOCK_CTRL);
 	ULPD_RESTORE(ULPD_STATUS_REQ);
 	ULPD_RESTORE(ULPD_STATUS_REQ);
 
 
-	if (cpu_is_omap1510()) {
+	if (cpu_is_omap730()) {
+		MPUI730_RESTORE(EMIFS_CONFIG);
+		MPUI730_RESTORE(EMIFF_SDRAM_CONFIG);
+		MPUI730_RESTORE(OMAP_IH1_MIR);
+		MPUI730_RESTORE(OMAP_IH2_0_MIR);
+		MPUI730_RESTORE(OMAP_IH2_1_MIR);
+	} else if (cpu_is_omap1510()) {
 		MPUI1510_RESTORE(MPUI_CTRL);
 		MPUI1510_RESTORE(MPUI_CTRL);
 		MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
 		MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
 		MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
 		MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
@@ -355,7 +382,14 @@ static int omap_pm_read_proc(
 	ULPD_SAVE(ULPD_DPLL_CTRL);
 	ULPD_SAVE(ULPD_DPLL_CTRL);
 	ULPD_SAVE(ULPD_POWER_CTRL);
 	ULPD_SAVE(ULPD_POWER_CTRL);
 
 
-	if (cpu_is_omap1510()) {
+	if (cpu_is_omap730()) {
+		MPUI730_SAVE(MPUI_CTRL);
+		MPUI730_SAVE(MPUI_DSP_STATUS);
+		MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI730_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
+		MPUI730_SAVE(EMIFS_CONFIG);
+	} else if (cpu_is_omap1510()) {
 		MPUI1510_SAVE(MPUI_CTRL);
 		MPUI1510_SAVE(MPUI_CTRL);
 		MPUI1510_SAVE(MPUI_DSP_STATUS);
 		MPUI1510_SAVE(MPUI_DSP_STATUS);
 		MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
 		MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
@@ -404,7 +438,21 @@ static int omap_pm_read_proc(
 		   ULPD_SHOW(ULPD_STATUS_REQ),
 		   ULPD_SHOW(ULPD_STATUS_REQ),
 		   ULPD_SHOW(ULPD_POWER_CTRL));
 		   ULPD_SHOW(ULPD_POWER_CTRL));
 
 
-		if (cpu_is_omap1510()) {
+		if (cpu_is_omap730()) {
+			my_buffer_offset += sprintf(my_base + my_buffer_offset,
+			   "MPUI730_CTRL_REG	     0x%-8x \n"
+			   "MPUI730_DSP_STATUS_REG:      0x%-8x \n"
+			   "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
+	 "MPUI730_DSP_API_CONFIG_REG:  0x%-8x \n"
+	 "MPUI730_SDRAM_CONFIG_REG:    0x%-8x \n"
+	 "MPUI730_EMIFS_CONFIG_REG:    0x%-8x \n",
+	 MPUI730_SHOW(MPUI_CTRL),
+	 MPUI730_SHOW(MPUI_DSP_STATUS),
+	 MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG),
+	 MPUI730_SHOW(MPUI_DSP_API_CONFIG),
+	 MPUI730_SHOW(EMIFF_SDRAM_CONFIG),
+	 MPUI730_SHOW(EMIFS_CONFIG));
+		} else if (cpu_is_omap1510()) {
 			my_buffer_offset += sprintf(my_base + my_buffer_offset,
 			my_buffer_offset += sprintf(my_base + my_buffer_offset,
 			   "MPUI1510_CTRL_REG             0x%-8x \n"
 			   "MPUI1510_CTRL_REG             0x%-8x \n"
 			   "MPUI1510_DSP_STATUS_REG:      0x%-8x \n"
 			   "MPUI1510_DSP_STATUS_REG:      0x%-8x \n"
@@ -553,7 +601,12 @@ static int __init omap_pm_init(void)
 	 * These routines need to be in SRAM as that's the only
 	 * These routines need to be in SRAM as that's the only
 	 * memory the MPU can see when it wakes up.
 	 * memory the MPU can see when it wakes up.
 	 */
 	 */
-	if (cpu_is_omap1510()) {
+	if (cpu_is_omap730()) {
+		omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend,
+						omap730_idle_loop_suspend_sz);
+		omap_sram_suspend = omap_sram_push(omap730_cpu_suspend,
+	 omap730_cpu_suspend_sz);
+	} else if (cpu_is_omap1510()) {
 		omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
 		omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
 						omap1510_idle_loop_suspend_sz);
 						omap1510_idle_loop_suspend_sz);
 		omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
 		omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
@@ -572,7 +625,11 @@ static int __init omap_pm_init(void)
 
 
 	pm_idle = omap_pm_idle;
 	pm_idle = omap_pm_idle;
 
 
-	setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
+	if (cpu_is_omap730())
+		setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq);
+	else if (cpu_is_omap16xx())
+		setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
+
 #if 0
 #if 0
 	/* --- BEGIN BOARD-DEPENDENT CODE --- */
 	/* --- BEGIN BOARD-DEPENDENT CODE --- */
 	/* Sleepx mask direction */
 	/* Sleepx mask direction */
@@ -591,7 +648,9 @@ static int __init omap_pm_init(void)
 	omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
 	omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
 
 
 	/* Configure IDLECT3 */
 	/* Configure IDLECT3 */
-	if (cpu_is_omap16xx())
+	if (cpu_is_omap730())
+		omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3);
+	else if (cpu_is_omap16xx())
 		omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
 		omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
 
 
 	pm_set_ops(&omap_pm_ops);
 	pm_set_ops(&omap_pm_ops);
@@ -600,8 +659,10 @@ static int __init omap_pm_init(void)
 	omap_pm_init_proc();
 	omap_pm_init_proc();
 #endif
 #endif
 
 
-	/* configure LOW_PWR pin */
-	omap_cfg_reg(T20_1610_LOW_PWR);
+	if (cpu_is_omap16xx()) {
+		/* configure LOW_PWR pin */
+		omap_cfg_reg(T20_1610_LOW_PWR);
+	}
 
 
 	return 0;
 	return 0;
 }
 }

+ 134 - 5
arch/arm/plat-omap/sleep.S

@@ -1,7 +1,7 @@
 /*
 /*
  * linux/arch/arm/plat-omap/sleep.S
  * linux/arch/arm/plat-omap/sleep.S
  *
  *
- * Low-level OMAP1510/1610 sleep/wakeUp support
+ * Low-level OMAP730/1510/1610 sleep/wakeUp support
  *
  *
  * Initial SA1110 code:
  * Initial SA1110 code:
  * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
  * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
@@ -52,7 +52,57 @@
  *       processor specific functions here.
  *       processor specific functions here.
  */
  */
 
 
-#ifdef CONFIG_ARCH_OMAP1510
+#if defined(CONFIG_ARCH_OMAP730)
+ENTRY(omap730_idle_loop_suspend)
+
+	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
+
+	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
+	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
+	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
+	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
+
+	@ turn off clock domains
+	@ get ARM_IDLECT2 into r2
+	ldrh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+	mov	r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff
+	orr	r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00
+	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+
+	@ request ARM idle
+	@ get ARM_IDLECT1 into r1
+	ldrh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+	orr	r3, r1, #OMAP730_IDLE_LOOP_REQUEST & 0xffff
+	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+	mov	r5, #IDLE_WAIT_CYCLES & 0xff
+	orr	r5, r5, #IDLE_WAIT_CYCLES & 0xff00
+l_730:	subs	r5, r5, #1
+	bne	l_730
+/*
+ * Let's wait for the next clock tick to wake us up.
+ */
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c0, 4		@ wait for interrupt
+/*
+ * omap730_idle_loop_suspend()'s resume point.
+ *
+ * It will just start executing here, so we'll restore stuff from the
+ * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
+ */
+
+	@ restore ARM_IDLECT1 and ARM_IDLECT2 and return
+	@ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
+	strh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+	strh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+	ldmfd	sp!, {r0 - r12, pc}		@ restore regs and return
+
+ENTRY(omap730_idle_loop_suspend_sz)
+	.word	. - omap730_idle_loop_suspend
+#endif /* CONFIG_ARCH_OMAP730 */
+
+#ifdef CONFIG_ARCH_OMAP15XX
 ENTRY(omap1510_idle_loop_suspend)
 ENTRY(omap1510_idle_loop_suspend)
 
 
 	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
 	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
@@ -100,7 +150,7 @@ l_1510:	subs	r5, r5, #1
 
 
 ENTRY(omap1510_idle_loop_suspend_sz)
 ENTRY(omap1510_idle_loop_suspend_sz)
 	.word	. - omap1510_idle_loop_suspend
 	.word	. - omap1510_idle_loop_suspend
-#endif /* CONFIG_ARCH_OMAP1510 */
+#endif /* CONFIG_ARCH_OMAP15XX */
 
 
 #if defined(CONFIG_ARCH_OMAP16XX)
 #if defined(CONFIG_ARCH_OMAP16XX)
 ENTRY(omap1610_idle_loop_suspend)
 ENTRY(omap1610_idle_loop_suspend)
@@ -169,7 +219,86 @@ ENTRY(omap1610_idle_loop_suspend_sz)
  *
  *
  */
  */
 
 
-#ifdef CONFIG_ARCH_OMAP1510
+#if defined(CONFIG_ARCH_OMAP730)
+ENTRY(omap730_cpu_suspend)
+
+	@ save registers on stack
+	stmfd	sp!, {r0 - r12, lr}
+
+	@ Drain write cache
+	mov	r4, #0
+	mcr	p15, 0, r0, c7, c10, 4
+	nop
+
+	@ load base address of Traffic Controller
+	mov	r6, #TCMIF_ASM_BASE & 0xff000000
+	orr	r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
+	orr	r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
+
+	@ prepare to put SDRAM into self-refresh manually
+	ldr	r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+	orr	r9, r7, #SELF_REFRESH_MODE & 0xff000000
+	orr	r9, r9, #SELF_REFRESH_MODE & 0x000000ff
+	str	r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+
+	@ prepare to put EMIFS to Sleep
+	ldr	r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+	orr	r9, r8, #IDLE_EMIFS_REQUEST & 0xff
+	str	r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
+	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
+	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
+	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
+
+	@ turn off clock domains
+	@ do not disable PERCK (0x04)
+	mov	r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff
+	orr	r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00
+	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+
+	@ request ARM idle
+	mov	r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff
+	orr	r3, r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff00
+	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+	@ disable instruction cache
+	mrc	p15, 0, r9, c1, c0, 0
+	bic	r2, r9, #0x1000
+	mcr	p15, 0, r2, c1, c0, 0
+	nop
+
+/*
+ * Let's wait for the next wake up event to wake us up. r0 can't be
+ * used here because r0 holds ARM_IDLECT1
+ */
+	mov	r2, #0
+	mcr	p15, 0, r2, c7, c0, 4		@ wait for interrupt
+/*
+ * omap730_cpu_suspend()'s resume point.
+ *
+ * It will just start executing here, so we'll restore stuff from the
+ * stack.
+ */
+	@ re-enable Icache
+	mcr	p15, 0, r9, c1, c0, 0
+
+	@ reset the ARM_IDLECT1 and ARM_IDLECT2.
+	strh	r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+	@ Restore EMIFF controls
+	str	r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+	str	r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+	@ restore regs and return
+	ldmfd	sp!, {r0 - r12, pc}
+
+ENTRY(omap730_cpu_suspend_sz)
+	.word	. - omap730_cpu_suspend
+#endif /* CONFIG_ARCH_OMAP730 */
+
+#ifdef CONFIG_ARCH_OMAP15XX
 ENTRY(omap1510_cpu_suspend)
 ENTRY(omap1510_cpu_suspend)
 
 
 	@ save registers on stack
 	@ save registers on stack
@@ -241,7 +370,7 @@ l_1510_2:
 
 
 ENTRY(omap1510_cpu_suspend_sz)
 ENTRY(omap1510_cpu_suspend_sz)
 	.word	. - omap1510_cpu_suspend
 	.word	. - omap1510_cpu_suspend
-#endif /* CONFIG_ARCH_OMAP1510 */
+#endif /* CONFIG_ARCH_OMAP15XX */
 
 
 #if defined(CONFIG_ARCH_OMAP16XX)
 #if defined(CONFIG_ARCH_OMAP16XX)
 ENTRY(omap1610_cpu_suspend)
 ENTRY(omap1610_cpu_suspend)

+ 116 - 27
arch/arm/plat-omap/sram.c

@@ -20,10 +20,13 @@
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
 
 
-#include "sram.h"
+#include <asm/arch/sram.h>
+
+#define OMAP1_SRAM_PA		0x20000000
+#define OMAP1_SRAM_VA		0xd0000000
+#define OMAP2_SRAM_PA		0x40200000
+#define OMAP2_SRAM_VA		0xd0000000
 
 
-#define OMAP1_SRAM_BASE		0xd0000000
-#define OMAP1_SRAM_START	0x20000000
 #define SRAM_BOOTLOADER_SZ	0x80
 #define SRAM_BOOTLOADER_SZ	0x80
 
 
 static unsigned long omap_sram_base;
 static unsigned long omap_sram_base;
@@ -31,37 +34,40 @@ static unsigned long omap_sram_size;
 static unsigned long omap_sram_ceil;
 static unsigned long omap_sram_ceil;
 
 
 /*
 /*
- * The amount of SRAM depends on the core type:
- * 730 = 200K, 1510 = 512K, 5912 = 256K, 1610 = 16K, 1710 = 16K
+ * The amount of SRAM depends on the core type.
  * Note that we cannot try to test for SRAM here because writes
  * Note that we cannot try to test for SRAM here because writes
  * to secure SRAM will hang the system. Also the SRAM is not
  * to secure SRAM will hang the system. Also the SRAM is not
  * yet mapped at this point.
  * yet mapped at this point.
  */
  */
 void __init omap_detect_sram(void)
 void __init omap_detect_sram(void)
 {
 {
-	omap_sram_base = OMAP1_SRAM_BASE;
+	if (!cpu_is_omap24xx())
+		omap_sram_base = OMAP1_SRAM_VA;
+	else
+		omap_sram_base = OMAP2_SRAM_VA;
 
 
 	if (cpu_is_omap730())
 	if (cpu_is_omap730())
-		omap_sram_size = 0x32000;
-	else if (cpu_is_omap1510())
-		omap_sram_size = 0x80000;
+		omap_sram_size = 0x32000;	/* 200K */
+	else if (cpu_is_omap15xx())
+		omap_sram_size = 0x30000;	/* 192K */
 	else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710())
 	else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710())
-		omap_sram_size = 0x4000;
+		omap_sram_size = 0x4000;	/* 16K */
 	else if (cpu_is_omap1611())
 	else if (cpu_is_omap1611())
-		omap_sram_size = 0x3e800;
+		omap_sram_size = 0x3e800;	/* 250K */
+	else if (cpu_is_omap2420())
+		omap_sram_size = 0xa0014;	/* 640K */
 	else {
 	else {
 		printk(KERN_ERR "Could not detect SRAM size\n");
 		printk(KERN_ERR "Could not detect SRAM size\n");
 		omap_sram_size = 0x4000;
 		omap_sram_size = 0x4000;
 	}
 	}
 
 
-	printk(KERN_INFO "SRAM size: 0x%lx\n", omap_sram_size);
 	omap_sram_ceil = omap_sram_base + omap_sram_size;
 	omap_sram_ceil = omap_sram_base + omap_sram_size;
 }
 }
 
 
 static struct map_desc omap_sram_io_desc[] __initdata = {
 static struct map_desc omap_sram_io_desc[] __initdata = {
 	{	/* .length gets filled in at runtime */
 	{	/* .length gets filled in at runtime */
-		.virtual	= OMAP1_SRAM_BASE,
-		.pfn		= __phys_to_pfn(OMAP1_SRAM_START),
+		.virtual	= OMAP1_SRAM_VA,
+		.pfn		= __phys_to_pfn(OMAP1_SRAM_PA),
 		.type		= MT_DEVICE
 		.type		= MT_DEVICE
 	}
 	}
 };
 };
@@ -76,10 +82,19 @@ void __init omap_map_sram(void)
 	if (omap_sram_size == 0)
 	if (omap_sram_size == 0)
 		return;
 		return;
 
 
+	if (cpu_is_omap24xx()) {
+		omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA;
+		omap_sram_io_desc[0].pfn = __phys_to_pfn(OMAP2_SRAM_PA);
+	}
+
 	omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE;
 	omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE;
 	omap_sram_io_desc[0].length *= PAGE_SIZE;
 	omap_sram_io_desc[0].length *= PAGE_SIZE;
 	iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
 	iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
 
 
+	printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n",
+	       omap_sram_io_desc[0].pfn, omap_sram_io_desc[0].virtual,
+	       omap_sram_io_desc[0].length);
+
 	/*
 	/*
 	 * Looks like we need to preserve some bootloader code at the
 	 * Looks like we need to preserve some bootloader code at the
 	 * beginning of SRAM for jumping to flash for reboot to work...
 	 * beginning of SRAM for jumping to flash for reboot to work...
@@ -88,16 +103,6 @@ void __init omap_map_sram(void)
 	       omap_sram_size - SRAM_BOOTLOADER_SZ);
 	       omap_sram_size - SRAM_BOOTLOADER_SZ);
 }
 }
 
 
-static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl) = NULL;
-
-void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
-{
-	if (_omap_sram_reprogram_clock == NULL)
-		panic("Cannot use SRAM");
-
-	return _omap_sram_reprogram_clock(dpllctl, ckctl);
-}
-
 void * omap_sram_push(void * start, unsigned long size)
 void * omap_sram_push(void * start, unsigned long size)
 {
 {
 	if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
 	if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
@@ -111,10 +116,94 @@ void * omap_sram_push(void * start, unsigned long size)
 	return (void *)omap_sram_ceil;
 	return (void *)omap_sram_ceil;
 }
 }
 
 
-void __init omap_sram_init(void)
+static void omap_sram_error(void)
+{
+	panic("Uninitialized SRAM function\n");
+}
+
+#ifdef CONFIG_ARCH_OMAP1
+
+static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl);
+
+void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
+{
+	if (!_omap_sram_reprogram_clock)
+		omap_sram_error();
+
+	return _omap_sram_reprogram_clock(dpllctl, ckctl);
+}
+
+int __init omap1_sram_init(void)
 {
 {
-	omap_detect_sram();
-	omap_map_sram();
 	_omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock,
 	_omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock,
 						    sram_reprogram_clock_sz);
 						    sram_reprogram_clock_sz);
+
+	return 0;
+}
+
+#else
+#define omap1_sram_init()	do {} while (0)
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2
+
+static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+			      u32 base_cs, u32 force_unlock);
+
+void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+		   u32 base_cs, u32 force_unlock)
+{
+	if (!_omap2_sram_ddr_init)
+		omap_sram_error();
+
+	return _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl,
+				    base_cs, force_unlock);
+}
+
+static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val,
+					  u32 mem_type);
+
+void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type)
+{
+	if (!_omap2_sram_reprogram_sdrc)
+		omap_sram_error();
+
+	return _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type);
+}
+
+static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
+
+u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass)
+{
+	if (!_omap2_set_prcm)
+		omap_sram_error();
+
+	return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass);
+}
+
+int __init omap2_sram_init(void)
+{
+	_omap2_sram_ddr_init = omap_sram_push(sram_ddr_init, sram_ddr_init_sz);
+
+	_omap2_sram_reprogram_sdrc = omap_sram_push(sram_reprogram_sdrc,
+						    sram_reprogram_sdrc_sz);
+	_omap2_set_prcm = omap_sram_push(sram_set_prcm, sram_set_prcm_sz);
+
+	return 0;
+}
+#else
+#define omap2_sram_init()	do {} while (0)
+#endif
+
+int __init omap_sram_init(void)
+{
+	omap_detect_sram();
+	omap_map_sram();
+
+	if (!cpu_is_omap24xx())
+		omap1_sram_init();
+	else
+		omap2_sram_init();
+
+	return 0;
 }
 }

+ 0 - 21
arch/arm/plat-omap/sram.h

@@ -1,21 +0,0 @@
-/*
- * linux/arch/arm/plat-omap/sram.h
- *
- * Interface for functions that need to be run in internal SRAM
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ARCH_ARM_OMAP_SRAM_H
-#define __ARCH_ARM_OMAP_SRAM_H
-
-extern void * omap_sram_push(void * start, unsigned long size);
-extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
-
-/* Do not use these */
-extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl);
-extern unsigned long sram_reprogram_clock_sz;
-
-#endif

+ 9 - 2
arch/arm/plat-omap/usb.c

@@ -91,6 +91,8 @@ EXPORT_SYMBOL(otg_set_transceiver);
 
 
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
 
 
+#if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP15XX)
+
 static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
 static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
 {
 {
 	u32	syscon1 = 0;
 	u32	syscon1 = 0;
@@ -271,6 +273,8 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
 	return syscon1 << 24;
 	return syscon1 << 24;
 }
 }
 
 
+#endif
+
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
 
 
 #if	defined(CONFIG_USB_GADGET_OMAP) || \
 #if	defined(CONFIG_USB_GADGET_OMAP) || \
@@ -494,7 +498,7 @@ static inline void omap_otg_init(struct omap_usb_config *config) {}
 
 
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
 
 
-#ifdef	CONFIG_ARCH_OMAP1510
+#ifdef	CONFIG_ARCH_OMAP15XX
 
 
 #define ULPD_DPLL_CTRL_REG	__REG16(ULPD_DPLL_CTRL)
 #define ULPD_DPLL_CTRL_REG	__REG16(ULPD_DPLL_CTRL)
 #define DPLL_IOB		(1 << 13)
 #define DPLL_IOB		(1 << 13)
@@ -507,7 +511,6 @@ static inline void omap_otg_init(struct omap_usb_config *config) {}
 
 
 static void __init omap_1510_usb_init(struct omap_usb_config *config)
 static void __init omap_1510_usb_init(struct omap_usb_config *config)
 {
 {
-	int status;
 	unsigned int val;
 	unsigned int val;
 
 
 	omap_usb0_init(config->pins[0], is_usb0_device(config));
 	omap_usb0_init(config->pins[0], is_usb0_device(config));
@@ -539,6 +542,8 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config)
 
 
 #ifdef	CONFIG_USB_GADGET_OMAP
 #ifdef	CONFIG_USB_GADGET_OMAP
 	if (config->register_dev) {
 	if (config->register_dev) {
+		int status;
+
 		udc_device.dev.platform_data = config;
 		udc_device.dev.platform_data = config;
 		status = platform_device_register(&udc_device);
 		status = platform_device_register(&udc_device);
 		if (status)
 		if (status)
@@ -549,6 +554,8 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config)
 
 
 #if	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 #if	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 	if (config->register_host) {
 	if (config->register_host) {
+		int status;
+
 		ohci_device.dev.platform_data = config;
 		ohci_device.dev.platform_data = config;
 		status = platform_device_register(&ohci_device);
 		status = platform_device_register(&ohci_device);
 		if (status)
 		if (status)

+ 1 - 2
arch/i386/pci/fixup.c

@@ -433,9 +433,8 @@ static void __devinit pci_post_fixup_toshiba_ohci1394(struct pci_dev *dev)
 		return; /* only applies to certain Toshibas (so far) */
 		return; /* only applies to certain Toshibas (so far) */
 
 
 	/* Restore config space on Toshiba laptops */
 	/* Restore config space on Toshiba laptops */
-	mdelay(10);
 	pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, toshiba_line_size);
 	pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, toshiba_line_size);
-	pci_write_config_word(dev, PCI_INTERRUPT_LINE, dev->irq);
+	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, (u8 *)&dev->irq);
 	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
 	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
 			       pci_resource_start(dev, 0));
 			       pci_resource_start(dev, 0));
 	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1,
 	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1,

+ 1 - 1
arch/ia64/kernel/efi.c

@@ -987,7 +987,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
 				break;
 				break;
 		}
 		}
 
 
-		if ((res = kcalloc(1, sizeof(struct resource), GFP_KERNEL)) == NULL) {
+		if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) {
 			printk(KERN_ERR "failed to alocate resource for iomem\n");
 			printk(KERN_ERR "failed to alocate resource for iomem\n");
 			return;
 			return;
 		}
 		}

+ 13 - 9
arch/ia64/kernel/kprobes.c

@@ -347,7 +347,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 		((struct fnptr *)kretprobe_trampoline)->ip;
 		((struct fnptr *)kretprobe_trampoline)->ip;
 
 
 	spin_lock_irqsave(&kretprobe_lock, flags);
 	spin_lock_irqsave(&kretprobe_lock, flags);
-        head = kretprobe_inst_table_head(current);
+	head = kretprobe_inst_table_head(current);
 
 
 	/*
 	/*
 	 * It is possible to have multiple instances associated with a given
 	 * It is possible to have multiple instances associated with a given
@@ -363,9 +363,9 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 	 *       kretprobe_trampoline
 	 *       kretprobe_trampoline
 	 */
 	 */
 	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
 	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
-                if (ri->task != current)
+		if (ri->task != current)
 			/* another task is sharing our hash bucket */
 			/* another task is sharing our hash bucket */
-                        continue;
+			continue;
 
 
 		if (ri->rp && ri->rp->handler)
 		if (ri->rp && ri->rp->handler)
 			ri->rp->handler(ri, regs);
 			ri->rp->handler(ri, regs);
@@ -394,7 +394,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 	 * kprobe_handler() that we don't want the post_handler
 	 * kprobe_handler() that we don't want the post_handler
 	 * to run (and have re-enabled preemption)
 	 * to run (and have re-enabled preemption)
 	 */
 	 */
-        return 1;
+	return 1;
 }
 }
 
 
 /* Called with kretprobe_lock held */
 /* Called with kretprobe_lock held */
@@ -739,12 +739,16 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
 
 
 	switch(val) {
 	switch(val) {
 	case DIE_BREAK:
 	case DIE_BREAK:
-		if (pre_kprobes_handler(args))
-			ret = NOTIFY_STOP;
+		/* err is break number from ia64_bad_break() */
+		if (args->err == 0x80200 || args->err == 0x80300)
+			if (pre_kprobes_handler(args))
+				ret = NOTIFY_STOP;
 		break;
 		break;
-	case DIE_SS:
-		if (post_kprobes_handler(args->regs))
-			ret = NOTIFY_STOP;
+	case DIE_FAULT:
+		/* err is vector number from ia64_fault() */
+		if (args->err == 36)
+			if (post_kprobes_handler(args->regs))
+				ret = NOTIFY_STOP;
 		break;
 		break;
 	case DIE_PAGE_FAULT:
 	case DIE_PAGE_FAULT:
 		/* kprobe_running() needs smp_processor_id() */
 		/* kprobe_running() needs smp_processor_id() */

+ 95 - 25
arch/ia64/kernel/mca.c

@@ -51,6 +51,9 @@
  *
  *
  * 2005-08-12 Keith Owens <kaos@sgi.com>
  * 2005-08-12 Keith Owens <kaos@sgi.com>
  *	      Convert MCA/INIT handlers to use per event stacks and SAL/OS state.
  *	      Convert MCA/INIT handlers to use per event stacks and SAL/OS state.
+ *
+ * 2005-10-07 Keith Owens <kaos@sgi.com>
+ *	      Add notify_die() hooks.
  */
  */
 #include <linux/config.h>
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/types.h>
@@ -58,7 +61,6 @@
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/irq.h>
-#include <linux/kallsyms.h>
 #include <linux/smp_lock.h>
 #include <linux/smp_lock.h>
 #include <linux/bootmem.h>
 #include <linux/bootmem.h>
 #include <linux/acpi.h>
 #include <linux/acpi.h>
@@ -69,6 +71,7 @@
 #include <linux/workqueue.h>
 #include <linux/workqueue.h>
 
 
 #include <asm/delay.h>
 #include <asm/delay.h>
+#include <asm/kdebug.h>
 #include <asm/machvec.h>
 #include <asm/machvec.h>
 #include <asm/meminit.h>
 #include <asm/meminit.h>
 #include <asm/page.h>
 #include <asm/page.h>
@@ -132,6 +135,14 @@ extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe);
 
 
 static int mca_init;
 static int mca_init;
 
 
+
+static void inline
+ia64_mca_spin(const char *func)
+{
+	printk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func);
+	while (1)
+		cpu_relax();
+}
 /*
 /*
  * IA64_MCA log support
  * IA64_MCA log support
  */
  */
@@ -526,13 +537,16 @@ ia64_mca_wakeup_all(void)
  *  Outputs :   None
  *  Outputs :   None
  */
  */
 static irqreturn_t
 static irqreturn_t
-ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
+ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 	int cpu = smp_processor_id();
 	int cpu = smp_processor_id();
 
 
 	/* Mask all interrupts */
 	/* Mask all interrupts */
 	local_irq_save(flags);
 	local_irq_save(flags);
+	if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, 0, 0, 0)
+			== NOTIFY_STOP)
+		ia64_mca_spin(__FUNCTION__);
 
 
 	ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
 	ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE;
 	/* Register with the SAL monarch that the slave has
 	/* Register with the SAL monarch that the slave has
@@ -540,10 +554,18 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *ptregs)
 	 */
 	 */
 	ia64_sal_mc_rendez();
 	ia64_sal_mc_rendez();
 
 
+	if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, 0, 0, 0)
+			== NOTIFY_STOP)
+		ia64_mca_spin(__FUNCTION__);
+
 	/* Wait for the monarch cpu to exit. */
 	/* Wait for the monarch cpu to exit. */
 	while (monarch_cpu != -1)
 	while (monarch_cpu != -1)
 	       cpu_relax();	/* spin until monarch leaves */
 	       cpu_relax();	/* spin until monarch leaves */
 
 
+	if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, 0, 0, 0)
+			== NOTIFY_STOP)
+		ia64_mca_spin(__FUNCTION__);
+
 	/* Enable all interrupts */
 	/* Enable all interrupts */
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
@@ -933,6 +955,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
 	oops_in_progress = 1;	/* FIXME: make printk NMI/MCA/INIT safe */
 	oops_in_progress = 1;	/* FIXME: make printk NMI/MCA/INIT safe */
 	previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
 	previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
 	monarch_cpu = cpu;
 	monarch_cpu = cpu;
+	if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, 0, 0, 0)
+			== NOTIFY_STOP)
+		ia64_mca_spin(__FUNCTION__);
 	ia64_wait_for_slaves(cpu);
 	ia64_wait_for_slaves(cpu);
 
 
 	/* Wakeup all the processors which are spinning in the rendezvous loop.
 	/* Wakeup all the processors which are spinning in the rendezvous loop.
@@ -942,6 +967,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
 	 * spinning in SAL does not work.
 	 * spinning in SAL does not work.
 	 */
 	 */
 	ia64_mca_wakeup_all();
 	ia64_mca_wakeup_all();
+	if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, 0, 0, 0)
+			== NOTIFY_STOP)
+		ia64_mca_spin(__FUNCTION__);
 
 
 	/* Get the MCA error record and log it */
 	/* Get the MCA error record and log it */
 	ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
 	ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
@@ -960,6 +988,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
 		ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
 		ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
 		sos->os_status = IA64_MCA_CORRECTED;
 		sos->os_status = IA64_MCA_CORRECTED;
 	}
 	}
+	if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, 0, 0, recover)
+			== NOTIFY_STOP)
+		ia64_mca_spin(__FUNCTION__);
 
 
 	set_curr_task(cpu, previous_current);
 	set_curr_task(cpu, previous_current);
 	monarch_cpu = -1;
 	monarch_cpu = -1;
@@ -1188,6 +1219,37 @@ ia64_mca_cpe_poll (unsigned long dummy)
 
 
 #endif /* CONFIG_ACPI */
 #endif /* CONFIG_ACPI */
 
 
+static int
+default_monarch_init_process(struct notifier_block *self, unsigned long val, void *data)
+{
+	int c;
+	struct task_struct *g, *t;
+	if (val != DIE_INIT_MONARCH_PROCESS)
+		return NOTIFY_DONE;
+	printk(KERN_ERR "Processes interrupted by INIT -");
+	for_each_online_cpu(c) {
+		struct ia64_sal_os_state *s;
+		t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET);
+		s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET);
+		g = s->prev_task;
+		if (g) {
+			if (g->pid)
+				printk(" %d", g->pid);
+			else
+				printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g);
+		}
+	}
+	printk("\n\n");
+	if (read_trylock(&tasklist_lock)) {
+		do_each_thread (g, t) {
+			printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
+			show_stack(t, NULL);
+		} while_each_thread (g, t);
+		read_unlock(&tasklist_lock);
+	}
+	return NOTIFY_DONE;
+}
+
 /*
 /*
  * C portion of the OS INIT handler
  * C portion of the OS INIT handler
  *
  *
@@ -1212,8 +1274,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
 	static atomic_t slaves;
 	static atomic_t slaves;
 	static atomic_t monarchs;
 	static atomic_t monarchs;
 	task_t *previous_current;
 	task_t *previous_current;
-	int cpu = smp_processor_id(), c;
-	struct task_struct *g, *t;
+	int cpu = smp_processor_id();
 
 
 	oops_in_progress = 1;	/* FIXME: make printk NMI/MCA/INIT safe */
 	oops_in_progress = 1;	/* FIXME: make printk NMI/MCA/INIT safe */
 	console_loglevel = 15;	/* make sure printks make it to console */
 	console_loglevel = 15;	/* make sure printks make it to console */
@@ -1253,8 +1314,17 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
 		ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT;
 		ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT;
 		while (monarch_cpu == -1)
 		while (monarch_cpu == -1)
 		       cpu_relax();	/* spin until monarch enters */
 		       cpu_relax();	/* spin until monarch enters */
+		if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, 0, 0, 0)
+				== NOTIFY_STOP)
+			ia64_mca_spin(__FUNCTION__);
+		if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, 0, 0, 0)
+				== NOTIFY_STOP)
+			ia64_mca_spin(__FUNCTION__);
 		while (monarch_cpu != -1)
 		while (monarch_cpu != -1)
 		       cpu_relax();	/* spin until monarch leaves */
 		       cpu_relax();	/* spin until monarch leaves */
+		if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, 0, 0, 0)
+				== NOTIFY_STOP)
+			ia64_mca_spin(__FUNCTION__);
 		printk("Slave on cpu %d returning to normal service.\n", cpu);
 		printk("Slave on cpu %d returning to normal service.\n", cpu);
 		set_curr_task(cpu, previous_current);
 		set_curr_task(cpu, previous_current);
 		ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
 		ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
@@ -1263,6 +1333,9 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
 	}
 	}
 
 
 	monarch_cpu = cpu;
 	monarch_cpu = cpu;
+	if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, 0, 0, 0)
+			== NOTIFY_STOP)
+		ia64_mca_spin(__FUNCTION__);
 
 
 	/*
 	/*
 	 * Wait for a bit.  On some machines (e.g., HP's zx2000 and zx6000, INIT can be
 	 * Wait for a bit.  On some machines (e.g., HP's zx2000 and zx6000, INIT can be
@@ -1273,27 +1346,16 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
 	printk("Delaying for 5 seconds...\n");
 	printk("Delaying for 5 seconds...\n");
 	udelay(5*1000000);
 	udelay(5*1000000);
 	ia64_wait_for_slaves(cpu);
 	ia64_wait_for_slaves(cpu);
-	printk(KERN_ERR "Processes interrupted by INIT -");
-	for_each_online_cpu(c) {
-		struct ia64_sal_os_state *s;
-		t = __va(__per_cpu_mca[c] + IA64_MCA_CPU_INIT_STACK_OFFSET);
-		s = (struct ia64_sal_os_state *)((char *)t + MCA_SOS_OFFSET);
-		g = s->prev_task;
-		if (g) {
-			if (g->pid)
-				printk(" %d", g->pid);
-			else
-				printk(" %d (cpu %d task 0x%p)", g->pid, task_cpu(g), g);
-		}
-	}
-	printk("\n\n");
-	if (read_trylock(&tasklist_lock)) {
-		do_each_thread (g, t) {
-			printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
-			show_stack(t, NULL);
-		} while_each_thread (g, t);
-		read_unlock(&tasklist_lock);
-	}
+	/* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through
+	 * to default_monarch_init_process() above and just print all the
+	 * tasks.
+	 */
+	if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, 0, 0, 0)
+			== NOTIFY_STOP)
+		ia64_mca_spin(__FUNCTION__);
+	if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, 0, 0, 0)
+			== NOTIFY_STOP)
+		ia64_mca_spin(__FUNCTION__);
 	printk("\nINIT dump complete.  Monarch on cpu %d returning to normal service.\n", cpu);
 	printk("\nINIT dump complete.  Monarch on cpu %d returning to normal service.\n", cpu);
 	atomic_dec(&monarchs);
 	atomic_dec(&monarchs);
 	set_curr_task(cpu, previous_current);
 	set_curr_task(cpu, previous_current);
@@ -1462,6 +1524,10 @@ ia64_mca_init(void)
 	s64 rc;
 	s64 rc;
 	struct ia64_sal_retval isrv;
 	struct ia64_sal_retval isrv;
 	u64 timeout = IA64_MCA_RENDEZ_TIMEOUT;	/* platform specific */
 	u64 timeout = IA64_MCA_RENDEZ_TIMEOUT;	/* platform specific */
+	static struct notifier_block default_init_monarch_nb = {
+		.notifier_call = default_monarch_init_process,
+		.priority = 0/* we need to notified last */
+	};
 
 
 	IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__);
 	IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__);
 
 
@@ -1555,6 +1621,10 @@ ia64_mca_init(void)
 		       "(status %ld)\n", rc);
 		       "(status %ld)\n", rc);
 		return;
 		return;
 	}
 	}
+	if (register_die_notifier(&default_init_monarch_nb)) {
+		printk(KERN_ERR "Failed to register default monarch INIT process\n");
+		return;
+	}
 
 
 	IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__);
 	IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__);
 
 

+ 13 - 4
arch/ia64/kernel/mca_drv.c

@@ -547,9 +547,20 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
 		(pal_processor_state_info_t*)peidx_psp(peidx);
 		(pal_processor_state_info_t*)peidx_psp(peidx);
 
 
 	/*
 	/*
-	 * We cannot recover errors with other than bus_check.
+	 * Processor recovery status must key off of the PAL recovery
+	 * status in the Processor State Parameter.
 	 */
 	 */
-	if (psp->cc || psp->rc || psp->uc)
+
+	/*
+	 * The machine check is corrected.
+	 */
+	if (psp->cm == 1)
+		return 1;
+
+	/*
+	 * The error was not contained.  Software must be reset.
+	 */
+	if (psp->us || psp->ci == 0)
 		return 0;
 		return 0;
 
 
 	/*
 	/*
@@ -570,8 +581,6 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
 		return 0;
 		return 0;
 	if (pbci->eb && pbci->bsi > 0)
 	if (pbci->eb && pbci->bsi > 0)
 		return 0;
 		return 0;
-	if (psp->ci == 0)
-		return 0;
 
 
 	/*
 	/*
 	 * This is a local MCA and estimated as recoverble external bus error.
 	 * This is a local MCA and estimated as recoverble external bus error.

+ 6 - 0
arch/ia64/kernel/process.c

@@ -4,6 +4,9 @@
  * Copyright (C) 1998-2003 Hewlett-Packard Co
  * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * 04/11/17 Ashok Raj	<ashok.raj@intel.com> Added CPU Hotplug Support
  * 04/11/17 Ashok Raj	<ashok.raj@intel.com> Added CPU Hotplug Support
+ *
+ * 2005-10-07 Keith Owens <kaos@sgi.com>
+ *	      Add notify_die() hooks.
  */
  */
 #define __KERNEL_SYSCALLS__	/* see <asm/unistd.h> */
 #define __KERNEL_SYSCALLS__	/* see <asm/unistd.h> */
 #include <linux/config.h>
 #include <linux/config.h>
@@ -34,6 +37,7 @@
 #include <asm/elf.h>
 #include <asm/elf.h>
 #include <asm/ia32.h>
 #include <asm/ia32.h>
 #include <asm/irq.h>
 #include <asm/irq.h>
+#include <asm/kdebug.h>
 #include <asm/pgalloc.h>
 #include <asm/pgalloc.h>
 #include <asm/processor.h>
 #include <asm/processor.h>
 #include <asm/sal.h>
 #include <asm/sal.h>
@@ -808,12 +812,14 @@ cpu_halt (void)
 void
 void
 machine_restart (char *restart_cmd)
 machine_restart (char *restart_cmd)
 {
 {
+	(void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0);
 	(*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL);
 	(*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL);
 }
 }
 
 
 void
 void
 machine_halt (void)
 machine_halt (void)
 {
 {
+	(void) notify_die(DIE_MACHINE_HALT, "", NULL, 0, 0, 0);
 	cpu_halt();
 	cpu_halt();
 }
 }
 
 

+ 1 - 0
arch/ia64/kernel/setup.c

@@ -461,6 +461,7 @@ setup_arch (char **cmdline_p)
 #endif
 #endif
 
 
 	cpu_init();	/* initialize the bootstrap CPU */
 	cpu_init();	/* initialize the bootstrap CPU */
+	mmu_context_init();	/* initialize context_id bitmap */
 
 
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_ACPI
 	acpi_boot_init();
 	acpi_boot_init();

+ 5 - 6
arch/ia64/kernel/signal.c

@@ -387,15 +387,14 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
 	     struct sigscratch *scr)
 	     struct sigscratch *scr)
 {
 {
 	extern char __kernel_sigtramp[];
 	extern char __kernel_sigtramp[];
-	unsigned long tramp_addr, new_rbs = 0;
+	unsigned long tramp_addr, new_rbs = 0, new_sp;
 	struct sigframe __user *frame;
 	struct sigframe __user *frame;
 	long err;
 	long err;
 
 
-	frame = (void __user *) scr->pt.r12;
+	new_sp = scr->pt.r12;
 	tramp_addr = (unsigned long) __kernel_sigtramp;
 	tramp_addr = (unsigned long) __kernel_sigtramp;
-	if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags((unsigned long) frame) == 0) {
-		frame = (void __user *) ((current->sas_ss_sp + current->sas_ss_size)
-					 & ~(STACK_ALIGN - 1));
+	if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(new_sp) == 0) {
+		new_sp = current->sas_ss_sp + current->sas_ss_size;
 		/*
 		/*
 		 * We need to check for the register stack being on the signal stack
 		 * We need to check for the register stack being on the signal stack
 		 * separately, because it's switched separately (memory stack is switched
 		 * separately, because it's switched separately (memory stack is switched
@@ -404,7 +403,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
 		if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
 		if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
 			new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
 			new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
 	}
 	}
-	frame = (void __user *) frame - ((sizeof(*frame) + STACK_ALIGN - 1) & ~(STACK_ALIGN - 1));
+	frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
 
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		return force_sigsegv_info(sig, frame);
 		return force_sigsegv_info(sig, frame);

+ 20 - 24
arch/ia64/kernel/traps.c

@@ -30,17 +30,20 @@ fpswa_interface_t *fpswa_interface;
 EXPORT_SYMBOL(fpswa_interface);
 EXPORT_SYMBOL(fpswa_interface);
 
 
 struct notifier_block *ia64die_chain;
 struct notifier_block *ia64die_chain;
-static DEFINE_SPINLOCK(die_notifier_lock);
 
 
-int register_die_notifier(struct notifier_block *nb)
+int
+register_die_notifier(struct notifier_block *nb)
 {
 {
-	int err = 0;
-	unsigned long flags;
-	spin_lock_irqsave(&die_notifier_lock, flags);
-	err = notifier_chain_register(&ia64die_chain, nb);
-	spin_unlock_irqrestore(&die_notifier_lock, flags);
-	return err;
+	return notifier_chain_register(&ia64die_chain, nb);
 }
 }
+EXPORT_SYMBOL_GPL(register_die_notifier);
+
+int
+unregister_die_notifier(struct notifier_block *nb)
+{
+	return notifier_chain_unregister(&ia64die_chain, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_die_notifier);
 
 
 void __init
 void __init
 trap_init (void)
 trap_init (void)
@@ -105,6 +108,7 @@ die (const char *str, struct pt_regs *regs, long err)
 	if (++die.lock_owner_depth < 3) {
 	if (++die.lock_owner_depth < 3) {
 		printk("%s[%d]: %s %ld [%d]\n",
 		printk("%s[%d]: %s %ld [%d]\n",
 			current->comm, current->pid, str, err, ++die_counter);
 			current->comm, current->pid, str, err, ++die_counter);
+		(void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
 		show_regs(regs);
 		show_regs(regs);
   	} else
   	} else
 		printk(KERN_ERR "Recursive die() failure, output suppressed\n");
 		printk(KERN_ERR "Recursive die() failure, output suppressed\n");
@@ -155,9 +159,8 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
 	switch (break_num) {
 	switch (break_num) {
 	      case 0: /* unknown error (used by GCC for __builtin_abort()) */
 	      case 0: /* unknown error (used by GCC for __builtin_abort()) */
 		if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
 		if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
-			       	== NOTIFY_STOP) {
+			       	== NOTIFY_STOP)
 			return;
 			return;
-		}
 		die_if_kernel("bugcheck!", regs, break_num);
 		die_if_kernel("bugcheck!", regs, break_num);
 		sig = SIGILL; code = ILL_ILLOPC;
 		sig = SIGILL; code = ILL_ILLOPC;
 		break;
 		break;
@@ -210,15 +213,6 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
 		sig = SIGILL; code = __ILL_BNDMOD;
 		sig = SIGILL; code = __ILL_BNDMOD;
 		break;
 		break;
 
 
-	      case 0x80200:
-	      case 0x80300:
-		if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
-			       	== NOTIFY_STOP) {
-			return;
-		}
-		sig = SIGTRAP; code = TRAP_BRKPT;
-		break;
-
 	      default:
 	      default:
 		if (break_num < 0x40000 || break_num > 0x100000)
 		if (break_num < 0x40000 || break_num > 0x100000)
 			die_if_kernel("Bad break", regs, break_num);
 			die_if_kernel("Bad break", regs, break_num);
@@ -226,6 +220,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
 		if (break_num < 0x80000) {
 		if (break_num < 0x80000) {
 			sig = SIGILL; code = __ILL_BREAK;
 			sig = SIGILL; code = __ILL_BREAK;
 		} else {
 		} else {
+			if (notify_die(DIE_BREAK, "bad break", regs, break_num, TRAP_BRKPT, SIGTRAP)
+					== NOTIFY_STOP)
+				return;
 			sig = SIGTRAP; code = TRAP_BRKPT;
 			sig = SIGTRAP; code = TRAP_BRKPT;
 		}
 		}
 	}
 	}
@@ -578,12 +575,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
 #endif
 #endif
 			break;
 			break;
 		      case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
 		      case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
-		      case 36:
-			      if (notify_die(DIE_SS, "ss", &regs, vector,
-					     vector, SIGTRAP) == NOTIFY_STOP)
-				      return;
-			      siginfo.si_code = TRAP_TRACE; ifa = 0; break;
+		      case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
 		}
 		}
+		if (notify_die(DIE_FAULT, "ia64_fault", &regs, vector, siginfo.si_code, SIGTRAP)
+			       	== NOTIFY_STOP)
+			return;
 		siginfo.si_signo = SIGTRAP;
 		siginfo.si_signo = SIGTRAP;
 		siginfo.si_errno = 0;
 		siginfo.si_errno = 0;
 		siginfo.si_addr  = (void __user *) ifa;
 		siginfo.si_addr  = (void __user *) ifa;

+ 9 - 10
arch/ia64/mm/discontig.c

@@ -350,14 +350,12 @@ static void __init initialize_pernode_data(void)
  *	for best.
  *	for best.
  * @nid: node id
  * @nid: node id
  * @pernodesize: size of this node's pernode data
  * @pernodesize: size of this node's pernode data
- * @align: alignment to use for this node's pernode data
  */
  */
-static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize,
-	unsigned long align)
+static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize)
 {
 {
 	void *ptr = NULL;
 	void *ptr = NULL;
 	u8 best = 0xff;
 	u8 best = 0xff;
-	int bestnode = -1, node;
+	int bestnode = -1, node, anynode = 0;
 
 
 	for_each_online_node(node) {
 	for_each_online_node(node) {
 		if (node_isset(node, memory_less_mask))
 		if (node_isset(node, memory_less_mask))
@@ -366,13 +364,15 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize,
 			best = node_distance(nid, node);
 			best = node_distance(nid, node);
 			bestnode = node;
 			bestnode = node;
 		}
 		}
+		anynode = node;
 	}
 	}
 
 
-	ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat,
-		pernodesize, align, __pa(MAX_DMA_ADDRESS));
+	if (bestnode == -1)
+		bestnode = anynode;
+
+	ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, pernodesize,
+		PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
 
 
-	if (!ptr)
-		panic("NO memory for memory less node\n");
 	return ptr;
 	return ptr;
 }
 }
 
 
@@ -413,8 +413,7 @@ static void __init memory_less_nodes(void)
 
 
 	for_each_node_mask(node, memory_less_mask) {
 	for_each_node_mask(node, memory_less_mask) {
 		pernodesize = compute_pernodesize(node);
 		pernodesize = compute_pernodesize(node);
-		pernode = memory_less_node_alloc(node, pernodesize,
-			(node) ? (node * PERCPU_PAGE_SIZE) : (1024*1024));
+		pernode = memory_less_node_alloc(node, pernodesize);
 		fill_pernode(node, __pa(pernode), pernodesize);
 		fill_pernode(node, __pa(pernode), pernodesize);
 	}
 	}
 
 

+ 43 - 42
arch/ia64/mm/tlb.c

@@ -8,6 +8,8 @@
  *		Modified RID allocation for SMP
  *		Modified RID allocation for SMP
  *          Goutham Rao <goutham.rao@intel.com>
  *          Goutham Rao <goutham.rao@intel.com>
  *              IPI based ptc implementation and A-step IPI implementation.
  *              IPI based ptc implementation and A-step IPI implementation.
+ * Rohit Seth <rohit.seth@intel.com>
+ * Ken Chen <kenneth.w.chen@intel.com>
  */
  */
 #include <linux/config.h>
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/module.h>
@@ -16,78 +18,75 @@
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/smp.h>
 #include <linux/mm.h>
 #include <linux/mm.h>
+#include <linux/bootmem.h>
 
 
 #include <asm/delay.h>
 #include <asm/delay.h>
 #include <asm/mmu_context.h>
 #include <asm/mmu_context.h>
 #include <asm/pgalloc.h>
 #include <asm/pgalloc.h>
 #include <asm/pal.h>
 #include <asm/pal.h>
 #include <asm/tlbflush.h>
 #include <asm/tlbflush.h>
+#include <asm/dma.h>
 
 
 static struct {
 static struct {
 	unsigned long mask;	/* mask of supported purge page-sizes */
 	unsigned long mask;	/* mask of supported purge page-sizes */
-	unsigned long max_bits;	/* log2() of largest supported purge page-size */
+	unsigned long max_bits;	/* log2 of largest supported purge page-size */
 } purge;
 } purge;
 
 
 struct ia64_ctx ia64_ctx = {
 struct ia64_ctx ia64_ctx = {
 	.lock =		SPIN_LOCK_UNLOCKED,
 	.lock =		SPIN_LOCK_UNLOCKED,
 	.next =		1,
 	.next =		1,
-	.limit =	(1 << 15) - 1,		/* start out with the safe (architected) limit */
 	.max_ctx =	~0U
 	.max_ctx =	~0U
 };
 };
 
 
 DEFINE_PER_CPU(u8, ia64_need_tlb_flush);
 DEFINE_PER_CPU(u8, ia64_need_tlb_flush);
 
 
+/*
+ * Initializes the ia64_ctx.bitmap array based on max_ctx+1.
+ * Called after cpu_init() has setup ia64_ctx.max_ctx based on
+ * maximum RID that is supported by boot CPU.
+ */
+void __init
+mmu_context_init (void)
+{
+	ia64_ctx.bitmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3);
+	ia64_ctx.flushmap = alloc_bootmem((ia64_ctx.max_ctx+1)>>3);
+}
+
 /*
 /*
  * Acquire the ia64_ctx.lock before calling this function!
  * Acquire the ia64_ctx.lock before calling this function!
  */
  */
 void
 void
 wrap_mmu_context (struct mm_struct *mm)
 wrap_mmu_context (struct mm_struct *mm)
 {
 {
-	unsigned long tsk_context, max_ctx = ia64_ctx.max_ctx;
-	struct task_struct *tsk;
-	int i;
+	int i, cpu;
+	unsigned long flush_bit;
 
 
-	if (ia64_ctx.next > max_ctx)
-		ia64_ctx.next = 300;	/* skip daemons */
-	ia64_ctx.limit = max_ctx + 1;
+	for (i=0; i <= ia64_ctx.max_ctx / BITS_PER_LONG; i++) {
+		flush_bit = xchg(&ia64_ctx.flushmap[i], 0);
+		ia64_ctx.bitmap[i] ^= flush_bit;
+	}
+ 
+	/* use offset at 300 to skip daemons */
+	ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap,
+				ia64_ctx.max_ctx, 300);
+	ia64_ctx.limit = find_next_bit(ia64_ctx.bitmap,
+				ia64_ctx.max_ctx, ia64_ctx.next);
 
 
 	/*
 	/*
-	 * Scan all the task's mm->context and set proper safe range
+	 * can't call flush_tlb_all() here because of race condition
+	 * with O(1) scheduler [EF]
 	 */
 	 */
-
-	read_lock(&tasklist_lock);
-  repeat:
-	for_each_process(tsk) {
-		if (!tsk->mm)
-			continue;
-		tsk_context = tsk->mm->context;
-		if (tsk_context == ia64_ctx.next) {
-			if (++ia64_ctx.next >= ia64_ctx.limit) {
-				/* empty range: reset the range limit and start over */
-				if (ia64_ctx.next > max_ctx)
-					ia64_ctx.next = 300;
-				ia64_ctx.limit = max_ctx + 1;
-				goto repeat;
-			}
-		}
-		if ((tsk_context > ia64_ctx.next) && (tsk_context < ia64_ctx.limit))
-			ia64_ctx.limit = tsk_context;
-	}
-	read_unlock(&tasklist_lock);
-	/* can't call flush_tlb_all() here because of race condition with O(1) scheduler [EF] */
-	{
-		int cpu = get_cpu(); /* prevent preemption/migration */
-		for_each_online_cpu(i) {
-			if (i != cpu)
-				per_cpu(ia64_need_tlb_flush, i) = 1;
-		}
-		put_cpu();
-	}
+	cpu = get_cpu(); /* prevent preemption/migration */
+	for_each_online_cpu(i)
+		if (i != cpu)
+			per_cpu(ia64_need_tlb_flush, i) = 1;
+	put_cpu();
 	local_flush_tlb_all();
 	local_flush_tlb_all();
 }
 }
 
 
 void
 void
-ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long nbits)
+ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start,
+		       unsigned long end, unsigned long nbits)
 {
 {
 	static DEFINE_SPINLOCK(ptcg_lock);
 	static DEFINE_SPINLOCK(ptcg_lock);
 
 
@@ -135,7 +134,8 @@ local_flush_tlb_all (void)
 }
 }
 
 
 void
 void
-flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end)
+flush_tlb_range (struct vm_area_struct *vma, unsigned long start,
+		 unsigned long end)
 {
 {
 	struct mm_struct *mm = vma->vm_mm;
 	struct mm_struct *mm = vma->vm_mm;
 	unsigned long size = end - start;
 	unsigned long size = end - start;
@@ -149,7 +149,8 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long
 #endif
 #endif
 
 
 	nbits = ia64_fls(size + 0xfff);
 	nbits = ia64_fls(size + 0xfff);
-	while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits))
+	while (unlikely (((1UL << nbits) & purge.mask) == 0) &&
+			(nbits < purge.max_bits))
 		++nbits;
 		++nbits;
 	if (nbits > purge.max_bits)
 	if (nbits > purge.max_bits)
 		nbits = purge.max_bits;
 		nbits = purge.max_bits;
@@ -191,5 +192,5 @@ ia64_tlb_init (void)
 	local_cpu_data->ptce_stride[0] = ptce_info.stride[0];
 	local_cpu_data->ptce_stride[0] = ptce_info.stride[0];
 	local_cpu_data->ptce_stride[1] = ptce_info.stride[1];
 	local_cpu_data->ptce_stride[1] = ptce_info.stride[1];
 
 
-	local_flush_tlb_all();		/* nuke left overs from bootstrapping... */
+	local_flush_tlb_all();	/* nuke left overs from bootstrapping... */
 }
 }

+ 82 - 24
arch/ia64/pci/pci.c

@@ -95,7 +95,7 @@ pci_sal_write (unsigned int seg, unsigned int bus, unsigned int devfn,
 }
 }
 
 
 static struct pci_raw_ops pci_sal_ops = {
 static struct pci_raw_ops pci_sal_ops = {
-	.read = 	pci_sal_read,
+	.read =		pci_sal_read,
 	.write =	pci_sal_write
 	.write =	pci_sal_write
 };
 };
 
 
@@ -137,35 +137,98 @@ alloc_pci_controller (int seg)
 	return controller;
 	return controller;
 }
 }
 
 
-static u64 __devinit
-add_io_space (struct acpi_resource_address64 *addr)
+struct pci_root_info {
+	struct pci_controller *controller;
+	char *name;
+};
+
+static unsigned int
+new_space (u64 phys_base, int sparse)
 {
 {
-	u64 offset;
-	int sparse = 0;
+	u64 mmio_base;
 	int i;
 	int i;
 
 
-	if (addr->address_translation_offset == 0)
-		return IO_SPACE_BASE(0);	/* part of legacy IO space */
-
-	if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
-		sparse = 1;
+	if (phys_base == 0)
+		return 0;	/* legacy I/O port space */
 
 
-	offset = (u64) ioremap(addr->address_translation_offset, 0);
+	mmio_base = (u64) ioremap(phys_base, 0);
 	for (i = 0; i < num_io_spaces; i++)
 	for (i = 0; i < num_io_spaces; i++)
-		if (io_space[i].mmio_base == offset &&
+		if (io_space[i].mmio_base == mmio_base &&
 		    io_space[i].sparse == sparse)
 		    io_space[i].sparse == sparse)
-			return IO_SPACE_BASE(i);
+			return i;
 
 
 	if (num_io_spaces == MAX_IO_SPACES) {
 	if (num_io_spaces == MAX_IO_SPACES) {
-		printk("Too many IO port spaces\n");
+		printk(KERN_ERR "PCI: Too many IO port spaces "
+			"(MAX_IO_SPACES=%lu)\n", MAX_IO_SPACES);
 		return ~0;
 		return ~0;
 	}
 	}
 
 
 	i = num_io_spaces++;
 	i = num_io_spaces++;
-	io_space[i].mmio_base = offset;
+	io_space[i].mmio_base = mmio_base;
 	io_space[i].sparse = sparse;
 	io_space[i].sparse = sparse;
 
 
-	return IO_SPACE_BASE(i);
+	return i;
+}
+
+static u64 __devinit
+add_io_space (struct pci_root_info *info, struct acpi_resource_address64 *addr)
+{
+	struct resource *resource;
+	char *name;
+	u64 base, min, max, base_port;
+	unsigned int sparse = 0, space_nr, len;
+
+	resource = kzalloc(sizeof(*resource), GFP_KERNEL);
+	if (!resource) {
+		printk(KERN_ERR "PCI: No memory for %s I/O port space\n",
+			info->name);
+		goto out;
+	}
+
+	len = strlen(info->name) + 32;
+	name = kzalloc(len, GFP_KERNEL);
+	if (!name) {
+		printk(KERN_ERR "PCI: No memory for %s I/O port space name\n",
+			info->name);
+		goto free_resource;
+	}
+
+	min = addr->min_address_range;
+	max = min + addr->address_length - 1;
+	if (addr->attribute.io.translation_attribute == ACPI_SPARSE_TRANSLATION)
+		sparse = 1;
+
+	space_nr = new_space(addr->address_translation_offset, sparse);
+	if (space_nr == ~0)
+		goto free_name;
+
+	base = __pa(io_space[space_nr].mmio_base);
+	base_port = IO_SPACE_BASE(space_nr);
+	snprintf(name, len, "%s I/O Ports %08lx-%08lx", info->name,
+		base_port + min, base_port + max);
+
+	/*
+	 * The SDM guarantees the legacy 0-64K space is sparse, but if the
+	 * mapping is done by the processor (not the bridge), ACPI may not
+	 * mark it as sparse.
+	 */
+	if (space_nr == 0)
+		sparse = 1;
+
+	resource->name  = name;
+	resource->flags = IORESOURCE_MEM;
+	resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
+	resource->end   = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
+	insert_resource(&iomem_resource, resource);
+
+	return base_port;
+
+free_name:
+	kfree(name);
+free_resource:
+	kfree(resource);
+out:
+	return ~0;
 }
 }
 
 
 static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
 static acpi_status __devinit resource_to_window(struct acpi_resource *resource,
@@ -205,11 +268,6 @@ count_window (struct acpi_resource *resource, void *data)
 	return AE_OK;
 	return AE_OK;
 }
 }
 
 
-struct pci_root_info {
-	struct pci_controller *controller;
-	char *name;
-};
-
 static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
 static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
 {
 {
 	struct pci_root_info *info = data;
 	struct pci_root_info *info = data;
@@ -231,7 +289,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
 	} else if (addr.resource_type == ACPI_IO_RANGE) {
 	} else if (addr.resource_type == ACPI_IO_RANGE) {
 		flags = IORESOURCE_IO;
 		flags = IORESOURCE_IO;
 		root = &ioport_resource;
 		root = &ioport_resource;
-		offset = add_io_space(&addr);
+		offset = add_io_space(info, &addr);
 		if (offset == ~0)
 		if (offset == ~0)
 			return AE_OK;
 			return AE_OK;
 	} else
 	} else
@@ -241,7 +299,7 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
 	window->resource.name = info->name;
 	window->resource.name = info->name;
 	window->resource.flags = flags;
 	window->resource.flags = flags;
 	window->resource.start = addr.min_address_range + offset;
 	window->resource.start = addr.min_address_range + offset;
-	window->resource.end = addr.max_address_range + offset;
+	window->resource.end = window->resource.start + addr.address_length - 1;
 	window->resource.child = NULL;
 	window->resource.child = NULL;
 	window->offset = offset;
 	window->offset = offset;
 
 
@@ -739,7 +797,7 @@ int pci_vector_resources(int last, int nr_released)
 {
 {
 	int count = nr_released;
 	int count = nr_released;
 
 
- 	count += (IA64_LAST_DEVICE_VECTOR - last);
+	count += (IA64_LAST_DEVICE_VECTOR - last);
 
 
 	return count;
 	return count;
 }
 }

+ 1 - 1
arch/ia64/sn/kernel/io_init.c

@@ -349,7 +349,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
 		return;		/*bus # does not exist */
 		return;		/*bus # does not exist */
 	prom_bussoft_ptr = __va(prom_bussoft_ptr);
 	prom_bussoft_ptr = __va(prom_bussoft_ptr);
 
 
- 	controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL);
+ 	controller = kzalloc(sizeof(struct pci_controller), GFP_KERNEL);
 	controller->segment = segment;
 	controller->segment = segment;
  	if (!controller)
  	if (!controller)
  		BUG();
  		BUG();

+ 1 - 1
arch/ia64/sn/kernel/xpc.h

@@ -163,7 +163,7 @@ struct xpc_vars {
 	u8 version;
 	u8 version;
 	u64 heartbeat;
 	u64 heartbeat;
 	u64 heartbeating_to_mask;
 	u64 heartbeating_to_mask;
-	u64 kdb_status;		/* 0 = machine running */
+	u64 heartbeat_offline;	/* if 0, heartbeat should be changing */
 	int act_nasid;
 	int act_nasid;
 	int act_phys_cpuid;
 	int act_phys_cpuid;
 	u64 vars_part_pa;
 	u64 vars_part_pa;

+ 102 - 0
arch/ia64/sn/kernel/xpc_main.c

@@ -57,6 +57,7 @@
 #include <linux/reboot.h>
 #include <linux/reboot.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/sn_sal.h>
+#include <asm/kdebug.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #include "xpc.h"
 #include "xpc.h"
 
 
@@ -188,6 +189,11 @@ static struct notifier_block xpc_reboot_notifier = {
 	.notifier_call = xpc_system_reboot,
 	.notifier_call = xpc_system_reboot,
 };
 };
 
 
+static int xpc_system_die(struct notifier_block *, unsigned long, void *);
+static struct notifier_block xpc_die_notifier = {
+	.notifier_call = xpc_system_die,
+};
+
 
 
 /*
 /*
  * Timer function to enforce the timelimit on the partition disengage request.
  * Timer function to enforce the timelimit on the partition disengage request.
@@ -997,6 +1003,9 @@ xpc_do_exit(enum xpc_retval reason)
 	/* take ourselves off of the reboot_notifier_list */
 	/* take ourselves off of the reboot_notifier_list */
 	(void) unregister_reboot_notifier(&xpc_reboot_notifier);
 	(void) unregister_reboot_notifier(&xpc_reboot_notifier);
 
 
+	/* take ourselves off of the die_notifier list */
+	(void) unregister_die_notifier(&xpc_die_notifier);
+
 	/* close down protections for IPI operations */
 	/* close down protections for IPI operations */
 	xpc_restrict_IPI_ops();
 	xpc_restrict_IPI_ops();
 
 
@@ -1010,6 +1019,63 @@ xpc_do_exit(enum xpc_retval reason)
 }
 }
 
 
 
 
+/*
+ * Called when the system is about to be either restarted or halted.
+ */
+static void
+xpc_die_disengage(void)
+{
+	struct xpc_partition *part;
+	partid_t partid;
+	unsigned long engaged;
+	long time, print_time, disengage_request_timeout;
+
+
+	/* keep xpc_hb_checker thread from doing anything (just in case) */
+	xpc_exiting = 1;
+
+	xpc_vars->heartbeating_to_mask = 0;  /* indicate we're deactivated */
+
+	for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
+		part = &xpc_partitions[partid];
+
+		if (!XPC_SUPPORTS_DISENGAGE_REQUEST(part->
+							remote_vars_version)) {
+
+			/* just in case it was left set by an earlier XPC */
+			xpc_clear_partition_engaged(1UL << partid);
+			continue;
+		}
+
+		if (xpc_partition_engaged(1UL << partid) ||
+					part->act_state != XPC_P_INACTIVE) {
+			xpc_request_partition_disengage(part);
+			xpc_mark_partition_disengaged(part);
+			xpc_IPI_send_disengage(part);
+		}
+	}
+
+	print_time = rtc_time();
+	disengage_request_timeout = print_time +
+		(xpc_disengage_request_timelimit * sn_rtc_cycles_per_second);
+
+	/* wait for all other partitions to disengage from us */
+
+	while ((engaged = xpc_partition_engaged(-1UL)) &&
+			(time = rtc_time()) < disengage_request_timeout) {
+
+		if (time >= print_time) {
+			dev_info(xpc_part, "waiting for remote partitions to "
+				"disengage, engaged=0x%lx\n", engaged);
+			print_time = time + (XPC_DISENGAGE_PRINTMSG_INTERVAL *
+						sn_rtc_cycles_per_second);
+		}
+	}
+	dev_info(xpc_part, "finished waiting for remote partitions to "
+				"disengage, engaged=0x%lx\n", engaged);
+}
+
+
 /*
 /*
  * This function is called when the system is being rebooted.
  * This function is called when the system is being rebooted.
  */
  */
@@ -1038,6 +1104,33 @@ xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
 }
 }
 
 
 
 
+/*
+ * This function is called when the system is being rebooted.
+ */
+static int
+xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
+{
+	switch (event) {
+	case DIE_MACHINE_RESTART:
+	case DIE_MACHINE_HALT:
+		xpc_die_disengage();
+		break;
+	case DIE_MCA_MONARCH_ENTER:
+	case DIE_INIT_MONARCH_ENTER:
+		xpc_vars->heartbeat++;
+		xpc_vars->heartbeat_offline = 1;
+		break;
+	case DIE_MCA_MONARCH_LEAVE:
+	case DIE_INIT_MONARCH_LEAVE:
+		xpc_vars->heartbeat++;
+		xpc_vars->heartbeat_offline = 0;
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+
 int __init
 int __init
 xpc_init(void)
 xpc_init(void)
 {
 {
@@ -1154,6 +1247,12 @@ xpc_init(void)
 		dev_warn(xpc_part, "can't register reboot notifier\n");
 		dev_warn(xpc_part, "can't register reboot notifier\n");
 	}
 	}
 
 
+	/* add ourselves to the die_notifier list (i.e., ia64die_chain) */
+	ret = register_die_notifier(&xpc_die_notifier);
+	if (ret != 0) {
+		dev_warn(xpc_part, "can't register die notifier\n");
+	}
+
 
 
 	/*
 	/*
 	 * Set the beating to other partitions into motion.  This is
 	 * Set the beating to other partitions into motion.  This is
@@ -1179,6 +1278,9 @@ xpc_init(void)
 		/* take ourselves off of the reboot_notifier_list */
 		/* take ourselves off of the reboot_notifier_list */
 		(void) unregister_reboot_notifier(&xpc_reboot_notifier);
 		(void) unregister_reboot_notifier(&xpc_reboot_notifier);
 
 
+		/* take ourselves off of the die_notifier list */
+		(void) unregister_die_notifier(&xpc_die_notifier);
+
 		del_timer_sync(&xpc_hb_timer);
 		del_timer_sync(&xpc_hb_timer);
 		free_irq(SGI_XPC_ACTIVATE, NULL);
 		free_irq(SGI_XPC_ACTIVATE, NULL);
 		xpc_restrict_IPI_ops();
 		xpc_restrict_IPI_ops();

+ 4 - 4
arch/ia64/sn/kernel/xpc_partition.c

@@ -436,13 +436,13 @@ xpc_check_remote_hb(void)
 		}
 		}
 
 
 		dev_dbg(xpc_part, "partid = %d, heartbeat = %ld, last_heartbeat"
 		dev_dbg(xpc_part, "partid = %d, heartbeat = %ld, last_heartbeat"
-			" = %ld, kdb_status = %ld, HB_mask = 0x%lx\n", partid,
-			remote_vars->heartbeat, part->last_heartbeat,
-			remote_vars->kdb_status,
+			" = %ld, heartbeat_offline = %ld, HB_mask = 0x%lx\n",
+			partid, remote_vars->heartbeat, part->last_heartbeat,
+			remote_vars->heartbeat_offline,
 			remote_vars->heartbeating_to_mask);
 			remote_vars->heartbeating_to_mask);
 
 
 		if (((remote_vars->heartbeat == part->last_heartbeat) &&
 		if (((remote_vars->heartbeat == part->last_heartbeat) &&
-			(remote_vars->kdb_status == 0)) ||
+			(remote_vars->heartbeat_offline == 0)) ||
 			     !xpc_hb_allowed(sn_partition_id, remote_vars)) {
 			     !xpc_hb_allowed(sn_partition_id, remote_vars)) {
 
 
 			XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat);
 			XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat);

+ 3 - 3
arch/ia64/sn/pci/tioce_provider.c

@@ -218,7 +218,7 @@ tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
 	if (i > last)
 	if (i > last)
 		return 0;
 		return 0;
 
 
-	map = kcalloc(1, sizeof(struct tioce_dmamap), GFP_ATOMIC);
+	map = kzalloc(sizeof(struct tioce_dmamap), GFP_ATOMIC);
 	if (!map)
 	if (!map)
 		return 0;
 		return 0;
 
 
@@ -555,7 +555,7 @@ tioce_kern_init(struct tioce_common *tioce_common)
 	struct tioce *tioce_mmr;
 	struct tioce *tioce_mmr;
 	struct tioce_kernel *tioce_kern;
 	struct tioce_kernel *tioce_kern;
 
 
-	tioce_kern = kcalloc(1, sizeof(struct tioce_kernel), GFP_KERNEL);
+	tioce_kern = kzalloc(sizeof(struct tioce_kernel), GFP_KERNEL);
 	if (!tioce_kern) {
 	if (!tioce_kern) {
 		return NULL;
 		return NULL;
 	}
 	}
@@ -727,7 +727,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont
 	 * Allocate kernel bus soft and copy from prom.
 	 * Allocate kernel bus soft and copy from prom.
 	 */
 	 */
 
 
-	tioce_common = kcalloc(1, sizeof(struct tioce_common), GFP_KERNEL);
+	tioce_common = kzalloc(sizeof(struct tioce_common), GFP_KERNEL);
 	if (!tioce_common)
 	if (!tioce_common)
 		return NULL;
 		return NULL;
 
 

+ 7 - 8
arch/powerpc/Kconfig

@@ -581,17 +581,12 @@ config ARCH_FLATMEM_ENABLE
        def_bool y
        def_bool y
        depends on PPC64 && !NUMA
        depends on PPC64 && !NUMA
 
 
-config ARCH_DISCONTIGMEM_ENABLE
-	def_bool y
-	depends on SMP && PPC_PSERIES
-
-config ARCH_DISCONTIGMEM_DEFAULT
+config ARCH_SPARSEMEM_ENABLE
 	def_bool y
 	def_bool y
-	depends on ARCH_DISCONTIGMEM_ENABLE
 
 
-config ARCH_SPARSEMEM_ENABLE
+config ARCH_SPARSEMEM_DEFAULT
 	def_bool y
 	def_bool y
-	depends on ARCH_DISCONTIGMEM_ENABLE
+	depends on SMP && PPC_PSERIES
 
 
 source "mm/Kconfig"
 source "mm/Kconfig"
 
 
@@ -599,6 +594,10 @@ config HAVE_ARCH_EARLY_PFN_TO_NID
 	def_bool y
 	def_bool y
 	depends on NEED_MULTIPLE_NODES
 	depends on NEED_MULTIPLE_NODES
 
 
+config ARCH_MEMORY_PROBE
+	def_bool y
+	depends on MEMORY_HOTPLUG
+
 # Some NUMA nodes have memory ranges that span
 # Some NUMA nodes have memory ranges that span
 # other nodes.  Even though a pfn is valid and
 # other nodes.  Even though a pfn is valid and
 # between a node's start and end pfns, it may not
 # between a node's start and end pfns, it may not

+ 16 - 3
arch/powerpc/kernel/Makefile

@@ -4,6 +4,7 @@
 
 
 ifeq ($(CONFIG_PPC64),y)
 ifeq ($(CONFIG_PPC64),y)
 EXTRA_CFLAGS	+= -mno-minimal-toc
 EXTRA_CFLAGS	+= -mno-minimal-toc
+CFLAGS_ioctl32.o += -Ifs/
 endif
 endif
 ifeq ($(CONFIG_PPC32),y)
 ifeq ($(CONFIG_PPC32),y)
 CFLAGS_prom_init.o      += -fPIC
 CFLAGS_prom_init.o      += -fPIC
@@ -11,17 +12,29 @@ CFLAGS_btext.o		+= -fPIC
 endif
 endif
 
 
 obj-y				:= semaphore.o cputable.o ptrace.o syscalls.o \
 obj-y				:= semaphore.o cputable.o ptrace.o syscalls.o \
-				   signal_32.o pmc.o
+				   irq.o signal_32.o pmc.o vdso.o
+obj-y				+= vdso32/
 obj-$(CONFIG_PPC64)		+= setup_64.o binfmt_elf32.o sys_ppc32.o \
 obj-$(CONFIG_PPC64)		+= setup_64.o binfmt_elf32.o sys_ppc32.o \
-				   signal_64.o ptrace32.o systbl.o
+				   signal_64.o ptrace32.o systbl.o \
+				   paca.o ioctl32.o cpu_setup_power4.o \
+				   firmware.o sysfs.o udbg.o
+obj-$(CONFIG_PPC64)		+= vdso64/
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
 obj-$(CONFIG_POWER4)		+= idle_power4.o
 obj-$(CONFIG_POWER4)		+= idle_power4.o
 obj-$(CONFIG_PPC_OF)		+= of_device.o
 obj-$(CONFIG_PPC_OF)		+= of_device.o
-obj-$(CONFIG_PPC_RTAS)		+= rtas.o
+procfs-$(CONFIG_PPC64)		:= proc_ppc64.o
+obj-$(CONFIG_PROC_FS)		+= $(procfs-y)
+rtaspci-$(CONFIG_PPC64)		:= rtas_pci.o
+obj-$(CONFIG_PPC_RTAS)		+= rtas.o $(rtaspci-y)
 obj-$(CONFIG_RTAS_FLASH)	+= rtas_flash.o
 obj-$(CONFIG_RTAS_FLASH)	+= rtas_flash.o
 obj-$(CONFIG_RTAS_PROC)		+= rtas-proc.o
 obj-$(CONFIG_RTAS_PROC)		+= rtas-proc.o
+obj-$(CONFIG_LPARCFG)		+= lparcfg.o
 obj-$(CONFIG_IBMVIO)		+= vio.o
 obj-$(CONFIG_IBMVIO)		+= vio.o
 obj-$(CONFIG_GENERIC_TBSYNC)	+= smp-tbsync.o
 obj-$(CONFIG_GENERIC_TBSYNC)	+= smp-tbsync.o
+obj-$(CONFIG_PPC_PSERIES)	+= udbg_16550.o
+obj-$(CONFIG_PPC_MAPLE)		+= udbg_16550.o
+udbgscc-$(CONFIG_PPC64)		:= udbg_scc.o
+obj-$(CONFIG_PPC_PMAC)		+= $(udbgscc-y)
 
 
 ifeq ($(CONFIG_PPC_MERGE),y)
 ifeq ($(CONFIG_PPC_MERGE),y)
 
 

+ 31 - 15
arch/powerpc/kernel/asm-offsets.c

@@ -37,12 +37,12 @@
 #include <asm/cputable.h>
 #include <asm/cputable.h>
 #include <asm/thread_info.h>
 #include <asm/thread_info.h>
 #include <asm/rtas.h>
 #include <asm/rtas.h>
+#include <asm/vdso_datapage.h>
 #ifdef CONFIG_PPC64
 #ifdef CONFIG_PPC64
 #include <asm/paca.h>
 #include <asm/paca.h>
 #include <asm/lppaca.h>
 #include <asm/lppaca.h>
 #include <asm/iseries/hv_lp_event.h>
 #include <asm/iseries/hv_lp_event.h>
 #include <asm/cache.h>
 #include <asm/cache.h>
-#include <asm/systemcfg.h>
 #include <asm/compat.h>
 #include <asm/compat.h>
 #endif
 #endif
 
 
@@ -106,7 +106,6 @@ int main(void)
 	DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
 	DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
 	DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
 	DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
 	DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
 	DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
-	DEFINE(PLATFORM, offsetof(struct systemcfg, platform));
 	DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
 	DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
 
 
 	/* paca */
 	/* paca */
@@ -252,25 +251,42 @@ int main(void)
 
 
 	DEFINE(TASK_SIZE, TASK_SIZE);
 	DEFINE(TASK_SIZE, TASK_SIZE);
 	DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
 	DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
-#else /* CONFIG_PPC64 */
-	/* systemcfg offsets for use by vdso */
-	DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct systemcfg, tb_orig_stamp));
-	DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct systemcfg, tb_ticks_per_sec));
-	DEFINE(CFG_TB_TO_XS, offsetof(struct systemcfg, tb_to_xs));
-	DEFINE(CFG_STAMP_XSEC, offsetof(struct systemcfg, stamp_xsec));
-	DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct systemcfg, tb_update_count));
-	DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct systemcfg, tz_minuteswest));
-	DEFINE(CFG_TZ_DSTTIME, offsetof(struct systemcfg, tz_dsttime));
-	DEFINE(CFG_SYSCALL_MAP32, offsetof(struct systemcfg, syscall_map_32));
-	DEFINE(CFG_SYSCALL_MAP64, offsetof(struct systemcfg, syscall_map_64));
+#endif /* ! CONFIG_PPC64 */
 
 
-	/* timeval/timezone offsets for use by vdso */
+	/* datapage offsets for use by vdso */
+	DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct vdso_data, tb_orig_stamp));
+	DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct vdso_data, tb_ticks_per_sec));
+	DEFINE(CFG_TB_TO_XS, offsetof(struct vdso_data, tb_to_xs));
+	DEFINE(CFG_STAMP_XSEC, offsetof(struct vdso_data, stamp_xsec));
+	DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct vdso_data, tb_update_count));
+	DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct vdso_data, tz_minuteswest));
+	DEFINE(CFG_TZ_DSTTIME, offsetof(struct vdso_data, tz_dsttime));
+	DEFINE(CFG_SYSCALL_MAP32, offsetof(struct vdso_data, syscall_map_32));
+	DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec));
+	DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
+#ifdef CONFIG_PPC64
+	DEFINE(CFG_SYSCALL_MAP64, offsetof(struct vdso_data, syscall_map_64));
 	DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec));
 	DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec));
 	DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec));
 	DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec));
 	DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec));
 	DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec));
 	DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec));
 	DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec));
+	DEFINE(TSPC32_TV_SEC, offsetof(struct compat_timespec, tv_sec));
+	DEFINE(TSPC32_TV_NSEC, offsetof(struct compat_timespec, tv_nsec));
+#else
+	DEFINE(TVAL32_TV_SEC, offsetof(struct timeval, tv_sec));
+	DEFINE(TVAL32_TV_USEC, offsetof(struct timeval, tv_usec));
+	DEFINE(TSPEC32_TV_SEC, offsetof(struct timespec, tv_sec));
+	DEFINE(TSPEC32_TV_NSEC, offsetof(struct timespec, tv_nsec));
+#endif
+	/* timeval/timezone offsets for use by vdso */
 	DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
 	DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
 	DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
 	DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
-#endif /* CONFIG_PPC64 */
+
+	/* Other bits used by the vdso */
+	DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
+	DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
+	DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
+	DEFINE(CLOCK_REALTIME_RES, TICK_NSEC);
+
 	return 0;
 	return 0;
 }
 }

+ 4 - 4
arch/ppc64/kernel/cpu_setup_power4.S → arch/powerpc/kernel/cpu_setup_power4.S

@@ -114,11 +114,11 @@ _GLOBAL(__setup_cpu_ppc970)
 
 
 	.data
 	.data
 	.balign	L1_CACHE_BYTES,0
 	.balign	L1_CACHE_BYTES,0
-cpu_state_storage:	
+cpu_state_storage:
 	.space	CS_SIZE
 	.space	CS_SIZE
 	.balign	L1_CACHE_BYTES,0
 	.balign	L1_CACHE_BYTES,0
 	.text
 	.text
-	
+
 /* Called in normal context to backup CPU 0 state. This
 /* Called in normal context to backup CPU 0 state. This
  * does not include cache settings. This function is also
  * does not include cache settings. This function is also
  * called for machine sleep. This does not include the MMU
  * called for machine sleep. This does not include the MMU
@@ -151,7 +151,7 @@ _GLOBAL(__save_cpu_setup)
 	std	r3,CS_HID4(r5)
 	std	r3,CS_HID4(r5)
 	mfspr	r3,SPRN_HID5
 	mfspr	r3,SPRN_HID5
 	std	r3,CS_HID5(r5)
 	std	r3,CS_HID5(r5)
-	
+
 2:
 2:
 	mtcr	r7
 	mtcr	r7
 	blr
 	blr
@@ -213,7 +213,7 @@ _GLOBAL(__restore_cpu_setup)
 	mtspr	SPRN_HID1,r3
 	mtspr	SPRN_HID1,r3
 	sync
 	sync
 	isync
 	isync
-	
+
 	/* Restore HID4 */
 	/* Restore HID4 */
 	ld	r3,CS_HID4(r5)
 	ld	r3,CS_HID4(r5)
 	sync
 	sync

+ 11 - 8
arch/powerpc/kernel/cputable.c

@@ -52,6 +52,9 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
 #define COMMON_USER		(PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \
 #define COMMON_USER		(PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \
 				 PPC_FEATURE_HAS_MMU)
 				 PPC_FEATURE_HAS_MMU)
 #define COMMON_USER_PPC64	(COMMON_USER | PPC_FEATURE_64)
 #define COMMON_USER_PPC64	(COMMON_USER | PPC_FEATURE_64)
+#define COMMON_USER_POWER4	(COMMON_USER_PPC64 | PPC_FEATURE_POWER4)
+#define COMMON_USER_POWER5	(COMMON_USER_PPC64 | PPC_FEATURE_POWER5)
+#define COMMON_USER_POWER5_PLUS	(COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS)
 
 
 
 
 /* We only set the spe features if the kernel was compiled with
 /* We only set the spe features if the kernel was compiled with
@@ -160,7 +163,7 @@ struct cpu_spec	cpu_specs[] = {
 		.pvr_value		= 0x00350000,
 		.pvr_value		= 0x00350000,
 		.cpu_name		= "POWER4 (gp)",
 		.cpu_name		= "POWER4 (gp)",
 		.cpu_features		= CPU_FTRS_POWER4,
 		.cpu_features		= CPU_FTRS_POWER4,
-		.cpu_user_features	= COMMON_USER_PPC64,
+		.cpu_user_features	= COMMON_USER_POWER4,
 		.icache_bsize		= 128,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 8,
 		.num_pmcs		= 8,
@@ -175,7 +178,7 @@ struct cpu_spec	cpu_specs[] = {
 		.pvr_value		= 0x00380000,
 		.pvr_value		= 0x00380000,
 		.cpu_name		= "POWER4+ (gq)",
 		.cpu_name		= "POWER4+ (gq)",
 		.cpu_features		= CPU_FTRS_POWER4,
 		.cpu_features		= CPU_FTRS_POWER4,
-		.cpu_user_features	= COMMON_USER_PPC64,
+		.cpu_user_features	= COMMON_USER_POWER4,
 		.icache_bsize		= 128,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 8,
 		.num_pmcs		= 8,
@@ -190,7 +193,7 @@ struct cpu_spec	cpu_specs[] = {
 		.pvr_value		= 0x00390000,
 		.pvr_value		= 0x00390000,
 		.cpu_name		= "PPC970",
 		.cpu_name		= "PPC970",
 		.cpu_features		= CPU_FTRS_PPC970,
 		.cpu_features		= CPU_FTRS_PPC970,
-		.cpu_user_features	= COMMON_USER_PPC64 |
+		.cpu_user_features	= COMMON_USER_POWER4 |
 			PPC_FEATURE_HAS_ALTIVEC_COMP,
 			PPC_FEATURE_HAS_ALTIVEC_COMP,
 		.icache_bsize		= 128,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.dcache_bsize		= 128,
@@ -212,7 +215,7 @@ struct cpu_spec	cpu_specs[] = {
 #else
 #else
 		.cpu_features		= CPU_FTRS_PPC970,
 		.cpu_features		= CPU_FTRS_PPC970,
 #endif
 #endif
-		.cpu_user_features	= COMMON_USER_PPC64 |
+		.cpu_user_features	= COMMON_USER_POWER4 |
 			PPC_FEATURE_HAS_ALTIVEC_COMP,
 			PPC_FEATURE_HAS_ALTIVEC_COMP,
 		.icache_bsize		= 128,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.dcache_bsize		= 128,
@@ -230,7 +233,7 @@ struct cpu_spec	cpu_specs[] = {
 		.pvr_value		= 0x00440000,
 		.pvr_value		= 0x00440000,
 		.cpu_name		= "PPC970MP",
 		.cpu_name		= "PPC970MP",
 		.cpu_features		= CPU_FTRS_PPC970,
 		.cpu_features		= CPU_FTRS_PPC970,
-		.cpu_user_features	= COMMON_USER_PPC64 |
+		.cpu_user_features	= COMMON_USER_POWER4 |
 			PPC_FEATURE_HAS_ALTIVEC_COMP,
 			PPC_FEATURE_HAS_ALTIVEC_COMP,
 		.icache_bsize		= 128,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.dcache_bsize		= 128,
@@ -245,7 +248,7 @@ struct cpu_spec	cpu_specs[] = {
 		.pvr_value		= 0x003a0000,
 		.pvr_value		= 0x003a0000,
 		.cpu_name		= "POWER5 (gr)",
 		.cpu_name		= "POWER5 (gr)",
 		.cpu_features		= CPU_FTRS_POWER5,
 		.cpu_features		= CPU_FTRS_POWER5,
-		.cpu_user_features	= COMMON_USER_PPC64,
+		.cpu_user_features	= COMMON_USER_POWER5,
 		.icache_bsize		= 128,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 6,
 		.num_pmcs		= 6,
@@ -260,7 +263,7 @@ struct cpu_spec	cpu_specs[] = {
 		.pvr_value		= 0x003b0000,
 		.pvr_value		= 0x003b0000,
 		.cpu_name		= "POWER5 (gs)",
 		.cpu_name		= "POWER5 (gs)",
 		.cpu_features		= CPU_FTRS_POWER5,
 		.cpu_features		= CPU_FTRS_POWER5,
-		.cpu_user_features	= COMMON_USER_PPC64,
+		.cpu_user_features	= COMMON_USER_POWER5_PLUS,
 		.icache_bsize		= 128,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 6,
 		.num_pmcs		= 6,
@@ -276,7 +279,7 @@ struct cpu_spec	cpu_specs[] = {
 		.cpu_name		= "Cell Broadband Engine",
 		.cpu_name		= "Cell Broadband Engine",
 		.cpu_features		= CPU_FTRS_CELL,
 		.cpu_features		= CPU_FTRS_CELL,
 		.cpu_user_features	= COMMON_USER_PPC64 |
 		.cpu_user_features	= COMMON_USER_PPC64 |
-			PPC_FEATURE_HAS_ALTIVEC_COMP,
+			PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP,
 		.icache_bsize		= 128,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.cpu_setup		= __setup_cpu_be,
 		.cpu_setup		= __setup_cpu_be,

+ 0 - 2
arch/ppc64/kernel/firmware.c → arch/powerpc/kernel/firmware.c

@@ -1,6 +1,4 @@
 /*
 /*
- *  arch/ppc64/kernel/firmware.c
- *
  *  Extracted from cputable.c
  *  Extracted from cputable.c
  *
  *
  *  Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
  *  Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)

+ 12 - 12
arch/powerpc/kernel/fpu.S

@@ -41,20 +41,20 @@ _GLOBAL(load_up_fpu)
 #ifndef CONFIG_SMP
 #ifndef CONFIG_SMP
 	LOADBASE(r3, last_task_used_math)
 	LOADBASE(r3, last_task_used_math)
 	toreal(r3)
 	toreal(r3)
-	LDL	r4,OFF(last_task_used_math)(r3)
-	CMPI	0,r4,0
+	PPC_LL	r4,OFF(last_task_used_math)(r3)
+	PPC_LCMPI	0,r4,0
 	beq	1f
 	beq	1f
 	toreal(r4)
 	toreal(r4)
 	addi	r4,r4,THREAD		/* want last_task_used_math->thread */
 	addi	r4,r4,THREAD		/* want last_task_used_math->thread */
 	SAVE_32FPRS(0, r4)
 	SAVE_32FPRS(0, r4)
 	mffs	fr0
 	mffs	fr0
 	stfd	fr0,THREAD_FPSCR(r4)
 	stfd	fr0,THREAD_FPSCR(r4)
-	LDL	r5,PT_REGS(r4)
+	PPC_LL	r5,PT_REGS(r4)
 	toreal(r5)
 	toreal(r5)
-	LDL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+	PPC_LL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 	li	r10,MSR_FP|MSR_FE0|MSR_FE1
 	li	r10,MSR_FP|MSR_FE0|MSR_FE1
 	andc	r4,r4,r10		/* disable FP for previous task */
 	andc	r4,r4,r10		/* disable FP for previous task */
-	STL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+	PPC_STL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 1:
 1:
 #endif /* CONFIG_SMP */
 #endif /* CONFIG_SMP */
 	/* enable use of FP after return */
 	/* enable use of FP after return */
@@ -77,7 +77,7 @@ _GLOBAL(load_up_fpu)
 #ifndef CONFIG_SMP
 #ifndef CONFIG_SMP
 	subi	r4,r5,THREAD
 	subi	r4,r5,THREAD
 	fromreal(r4)
 	fromreal(r4)
-	STL	r4,OFF(last_task_used_math)(r3)
+	PPC_STL	r4,OFF(last_task_used_math)(r3)
 #endif /* CONFIG_SMP */
 #endif /* CONFIG_SMP */
 	/* restore registers and return */
 	/* restore registers and return */
 	/* we haven't used ctr or xer or lr */
 	/* we haven't used ctr or xer or lr */
@@ -97,24 +97,24 @@ _GLOBAL(giveup_fpu)
 	MTMSRD(r5)			/* enable use of fpu now */
 	MTMSRD(r5)			/* enable use of fpu now */
 	SYNC_601
 	SYNC_601
 	isync
 	isync
-	CMPI	0,r3,0
+	PPC_LCMPI	0,r3,0
 	beqlr-				/* if no previous owner, done */
 	beqlr-				/* if no previous owner, done */
 	addi	r3,r3,THREAD	        /* want THREAD of task */
 	addi	r3,r3,THREAD	        /* want THREAD of task */
-	LDL	r5,PT_REGS(r3)
-	CMPI	0,r5,0
+	PPC_LL	r5,PT_REGS(r3)
+	PPC_LCMPI	0,r5,0
 	SAVE_32FPRS(0, r3)
 	SAVE_32FPRS(0, r3)
 	mffs	fr0
 	mffs	fr0
 	stfd	fr0,THREAD_FPSCR(r3)
 	stfd	fr0,THREAD_FPSCR(r3)
 	beq	1f
 	beq	1f
-	LDL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+	PPC_LL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 	li	r3,MSR_FP|MSR_FE0|MSR_FE1
 	li	r3,MSR_FP|MSR_FE0|MSR_FE1
 	andc	r4,r4,r3		/* disable FP for previous task */
 	andc	r4,r4,r3		/* disable FP for previous task */
-	STL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+	PPC_STL	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 1:
 1:
 #ifndef CONFIG_SMP
 #ifndef CONFIG_SMP
 	li	r5,0
 	li	r5,0
 	LOADBASE(r4,last_task_used_math)
 	LOADBASE(r4,last_task_used_math)
-	STL	r5,OFF(last_task_used_math)(r4)
+	PPC_STL	r5,OFF(last_task_used_math)(r4)
 #endif /* CONFIG_SMP */
 #endif /* CONFIG_SMP */
 	blr
 	blr
 
 

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