Browse Source

Merge branch 'for-rmk' of git://git.pengutronix.de/git/imx/linux-2.6 into devel

Conflicts:

	arch/arm/mach-at91/gpio.c
Russell King 16 years ago
parent
commit
97fb44eb6b
100 changed files with 5105 additions and 3324 deletions
  1. 0 1
      CREDITS
  2. 43 0
      Documentation/ABI/testing/sysfs-bus-pci
  3. 1 1
      Documentation/ABI/testing/sysfs-firmware-memmap
  4. 1 1
      Documentation/DocBook/Makefile
  5. 418 0
      Documentation/DocBook/device-drivers.tmpl
  6. 0 377
      Documentation/DocBook/kernel-api.tmpl
  7. 1 1
      Documentation/PCI/PCIEBUS-HOWTO.txt
  8. 12 0
      Documentation/RCU/checklist.txt
  9. 2 4
      Documentation/cgroups/cgroups.txt
  10. 37 28
      Documentation/cgroups/cpusets.txt
  11. 2 4
      Documentation/connector/cn_test.c
  12. 0 16
      Documentation/cpu-freq/user-guide.txt
  13. 5 3
      Documentation/driver-model/device.txt
  14. 0 205
      Documentation/dvb/README.flexcop
  15. 20 14
      Documentation/dvb/technisat.txt
  16. 9 0
      Documentation/feature-removal-schedule.txt
  17. 1 1
      Documentation/filesystems/squashfs.txt
  18. 12 1
      Documentation/filesystems/sysfs-pci.txt
  19. 28 22
      Documentation/filesystems/sysfs.txt
  20. 101 0
      Documentation/hwmon/hpfall.c
  21. 8 0
      Documentation/hwmon/lis3lv02d
  22. 4 3
      Documentation/kernel-doc-nano-HOWTO.txt
  23. 9 5
      Documentation/kernel-parameters.txt
  24. 35 0
      Documentation/networking/ipv6.txt
  25. 5 6
      Documentation/scsi/cxgb3i.txt
  26. 2 4
      Documentation/tracers/mmiotrace.txt
  27. 29 14
      MAINTAINERS
  28. 2 2
      Makefile
  29. 1 1
      README
  30. 4 4
      arch/alpha/kernel/process.c
  31. 6 6
      arch/alpha/kernel/smp.c
  32. 1 1
      arch/arm/configs/at91sam9260ek_defconfig
  33. 1 1
      arch/arm/configs/at91sam9261ek_defconfig
  34. 1 1
      arch/arm/configs/at91sam9263ek_defconfig
  35. 1 1
      arch/arm/configs/at91sam9rlek_defconfig
  36. 1 1
      arch/arm/configs/qil-a9260_defconfig
  37. 2 2
      arch/arm/kernel/elf.c
  38. 2 2
      arch/arm/kernel/machine_kexec.c
  39. 7 6
      arch/arm/kernel/setup.c
  40. 1 1
      arch/arm/mach-at91/at91cap9_devices.c
  41. 1 1
      arch/arm/mach-at91/at91sam9260_devices.c
  42. 1 1
      arch/arm/mach-at91/at91sam9261_devices.c
  43. 106 1
      arch/arm/mach-at91/at91sam9263_devices.c
  44. 1 1
      arch/arm/mach-at91/at91sam9rl_devices.c
  45. 65 4
      arch/arm/mach-at91/gpio.c
  46. 4 0
      arch/arm/mach-at91/include/mach/board.h
  47. 0 1
      arch/arm/mach-at91/pm.c
  48. 3 3
      arch/arm/mach-davinci/board-evm.c
  49. 5 0
      arch/arm/mach-davinci/clock.c
  50. 1 0
      arch/arm/mach-davinci/usb.c
  51. 0 3
      arch/arm/mach-ep93xx/include/mach/gesbc9312.h
  52. 0 1
      arch/arm/mach-ep93xx/include/mach/hardware.h
  53. 1 1
      arch/arm/mach-kirkwood/irq.c
  54. 1 1
      arch/arm/mach-mv78xx0/irq.c
  55. 6 1
      arch/arm/mach-mx1/Kconfig
  56. 1 0
      arch/arm/mach-mx1/Makefile
  57. 8 32
      arch/arm/mach-mx1/clock.c
  58. 3 0
      arch/arm/mach-mx1/devices.c
  59. 65 3
      arch/arm/mach-mx1/mx1ads.c
  60. 160 0
      arch/arm/mach-mx1/scb9328.c
  61. 15 5
      arch/arm/mach-mx2/Kconfig
  62. 2 0
      arch/arm/mach-mx2/Makefile
  63. 7 3
      arch/arm/mach-mx2/Makefile.boot
  64. 984 0
      arch/arm/mach-mx2/clock_imx21.c
  65. 366 1238
      arch/arm/mach-mx2/clock_imx27.c
  66. 2 2
      arch/arm/mach-mx2/cpu_imx27.c
  67. 149 164
      arch/arm/mach-mx2/crm_regs.h
  68. 190 6
      arch/arm/mach-mx2/devices.c
  69. 7 1
      arch/arm/mach-mx2/devices.h
  70. 1 0
      arch/arm/mach-mx2/generic.c
  71. 7 12
      arch/arm/mach-mx2/mx27ads.c
  72. 68 14
      arch/arm/mach-mx2/pcm038.c
  73. 132 1
      arch/arm/mach-mx2/pcm970-baseboard.c
  74. 3 0
      arch/arm/mach-mx2/serial.c
  75. 32 4
      arch/arm/mach-mx3/Kconfig
  76. 6 2
      arch/arm/mach-mx3/Makefile
  77. 487 0
      arch/arm/mach-mx3/clock-imx35.c
  78. 206 751
      arch/arm/mach-mx3/clock.c
  79. 0 153
      arch/arm/mach-mx3/crm_regs.h
  80. 191 2
      arch/arm/mach-mx3/devices.c
  81. 8 0
      arch/arm/mach-mx3/devices.h
  82. 84 4
      arch/arm/mach-mx3/iomux.c
  83. 36 1
      arch/arm/mach-mx3/mm.c
  84. 307 21
      arch/arm/mach-mx3/mx31ads.c
  85. 1 12
      arch/arm/mach-mx3/mx31lite.c
  86. 48 0
      arch/arm/mach-mx3/mx31moboard-devboard.c
  87. 37 0
      arch/arm/mach-mx3/mx31moboard-marxbot.c
  88. 29 45
      arch/arm/mach-mx3/mx31moboard.c
  89. 10 34
      arch/arm/mach-mx3/mx31pdk.c
  90. 98 40
      arch/arm/mach-mx3/pcm037.c
  91. 312 0
      arch/arm/mach-mx3/qong.c
  92. 1 1
      arch/arm/mach-omap2/board-ldp.c
  93. 8 8
      arch/arm/mach-omap2/clock.c
  94. 1 1
      arch/arm/mach-orion5x/irq.c
  95. 6 0
      arch/arm/mach-rpc/riscpc.c
  96. 2 1
      arch/arm/mm/Kconfig
  97. 2 1
      arch/arm/mm/abort-ev6.S
  98. 2 1
      arch/arm/mm/mmu.c
  99. 9 1
      arch/arm/plat-mxc/Kconfig
  100. 2 1
      arch/arm/plat-mxc/Makefile

+ 0 - 1
CREDITS

@@ -2166,7 +2166,6 @@ D: Initial implementation of VC's, pty's and select()
 
 N: Pavel Machek
 E: pavel@ucw.cz
-E: pavel@suse.cz
 D: Softcursor for vga, hypertech cdrom support, vcsa bugfix, nbd
 D: sun4/330 port, capabilities for elf, speedup for rm on ext2, USB,
 D: work on suspend-to-ram/disk, killing duplicates from ioctl32

+ 43 - 0
Documentation/ABI/testing/sysfs-bus-pci

@@ -1,3 +1,46 @@
+What:		/sys/bus/pci/drivers/.../bind
+Date:		December 2003
+Contact:	linux-pci@vger.kernel.org
+Description:
+		Writing a device location to this file will cause
+		the driver to attempt to bind to the device found at
+		this location.	This is useful for overriding default
+		bindings.  The format for the location is: DDDD:BB:DD.F.
+		That is Domain:Bus:Device.Function and is the same as
+		found in /sys/bus/pci/devices/.  For example:
+		# echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/bind
+		(Note: kernels before 2.6.28 may require echo -n).
+
+What:		/sys/bus/pci/drivers/.../unbind
+Date:		December 2003
+Contact:	linux-pci@vger.kernel.org
+Description:
+		Writing a device location to this file will cause the
+		driver to attempt to unbind from the device found at
+		this location.	This may be useful when overriding default
+		bindings.  The format for the location is: DDDD:BB:DD.F.
+		That is Domain:Bus:Device.Function and is the same as
+		found in /sys/bus/pci/devices/. For example:
+		# echo 0000:00:19.0 > /sys/bus/pci/drivers/foo/unbind
+		(Note: kernels before 2.6.28 may require echo -n).
+
+What:		/sys/bus/pci/drivers/.../new_id
+Date:		December 2003
+Contact:	linux-pci@vger.kernel.org
+Description:
+		Writing a device ID to this file will attempt to
+		dynamically add a new device ID to a PCI device driver.
+		This may allow the driver to support more hardware than
+		was included in the driver's static device ID support
+		table at compile time.  The format for the device ID is:
+		VVVV DDDD SVVV SDDD CCCC MMMM PPPP.  That is Vendor ID,
+		Device ID, Subsystem Vendor ID, Subsystem Device ID,
+		Class, Class Mask, and Private Driver Data.  The Vendor ID
+		and Device ID fields are required, the rest are optional.
+		Upon successfully adding an ID, the driver will probe
+		for the device and attempt to bind to it.  For example:
+		# echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id
+
 What:		/sys/bus/pci/devices/.../vpd
 Date:		February 2008
 Contact:	Ben Hutchings <bhutchings@solarflare.com>

+ 1 - 1
Documentation/ABI/testing/sysfs-firmware-memmap

@@ -1,6 +1,6 @@
 What:		/sys/firmware/memmap/
 Date:		June 2008
-Contact:	Bernhard Walle <bwalle@suse.de>
+Contact:	Bernhard Walle <bernhard.walle@gmx.de>
 Description:
 		On all platforms, the firmware provides a memory map which the
 		kernel reads. The resources from that memory map are registered

+ 1 - 1
Documentation/DocBook/Makefile

@@ -6,7 +6,7 @@
 # To add a new book the only step required is to add the book to the
 # list of DOCBOOKS.
 
-DOCBOOKS := z8530book.xml mcabook.xml \
+DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \
 	    kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
 	    procfs-guide.xml writing_usb_driver.xml networking.xml \
 	    kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \

+ 418 - 0
Documentation/DocBook/device-drivers.tmpl

@@ -0,0 +1,418 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
+
+<book id="LinuxDriversAPI">
+ <bookinfo>
+  <title>Linux Device Drivers</title>
+
+  <legalnotice>
+   <para>
+     This documentation 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.
+   </para>
+
+   <para>
+     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.
+   </para>
+
+   <para>
+     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
+   </para>
+
+   <para>
+     For more details see the file COPYING in the source
+     distribution of Linux.
+   </para>
+  </legalnotice>
+ </bookinfo>
+
+<toc></toc>
+
+  <chapter id="Basics">
+     <title>Driver Basics</title>
+     <sect1><title>Driver Entry and Exit points</title>
+!Iinclude/linux/init.h
+     </sect1>
+
+     <sect1><title>Atomic and pointer manipulation</title>
+!Iarch/x86/include/asm/atomic_32.h
+!Iarch/x86/include/asm/unaligned.h
+     </sect1>
+
+     <sect1><title>Delaying, scheduling, and timer routines</title>
+!Iinclude/linux/sched.h
+!Ekernel/sched.c
+!Ekernel/timer.c
+     </sect1>
+     <sect1><title>High-resolution timers</title>
+!Iinclude/linux/ktime.h
+!Iinclude/linux/hrtimer.h
+!Ekernel/hrtimer.c
+     </sect1>
+     <sect1><title>Workqueues and Kevents</title>
+!Ekernel/workqueue.c
+     </sect1>
+     <sect1><title>Internal Functions</title>
+!Ikernel/exit.c
+!Ikernel/signal.c
+!Iinclude/linux/kthread.h
+!Ekernel/kthread.c
+     </sect1>
+
+     <sect1><title>Kernel objects manipulation</title>
+<!--
+X!Iinclude/linux/kobject.h
+-->
+!Elib/kobject.c
+     </sect1>
+
+     <sect1><title>Kernel utility functions</title>
+!Iinclude/linux/kernel.h
+!Ekernel/printk.c
+!Ekernel/panic.c
+!Ekernel/sys.c
+!Ekernel/rcupdate.c
+     </sect1>
+
+     <sect1><title>Device Resource Management</title>
+!Edrivers/base/devres.c
+     </sect1>
+
+  </chapter>
+
+  <chapter id="devdrivers">
+     <title>Device drivers infrastructure</title>
+     <sect1><title>Device Drivers Base</title>
+<!--
+X!Iinclude/linux/device.h
+-->
+!Edrivers/base/driver.c
+!Edrivers/base/core.c
+!Edrivers/base/class.c
+!Edrivers/base/firmware_class.c
+!Edrivers/base/transport_class.c
+<!-- Cannot be included, because
+     attribute_container_add_class_device_adapter
+ and attribute_container_classdev_to_container
+     exceed allowed 44 characters maximum
+X!Edrivers/base/attribute_container.c
+-->
+!Edrivers/base/sys.c
+<!--
+X!Edrivers/base/interface.c
+-->
+!Edrivers/base/platform.c
+!Edrivers/base/bus.c
+     </sect1>
+     <sect1><title>Device Drivers Power Management</title>
+!Edrivers/base/power/main.c
+     </sect1>
+     <sect1><title>Device Drivers ACPI Support</title>
+<!-- Internal functions only
+X!Edrivers/acpi/sleep/main.c
+X!Edrivers/acpi/sleep/wakeup.c
+X!Edrivers/acpi/motherboard.c
+X!Edrivers/acpi/bus.c
+-->
+!Edrivers/acpi/scan.c
+!Idrivers/acpi/scan.c
+<!-- No correct structured comments
+X!Edrivers/acpi/pci_bind.c
+-->
+     </sect1>
+     <sect1><title>Device drivers PnP support</title>
+!Idrivers/pnp/core.c
+<!-- No correct structured comments
+X!Edrivers/pnp/system.c
+ -->
+!Edrivers/pnp/card.c
+!Idrivers/pnp/driver.c
+!Edrivers/pnp/manager.c
+!Edrivers/pnp/support.c
+     </sect1>
+     <sect1><title>Userspace IO devices</title>
+!Edrivers/uio/uio.c
+!Iinclude/linux/uio_driver.h
+     </sect1>
+  </chapter>
+
+  <chapter id="parportdev">
+     <title>Parallel Port Devices</title>
+!Iinclude/linux/parport.h
+!Edrivers/parport/ieee1284.c
+!Edrivers/parport/share.c
+!Idrivers/parport/daisy.c
+  </chapter>
+
+  <chapter id="message_devices">
+	<title>Message-based devices</title>
+     <sect1><title>Fusion message devices</title>
+!Edrivers/message/fusion/mptbase.c
+!Idrivers/message/fusion/mptbase.c
+!Edrivers/message/fusion/mptscsih.c
+!Idrivers/message/fusion/mptscsih.c
+!Idrivers/message/fusion/mptctl.c
+!Idrivers/message/fusion/mptspi.c
+!Idrivers/message/fusion/mptfc.c
+!Idrivers/message/fusion/mptlan.c
+     </sect1>
+     <sect1><title>I2O message devices</title>
+!Iinclude/linux/i2o.h
+!Idrivers/message/i2o/core.h
+!Edrivers/message/i2o/iop.c
+!Idrivers/message/i2o/iop.c
+!Idrivers/message/i2o/config-osm.c
+!Edrivers/message/i2o/exec-osm.c
+!Idrivers/message/i2o/exec-osm.c
+!Idrivers/message/i2o/bus-osm.c
+!Edrivers/message/i2o/device.c
+!Idrivers/message/i2o/device.c
+!Idrivers/message/i2o/driver.c
+!Idrivers/message/i2o/pci.c
+!Idrivers/message/i2o/i2o_block.c
+!Idrivers/message/i2o/i2o_scsi.c
+!Idrivers/message/i2o/i2o_proc.c
+     </sect1>
+  </chapter>
+
+  <chapter id="snddev">
+     <title>Sound Devices</title>
+!Iinclude/sound/core.h
+!Esound/sound_core.c
+!Iinclude/sound/pcm.h
+!Esound/core/pcm.c
+!Esound/core/device.c
+!Esound/core/info.c
+!Esound/core/rawmidi.c
+!Esound/core/sound.c
+!Esound/core/memory.c
+!Esound/core/pcm_memory.c
+!Esound/core/init.c
+!Esound/core/isadma.c
+!Esound/core/control.c
+!Esound/core/pcm_lib.c
+!Esound/core/hwdep.c
+!Esound/core/pcm_native.c
+!Esound/core/memalloc.c
+<!-- FIXME: Removed for now since no structured comments in source
+X!Isound/sound_firmware.c
+-->
+  </chapter>
+
+  <chapter id="uart16x50">
+     <title>16x50 UART Driver</title>
+!Iinclude/linux/serial_core.h
+!Edrivers/serial/serial_core.c
+!Edrivers/serial/8250.c
+  </chapter>
+
+  <chapter id="fbdev">
+     <title>Frame Buffer Library</title>
+
+     <para>
+       The frame buffer drivers depend heavily on four data structures.
+       These structures are declared in include/linux/fb.h.  They are
+       fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs.
+       The last three can be made available to and from userland.
+     </para>
+
+     <para>
+       fb_info defines the current state of a particular video card.
+       Inside fb_info, there exists a fb_ops structure which is a
+       collection of needed functions to make fbdev and fbcon work.
+       fb_info is only visible to the kernel.
+     </para>
+
+     <para>
+       fb_var_screeninfo is used to describe the features of a video card
+       that are user defined.  With fb_var_screeninfo, things such as
+       depth and the resolution may be defined.
+     </para>
+
+     <para>
+       The next structure is fb_fix_screeninfo. This defines the
+       properties of a card that are created when a mode is set and can't
+       be changed otherwise.  A good example of this is the start of the
+       frame buffer memory.  This "locks" the address of the frame buffer
+       memory, so that it cannot be changed or moved.
+     </para>
+
+     <para>
+       The last structure is fb_monospecs. In the old API, there was
+       little importance for fb_monospecs. This allowed for forbidden things
+       such as setting a mode of 800x600 on a fix frequency monitor. With
+       the new API, fb_monospecs prevents such things, and if used
+       correctly, can prevent a monitor from being cooked.  fb_monospecs
+       will not be useful until kernels 2.5.x.
+     </para>
+
+     <sect1><title>Frame Buffer Memory</title>
+!Edrivers/video/fbmem.c
+     </sect1>
+<!--
+     <sect1><title>Frame Buffer Console</title>
+X!Edrivers/video/console/fbcon.c
+     </sect1>
+-->
+     <sect1><title>Frame Buffer Colormap</title>
+!Edrivers/video/fbcmap.c
+     </sect1>
+<!-- FIXME:
+  drivers/video/fbgen.c has no docs, which stuffs up the sgml.  Comment
+  out until somebody adds docs.  KAO
+     <sect1><title>Frame Buffer Generic Functions</title>
+X!Idrivers/video/fbgen.c
+     </sect1>
+KAO -->
+     <sect1><title>Frame Buffer Video Mode Database</title>
+!Idrivers/video/modedb.c
+!Edrivers/video/modedb.c
+     </sect1>
+     <sect1><title>Frame Buffer Macintosh Video Mode Database</title>
+!Edrivers/video/macmodes.c
+     </sect1>
+     <sect1><title>Frame Buffer Fonts</title>
+        <para>
+           Refer to the file drivers/video/console/fonts.c for more information.
+        </para>
+<!-- FIXME: Removed for now since no structured comments in source
+X!Idrivers/video/console/fonts.c
+-->
+     </sect1>
+  </chapter>
+
+  <chapter id="input_subsystem">
+     <title>Input Subsystem</title>
+!Iinclude/linux/input.h
+!Edrivers/input/input.c
+!Edrivers/input/ff-core.c
+!Edrivers/input/ff-memless.c
+  </chapter>
+
+  <chapter id="spi">
+      <title>Serial Peripheral Interface (SPI)</title>
+  <para>
+	SPI is the "Serial Peripheral Interface", widely used with
+	embedded systems because it is a simple and efficient
+	interface:  basically a multiplexed shift register.
+	Its three signal wires hold a clock (SCK, often in the range
+	of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and
+	a "Master In, Slave Out" (MISO) data line.
+	SPI is a full duplex protocol; for each bit shifted out the
+	MOSI line (one per clock) another is shifted in on the MISO line.
+	Those bits are assembled into words of various sizes on the
+	way to and from system memory.
+	An additional chipselect line is usually active-low (nCS);
+	four signals are normally used for each peripheral, plus
+	sometimes an interrupt.
+  </para>
+  <para>
+	The SPI bus facilities listed here provide a generalized
+	interface to declare SPI busses and devices, manage them
+	according to the standard Linux driver model, and perform
+	input/output operations.
+	At this time, only "master" side interfaces are supported,
+	where Linux talks to SPI peripherals and does not implement
+	such a peripheral itself.
+	(Interfaces to support implementing SPI slaves would
+	necessarily look different.)
+  </para>
+  <para>
+	The programming interface is structured around two kinds of driver,
+	and two kinds of device.
+	A "Controller Driver" abstracts the controller hardware, which may
+	be as simple as a set of GPIO pins or as complex as a pair of FIFOs
+	connected to dual DMA engines on the other side of the SPI shift
+	register (maximizing throughput).  Such drivers bridge between
+	whatever bus they sit on (often the platform bus) and SPI, and
+	expose the SPI side of their device as a
+	<structname>struct spi_master</structname>.
+	SPI devices are children of that master, represented as a
+	<structname>struct spi_device</structname> and manufactured from
+	<structname>struct spi_board_info</structname> descriptors which
+	are usually provided by board-specific initialization code.
+	A <structname>struct spi_driver</structname> is called a
+	"Protocol Driver", and is bound to a spi_device using normal
+	driver model calls.
+  </para>
+  <para>
+	The I/O model is a set of queued messages.  Protocol drivers
+	submit one or more <structname>struct spi_message</structname>
+	objects, which are processed and completed asynchronously.
+	(There are synchronous wrappers, however.)  Messages are
+	built from one or more <structname>struct spi_transfer</structname>
+	objects, each of which wraps a full duplex SPI transfer.
+	A variety of protocol tweaking options are needed, because
+	different chips adopt very different policies for how they
+	use the bits transferred with SPI.
+  </para>
+!Iinclude/linux/spi/spi.h
+!Fdrivers/spi/spi.c spi_register_board_info
+!Edrivers/spi/spi.c
+  </chapter>
+
+  <chapter id="i2c">
+     <title>I<superscript>2</superscript>C and SMBus Subsystem</title>
+
+     <para>
+	I<superscript>2</superscript>C (or without fancy typography, "I2C")
+	is an acronym for the "Inter-IC" bus, a simple bus protocol which is
+	widely used where low data rate communications suffice.
+	Since it's also a licensed trademark, some vendors use another
+	name (such as "Two-Wire Interface", TWI) for the same bus.
+	I2C only needs two signals (SCL for clock, SDA for data), conserving
+	board real estate and minimizing signal quality issues.
+	Most I2C devices use seven bit addresses, and bus speeds of up
+	to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet
+	found wide use.
+	I2C is a multi-master bus; open drain signaling is used to
+	arbitrate between masters, as well as to handshake and to
+	synchronize clocks from slower clients.
+     </para>
+
+     <para>
+	The Linux I2C programming interfaces support only the master
+	side of bus interactions, not the slave side.
+	The programming interface is structured around two kinds of driver,
+	and two kinds of device.
+	An I2C "Adapter Driver" abstracts the controller hardware; it binds
+	to a physical device (perhaps a PCI device or platform_device) and
+	exposes a <structname>struct i2c_adapter</structname> representing
+	each I2C bus segment it manages.
+	On each I2C bus segment will be I2C devices represented by a
+	<structname>struct i2c_client</structname>.  Those devices will
+	be bound to a <structname>struct i2c_driver</structname>,
+	which should follow the standard Linux driver model.
+	(At this writing, a legacy model is more widely used.)
+	There are functions to perform various I2C protocol operations; at
+	this writing all such functions are usable only from task context.
+     </para>
+
+     <para>
+	The System Management Bus (SMBus) is a sibling protocol.  Most SMBus
+	systems are also I2C conformant.  The electrical constraints are
+	tighter for SMBus, and it standardizes particular protocol messages
+	and idioms.  Controllers that support I2C can also support most
+	SMBus operations, but SMBus controllers don't support all the protocol
+	options that an I2C controller will.
+	There are functions to perform various SMBus protocol operations,
+	either using I2C primitives or by issuing SMBus commands to
+	i2c_adapter devices which don't support those I2C operations.
+     </para>
+
+!Iinclude/linux/i2c.h
+!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info
+!Edrivers/i2c/i2c-core.c
+  </chapter>
+
+</book>

+ 0 - 377
Documentation/DocBook/kernel-api.tmpl

@@ -38,58 +38,6 @@
 
 <toc></toc>
 
-  <chapter id="Basics">
-     <title>Driver Basics</title>
-     <sect1><title>Driver Entry and Exit points</title>
-!Iinclude/linux/init.h
-     </sect1>
-
-     <sect1><title>Atomic and pointer manipulation</title>
-!Iarch/x86/include/asm/atomic_32.h
-!Iarch/x86/include/asm/unaligned.h
-     </sect1>
-
-     <sect1><title>Delaying, scheduling, and timer routines</title>
-!Iinclude/linux/sched.h
-!Ekernel/sched.c
-!Ekernel/timer.c
-     </sect1>
-     <sect1><title>High-resolution timers</title>
-!Iinclude/linux/ktime.h
-!Iinclude/linux/hrtimer.h
-!Ekernel/hrtimer.c
-     </sect1>
-     <sect1><title>Workqueues and Kevents</title>
-!Ekernel/workqueue.c
-     </sect1>
-     <sect1><title>Internal Functions</title>
-!Ikernel/exit.c
-!Ikernel/signal.c
-!Iinclude/linux/kthread.h
-!Ekernel/kthread.c
-     </sect1>
-
-     <sect1><title>Kernel objects manipulation</title>
-<!--
-X!Iinclude/linux/kobject.h
--->
-!Elib/kobject.c
-     </sect1>
-
-     <sect1><title>Kernel utility functions</title>
-!Iinclude/linux/kernel.h
-!Ekernel/printk.c
-!Ekernel/panic.c
-!Ekernel/sys.c
-!Ekernel/rcupdate.c
-     </sect1>
-
-     <sect1><title>Device Resource Management</title>
-!Edrivers/base/devres.c
-     </sect1>
-
-  </chapter>
-
   <chapter id="adt">
      <title>Data Types</title>
      <sect1><title>Doubly Linked Lists</title>
@@ -298,62 +246,6 @@ X!Earch/x86/kernel/mca_32.c
 !Ikernel/acct.c
   </chapter>
 
-  <chapter id="devdrivers">
-     <title>Device drivers infrastructure</title>
-     <sect1><title>Device Drivers Base</title>
-<!--
-X!Iinclude/linux/device.h
--->
-!Edrivers/base/driver.c
-!Edrivers/base/core.c
-!Edrivers/base/class.c
-!Edrivers/base/firmware_class.c
-!Edrivers/base/transport_class.c
-<!-- Cannot be included, because
-     attribute_container_add_class_device_adapter
- and attribute_container_classdev_to_container
-     exceed allowed 44 characters maximum
-X!Edrivers/base/attribute_container.c
--->
-!Edrivers/base/sys.c
-<!--
-X!Edrivers/base/interface.c
--->
-!Edrivers/base/platform.c
-!Edrivers/base/bus.c
-     </sect1>
-     <sect1><title>Device Drivers Power Management</title>
-!Edrivers/base/power/main.c
-     </sect1>
-     <sect1><title>Device Drivers ACPI Support</title>
-<!-- Internal functions only
-X!Edrivers/acpi/sleep/main.c
-X!Edrivers/acpi/sleep/wakeup.c
-X!Edrivers/acpi/motherboard.c
-X!Edrivers/acpi/bus.c
--->
-!Edrivers/acpi/scan.c
-!Idrivers/acpi/scan.c
-<!-- No correct structured comments
-X!Edrivers/acpi/pci_bind.c
--->
-     </sect1>
-     <sect1><title>Device drivers PnP support</title>
-!Idrivers/pnp/core.c
-<!-- No correct structured comments
-X!Edrivers/pnp/system.c
- -->
-!Edrivers/pnp/card.c
-!Idrivers/pnp/driver.c
-!Edrivers/pnp/manager.c
-!Edrivers/pnp/support.c
-     </sect1>
-     <sect1><title>Userspace IO devices</title>
-!Edrivers/uio/uio.c
-!Iinclude/linux/uio_driver.h
-     </sect1>
-  </chapter>
-
   <chapter id="blkdev">
      <title>Block Devices</title>
 !Eblock/blk-core.c
@@ -381,275 +273,6 @@ X!Edrivers/pnp/system.c
 !Edrivers/char/misc.c
   </chapter>
 
-  <chapter id="parportdev">
-     <title>Parallel Port Devices</title>
-!Iinclude/linux/parport.h
-!Edrivers/parport/ieee1284.c
-!Edrivers/parport/share.c
-!Idrivers/parport/daisy.c
-  </chapter>
-
-  <chapter id="message_devices">
-	<title>Message-based devices</title>
-     <sect1><title>Fusion message devices</title>
-!Edrivers/message/fusion/mptbase.c
-!Idrivers/message/fusion/mptbase.c
-!Edrivers/message/fusion/mptscsih.c
-!Idrivers/message/fusion/mptscsih.c
-!Idrivers/message/fusion/mptctl.c
-!Idrivers/message/fusion/mptspi.c
-!Idrivers/message/fusion/mptfc.c
-!Idrivers/message/fusion/mptlan.c
-     </sect1>
-     <sect1><title>I2O message devices</title>
-!Iinclude/linux/i2o.h
-!Idrivers/message/i2o/core.h
-!Edrivers/message/i2o/iop.c
-!Idrivers/message/i2o/iop.c
-!Idrivers/message/i2o/config-osm.c
-!Edrivers/message/i2o/exec-osm.c
-!Idrivers/message/i2o/exec-osm.c
-!Idrivers/message/i2o/bus-osm.c
-!Edrivers/message/i2o/device.c
-!Idrivers/message/i2o/device.c
-!Idrivers/message/i2o/driver.c
-!Idrivers/message/i2o/pci.c
-!Idrivers/message/i2o/i2o_block.c
-!Idrivers/message/i2o/i2o_scsi.c
-!Idrivers/message/i2o/i2o_proc.c
-     </sect1>
-  </chapter>
-
-  <chapter id="snddev">
-     <title>Sound Devices</title>
-!Iinclude/sound/core.h
-!Esound/sound_core.c
-!Iinclude/sound/pcm.h
-!Esound/core/pcm.c
-!Esound/core/device.c
-!Esound/core/info.c
-!Esound/core/rawmidi.c
-!Esound/core/sound.c
-!Esound/core/memory.c
-!Esound/core/pcm_memory.c
-!Esound/core/init.c
-!Esound/core/isadma.c
-!Esound/core/control.c
-!Esound/core/pcm_lib.c
-!Esound/core/hwdep.c
-!Esound/core/pcm_native.c
-!Esound/core/memalloc.c
-<!-- FIXME: Removed for now since no structured comments in source
-X!Isound/sound_firmware.c
--->
-  </chapter>
-
-  <chapter id="uart16x50">
-     <title>16x50 UART Driver</title>
-!Iinclude/linux/serial_core.h
-!Edrivers/serial/serial_core.c
-!Edrivers/serial/8250.c
-  </chapter>
-
-  <chapter id="fbdev">
-     <title>Frame Buffer Library</title>
-
-     <para>
-       The frame buffer drivers depend heavily on four data structures.  
-       These structures are declared in include/linux/fb.h.  They are 
-       fb_info, fb_var_screeninfo, fb_fix_screeninfo and fb_monospecs. 
-       The last three can be made available to and from userland. 
-     </para>
-
-     <para>
-       fb_info defines the current state of a particular video card. 
-       Inside fb_info, there exists a fb_ops structure which is a 
-       collection of needed functions to make fbdev and fbcon work.
-       fb_info is only visible to the kernel.
-     </para>
-
-     <para>
-       fb_var_screeninfo is used to describe the features of a video card 
-       that are user defined.  With fb_var_screeninfo, things such as
-       depth and the resolution may be defined.
-     </para>
-
-     <para>
-       The next structure is fb_fix_screeninfo. This defines the 
-       properties of a card that are created when a mode is set and can't 
-       be changed otherwise.  A good example of this is the start of the 
-       frame buffer memory.  This "locks" the address of the frame buffer
-       memory, so that it cannot be changed or moved.
-     </para>
-
-     <para>
-       The last structure is fb_monospecs. In the old API, there was 
-       little importance for fb_monospecs. This allowed for forbidden things 
-       such as setting a mode of 800x600 on a fix frequency monitor. With 
-       the new API, fb_monospecs prevents such things, and if used 
-       correctly, can prevent a monitor from being cooked.  fb_monospecs
-       will not be useful until kernels 2.5.x.
-     </para>
-
-     <sect1><title>Frame Buffer Memory</title>
-!Edrivers/video/fbmem.c
-     </sect1>
-<!--
-     <sect1><title>Frame Buffer Console</title>
-X!Edrivers/video/console/fbcon.c
-     </sect1>
--->
-     <sect1><title>Frame Buffer Colormap</title>
-!Edrivers/video/fbcmap.c
-     </sect1>
-<!-- FIXME:
-  drivers/video/fbgen.c has no docs, which stuffs up the sgml.  Comment
-  out until somebody adds docs.  KAO
-     <sect1><title>Frame Buffer Generic Functions</title>
-X!Idrivers/video/fbgen.c
-     </sect1>
-KAO -->
-     <sect1><title>Frame Buffer Video Mode Database</title>
-!Idrivers/video/modedb.c
-!Edrivers/video/modedb.c
-     </sect1>
-     <sect1><title>Frame Buffer Macintosh Video Mode Database</title>
-!Edrivers/video/macmodes.c
-     </sect1>
-     <sect1><title>Frame Buffer Fonts</title>
-        <para>
-           Refer to the file drivers/video/console/fonts.c for more information.
-        </para>
-<!-- FIXME: Removed for now since no structured comments in source
-X!Idrivers/video/console/fonts.c
--->
-     </sect1>
-  </chapter>
-
-  <chapter id="input_subsystem">
-     <title>Input Subsystem</title>
-!Iinclude/linux/input.h
-!Edrivers/input/input.c
-!Edrivers/input/ff-core.c
-!Edrivers/input/ff-memless.c
-  </chapter>
-
-  <chapter id="spi">
-      <title>Serial Peripheral Interface (SPI)</title>
-  <para>
-	SPI is the "Serial Peripheral Interface", widely used with
-	embedded systems because it is a simple and efficient
-	interface:  basically a multiplexed shift register.
-	Its three signal wires hold a clock (SCK, often in the range
-	of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and
-	a "Master In, Slave Out" (MISO) data line.
-	SPI is a full duplex protocol; for each bit shifted out the
-	MOSI line (one per clock) another is shifted in on the MISO line.
-	Those bits are assembled into words of various sizes on the
-	way to and from system memory.
-	An additional chipselect line is usually active-low (nCS);
-	four signals are normally used for each peripheral, plus
-	sometimes an interrupt.
-  </para>
-  <para>
-	The SPI bus facilities listed here provide a generalized
-	interface to declare SPI busses and devices, manage them
-	according to the standard Linux driver model, and perform
-	input/output operations.
-	At this time, only "master" side interfaces are supported,
-	where Linux talks to SPI peripherals and does not implement
-	such a peripheral itself.
-	(Interfaces to support implementing SPI slaves would
-	necessarily look different.)
-  </para>
-  <para>
-	The programming interface is structured around two kinds of driver,
-	and two kinds of device.
-	A "Controller Driver" abstracts the controller hardware, which may
-	be as simple as a set of GPIO pins or as complex as a pair of FIFOs
-	connected to dual DMA engines on the other side of the SPI shift
-	register (maximizing throughput).  Such drivers bridge between
-	whatever bus they sit on (often the platform bus) and SPI, and
-	expose the SPI side of their device as a
-	<structname>struct spi_master</structname>.
-	SPI devices are children of that master, represented as a
-	<structname>struct spi_device</structname> and manufactured from
-	<structname>struct spi_board_info</structname> descriptors which
-	are usually provided by board-specific initialization code.
-	A <structname>struct spi_driver</structname> is called a
-	"Protocol Driver", and is bound to a spi_device using normal
-	driver model calls.
-  </para>
-  <para>
-	The I/O model is a set of queued messages.  Protocol drivers
-	submit one or more <structname>struct spi_message</structname>
-	objects, which are processed and completed asynchronously.
-	(There are synchronous wrappers, however.)  Messages are
-	built from one or more <structname>struct spi_transfer</structname>
-	objects, each of which wraps a full duplex SPI transfer.
-	A variety of protocol tweaking options are needed, because
-	different chips adopt very different policies for how they
-	use the bits transferred with SPI.
-  </para>
-!Iinclude/linux/spi/spi.h
-!Fdrivers/spi/spi.c spi_register_board_info
-!Edrivers/spi/spi.c
-  </chapter>
-
-  <chapter id="i2c">
-     <title>I<superscript>2</superscript>C and SMBus Subsystem</title>
-
-     <para>
-	I<superscript>2</superscript>C (or without fancy typography, "I2C")
-	is an acronym for the "Inter-IC" bus, a simple bus protocol which is
-	widely used where low data rate communications suffice.
-	Since it's also a licensed trademark, some vendors use another
-	name (such as "Two-Wire Interface", TWI) for the same bus.
-	I2C only needs two signals (SCL for clock, SDA for data), conserving
-	board real estate and minimizing signal quality issues.
-	Most I2C devices use seven bit addresses, and bus speeds of up
-	to 400 kHz; there's a high speed extension (3.4 MHz) that's not yet
-	found wide use.
-	I2C is a multi-master bus; open drain signaling is used to
-	arbitrate between masters, as well as to handshake and to
-	synchronize clocks from slower clients.
-     </para>
-
-     <para>
-	The Linux I2C programming interfaces support only the master
-	side of bus interactions, not the slave side.
-	The programming interface is structured around two kinds of driver,
-	and two kinds of device.
-	An I2C "Adapter Driver" abstracts the controller hardware; it binds
-	to a physical device (perhaps a PCI device or platform_device) and
-	exposes a <structname>struct i2c_adapter</structname> representing
-	each I2C bus segment it manages.
-	On each I2C bus segment will be I2C devices represented by a
-	<structname>struct i2c_client</structname>.  Those devices will
-	be bound to a <structname>struct i2c_driver</structname>,
-	which should follow the standard Linux driver model.
-	(At this writing, a legacy model is more widely used.)
-	There are functions to perform various I2C protocol operations; at
-	this writing all such functions are usable only from task context.
-     </para>
-
-     <para>
-	The System Management Bus (SMBus) is a sibling protocol.  Most SMBus
-	systems are also I2C conformant.  The electrical constraints are
-	tighter for SMBus, and it standardizes particular protocol messages
-	and idioms.  Controllers that support I2C can also support most
-	SMBus operations, but SMBus controllers don't support all the protocol
-	options that an I2C controller will.
-	There are functions to perform various SMBus protocol operations,
-	either using I2C primitives or by issuing SMBus commands to
-	i2c_adapter devices which don't support those I2C operations.
-     </para>
-
-!Iinclude/linux/i2c.h
-!Fdrivers/i2c/i2c-boardinfo.c i2c_register_board_info
-!Edrivers/i2c/i2c-core.c
-  </chapter>
-
   <chapter id="clk">
      <title>Clock Framework</title>
 

+ 1 - 1
Documentation/PCI/PCIEBUS-HOWTO.txt

@@ -93,7 +93,7 @@ the PCI Express Port Bus driver from loading a service driver.
 
 int pcie_port_service_register(struct pcie_port_service_driver *new)
 
-This API replaces the Linux Driver Model's pci_module_init API. A
+This API replaces the Linux Driver Model's pci_register_driver API. A
 service driver should always calls pcie_port_service_register at
 module init. Note that after service driver being loaded, calls
 such as pci_enable_device(dev) and pci_set_master(dev) are no longer

+ 12 - 0
Documentation/RCU/checklist.txt

@@ -298,3 +298,15 @@ over a rather long period of time, but improvements are always welcome!
 
 	Note that, rcu_assign_pointer() and rcu_dereference() relate to
 	SRCU just as they do to other forms of RCU.
+
+15.	The whole point of call_rcu(), synchronize_rcu(), and friends
+	is to wait until all pre-existing readers have finished before
+	carrying out some otherwise-destructive operation.  It is
+	therefore critically important to -first- remove any path
+	that readers can follow that could be affected by the
+	destructive operation, and -only- -then- invoke call_rcu(),
+	synchronize_rcu(), or friends.
+
+	Because these primitives only wait for pre-existing readers,
+	it is the caller's responsibility to guarantee safety to
+	any subsequent readers.

+ 2 - 4
Documentation/cgroups/cgroups.txt

@@ -252,10 +252,8 @@ cgroup file system directories.
 When a task is moved from one cgroup to another, it gets a new
 css_set pointer - if there's an already existing css_set with the
 desired collection of cgroups then that group is reused, else a new
-css_set is allocated. Note that the current implementation uses a
-linear search to locate an appropriate existing css_set, so isn't
-very efficient. A future version will use a hash table for better
-performance.
+css_set is allocated. The appropriate existing css_set is located by
+looking into a hash table.
 
 To allow access from a cgroup to the css_sets (and hence tasks)
 that comprise it, a set of cg_cgroup_link objects form a lattice;

+ 37 - 28
Documentation/cgroups/cpusets.txt

@@ -142,7 +142,7 @@ into the rest of the kernel, none in performance critical paths:
  - in fork and exit, to attach and detach a task from its cpuset.
  - in sched_setaffinity, to mask the requested CPUs by what's
    allowed in that tasks cpuset.
- - in sched.c migrate_all_tasks(), to keep migrating tasks within
+ - in sched.c migrate_live_tasks(), to keep migrating tasks within
    the CPUs allowed by their cpuset, if possible.
  - in the mbind and set_mempolicy system calls, to mask the requested
    Memory Nodes by what's allowed in that tasks cpuset.
@@ -175,6 +175,10 @@ files describing that cpuset:
  - mem_exclusive flag: is memory placement exclusive?
  - mem_hardwall flag:  is memory allocation hardwalled
  - memory_pressure: measure of how much paging pressure in cpuset
+ - memory_spread_page flag: if set, spread page cache evenly on allowed nodes
+ - memory_spread_slab flag: if set, spread slab cache evenly on allowed nodes
+ - sched_load_balance flag: if set, load balance within CPUs on that cpuset
+ - sched_relax_domain_level: the searching range when migrating tasks
 
 In addition, the root cpuset only has the following file:
  - memory_pressure_enabled flag: compute memory_pressure?
@@ -252,7 +256,7 @@ is causing.
 
 This is useful both on tightly managed systems running a wide mix of
 submitted jobs, which may choose to terminate or re-prioritize jobs that
-are trying to use more memory than allowed on the nodes assigned them,
+are trying to use more memory than allowed on the nodes assigned to them,
 and with tightly coupled, long running, massively parallel scientific
 computing jobs that will dramatically fail to meet required performance
 goals if they start to use more memory than allowed to them.
@@ -378,7 +382,7 @@ as cpusets and sched_setaffinity.
 The algorithmic cost of load balancing and its impact on key shared
 kernel data structures such as the task list increases more than
 linearly with the number of CPUs being balanced.  So the scheduler
-has support to  partition the systems CPUs into a number of sched
+has support to partition the systems CPUs into a number of sched
 domains such that it only load balances within each sched domain.
 Each sched domain covers some subset of the CPUs in the system;
 no two sched domains overlap; some CPUs might not be in any sched
@@ -485,17 +489,22 @@ of CPUs allowed to a cpuset having 'sched_load_balance' enabled.
 The internal kernel cpuset to scheduler interface passes from the
 cpuset code to the scheduler code a partition of the load balanced
 CPUs in the system. This partition is a set of subsets (represented
-as an array of cpumask_t) of CPUs, pairwise disjoint, that cover all
-the CPUs that must be load balanced.
-
-Whenever the 'sched_load_balance' flag changes, or CPUs come or go
-from a cpuset with this flag enabled, or a cpuset with this flag
-enabled is removed, the cpuset code builds a new such partition and
-passes it to the scheduler sched domain setup code, to have the sched
-domains rebuilt as necessary.
+as an array of struct cpumask) of CPUs, pairwise disjoint, that cover
+all the CPUs that must be load balanced.
+
+The cpuset code builds a new such partition and passes it to the
+scheduler sched domain setup code, to have the sched domains rebuilt
+as necessary, whenever:
+ - the 'sched_load_balance' flag of a cpuset with non-empty CPUs changes,
+ - or CPUs come or go from a cpuset with this flag enabled,
+ - or 'sched_relax_domain_level' value of a cpuset with non-empty CPUs
+   and with this flag enabled changes,
+ - or a cpuset with non-empty CPUs and with this flag enabled is removed,
+ - or a cpu is offlined/onlined.
 
 This partition exactly defines what sched domains the scheduler should
-setup - one sched domain for each element (cpumask_t) in the partition.
+setup - one sched domain for each element (struct cpumask) in the
+partition.
 
 The scheduler remembers the currently active sched domain partitions.
 When the scheduler routine partition_sched_domains() is invoked from
@@ -559,7 +568,7 @@ domain, the largest value among those is used.  Be careful, if one
 requests 0 and others are -1 then 0 is used.
 
 Note that modifying this file will have both good and bad effects,
-and whether it is acceptable or not will be depend on your situation.
+and whether it is acceptable or not depends on your situation.
 Don't modify this file if you are not sure.
 
 If your situation is:
@@ -600,19 +609,15 @@ to allocate a page of memory for that task.
 
 If a cpuset has its 'cpus' modified, then each task in that cpuset
 will have its allowed CPU placement changed immediately.  Similarly,
-if a tasks pid is written to a cpusets 'tasks' file, in either its
-current cpuset or another cpuset, then its allowed CPU placement is
-changed immediately.  If such a task had been bound to some subset
-of its cpuset using the sched_setaffinity() call, the task will be
-allowed to run on any CPU allowed in its new cpuset, negating the
-affect of the prior sched_setaffinity() call.
+if a tasks pid is written to another cpusets 'tasks' file, then its
+allowed CPU placement is changed immediately.  If such a task had been
+bound to some subset of its cpuset using the sched_setaffinity() call,
+the task will be allowed to run on any CPU allowed in its new cpuset,
+negating the effect of the prior sched_setaffinity() call.
 
 In summary, the memory placement of a task whose cpuset is changed is
 updated by the kernel, on the next allocation of a page for that task,
-but the processor placement is not updated, until that tasks pid is
-rewritten to the 'tasks' file of its cpuset.  This is done to avoid
-impacting the scheduler code in the kernel with a check for changes
-in a tasks processor placement.
+and the processor placement is updated immediately.
 
 Normally, once a page is allocated (given a physical page
 of main memory) then that page stays on whatever node it
@@ -681,10 +686,14 @@ and then start a subshell 'sh' in that cpuset:
   # The next line should display '/Charlie'
   cat /proc/self/cpuset
 
-In the future, a C library interface to cpusets will likely be
-available.  For now, the only way to query or modify cpusets is
-via the cpuset file system, using the various cd, mkdir, echo, cat,
-rmdir commands from the shell, or their equivalent from C.
+There are ways to query or modify cpusets:
+ - via the cpuset file system directly, using the various cd, mkdir, echo,
+   cat, rmdir commands from the shell, or their equivalent from C.
+ - via the C library libcpuset.
+ - via the C library libcgroup.
+   (http://sourceforge.net/proects/libcg/)
+ - via the python application cset.
+   (http://developer.novell.com/wiki/index.php/Cpuset)
 
 The sched_setaffinity calls can also be done at the shell prompt using
 SGI's runon or Robert Love's taskset.  The mbind and set_mempolicy
@@ -756,7 +765,7 @@ mount -t cpuset X /dev/cpuset
 
 is equivalent to
 
-mount -t cgroup -ocpuset X /dev/cpuset
+mount -t cgroup -ocpuset,noprefix X /dev/cpuset
 echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent
 
 2.2 Adding/removing cpus

+ 2 - 4
Documentation/connector/cn_test.c

@@ -137,7 +137,7 @@ static void cn_test_timer_func(unsigned long __data)
 
 		memcpy(m + 1, data, m->len);
 
-		cn_netlink_send(m, 0, gfp_any());
+		cn_netlink_send(m, 0, GFP_ATOMIC);
 		kfree(m);
 	}
 
@@ -160,10 +160,8 @@ static int cn_test_init(void)
 		goto err_out;
 	}
 
-	init_timer(&cn_test_timer);
-	cn_test_timer.function = cn_test_timer_func;
+	setup_timer(&cn_test_timer, cn_test_timer_func, 0);
 	cn_test_timer.expires = jiffies + HZ;
-	cn_test_timer.data = 0;
 	add_timer(&cn_test_timer);
 
 	return 0;

+ 0 - 16
Documentation/cpu-freq/user-guide.txt

@@ -195,19 +195,3 @@ scaling_setspeed.		By "echoing" a new frequency into this
 				you can change the speed of the CPU,
 				but only within the limits of
 				scaling_min_freq and scaling_max_freq.
-				
-
-3.2 Deprecated Interfaces
--------------------------
-
-Depending on your kernel configuration, you might find the following 
-cpufreq-related files:
-/proc/cpufreq
-/proc/sys/cpu/*/speed
-/proc/sys/cpu/*/speed-min
-/proc/sys/cpu/*/speed-max
-
-These are files for deprecated interfaces to cpufreq, which offer far
-less functionality. Because of this, these interfaces aren't described
-here.
-

+ 5 - 3
Documentation/driver-model/device.txt

@@ -127,9 +127,11 @@ void unlock_device(struct device * dev);
 Attributes
 ~~~~~~~~~~
 struct device_attribute {
-        struct attribute        attr;
-        ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off);
-        ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off);
+	struct attribute	attr;
+	ssize_t (*show)(struct device *dev, struct device_attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+			 const char *buf, size_t count);
 };
 
 Attributes of devices can be exported via drivers using a simple

+ 0 - 205
Documentation/dvb/README.flexcop

@@ -1,205 +0,0 @@
-This README escorted the skystar2-driver rewriting procedure. It describes the
-state of the new flexcop-driver set and some internals are written down here
-too.
-
-This document hopefully describes things about the flexcop and its
-device-offsprings. Goal was to write an easy-to-write and easy-to-read set of
-drivers based on the skystar2.c and other information.
-
-Remark: flexcop-pci.c was a copy of skystar2.c, but every line has been
-touched and rewritten.
-
-History & News
-==============
-  2005-04-01 - correct USB ISOC transfers (thanks to Vadim Catana)
-
-
-
-
-General coding processing
-=========================
-
-We should proceed as follows (as long as no one complains):
-
-0) Think before start writing code!
-
-1) rewriting the skystar2.c with the help of the flexcop register descriptions
-and splitting up the files to a pci-bus-part and a flexcop-part.
-The new driver will be called b2c2-flexcop-pci.ko/b2c2-flexcop-usb.ko for the
-device-specific part and b2c2-flexcop.ko for the common flexcop-functions.
-
-2) Search for errors in the leftover of flexcop-pci.c (compare with pluto2.c
-and other pci drivers)
-
-3) make some beautification (see 'Improvements when rewriting (refactoring) is
-done')
-
-4) Testing the new driver and maybe substitute the skystar2.c with it, to reach
-a wider tester audience.
-
-5) creating an usb-bus-part using the already written flexcop code for the pci
-card.
-
-Idea: create a kernel-object for the flexcop and export all important
-functions. This option saves kernel-memory, but maybe a lot of functions have
-to be exported to kernel namespace.
-
-
-Current situation
-=================
-
-0) Done :)
-1) Done (some minor issues left)
-2) Done
-3) Not ready yet, more information is necessary
-4) next to be done (see the table below)
-5) USB driver is working (yes, there are some minor issues)
-
-What seems to be ready?
------------------------
-
-1) Rewriting
-1a) i2c is cut off from the flexcop-pci.c and seems to work
-1b) moved tuner and demod stuff from flexcop-pci.c to flexcop-tuner-fe.c
-1c) moved lnb and diseqc stuff from flexcop-pci.c to flexcop-tuner-fe.c
-1e) eeprom (reading MAC address)
-1d) sram (no dynamic sll size detection (commented out) (using default as JJ told me))
-1f) misc. register accesses for reading parameters (e.g. resetting, revision)
-1g) pid/mac filter (flexcop-hw-filter.c)
-1i) dvb-stuff initialization in flexcop.c (done)
-1h) dma stuff (now just using the size-irq, instead of all-together, to be done)
-1j) remove flexcop initialization from flexcop-pci.c completely (done)
-1l) use a well working dma IRQ method (done, see 'Known bugs and problems and TODO')
-1k) cleanup flexcop-files (remove unused EXPORT_SYMBOLs, make static from
-non-static where possible, moved code to proper places)
-
-2) Search for errors in the leftover of flexcop-pci.c (partially done)
-5a) add MAC address reading
-5c) feeding of ISOC data to the software demux (format of the isochronous data
-and speed optimization, no real error) (thanks to Vadim Catana)
-
-What to do in the near future?
---------------------------------------
-(no special order here)
-
-5) USB driver
-5b) optimize isoc-transfer (submitting/killing isoc URBs when transfer is starting)
-
-Testing changes
----------------
-
-O             = item is working
-P             = item is partially working
-X             = item is not working
-N             = item does not apply here
-<empty field> = item need to be examined
-
-       | PCI                               | USB
-item   | mt352 | nxt2002 | stv0299 | mt312 | mt352 | nxt2002 | stv0299 | mt312
--------+-------+---------+---------+-------+-------+---------+---------+-------
-1a)    | O     |         |         |       | N     | N       | N       | N
-1b)    | O     |         |         |       |       |         | O       |
-1c)    | N     | N       |         |       | N     | N       | O       |
-1d)    |                 O                 |                 O
-1e)    |                 O                 |                 O
-1f)    |                                   P
-1g)    |                                   O
-1h)    |                 P                 |
-1i)    |                 O                 |                 N
-1j)    |                 O                 |                 N
-1l)    |                 O                 |                 N
-2)     |                 O                 |                 N
-5a)    |                 N                 |                 O
-5b)*   |                 N                 |
-5c)    |                 N                 |                 O
-
-* - not done yet
-
-Known bugs and problems and TODO
---------------------------------
-
-1g/h/l) when pid filtering is enabled on the pci card
-
-DMA usage currently:
-  The DMA is splitted in 2 equal-sized subbuffers. The Flexcop writes to first
-  address and triggers an IRQ when it's full and starts writing to the second
-  address. When the second address is full, the IRQ is triggered again, and
-  the flexcop writes to first address again, and so on.
-  The buffersize of each address is currently 640*188 bytes.
-
-  Problem is, when using hw-pid-filtering and doing some low-bandwidth
-  operation (like scanning) the buffers won't be filled enough to trigger
-  the IRQ. That's why:
-
-  When PID filtering is activated, the timer IRQ is used. Every 1.97 ms the IRQ
-  is triggered.  Is the current write address of DMA1 different to the one
-  during the last IRQ, then the data is passed to the demuxer.
-
-  There is an additional DMA-IRQ-method: packet count IRQ. This isn't
-  implemented correctly yet.
-
-  The solution is to disable HW PID filtering, but I don't know how the DVB
-  API software demux behaves on slow systems with 45MBit/s TS.
-
-Solved bugs :)
---------------
-1g) pid-filtering (somehow pid index 4 and 5 (EMM_PID and ECM_PID) aren't
-working)
-SOLUTION: also index 0 was affected, because net_translation is done for
-these indexes by default
-
-5b) isochronous transfer does only work in the first attempt (for the Sky2PC
-USB, Air2PC is working) SOLUTION: the flexcop was going asleep and never really
-woke up again (don't know if this need fixes, see
-flexcop-fe-tuner.c:flexcop_sleep)
-
-NEWS: when the driver is loaded and unloaded and loaded again (w/o doing
-anything in the while the driver is loaded the first time), no transfers take
-place anymore.
-
-Improvements when rewriting (refactoring) is done
-=================================================
-
-- split sleeping of the flexcop (misc_204.ACPI3_sig = 1;) from lnb_control
-  (enable sleeping for other demods than dvb-s)
-- add support for CableStar (stv0297 Microtune 203x/ALPS) (almost done, incompatibilities with the Nexus-CA)
-
-Debugging
----------
-- add verbose debugging to skystar2.c (dump the reg_dw_data) and compare it
-  with this flexcop, this is important, because i2c is now using the
-  flexcop_ibi_value union from flexcop-reg.h (do you have a better idea for
-  that, please tell us so).
-
-Everything which is identical in the following table, can be put into a common
-flexcop-module.
-
-		  PCI                  USB
--------------------------------------------------------------------------------
-Different:
-Register access:  accessing IO memory  USB control message
-I2C bus:          I2C bus of the FC    USB control message
-Data transfer:    DMA                  isochronous transfer
-EEPROM transfer:  through i2c bus      not clear yet
-
-Identical:
-Streaming:                 accessing registers
-PID Filtering:             accessing registers
-Sram destinations:         accessing registers
-Tuner/Demod:                     I2C bus
-DVB-stuff:            can be written for common use
-
-Acknowledgements (just for the rewriting part)
-================
-
-Bjarne Steinsbo thought a lot in the first place of the pci part for this code
-sharing idea.
-
-Andreas Oberritter for providing a recent PCI initialization template
-(pluto2.c).
-
-Boleslaw Ciesielski for pointing out a problem with firmware loader.
-
-Vadim Catana for correcting the USB transfer.
-
-comments, critics and ideas to linux-dvb@linuxtv.org.

+ 20 - 14
Documentation/dvb/technisat.txt

@@ -1,5 +1,5 @@
-How to set up the Technisat devices
-===================================
+How to set up the Technisat/B2C2 Flexcop devices
+================================================
 
 1) Find out what device you have
 ================================
@@ -16,54 +16,60 @@ DVB: registering frontend 0 (Conexant CX24123/CX24109)...
 
 If the Technisat is the only TV device in your box get rid of unnecessary modules and check this one:
 "Multimedia devices" => "Customise analog and hybrid tuner modules to build"
-In this directory uncheck every driver which is activated there.
+In this directory uncheck every driver which is activated there (except "Simple tuner support" for case 9 only).
 
 Then please activate:
 2a) Main module part:
 
 a.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters"
-b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card OR
+b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card
+OR
 c.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC USB" in case of an USB 1.1 adapter
 d.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Enable debug for the B2C2 FlexCop drivers"
 Notice: d.) is helpful for troubleshooting
 
 2b) Frontend module part:
 
-1.) Revision 2.3:
+1.) SkyStar DVB-S Revision 2.3:
 a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
 b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink VP310/MT312/ZL10313 based"
 
-2.) Revision 2.6:
+2.) SkyStar DVB-S Revision 2.6:
 a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
 b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0299 based"
 
-3.) Revision 2.7:
+3.) SkyStar DVB-S Revision 2.7:
 a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
 b.)"Multimedia devices" => "Customise DVB frontends" => "Samsung S5H1420 based"
 c.)"Multimedia devices" => "Customise DVB frontends" => "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
 d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
 
-4.) Revision 2.8:
+4.) SkyStar DVB-S Revision 2.8:
 a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
 b.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
 c.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24123 based"
 d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
 
-5.) DVB-T card:
+5.) AirStar DVB-T card:
 a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
 b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink MT352 based"
 
-6.) DVB-C card:
+6.) CableStar DVB-C card:
 a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
 b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0297 based"
 
-7.) ATSC card 1st generation:
+7.) AirStar ATSC card 1st generation:
 a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
 b.)"Multimedia devices" => "Customise DVB frontends" => "Broadcom BCM3510"
 
-8.) ATSC card 2nd generation:
+8.) AirStar ATSC card 2nd generation:
 a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
 b.)"Multimedia devices" => "Customise DVB frontends" => "NxtWave Communications NXT2002/NXT2004 based"
-c.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based"
+c.)"Multimedia devices" => "Customise DVB frontends" => "Generic I2C PLL based tuners"
 
-Author: Uwe Bugla <uwe.bugla@gmx.de> December 2008
+9.) AirStar ATSC card 3rd generation:
+a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
+b.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based"
+c.)"Multimedia devices" => "Customise analog and hybrid tuner modules to build" => "Simple tuner support"
+
+Author: Uwe Bugla <uwe.bugla@gmx.de> February 2009

+ 9 - 0
Documentation/feature-removal-schedule.txt

@@ -335,3 +335,12 @@ Why:	In 2.6.18 the Secmark concept was introduced to replace the "compat_net"
 	Secmark, it is time to deprecate the older mechanism and start the
 	process of removing the old code.
 Who:	Paul Moore <paul.moore@hp.com>
+---------------------------
+
+What:	sysfs ui for changing p4-clockmod parameters
+When:	September 2009
+Why:	See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and
+	e088e4c9cdb618675874becb91b2fd581ee707e6.
+	Removal is subject to fixing any remaining bugs in ACPI which may
+	cause the thermal throttling not to happen at the right time.
+Who:	Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com>

+ 1 - 1
Documentation/filesystems/squashfs.txt

@@ -22,7 +22,7 @@ Squashfs filesystem features versus Cramfs:
 
 				Squashfs		Cramfs
 
-Max filesystem size:		2^64			16 MiB
+Max filesystem size:		2^64			256 MiB
 Max file size:			~ 2 TiB			16 MiB
 Max files:			unlimited		unlimited
 Max directories:		unlimited		unlimited

+ 12 - 1
Documentation/filesystems/sysfs-pci.txt

@@ -9,6 +9,7 @@ that support it.  For example, a given bus might look like this:
      |   |-- class
      |   |-- config
      |   |-- device
+     |   |-- enable
      |   |-- irq
      |   |-- local_cpus
      |   |-- resource
@@ -32,6 +33,7 @@ files, each with their own function.
        class		   PCI class (ascii, ro)
        config		   PCI config space (binary, rw)
        device		   PCI device (ascii, ro)
+       enable	           Whether the device is enabled (ascii, rw)
        irq		   IRQ number (ascii, ro)
        local_cpus	   nearby CPU mask (cpumask, ro)
        resource		   PCI resource host addresses (ascii, ro)
@@ -57,10 +59,19 @@ used to do actual device programming from userspace.  Note that some platforms
 don't support mmapping of certain resources, so be sure to check the return
 value from any attempted mmap.
 
+The 'enable' file provides a counter that indicates how many times the device 
+has been enabled.  If the 'enable' file currently returns '4', and a '1' is
+echoed into it, it will then return '5'.  Echoing a '0' into it will decrease
+the count.  Even when it returns to 0, though, some of the initialisation
+may not be reversed.  
+
 The 'rom' file is special in that it provides read-only access to the device's
 ROM file, if available.  It's disabled by default, however, so applications
 should write the string "1" to the file to enable it before attempting a read
-call, and disable it following the access by writing "0" to the file.
+call, and disable it following the access by writing "0" to the file.  Note
+that the device must be enabled for a rom read to return data succesfully.
+In the event a driver is not bound to the device, it can be enabled using the
+'enable' file, documented above.
 
 Accessing legacy resources through sysfs
 ----------------------------------------

+ 28 - 22
Documentation/filesystems/sysfs.txt

@@ -2,8 +2,10 @@
 sysfs - _The_ filesystem for exporting kernel objects. 
 
 Patrick Mochel	<mochel@osdl.org>
+Mike Murphy <mamurph@cs.clemson.edu>
 
-10 January 2003
+Revised:    22 February 2009
+Original:   10 January 2003
 
 
 What it is:
@@ -64,12 +66,13 @@ An attribute definition is simply:
 
 struct attribute {
         char                    * name;
+        struct module		*owner;
         mode_t                  mode;
 };
 
 
-int sysfs_create_file(struct kobject * kobj, struct attribute * attr);
-void sysfs_remove_file(struct kobject * kobj, struct attribute * attr);
+int sysfs_create_file(struct kobject * kobj, const struct attribute * attr);
+void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr);
 
 
 A bare attribute contains no means to read or write the value of the
@@ -80,9 +83,11 @@ a specific object type.
 For example, the driver model defines struct device_attribute like:
 
 struct device_attribute {
-        struct attribute        attr;
-        ssize_t (*show)(struct device * dev, char * buf);
-        ssize_t (*store)(struct device * dev, const char * buf);
+	struct attribute	attr;
+	ssize_t (*show)(struct device *dev, struct device_attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+			 const char *buf, size_t count);
 };
 
 int device_create_file(struct device *, struct device_attribute *);
@@ -90,12 +95,8 @@ void device_remove_file(struct device *, struct device_attribute *);
 
 It also defines this helper for defining device attributes: 
 
-#define DEVICE_ATTR(_name, _mode, _show, _store)      \
-struct device_attribute dev_attr_##_name = {            \
-        .attr = {.name  = __stringify(_name) , .mode   = _mode },      \
-        .show   = _show,                                \
-        .store  = _store,                               \
-};
+#define DEVICE_ATTR(_name, _mode, _show, _store) \
+struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
 
 For example, declaring
 
@@ -107,9 +108,9 @@ static struct device_attribute dev_attr_foo = {
        .attr	= {
 		.name = "foo",
 		.mode = S_IWUSR | S_IRUGO,
+		.show = show_foo,
+		.store = store_foo,
 	},
-	.show = show_foo,
-	.store = store_foo,
 };
 
 
@@ -161,10 +162,12 @@ To read or write attributes, show() or store() methods must be
 specified when declaring the attribute. The method types should be as
 simple as those defined for device attributes:
 
-        ssize_t (*show)(struct device * dev, char * buf);
-        ssize_t (*store)(struct device * dev, const char * buf);
+ssize_t (*show)(struct device * dev, struct device_attribute * attr,
+                char * buf);
+ssize_t (*store)(struct device * dev, struct device_attribute * attr,
+                 const char * buf);
 
-IOW, they should take only an object and a buffer as parameters. 
+IOW, they should take only an object, an attribute, and a buffer as parameters.
 
 
 sysfs allocates a buffer of size (PAGE_SIZE) and passes it to the
@@ -299,14 +302,16 @@ The following interface layers currently exist in sysfs:
 Structure:
 
 struct device_attribute {
-        struct attribute        attr;
-        ssize_t (*show)(struct device * dev, char * buf);
-        ssize_t (*store)(struct device * dev, const char * buf);
+	struct attribute	attr;
+	ssize_t (*show)(struct device *dev, struct device_attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+			 const char *buf, size_t count);
 };
 
 Declaring:
 
-DEVICE_ATTR(_name, _str, _mode, _show, _store);
+DEVICE_ATTR(_name, _mode, _show, _store);
 
 Creation/Removal:
 
@@ -342,7 +347,8 @@ Structure:
 struct driver_attribute {
         struct attribute        attr;
         ssize_t (*show)(struct device_driver *, char * buf);
-        ssize_t (*store)(struct device_driver *, const char * buf);
+        ssize_t (*store)(struct device_driver *, const char * buf,
+                         size_t count);
 };
 
 Declaring:

+ 101 - 0
Documentation/hwmon/hpfall.c

@@ -0,0 +1,101 @@
+/* Disk protection for HP machines.
+ *
+ * Copyright 2008 Eric Piel
+ * Copyright 2009 Pavel Machek <pavel@suse.cz>
+ *
+ * GPLv2.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+#include <signal.h>
+
+void write_int(char *path, int i)
+{
+	char buf[1024];
+	int fd = open(path, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+	sprintf(buf, "%d", i);
+	if (write(fd, buf, strlen(buf)) != strlen(buf)) {
+		perror("write");
+		exit(1);
+	}
+	close(fd);
+}
+
+void set_led(int on)
+{
+	write_int("/sys/class/leds/hp::hddprotect/brightness", on);
+}
+
+void protect(int seconds)
+{
+	write_int("/sys/block/sda/device/unload_heads", seconds*1000);
+}
+
+int on_ac(void)
+{
+//	/sys/class/power_supply/AC0/online
+}
+
+int lid_open(void)
+{
+//	/proc/acpi/button/lid/LID/state
+}
+
+void ignore_me(void)
+{
+	protect(0);
+	set_led(0);
+
+}
+
+int main(int argc, char* argv[])
+{
+       int fd, ret;
+
+       fd = open("/dev/freefall", O_RDONLY);
+       if (fd < 0) {
+               perror("open");
+               return EXIT_FAILURE;
+       }
+
+	signal(SIGALRM, ignore_me);
+
+       for (;;) {
+	       unsigned char count;
+
+               ret = read(fd, &count, sizeof(count));
+	       alarm(0);
+	       if ((ret == -1) && (errno == EINTR)) {
+		       /* Alarm expired, time to unpark the heads */
+		       continue;
+	       }
+
+               if (ret != sizeof(count)) {
+                       perror("read");
+                       break;
+               }
+
+	       protect(21);
+	       set_led(1);
+	       if (1 || on_ac() || lid_open()) {
+		       alarm(2);
+	       } else {
+		       alarm(20);
+	       }
+       }
+
+       close(fd);
+       return EXIT_SUCCESS;
+}

+ 8 - 0
Documentation/hwmon/lis3lv02d

@@ -33,6 +33,14 @@ rate - reports the sampling rate of the accelerometer device in HZ
 This driver also provides an absolute input class device, allowing
 the laptop to act as a pinball machine-esque joystick.
 
+Another feature of the driver is misc device called "freefall" that
+acts similar to /dev/rtc and reacts on free-fall interrupts received
+from the device. It supports blocking operations, poll/select and
+fasync operation modes. You must read 1 bytes from the device.  The
+result is number of free-fall interrupts since the last successful
+read (or 255 if number of interrupts would not fit).
+
+
 Axes orientation
 ----------------
 

+ 4 - 3
Documentation/kernel-doc-nano-HOWTO.txt

@@ -43,7 +43,8 @@ Only comments so marked will be considered by the kernel-doc scripts,
 and any comment so marked must be in kernel-doc format.  Do not use
 "/**" to be begin a comment block unless the comment block contains
 kernel-doc formatted comments.  The closing comment marker for
-kernel-doc comments can be either "*/" or "**/".
+kernel-doc comments can be either "*/" or "**/", but "*/" is
+preferred in the Linux kernel tree.
 
 Kernel-doc comments should be placed just before the function
 or data structure being described.
@@ -63,7 +64,7 @@ Example kernel-doc function comment:
  * comment lines.
  *
  * The longer description can have multiple paragraphs.
- **/
+ */
 
 The first line, with the short description, must be on a single line.
 
@@ -85,7 +86,7 @@ Example kernel-doc data structure comment.
  *		perhaps with more lines and words.
  *
  * Longer description of this structure.
- **/
+ */
 
 The kernel-doc function comments describe each parameter to the
 function, in order, with the @name lines.

+ 9 - 5
Documentation/kernel-parameters.txt

@@ -114,7 +114,7 @@ In addition, the following text indicates that the option:
 Parameters denoted with BOOT are actually interpreted by the boot
 loader, and have no meaning to the kernel directly.
 Do not modify the syntax of boot loader parameters without extreme
-need or coordination with <Documentation/x86/i386/boot.txt>.
+need or coordination with <Documentation/x86/boot.txt>.
 
 There are also arch-specific kernel-parameters not documented here.
 See for example <Documentation/x86/x86_64/boot-options.txt>.
@@ -134,7 +134,7 @@ and is between 256 and 4096 characters. It is defined in the file
 
 	acpi=		[HW,ACPI,X86-64,i386]
 			Advanced Configuration and Power Interface
-			Format: { force | off | ht | strict | noirq }
+			Format: { force | off | ht | strict | noirq | rsdt }
 			force -- enable ACPI if default was off
 			off -- disable ACPI if default was on
 			noirq -- do not use ACPI for IRQ routing
@@ -868,8 +868,10 @@ and is between 256 and 4096 characters. It is defined in the file
 	icn=		[HW,ISDN]
 			Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]]
 
-	ide=		[HW] (E)IDE subsystem
-			Format: ide=nodma or ide=doubler
+	ide-core.nodma=	[HW] (E)IDE subsystem
+			Format: =0.0 to prevent dma on hda, =0.1 hdb =1.0 hdc
+			.vlb_clock .pci_clock .noflush .noprobe .nowerr .cdrom
+			.chs .ignore_cable are additional options
 			See Documentation/ide/ide.txt.
 
 	idebus=		[HW] (E)IDE subsystem - VLB/PCI bus speed
@@ -937,6 +939,8 @@ and is between 256 and 4096 characters. It is defined in the file
 
 
 	intel_iommu=	[DMAR] Intel IOMMU driver (DMAR) option
+		on
+			Enable intel iommu driver.
 		off
 			Disable intel iommu driver.
 		igfx_off [Default Off]
@@ -2447,7 +2451,7 @@ and is between 256 and 4096 characters. It is defined in the file
 			See Documentation/fb/modedb.txt.
 
 	vga=		[BOOT,X86-32] Select a particular video mode
-			See Documentation/x86/i386/boot.txt and
+			See Documentation/x86/boot.txt and
 			Documentation/svga.txt.
 			Use vga=ask for menu.
 			This is actually a boot loader parameter; the value is

+ 35 - 0
Documentation/networking/ipv6.txt

@@ -0,0 +1,35 @@
+
+Options for the ipv6 module are supplied as parameters at load time.
+
+Module options may be given as command line arguments to the insmod
+or modprobe command, but are usually specified in either the
+/etc/modules.conf or /etc/modprobe.conf configuration file, or in a
+distro-specific configuration file.
+
+The available ipv6 module parameters are listed below.  If a parameter
+is not specified the default value is used.
+
+The parameters are as follows:
+
+disable
+
+	Specifies whether to load the IPv6 module, but disable all
+	its functionality.  This might be used when another module
+	has a dependency on the IPv6 module being loaded, but no
+	IPv6 addresses or operations are desired.
+
+	The possible values and their effects are:
+
+	0
+		IPv6 is enabled.
+
+		This is the default value.
+
+	1
+		IPv6 is disabled.
+
+		No IPv6 addresses will be added to interfaces, and
+		it will not be possible to open an IPv6 socket.
+
+		A reboot is required to enable IPv6.
+

+ 5 - 6
Documentation/scsi/cxgb3i.txt

@@ -4,7 +4,7 @@ Introduction
 ============
 
 The Chelsio T3 ASIC based Adapters (S310, S320, S302, S304, Mezz cards, etc.
-series of products) supports iSCSI acceleration and iSCSI Direct Data Placement
+series of products) support iSCSI acceleration and iSCSI Direct Data Placement
 (DDP) where the hardware handles the expensive byte touching operations, such
 as CRC computation and verification, and direct DMA to the final host memory
 destination:
@@ -31,9 +31,9 @@ destination:
 	  the TCP segments onto the wire. It handles TCP retransmission if
 	  needed.
 
-	  On receving, S3 h/w recovers the iSCSI PDU by reassembling TCP
+	  On receiving, S3 h/w recovers the iSCSI PDU by reassembling TCP
 	  segments, separating the header and data, calculating and verifying
-	  the digests, then forwards the header to the host. The payload data,
+	  the digests, then forwarding the header to the host. The payload data,
 	  if possible, will be directly placed into the pre-posted host DDP
 	  buffer. Otherwise, the payload data will be sent to the host too.
 
@@ -68,9 +68,8 @@ The following steps need to be taken to accelerates the open-iscsi initiator:
 	sure the ip address is unique in the network.
 
 3. edit /etc/iscsi/iscsid.conf
-   The default setting for MaxRecvDataSegmentLength (131072) is too big,
-   replace "node.conn[0].iscsi.MaxRecvDataSegmentLength" to be a value no
-   bigger than 15360 (for example 8192):
+   The default setting for MaxRecvDataSegmentLength (131072) is too big;
+   replace with a value no bigger than 15360 (for example 8192):
 
 	node.conn[0].iscsi.MaxRecvDataSegmentLength = 8192
 

+ 2 - 4
Documentation/tracers/mmiotrace.txt

@@ -78,12 +78,10 @@ to view your kernel log and look for "mmiotrace has lost events" warning. If
 events were lost, the trace is incomplete. You should enlarge the buffers and
 try again. Buffers are enlarged by first seeing how large the current buffers
 are:
-$ cat /debug/tracing/trace_entries
+$ cat /debug/tracing/buffer_size_kb
 gives you a number. Approximately double this number and write it back, for
 instance:
-$ echo 0 > /debug/tracing/tracing_enabled
-$ echo 128000 > /debug/tracing/trace_entries
-$ echo 1 > /debug/tracing/tracing_enabled
+$ echo 128000 > /debug/tracing/buffer_size_kb
 Then start again from the top.
 
 If you are doing a trace for a driver project, e.g. Nouveau, you should also

+ 29 - 14
MAINTAINERS

@@ -692,6 +692,13 @@ M:	kernel@wantstofly.org
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 S:	Maintained
 
+ARM/NUVOTON W90X900 ARM ARCHITECTURE
+P:      Wan ZongShun
+M:      mcuos.com@gmail.com
+L:      linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+W:      http://www.mcuos.com
+S:      Maintained
+
 ARPD SUPPORT
 P:	Jonathan Layes
 L:	netdev@vger.kernel.org
@@ -1202,6 +1209,8 @@ S:	Supported
 CONTROL GROUPS (CGROUPS)
 P:	Paul Menage
 M:	menage@google.com
+P:	Li Zefan
+M:	lizf@cn.fujitsu.com
 L:	containers@lists.linux-foundation.org
 S:	Maintained
 
@@ -1903,10 +1912,10 @@ W:	http://gigaset307x.sourceforge.net/
 S:	Maintained
 
 HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
-P:	Robert Love
-M:	rlove@rlove.org
-M:	linux-kernel@vger.kernel.org
-W:	http://www.kernel.org/pub/linux/kernel/people/rml/hdaps/
+P:	Frank Seidel
+M:	frank@f-seidel.de
+L:	lm-sensors@lm-sensors.org
+W:	http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
 S:	Maintained
 
 GSPCA FINEPIX SUBDRIVER
@@ -1999,7 +2008,7 @@ S:	Maintained
 
 HIBERNATION (aka Software Suspend, aka swsusp)
 P:	Pavel Machek
-M:	pavel@suse.cz
+M:	pavel@ucw.cz
 P:	Rafael J. Wysocki
 M:	rjw@sisk.pl
 L:	linux-pm@lists.linux-foundation.org
@@ -2455,7 +2464,7 @@ S:	Maintained
 
 ISDN SUBSYSTEM
 P:	Karsten Keil
-M:	kkeil@suse.de
+M:	isdn@linux-pingi.de
 L:	isdn4linux@listserv.isdn4linux.de (subscribers-only)
 W:	http://www.isdn4linux.de
 T:	git kernel.org:/pub/scm/linux/kernel/kkeil/isdn-2.6.git
@@ -3325,8 +3334,8 @@ P:	Jeremy Fitzhardinge
 M:	jeremy@xensource.com
 P:	Chris Wright
 M:	chrisw@sous-sol.org
-P:	Zachary Amsden
-M:	zach@vmware.com
+P:	Alok Kataria
+M:	akataria@vmware.com
 P:	Rusty Russell
 M:	rusty@rustcorp.com.au
 L:	virtualization@lists.osdl.org
@@ -3537,6 +3546,12 @@ S:	Maintained
 PXA MMCI DRIVER
 S:	Orphan
 
+PXA RTC DRIVER
+P:	Robert Jarzmik
+M:	robert.jarzmik@free.fr
+L:	rtc-linux@googlegroups.com
+S:	Maintained
+
 QLOGIC QLA2XXX FC-SCSI DRIVER
 P:	Andrew Vasquez
 M:	linux-driver@qlogic.com
@@ -4164,7 +4179,7 @@ SUSPEND TO RAM
 P:	Len Brown
 M:	len.brown@intel.com
 P:	Pavel Machek
-M:	pavel@suse.cz
+M:	pavel@ucw.cz
 P:	Rafael J. Wysocki
 M:	rjw@sisk.pl
 L:	linux-pm@lists.linux-foundation.org
@@ -4285,8 +4300,8 @@ P:	Rajiv Andrade
 M:	srajiv@linux.vnet.ibm.com
 W:	http://tpmdd.sourceforge.net
 P:	Marcel Selhorst
-M:	tpm@selhorst.net
-W:	http://www.prosec.rub.de/tpm/
+M:	m.selhorst@sirrix.com
+W:	http://www.sirrix.com
 L:	tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
 S:	Maintained
 
@@ -4916,11 +4931,11 @@ L:	zd1211-devs@lists.sourceforge.net (subscribers-only)
 S:	Maintained
 
 ZR36067 VIDEO FOR LINUX DRIVER
-P:	Ronald Bultje
-M:	rbultje@ronald.bitfreak.net
 L:	mjpeg-users@lists.sourceforge.net
+L:	linux-media@vger.kernel.org
 W:	http://mjpeg.sourceforge.net/driver-zoran/
-S:	Maintained
+T:	Mercurial http://linuxtv.org/hg/v4l-dvb
+S:	Odd Fixes
 
 ZS DECSTATION Z85C30 SERIAL DRIVER
 P:	Maciej W. Rozycki

+ 2 - 2
Makefile

@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 29
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc7
 NAME = Erotic Pickled Herring
 
 # *DOCUMENTATION*
@@ -389,6 +389,7 @@ PHONY += outputmakefile
 # output directory.
 outputmakefile:
 ifneq ($(KBUILD_SRC),)
+	$(Q)ln -fsn $(srctree) source
 	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
 	    $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
 endif
@@ -946,7 +947,6 @@ ifneq ($(KBUILD_SRC),)
 	    mkdir -p include2;                                          \
 	    ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm;     \
 	fi
-	ln -fsn $(srctree) source
 endif
 
 # prepare2 creates a makefile if using a separate output directory

+ 1 - 1
README

@@ -188,7 +188,7 @@ CONFIGURING the kernel:
 			   values to random values.
 
    You can find more information on using the Linux kernel config tools
-   in Documentation/kbuild/make-configs.txt.
+   in Documentation/kbuild/kconfig.txt.
 
 	NOTES on "make config":
 	- having unnecessary drivers will make the kernel bigger, and can

+ 4 - 4
arch/alpha/kernel/process.c

@@ -93,8 +93,8 @@ common_shutdown_1(void *generic_ptr)
 	if (cpuid != boot_cpuid) {
 		flags |= 0x00040000UL; /* "remain halted" */
 		*pflags = flags;
-		cpu_clear(cpuid, cpu_present_map);
-		cpu_clear(cpuid, cpu_possible_map);
+		set_cpu_present(cpuid, false);
+		set_cpu_possible(cpuid, false);
 		halt();
 	}
 #endif
@@ -120,8 +120,8 @@ common_shutdown_1(void *generic_ptr)
 
 #ifdef CONFIG_SMP
 	/* Wait for the secondaries to halt. */
-	cpu_clear(boot_cpuid, cpu_present_map);
-	cpu_clear(boot_cpuid, cpu_possible_map);
+	set_cpu_present(boot_cpuid, false);
+	set_cpu_possible(boot_cpuid, false);
 	while (cpus_weight(cpu_present_map))
 		barrier();
 #endif

+ 6 - 6
arch/alpha/kernel/smp.c

@@ -120,12 +120,12 @@ void __cpuinit
 smp_callin(void)
 {
 	int cpuid = hard_smp_processor_id();
-	cpumask_t mask = cpu_online_map;
 
-	if (cpu_test_and_set(cpuid, mask)) {
+	if (cpu_online(cpuid)) {
 		printk("??, cpu 0x%x already present??\n", cpuid);
 		BUG();
 	}
+	set_cpu_online(cpuid, true);
 
 	/* Turn on machine checks.  */
 	wrmces(7);
@@ -436,8 +436,8 @@ setup_smp(void)
 				((char *)cpubase + i*hwrpb->processor_size);
 			if ((cpu->flags & 0x1cc) == 0x1cc) {
 				smp_num_probed++;
-				cpu_set(i, cpu_possible_map);
-				cpu_set(i, cpu_present_map);
+				set_cpu_possible(i, true);
+				set_cpu_present(i, true);
 				cpu->pal_revision = boot_cpu_palrev;
 			}
 
@@ -470,8 +470,8 @@ smp_prepare_cpus(unsigned int max_cpus)
 
 	/* Nothing to do on a UP box, or when told not to.  */
 	if (smp_num_probed == 1 || max_cpus == 0) {
-		cpu_possible_map = cpumask_of_cpu(boot_cpuid);
-		cpu_present_map = cpumask_of_cpu(boot_cpuid);
+		init_cpu_possible(cpumask_of(boot_cpuid));
+		init_cpu_present(cpumask_of(boot_cpuid));
 		printk(KERN_INFO "SMP mode deactivated.\n");
 		return;
 	}

+ 1 - 1
arch/arm/configs/at91sam9260ek_defconfig

@@ -608,7 +608,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91SAM9_WATCHDOG=y
+CONFIG_AT91SAM9X_WATCHDOG=y
 
 #
 # USB-based Watchdog Cards

+ 1 - 1
arch/arm/configs/at91sam9261ek_defconfig

@@ -700,7 +700,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91SAM9_WATCHDOG=y
+CONFIG_AT91SAM9X_WATCHDOG=y
 
 #
 # USB-based Watchdog Cards

+ 1 - 1
arch/arm/configs/at91sam9263ek_defconfig

@@ -710,7 +710,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91SAM9_WATCHDOG=y
+CONFIG_AT91SAM9X_WATCHDOG=y
 
 #
 # USB-based Watchdog Cards

+ 1 - 1
arch/arm/configs/at91sam9rlek_defconfig

@@ -606,7 +606,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT91SAM9_WATCHDOG=y
+CONFIG_AT91SAM9X_WATCHDOG=y
 
 #
 # Sonics Silicon Backplane

+ 1 - 1
arch/arm/configs/qil-a9260_defconfig

@@ -727,7 +727,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_AT91SAM9_WATCHDOG is not set
+# CONFIG_AT91SAM9X_WATCHDOG is not set
 
 #
 # USB-based Watchdog Cards

+ 2 - 2
arch/arm/kernel/elf.c

@@ -74,9 +74,9 @@ EXPORT_SYMBOL(elf_set_personality);
  */
 int arm_elf_read_implies_exec(const struct elf32_hdr *x, int executable_stack)
 {
-	if (executable_stack != EXSTACK_ENABLE_X)
+	if (executable_stack != EXSTACK_DISABLE_X)
 		return 1;
-	if (cpu_architecture() <= CPU_ARCH_ARMv6)
+	if (cpu_architecture() < CPU_ARCH_ARMv6)
 		return 1;
 	return 0;
 }

+ 2 - 2
arch/arm/kernel/machine_kexec.c

@@ -13,8 +13,8 @@
 #include <asm/cacheflush.h>
 #include <asm/mach-types.h>
 
-const extern unsigned char relocate_new_kernel[];
-const extern unsigned int relocate_new_kernel_size;
+extern const unsigned char relocate_new_kernel[];
+extern const unsigned int relocate_new_kernel_size;
 
 extern void setup_mm_for_reboot(char mode);
 

+ 7 - 6
arch/arm/kernel/setup.c

@@ -234,12 +234,13 @@ static void __init cacheid_init(void)
 	unsigned int cachetype = read_cpuid_cachetype();
 	unsigned int arch = cpu_architecture();
 
-	if (arch >= CPU_ARCH_ARMv7) {
-		cacheid = CACHEID_VIPT_NONALIASING;
-		if ((cachetype & (3 << 14)) == 1 << 14)
-			cacheid |= CACHEID_ASID_TAGGED;
-	} else if (arch >= CPU_ARCH_ARMv6) {
-		if (cachetype & (1 << 23))
+	if (arch >= CPU_ARCH_ARMv6) {
+		if ((cachetype & (7 << 29)) == 4 << 29) {
+			/* ARMv7 register format */
+			cacheid = CACHEID_VIPT_NONALIASING;
+			if ((cachetype & (3 << 14)) == 1 << 14)
+				cacheid |= CACHEID_ASID_TAGGED;
+		} else if (cachetype & (1 << 23))
 			cacheid = CACHEID_VIPT_ALIASING;
 		else
 			cacheid = CACHEID_VIPT_NONALIASING;

+ 1 - 1
arch/arm/mach-at91/at91cap9_devices.c

@@ -697,7 +697,7 @@ static void __init at91_add_device_rtt(void)
  *  Watchdog
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
 static struct platform_device at91cap9_wdt_device = {
 	.name		= "at91_wdt",
 	.id		= -1,

+ 1 - 1
arch/arm/mach-at91/at91sam9260_devices.c

@@ -643,7 +643,7 @@ static void __init at91_add_device_rtt(void)
  *  Watchdog
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
 static struct platform_device at91sam9260_wdt_device = {
 	.name		= "at91_wdt",
 	.id		= -1,

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

@@ -621,7 +621,7 @@ static void __init at91_add_device_rtt(void)
  *  Watchdog
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
 static struct platform_device at91sam9261_wdt_device = {
 	.name		= "at91_wdt",
 	.id		= -1,

+ 106 - 1
arch/arm/mach-at91/at91sam9263_devices.c

@@ -347,6 +347,111 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
 void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
 #endif
 
+/* --------------------------------------------------------------------
+ *  Compact Flash (PCMCIA or IDE)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) || \
+    defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE)
+
+static struct at91_cf_data cf0_data;
+
+static struct resource cf0_resources[] = {
+	[0] = {
+		.start	= AT91_CHIPSELECT_4,
+		.end	= AT91_CHIPSELECT_4 + SZ_256M - 1,
+		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT,
+	}
+};
+
+static struct platform_device cf0_device = {
+	.id		= 0,
+	.dev		= {
+				.platform_data	= &cf0_data,
+	},
+	.resource	= cf0_resources,
+	.num_resources	= ARRAY_SIZE(cf0_resources),
+};
+
+static struct at91_cf_data cf1_data;
+
+static struct resource cf1_resources[] = {
+	[0] = {
+		.start	= AT91_CHIPSELECT_5,
+		.end	= AT91_CHIPSELECT_5 + SZ_256M - 1,
+		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT,
+	}
+};
+
+static struct platform_device cf1_device = {
+	.id		= 1,
+	.dev		= {
+				.platform_data	= &cf1_data,
+	},
+	.resource	= cf1_resources,
+	.num_resources	= ARRAY_SIZE(cf1_resources),
+};
+
+void __init at91_add_device_cf(struct at91_cf_data *data)
+{
+	unsigned long ebi0_csa;
+	struct platform_device *pdev;
+
+	if (!data)
+		return;
+
+	/*
+	 * assign CS4 or CS5 to SMC with Compact Flash logic support,
+	 * we assume SMC timings are configured by board code,
+	 * except True IDE where timings are controlled by driver
+	 */
+	ebi0_csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
+	switch (data->chipselect) {
+	case 4:
+		at91_set_A_periph(AT91_PIN_PD6, 0);  /* EBI0_NCS4/CFCS0 */
+		ebi0_csa |= AT91_MATRIX_EBI0_CS4A_SMC_CF1;
+		cf0_data = *data;
+		pdev = &cf0_device;
+		break;
+	case 5:
+		at91_set_A_periph(AT91_PIN_PD7, 0);  /* EBI0_NCS5/CFCS1 */
+		ebi0_csa |= AT91_MATRIX_EBI0_CS5A_SMC_CF2;
+		cf1_data = *data;
+		pdev = &cf1_device;
+		break;
+	default:
+		printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n",
+		       data->chipselect);
+		return;
+	}
+	at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa);
+
+	if (data->det_pin) {
+		at91_set_gpio_input(data->det_pin, 1);
+		at91_set_deglitch(data->det_pin, 1);
+	}
+
+	if (data->irq_pin) {
+		at91_set_gpio_input(data->irq_pin, 1);
+		at91_set_deglitch(data->irq_pin, 1);
+	}
+
+	if (data->vcc_pin)
+		/* initially off */
+		at91_set_gpio_output(data->vcc_pin, 0);
+
+	/* enable EBI controlled pins */
+	at91_set_A_periph(AT91_PIN_PD5, 1);  /* NWAIT */
+	at91_set_A_periph(AT91_PIN_PD8, 0);  /* CFCE1 */
+	at91_set_A_periph(AT91_PIN_PD9, 0);  /* CFCE2 */
+	at91_set_A_periph(AT91_PIN_PD14, 0); /* CFNRW */
+
+	pdev->name = (data->flags & AT91_CF_TRUE_IDE) ? "at91_ide" : "at91_cf";
+	platform_device_register(pdev);
+}
+#else
+void __init at91_add_device_cf(struct at91_cf_data *data) {}
+#endif
 
 /* --------------------------------------------------------------------
  *  NAND / SmartMedia
@@ -854,7 +959,7 @@ static void __init at91_add_device_rtt(void)
  *  Watchdog
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
 static struct platform_device at91sam9263_wdt_device = {
 	.name		= "at91_wdt",
 	.id		= -1,

+ 1 - 1
arch/arm/mach-at91/at91sam9rl_devices.c

@@ -609,7 +609,7 @@ static void __init at91_add_device_rtt(void)
  *  Watchdog
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
 static struct platform_device at91sam9rl_wdt_device = {
 	.name		= "at91_wdt",
 	.id		= -1,

+ 65 - 4
arch/arm/mach-at91/gpio.c

@@ -437,7 +437,68 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 
 /*--------------------------------------------------------------------------*/
 
-/* This lock class tells lockdep that GPIO irqs are in a different
+#ifdef CONFIG_DEBUG_FS
+
+static int at91_gpio_show(struct seq_file *s, void *unused)
+{
+	int bank, j;
+
+	/* print heading */
+	seq_printf(s, "Pin\t");
+	for (bank = 0; bank < gpio_banks; bank++) {
+		seq_printf(s, "PIO%c\t", 'A' + bank);
+	};
+	seq_printf(s, "\n\n");
+
+	/* print pin status */
+	for (j = 0; j < 32; j++) {
+		seq_printf(s, "%i:\t", j);
+
+		for (bank = 0; bank < gpio_banks; bank++) {
+			unsigned	pin  = PIN_BASE + (32 * bank) + j;
+			void __iomem	*pio = pin_to_controller(pin);
+			unsigned	mask = pin_to_mask(pin);
+
+			if (__raw_readl(pio + PIO_PSR) & mask)
+				seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0");
+			else
+				seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A");
+
+			seq_printf(s, "\t");
+		}
+
+		seq_printf(s, "\n");
+	}
+
+	return 0;
+}
+
+static int at91_gpio_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, at91_gpio_show, NULL);
+}
+
+static const struct file_operations at91_gpio_operations = {
+	.open		= at91_gpio_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init at91_gpio_debugfs_init(void)
+{
+	/* /sys/kernel/debug/at91_gpio */
+	(void) debugfs_create_file("at91_gpio", S_IFREG | S_IRUGO, NULL, NULL, &at91_gpio_operations);
+	return 0;
+}
+postcore_initcall(at91_gpio_debugfs_init);
+
+#endif
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ * This lock class tells lockdep that GPIO irqs are in a different
  * category than their parents, so it won't report false recursion.
  */
 static struct lock_class_key gpio_lock_class;
@@ -456,9 +517,6 @@ void __init at91_gpio_irq_setup(void)
 		unsigned	id = this->bank->id;
 		unsigned	i;
 
-		/* enable PIO controller's clock */
-		clk_enable(this->bank->clock);
-
 		__raw_writel(~0, this->regbase + PIO_IDR);
 
 		for (i = 0, pin = this->chip.base; i < 32; i++, pin++) {
@@ -589,6 +647,9 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
 		at91_gpio->regbase = at91_gpio->bank->offset +
 			(void __iomem *)AT91_VA_BASE_SYS;
 
+		/* enable PIO controller's clock */
+		clk_enable(at91_gpio->bank->clock);
+
 		/* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
 		if (last && last->bank->id == at91_gpio->bank->id)
 			last->next = at91_gpio;

+ 4 - 0
arch/arm/mach-at91/include/mach/board.h

@@ -56,6 +56,9 @@ struct at91_cf_data {
 	u8	vcc_pin;		/* power switching */
 	u8	rst_pin;		/* card reset */
 	u8	chipselect;		/* EBI Chip Select number */
+	u8	flags;
+#define AT91_CF_TRUE_IDE	0x01
+#define AT91_IDE_SWAP_A0_A2	0x02
 };
 extern void __init at91_add_device_cf(struct at91_cf_data *data);
 
@@ -93,6 +96,7 @@ struct atmel_nand_data {
 	u8		enable_pin;	/* chip enable */
 	u8		det_pin;	/* card detect */
 	u8		rdy_pin;	/* ready/busy */
+	u8              rdy_pin_active_low;     /* rdy_pin value is inverted */
 	u8		ale;		/* address line number connected to ALE */
 	u8		cle;		/* address line number connected to CLE */
 	u8		bus_width_16;	/* buswidth is 16 bit */

+ 0 - 1
arch/arm/mach-at91/pm.c

@@ -332,7 +332,6 @@ static int at91_pm_enter(suspend_state_t state)
 			at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR));
 
 error:
-	sdram_selfrefresh_disable();
 	target_state = PM_SUSPEND_ON;
 	at91_irq_resume();
 	at91_gpio_resume();

+ 3 - 3
arch/arm/mach-davinci/board-evm.c

@@ -311,6 +311,9 @@ evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
 	gpio_request(gpio + 7, "nCF_SEL");
 	gpio_direction_output(gpio + 7, 1);
 
+	/* irlml6401 sustains over 3A, switches 5V in under 8 msec */
+	setup_usb(500, 8);
+
 	return 0;
 }
 
@@ -417,9 +420,6 @@ static __init void davinci_evm_init(void)
 	platform_add_devices(davinci_evm_devices,
 			     ARRAY_SIZE(davinci_evm_devices));
 	evm_init_i2c();
-
-	/* irlml6401 sustains over 3A, switches 5V in under 8 msec */
-	setup_usb(500, 8);
 }
 
 static __init void davinci_evm_irq_init(void)

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

@@ -230,6 +230,11 @@ static struct clk davinci_clks[] = {
 		.rate = &commonrate,
 		.lpsc = DAVINCI_LPSC_GPIO,
 	},
+	{
+		.name = "usb",
+		.rate = &commonrate,
+		.lpsc = DAVINCI_LPSC_USB,
+	},
 	{
 		.name = "AEMIFCLK",
 		.rate = &commonrate,

+ 1 - 0
arch/arm/mach-davinci/usb.c

@@ -47,6 +47,7 @@ static struct musb_hdrc_platform_data usb_data = {
 #elif defined(CONFIG_USB_MUSB_HOST)
 	.mode           = MUSB_HOST,
 #endif
+	.clock		= "usb",
 	.config		= &musb_config,
 };
 

+ 0 - 3
arch/arm/mach-ep93xx/include/mach/gesbc9312.h

@@ -1,3 +0,0 @@
-/*
- * arch/arm/mach-ep93xx/include/mach/gesbc9312.h
- */

+ 0 - 1
arch/arm/mach-ep93xx/include/mach/hardware.h

@@ -10,7 +10,6 @@
 
 #include "platform.h"
 
-#include "gesbc9312.h"
 #include "ts72xx.h"
 
 #endif

+ 1 - 1
arch/arm/mach-kirkwood/irq.c

@@ -42,7 +42,7 @@ void __init kirkwood_init_irq(void)
 	writel(0, GPIO_EDGE_CAUSE(32));
 
 	for (i = IRQ_KIRKWOOD_GPIO_START; i < NR_IRQS; i++) {
-		set_irq_chip(i, &orion_gpio_irq_level_chip);
+		set_irq_chip(i, &orion_gpio_irq_chip);
 		set_irq_handler(i, handle_level_irq);
 		irq_desc[i].status |= IRQ_LEVEL;
 		set_irq_flags(i, IRQF_VALID);

+ 1 - 1
arch/arm/mach-mv78xx0/irq.c

@@ -40,7 +40,7 @@ void __init mv78xx0_init_irq(void)
 	writel(0, GPIO_EDGE_CAUSE(0));
 
 	for (i = IRQ_MV78XX0_GPIO_START; i < NR_IRQS; i++) {
-		set_irq_chip(i, &orion_gpio_irq_level_chip);
+		set_irq_chip(i, &orion_gpio_irq_chip);
 		set_irq_handler(i, handle_level_irq);
 		irq_desc[i].status |= IRQ_LEVEL;
 		set_irq_flags(i, IRQF_VALID);

+ 6 - 1
arch/arm/mach-mx1/Kconfig

@@ -1,6 +1,6 @@
 if ARCH_MX1
 
-comment "MX1 Platforms"
+comment "MX1 platforms:"
 
 config MACH_MXLADS
 	bool
@@ -11,4 +11,9 @@ config ARCH_MX1ADS
 	help
 	  Say Y here if you are using Motorola MX1ADS/MXLADS boards
 
+config MACH_SCB9328
+	bool "Synertronixx scb9328"
+	help
+	  Say Y here if you are using a Synertronixx scb9328 board
+
 endif

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

@@ -8,3 +8,4 @@ obj-y			+= generic.o clock.o devices.o
 
 # Specific board support
 obj-$(CONFIG_ARCH_MX1ADS) += mx1ads.o
+obj-$(CONFIG_MACH_SCB9328) += scb9328.o

+ 8 - 32
arch/arm/mach-mx1/clock.c

@@ -25,6 +25,7 @@
 
 #include <mach/clock.h>
 #include <mach/hardware.h>
+#include <mach/common.h>
 #include "crm_regs.h"
 
 static int _clk_enable(struct clk *clk)
@@ -87,33 +88,6 @@ static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
 	return clk->parent->set_rate(clk->parent, rate);
 }
 
-/*
- *  get the system pll clock in Hz
- *
- *                  mfi + mfn / (mfd +1)
- *  f = 2 * f_ref * --------------------
- *                        pd + 1
- */
-static unsigned long mx1_decode_pll(unsigned int pll, u32 f_ref)
-{
-	unsigned long long ll;
-	unsigned long quot;
-
-	u32 mfi = (pll >> 10) & 0xf;
-	u32 mfn = pll & 0x3ff;
-	u32 mfd = (pll >> 16) & 0x3ff;
-	u32 pd =  (pll >> 26) & 0xf;
-
-	mfi = mfi <= 5 ? 5 : mfi;
-
-	ll = 2 * (unsigned long long)f_ref *
-		((mfi << 16) + (mfn << 16) / (mfd + 1));
-	quot = (pd + 1) * (1 << 16);
-	ll += quot / 2;
-	do_div(ll, quot);
-	return (unsigned long)ll;
-}
-
 static unsigned long clk16m_get_rate(struct clk *clk)
 {
 	return 16000000;
@@ -188,7 +162,7 @@ static struct clk prem_clk = {
 
 static unsigned long system_clk_get_rate(struct clk *clk)
 {
-	return mx1_decode_pll(__raw_readl(CCM_SPCTL0),
+	return mxc_decode_pll(__raw_readl(CCM_SPCTL0),
 			      clk_get_rate(clk->parent));
 }
 
@@ -200,7 +174,7 @@ static struct clk system_clk = {
 
 static unsigned long mcu_clk_get_rate(struct clk *clk)
 {
-	return mx1_decode_pll(__raw_readl(CCM_MPCTL0),
+	return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
 			      clk_get_rate(clk->parent));
 }
 
@@ -488,7 +462,7 @@ static struct clk clko_clk = {
 };
 
 static struct clk dma_clk = {
-	.name = "dma_clk",
+	.name = "dma",
 	.parent = &hclk,
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
@@ -539,7 +513,7 @@ static struct clk gpt_clk = {
 };
 
 static struct clk uart_clk = {
-	.name = "uart_clk",
+	.name = "uart",
 	.parent = &perclk[0],
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
@@ -621,7 +595,7 @@ static struct clk *mxc_clks[] = {
 	&rtc_clk,
 };
 
-int __init mxc_clocks_init(unsigned long fref)
+int __init mx1_clocks_init(unsigned long fref)
 {
 	struct clk **clkp;
 	unsigned int reg;
@@ -652,5 +626,7 @@ int __init mxc_clocks_init(unsigned long fref)
 	clk_enable(&hclk);
 	clk_enable(&fclk);
 
+	mxc_timer_init(&gpt_clk);
+
 	return 0;
 }

+ 3 - 0
arch/arm/mach-mx1/devices.c

@@ -23,8 +23,11 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <mach/irqs.h>
 #include <mach/hardware.h>
 
+#include "devices.h"
+
 static struct resource imx_csi_resources[] = {
 	[0] = {
 		.start  = 0x00224000,

+ 65 - 3
arch/arm/mach-mx1/mx1ads.c

@@ -16,6 +16,8 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -24,7 +26,11 @@
 #include <mach/hardware.h>
 #include <mach/common.h>
 #include <mach/imx-uart.h>
-#include <mach/iomux-mx1-mx2.h>
+#include <mach/irqs.h>
+#ifdef CONFIG_I2C_IMX
+#include <mach/i2c.h>
+#endif
+#include <mach/iomux.h>
 #include "devices.h"
 
 /*
@@ -103,6 +109,55 @@ static struct platform_device flash_device = {
 	.num_resources = 1,
 };
 
+/*
+ * I2C
+ */
+
+#ifdef CONFIG_I2C_IMX
+static int i2c_pins[] = {
+	PA15_PF_I2C_SDA,
+	PA16_PF_I2C_SCL,
+};
+
+static int i2c_init(struct device *dev)
+{
+	return mxc_gpio_setup_multiple_pins(i2c_pins,
+			ARRAY_SIZE(i2c_pins), "I2C");
+}
+
+static void i2c_exit(struct device *dev)
+{
+	mxc_gpio_release_multiple_pins(i2c_pins,
+			ARRAY_SIZE(i2c_pins));
+}
+
+static struct pcf857x_platform_data pcf857x_data[] = {
+	{
+		.gpio_base = 4 * 32,
+	}, {
+		.gpio_base = 4 * 32 + 16,
+	}
+};
+
+static struct imxi2c_platform_data mx1ads_i2c_data = {
+	.bitrate = 100000,
+	.init = i2c_init,
+	.exit = i2c_exit,
+};
+
+static struct i2c_board_info mx1ads_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("pcf857x", 0x22),
+		.type = "pcf8575",
+		.platform_data = &pcf857x_data[0],
+	}, {
+		I2C_BOARD_INFO("pcf857x", 0x24),
+		.type = "pcf8575",
+		.platform_data = &pcf857x_data[1],
+	},
+};
+#endif
+
 /*
  * Board init
  */
@@ -114,12 +169,19 @@ static void __init mx1ads_init(void)
 
 	/* Physmap flash */
 	mxc_register_device(&flash_device, &mx1ads_flash_data);
+
+	/* I2C */
+#ifdef CONFIG_I2C_IMX
+	i2c_register_board_info(0, mx1ads_i2c_devices,
+				ARRAY_SIZE(mx1ads_i2c_devices));
+
+	mxc_register_device(&imx_i2c_device, &mx1ads_i2c_data);
+#endif
 }
 
 static void __init mx1ads_timer_init(void)
 {
-	mxc_clocks_init(32000);
-	mxc_timer_init("gpt_clk");
+	mx1_clocks_init(32000);
 }
 
 struct sys_timer mx1ads_timer = {

+ 160 - 0
arch/arm/mach-mx1/scb9328.c

@@ -0,0 +1,160 @@
+/*
+ * linux/arch/arm/mach-mx1/scb9328.c
+ *
+ * Copyright (c) 2004 Sascha Hauer <saschahauer@web.de>
+ * Copyright (c) 2006-2008 Juergen Beisert <jbeisert@netscape.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/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/interrupt.h>
+#include <linux/dm9000.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux.h>
+
+#include "devices.h"
+
+/*
+ * This scb9328 has a 32MiB flash
+ */
+static struct resource flash_resource = {
+	.start	= IMX_CS0_PHYS,
+	.end	= IMX_CS0_PHYS + (32 * 1024 * 1024) - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data scb_flash_data = {
+	.width  = 2,
+};
+
+static struct platform_device scb_flash_device = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev = {
+		.platform_data = &scb_flash_data,
+	},
+	.resource = &flash_resource,
+	.num_resources = 1,
+};
+
+/*
+ * scb9328 has a DM9000 network controller
+ * connected to CS5, with 16 bit data path
+ * and interrupt connected to GPIO 3
+ */
+
+/*
+ * internal datapath is fixed 16 bit
+ */
+static struct dm9000_plat_data dm9000_platdata = {
+	.flags	= DM9000_PLATF_16BITONLY,
+};
+
+/*
+ * the DM9000 drivers wants two defined address spaces
+ * to gain access to address latch registers and the data path.
+ */
+static struct resource dm9000x_resources[] = {
+	[0] = {
+		.name	= "address area",
+		.start	= IMX_CS5_PHYS,
+		.end	= IMX_CS5_PHYS + 1,
+		.flags	= IORESOURCE_MEM	/* address access */
+	},
+	[1] = {
+		.name	= "data area",
+		.start	= IMX_CS5_PHYS + 4,
+		.end	= IMX_CS5_PHYS + 5,
+		.flags	= IORESOURCE_MEM	/* data access */
+	},
+	[2] = {
+		.start	= IRQ_GPIOC(3),
+		.end	= IRQ_GPIOC(3),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL
+	},
+};
+
+static struct platform_device dm9000x_device = {
+	.name		= "dm9000",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dm9000x_resources),
+	.resource	= dm9000x_resources,
+	.dev		= {
+		.platform_data = &dm9000_platdata,
+	}
+};
+
+static int mxc_uart1_pins[] = {
+	PC9_PF_UART1_CTS,
+	PC10_PF_UART1_RTS,
+	PC11_PF_UART1_TXD,
+	PC12_PF_UART1_RXD,
+};
+
+static int uart1_mxc_init(struct platform_device *pdev)
+{
+	return mxc_gpio_setup_multiple_pins(mxc_uart1_pins,
+			ARRAY_SIZE(mxc_uart1_pins), "UART1");
+}
+
+static int uart1_mxc_exit(struct platform_device *pdev)
+{
+	mxc_gpio_release_multiple_pins(mxc_uart1_pins,
+			ARRAY_SIZE(mxc_uart1_pins));
+	return 0;
+}
+
+static struct imxuart_platform_data uart_pdata = {
+	.init = uart1_mxc_init,
+	.exit = uart1_mxc_exit,
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&scb_flash_device,
+	&dm9000x_device,
+};
+
+/*
+ * scb9328_init - Init the CPU card itself
+ */
+static void __init scb9328_init(void)
+{
+	mxc_register_device(&imx_uart1_device, &uart_pdata);
+
+	printk(KERN_INFO"Scb9328: Adding devices\n");
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init scb9328_timer_init(void)
+{
+	mx1_clocks_init(32000);
+}
+
+static struct sys_timer scb9328_timer = {
+	.init	= scb9328_timer_init,
+};
+
+MACHINE_START(SCB9328, "Synertronixx scb9328")
+    /* Sascha Hauer */
+	.phys_io	= 0x00200000,
+	.io_pg_offst	= ((0xe0200000) >> 18) & 0xfffc,
+	.boot_params	= 0x08000100,
+	.map_io		= mxc_map_io,
+	.init_irq	= mxc_init_irq,
+	.timer		= &scb9328_timer,
+	.init_machine	= scb9328_init,
+MACHINE_END

+ 15 - 5
arch/arm/mach-mx2/Kconfig

@@ -1,14 +1,22 @@
-comment "MX2 family CPU support"
-	depends on ARCH_MX2
+if ARCH_MX2
+
+choice
+	prompt "CPUs:"
+	default MACH_MX21
+
+config MACH_MX21
+	bool "i.MX21 support"
+	help
+	  This enables support for Freescale's MX2 based i.MX21 processor.
 
 config MACH_MX27
 	bool "i.MX27 support"
-	depends on ARCH_MX2
 	help
 	  This enables support for Freescale's MX2 based i.MX27 processor.
 
-comment "MX2 Platforms"
-	depends on ARCH_MX2
+endchoice
+
+comment "MX2 platforms:"
 
 config MACH_MX27ADS
 	bool "MX27ADS platform"
@@ -37,3 +45,5 @@ config MACH_PCM970_BASEBOARD
 	  PCM970 evaluation board.
 
 endchoice
+
+endif

+ 2 - 0
arch/arm/mach-mx2/Makefile

@@ -6,6 +6,8 @@
 
 obj-y	:=  system.o generic.o devices.o serial.o
 
+obj-$(CONFIG_MACH_MX21) += clock_imx21.o
+
 obj-$(CONFIG_MACH_MX27) += cpu_imx27.o
 obj-$(CONFIG_MACH_MX27) += clock_imx27.o
 

+ 7 - 3
arch/arm/mach-mx2/Makefile.boot

@@ -1,3 +1,7 @@
-   zreladdr-y	:= 0xA0008000
-params_phys-y	:= 0xA0000100
-initrd_phys-y	:= 0xA0800000
+zreladdr-$(CONFIG_MACH_MX21)	:= 0xC0008000
+params_phys-$(CONFIG_MACH_MX21)	:= 0xC0000100
+initrd_phys-$(CONFIG_MACH_MX21)	:= 0xC0800000
+
+zreladdr-$(CONFIG_MACH_MX27)	:= 0xA0008000
+params_phys-$(CONFIG_MACH_MX27)	:= 0xA0000100
+initrd_phys-$(CONFIG_MACH_MX27)	:= 0xA0800000

+ 984 - 0
arch/arm/mach-mx2/clock_imx21.c

@@ -0,0 +1,984 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+
+#include <mach/clock.h>
+#include <mach/common.h>
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include "crm_regs.h"
+
+static int _clk_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg |= 1 << clk->enable_shift;
+	__raw_writel(reg, clk->enable_reg);
+	return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg &= ~(1 << clk->enable_shift);
+	__raw_writel(reg, clk->enable_reg);
+}
+
+static int _clk_spll_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(CCM_CSCR);
+	reg |= CCM_CSCR_SPEN;
+	__raw_writel(reg, CCM_CSCR);
+
+	while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
+		;
+	return 0;
+}
+
+static void _clk_spll_disable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(CCM_CSCR);
+	reg &= ~CCM_CSCR_SPEN;
+	__raw_writel(reg, CCM_CSCR);
+}
+
+
+#define CSCR() (__raw_readl(CCM_CSCR))
+#define PCDR0() (__raw_readl(CCM_PCDR0))
+#define PCDR1() (__raw_readl(CCM_PCDR1))
+
+static unsigned long _clk_perclkx_round_rate(struct clk *clk,
+					     unsigned long rate)
+{
+	u32 div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	div = parent_rate / rate;
+	if (parent_rate % rate)
+		div++;
+
+	if (div > 64)
+		div = 64;
+
+	return parent_rate / div;
+}
+
+static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 reg;
+	u32 div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	if (clk->id < 0 || clk->id > 3)
+		return -EINVAL;
+
+	div = parent_rate / rate;
+	if (div > 64 || div < 1 || ((parent_rate / div) != rate))
+		return -EINVAL;
+	div--;
+
+	reg =
+	    __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
+				       (clk->id << 3));
+	reg |= div << (clk->id << 3);
+	__raw_writel(reg, CCM_PCDR1);
+
+	return 0;
+}
+
+static unsigned long _clk_usb_recalc(struct clk *clk)
+{
+	unsigned long usb_pdf;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
+
+	return parent_rate / (usb_pdf + 1U);
+}
+
+static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf)
+{
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	pdf = (pdf < 2) ? 124UL : pdf;  /* MX21 & MX27 TO1 */
+
+	return 2UL * parent_rate / pdf;
+}
+
+static unsigned long _clk_ssi1_recalc(struct clk *clk)
+{
+	return _clk_ssix_recalc(clk,
+		(PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK)
+		>> CCM_PCDR0_SSI1BAUDDIV_OFFSET);
+}
+
+static unsigned long _clk_ssi2_recalc(struct clk *clk)
+{
+	return _clk_ssix_recalc(clk,
+		(PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
+		CCM_PCDR0_SSI2BAUDDIV_OFFSET);
+}
+
+static unsigned long _clk_nfc_recalc(struct clk *clk)
+{
+	unsigned long nfc_pdf;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK)
+		>> CCM_PCDR0_NFCDIV_OFFSET;
+
+	return parent_rate / (nfc_pdf + 1);
+}
+
+static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
+{
+	return clk->parent->round_rate(clk->parent, rate);
+}
+
+static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
+{
+	return clk->parent->set_rate(clk->parent, rate);
+}
+
+static unsigned long external_high_reference; /* in Hz */
+
+static unsigned long get_high_reference_clock_rate(struct clk *clk)
+{
+	return external_high_reference;
+}
+
+/*
+ * the high frequency external clock reference
+ * Default case is 26MHz.
+ */
+static struct clk ckih_clk = {
+	.get_rate = get_high_reference_clock_rate,
+};
+
+static unsigned long external_low_reference; /* in Hz */
+
+static unsigned long get_low_reference_clock_rate(struct clk *clk)
+{
+	return external_low_reference;
+}
+
+/*
+ * the low frequency external clock reference
+ * Default case is 32.768kHz.
+ */
+static struct clk ckil_clk = {
+	.get_rate = get_low_reference_clock_rate,
+};
+
+
+static unsigned long _clk_fpm_recalc(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) * 512;
+}
+
+/* Output of frequency pre multiplier */
+static struct clk fpm_clk = {
+	.parent = &ckil_clk,
+	.get_rate = _clk_fpm_recalc,
+};
+
+static unsigned long get_mpll_clk(struct clk *clk)
+{
+	uint32_t reg;
+	unsigned long ref_clk;
+	unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
+	unsigned long long temp;
+
+	ref_clk = clk_get_rate(clk->parent);
+
+	reg = __raw_readl(CCM_MPCTL0);
+	pdf = (reg & CCM_MPCTL0_PD_MASK)  >> CCM_MPCTL0_PD_OFFSET;
+	mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
+	mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
+	mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
+
+	mfi = (mfi <= 5) ? 5 : mfi;
+	temp = 2LL * ref_clk * mfn;
+	do_div(temp, mfd + 1);
+	temp = 2LL * ref_clk * mfi + temp;
+	do_div(temp, pdf + 1);
+
+	return (unsigned long)temp;
+}
+
+static struct clk mpll_clk = {
+	.parent = &ckih_clk,
+	.get_rate = get_mpll_clk,
+};
+
+static unsigned long _clk_fclk_get_rate(struct clk *clk)
+{
+	unsigned long parent_rate;
+	u32 div;
+
+	div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
+	parent_rate = clk_get_rate(clk->parent);
+
+	return parent_rate / (div+1);
+}
+
+static struct clk fclk_clk = {
+	.parent = &mpll_clk,
+	.get_rate = _clk_fclk_get_rate
+};
+
+static unsigned long get_spll_clk(struct clk *clk)
+{
+	uint32_t reg;
+	unsigned long ref_clk;
+	unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
+	unsigned long long temp;
+
+	ref_clk = clk_get_rate(clk->parent);
+
+	reg = __raw_readl(CCM_SPCTL0);
+	pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
+	mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
+	mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
+	mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
+
+	mfi = (mfi <= 5) ? 5 : mfi;
+	temp = 2LL * ref_clk * mfn;
+	do_div(temp, mfd + 1);
+	temp = 2LL * ref_clk * mfi + temp;
+	do_div(temp, pdf + 1);
+
+	return (unsigned long)temp;
+}
+
+static struct clk spll_clk = {
+	.parent = &ckih_clk,
+	.get_rate = get_spll_clk,
+	.enable = _clk_spll_enable,
+	.disable = _clk_spll_disable,
+};
+
+static unsigned long get_hclk_clk(struct clk *clk)
+{
+	unsigned long rate;
+	unsigned long bclk_pdf;
+
+	bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
+		>> CCM_CSCR_BCLK_OFFSET;
+
+	rate = clk_get_rate(clk->parent);
+	return rate / (bclk_pdf + 1);
+}
+
+static struct clk hclk_clk = {
+	.parent = &fclk_clk,
+	.get_rate = get_hclk_clk,
+};
+
+static unsigned long get_ipg_clk(struct clk *clk)
+{
+	unsigned long rate;
+	unsigned long ipg_pdf;
+
+	ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
+
+	rate = clk_get_rate(clk->parent);
+	return rate / (ipg_pdf + 1);
+}
+
+static struct clk ipg_clk = {
+	.parent = &hclk_clk,
+	.get_rate = get_ipg_clk,
+};
+
+static unsigned long _clk_perclkx_recalc(struct clk *clk)
+{
+	unsigned long perclk_pdf;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	if (clk->id < 0 || clk->id > 3)
+		return 0;
+
+	perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
+
+	return parent_rate / (perclk_pdf + 1);
+}
+
+static struct clk per_clk[] = {
+	{
+		.id = 0,
+		.parent = &mpll_clk,
+		.get_rate = _clk_perclkx_recalc,
+	}, {
+		.id = 1,
+		.parent = &mpll_clk,
+		.get_rate = _clk_perclkx_recalc,
+	}, {
+		.id = 2,
+		.parent = &mpll_clk,
+		.round_rate = _clk_perclkx_round_rate,
+		.set_rate = _clk_perclkx_set_rate,
+		.get_rate = _clk_perclkx_recalc,
+		/* Enable/Disable done via lcd_clkc[1] */
+	}, {
+		.id = 3,
+		.parent = &mpll_clk,
+		.round_rate = _clk_perclkx_round_rate,
+		.set_rate = _clk_perclkx_set_rate,
+		.get_rate = _clk_perclkx_recalc,
+		/* Enable/Disable done via csi_clk[1] */
+	},
+};
+
+static struct clk uart_ipg_clk[];
+
+static struct clk uart_clk[] = {
+	{
+		.id = 0,
+		.parent = &per_clk[0],
+		.secondary = &uart_ipg_clk[0],
+	}, {
+		.id = 1,
+		.parent = &per_clk[0],
+		.secondary = &uart_ipg_clk[1],
+	}, {
+		.id = 2,
+		.parent = &per_clk[0],
+		.secondary = &uart_ipg_clk[2],
+	}, {
+		.id = 3,
+		.parent = &per_clk[0],
+		.secondary = &uart_ipg_clk[3],
+	},
+};
+
+static struct clk uart_ipg_clk[] = {
+	{
+		.id = 0,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_UART1_REG,
+		.enable_shift = CCM_PCCR_UART1_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 1,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_UART2_REG,
+		.enable_shift = CCM_PCCR_UART2_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 2,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_UART3_REG,
+		.enable_shift = CCM_PCCR_UART3_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 3,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_UART4_REG,
+		.enable_shift = CCM_PCCR_UART4_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk gpt_ipg_clk[];
+
+static struct clk gpt_clk[] = {
+	{
+		.id = 0,
+		.parent = &per_clk[0],
+		.secondary = &gpt_ipg_clk[0],
+	}, {
+		.id = 1,
+		.parent = &per_clk[0],
+		.secondary = &gpt_ipg_clk[1],
+	}, {
+		.id = 2,
+		.parent = &per_clk[0],
+		.secondary = &gpt_ipg_clk[2],
+	},
+};
+
+static struct clk gpt_ipg_clk[] = {
+	{
+		.id = 0,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_GPT1_REG,
+		.enable_shift = CCM_PCCR_GPT1_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 1,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_GPT2_REG,
+		.enable_shift = CCM_PCCR_GPT2_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 2,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_GPT3_REG,
+		.enable_shift = CCM_PCCR_GPT3_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk pwm_clk[] = {
+	{
+		.parent = &per_clk[0],
+		.secondary = &pwm_clk[1],
+	}, {
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_PWM_REG,
+		.enable_shift = CCM_PCCR_PWM_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk sdhc_ipg_clk[];
+
+static struct clk sdhc_clk[] = {
+	{
+		.id = 0,
+		.parent = &per_clk[1],
+		.secondary = &sdhc_ipg_clk[0],
+	}, {
+		.id = 1,
+		.parent = &per_clk[1],
+		.secondary = &sdhc_ipg_clk[1],
+	},
+};
+
+static struct clk sdhc_ipg_clk[] = {
+	{
+		.id = 0,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SDHC1_REG,
+		.enable_shift = CCM_PCCR_SDHC1_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 1,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SDHC2_REG,
+		.enable_shift = CCM_PCCR_SDHC2_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk cspi_ipg_clk[];
+
+static struct clk cspi_clk[] = {
+	{
+		.id = 0,
+		.parent = &per_clk[1],
+		.secondary = &cspi_ipg_clk[0],
+	}, {
+		.id = 1,
+		.parent = &per_clk[1],
+		.secondary = &cspi_ipg_clk[1],
+	}, {
+		.id = 2,
+		.parent = &per_clk[1],
+		.secondary = &cspi_ipg_clk[2],
+	},
+};
+
+static struct clk cspi_ipg_clk[] = {
+	{
+		.id = 0,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_CSPI1_REG,
+		.enable_shift = CCM_PCCR_CSPI1_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 1,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_CSPI2_REG,
+		.enable_shift = CCM_PCCR_CSPI2_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 3,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_CSPI3_REG,
+		.enable_shift = CCM_PCCR_CSPI3_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk lcdc_clk[] = {
+	{
+		.parent = &per_clk[2],
+		.secondary = &lcdc_clk[1],
+		.round_rate = _clk_parent_round_rate,
+		.set_rate = _clk_parent_set_rate,
+	}, {
+		.parent = &ipg_clk,
+		.secondary = &lcdc_clk[2],
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_LCDC_REG,
+		.enable_shift = CCM_PCCR_LCDC_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.parent = &hclk_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_HCLK_LCDC_REG,
+		.enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk csi_clk[] = {
+	{
+		.parent = &per_clk[3],
+		.secondary = &csi_clk[1],
+		.round_rate = _clk_parent_round_rate,
+		.set_rate = _clk_parent_set_rate,
+	}, {
+		.parent = &hclk_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_HCLK_CSI_REG,
+		.enable_shift = CCM_PCCR_HCLK_CSI_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk usb_clk[] = {
+	{
+		.parent = &spll_clk,
+		.get_rate = _clk_usb_recalc,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_USBOTG_REG,
+		.enable_shift = CCM_PCCR_USBOTG_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.parent = &hclk_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_HCLK_USBOTG_REG,
+		.enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET,
+		.disable = _clk_disable,
+	}
+};
+
+static struct clk ssi_ipg_clk[];
+
+static struct clk ssi_clk[] = {
+	{
+		.id = 0,
+		.parent = &mpll_clk,
+		.secondary = &ssi_ipg_clk[0],
+		.get_rate = _clk_ssi1_recalc,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SSI1_BAUD_REG,
+		.enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 1,
+		.parent = &mpll_clk,
+		.secondary = &ssi_ipg_clk[1],
+		.get_rate = _clk_ssi2_recalc,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SSI2_BAUD_REG,
+		.enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk ssi_ipg_clk[] = {
+	{
+		.id = 0,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SSI1_REG,
+		.enable_shift = CCM_PCCR_SSI1_IPG_OFFSET,
+		.disable = _clk_disable,
+	}, {
+		.id = 1,
+		.parent = &ipg_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SSI2_REG,
+		.enable_shift = CCM_PCCR_SSI2_IPG_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+
+static struct clk nfc_clk = {
+	.parent = &fclk_clk,
+	.get_rate = _clk_nfc_recalc,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_NFC_REG,
+	.enable_shift = CCM_PCCR_NFC_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk dma_clk[] = {
+	{
+		.parent = &hclk_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_DMA_REG,
+		.enable_shift = CCM_PCCR_DMA_OFFSET,
+		.disable = _clk_disable,
+		.secondary = &dma_clk[1],
+	},  {
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_HCLK_DMA_REG,
+		.enable_shift = CCM_PCCR_HCLK_DMA_OFFSET,
+		.disable = _clk_disable,
+	},
+};
+
+static struct clk brom_clk = {
+	.parent = &hclk_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_HCLK_BROM_REG,
+	.enable_shift = CCM_PCCR_HCLK_BROM_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk emma_clk[] = {
+	{
+		.parent = &hclk_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_EMMA_REG,
+		.enable_shift = CCM_PCCR_EMMA_OFFSET,
+		.disable = _clk_disable,
+		.secondary = &emma_clk[1],
+	}, {
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_HCLK_EMMA_REG,
+		.enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET,
+		.disable = _clk_disable,
+	}
+};
+
+static struct clk slcdc_clk[] = {
+	{
+		.parent = &hclk_clk,
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_SLCDC_REG,
+		.enable_shift = CCM_PCCR_SLCDC_OFFSET,
+		.disable = _clk_disable,
+		.secondary = &slcdc_clk[1],
+	}, {
+		.enable = _clk_enable,
+		.enable_reg = CCM_PCCR_HCLK_SLCDC_REG,
+		.enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET,
+		.disable = _clk_disable,
+	}
+};
+
+static struct clk wdog_clk = {
+	.parent = &ipg_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_WDT_REG,
+	.enable_shift = CCM_PCCR_WDT_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk gpio_clk = {
+	.parent = &ipg_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_GPIO_REG,
+	.enable_shift = CCM_PCCR_GPIO_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk i2c_clk = {
+	.id = 0,
+	.parent = &ipg_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_I2C1_REG,
+	.enable_shift = CCM_PCCR_I2C1_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk kpp_clk = {
+	.parent = &ipg_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_KPP_REG,
+	.enable_shift = CCM_PCCR_KPP_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk owire_clk = {
+	.parent = &ipg_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_OWIRE_REG,
+	.enable_shift = CCM_PCCR_OWIRE_OFFSET,
+	.disable = _clk_disable,
+};
+
+static struct clk rtc_clk = {
+	.parent = &ipg_clk,
+	.enable = _clk_enable,
+	.enable_reg = CCM_PCCR_RTC_REG,
+	.enable_shift = CCM_PCCR_RTC_OFFSET,
+	.disable = _clk_disable,
+};
+
+static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
+{
+	u32 div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+	div = parent_rate / rate;
+	if (parent_rate % rate)
+		div++;
+
+	if (div > 8)
+		div = 8;
+
+	return parent_rate / div;
+}
+
+static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 reg;
+	u32 div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	div = parent_rate / rate;
+
+	if (div > 8 || div < 1 || ((parent_rate / div) != rate))
+		return -EINVAL;
+	div--;
+
+	reg = __raw_readl(CCM_PCDR0);
+
+	if (clk->parent == &usb_clk[0]) {
+		reg &= ~CCM_PCDR0_48MDIV_MASK;
+		reg |= div << CCM_PCDR0_48MDIV_OFFSET;
+	}
+	__raw_writel(reg, CCM_PCDR0);
+
+	return 0;
+}
+
+static unsigned long _clk_clko_recalc(struct clk *clk)
+{
+	u32 div = 0;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	if (clk->parent == &usb_clk[0]) /* 48M */
+		div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK
+			 >> CCM_PCDR0_48MDIV_OFFSET;
+	div++;
+
+	return parent_rate / div;
+}
+
+static struct clk clko_clk;
+
+static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg;
+
+	reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
+
+	if (parent == &ckil_clk)
+		reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &fpm_clk)
+		reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &ckih_clk)
+		reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == mpll_clk.parent)
+		reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == spll_clk.parent)
+		reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &mpll_clk)
+		reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &spll_clk)
+		reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &fclk_clk)
+		reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &hclk_clk)
+		reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &ipg_clk)
+		reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &per_clk[0])
+		reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &per_clk[1])
+		reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &per_clk[2])
+		reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &per_clk[3])
+		reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &ssi_clk[0])
+		reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &ssi_clk[1])
+		reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &nfc_clk)
+		reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &usb_clk[0])
+		reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET;
+	else if (parent == &clko_clk)
+		reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
+	else
+		return -EINVAL;
+
+	__raw_writel(reg, CCM_CCSR);
+
+	return 0;
+}
+
+static struct clk clko_clk = {
+	.get_rate = _clk_clko_recalc,
+	.set_rate = _clk_clko_set_rate,
+	.round_rate = _clk_clko_round_rate,
+	.set_parent = _clk_clko_set_parent,
+};
+
+
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	},
+static struct clk_lookup lookups[] __initdata = {
+/* It's unlikely that any driver wants one of them directly:
+	_REGISTER_CLOCK(NULL, "ckih", ckih_clk)
+	_REGISTER_CLOCK(NULL, "ckil", ckil_clk)
+	_REGISTER_CLOCK(NULL, "fpm", fpm_clk)
+	_REGISTER_CLOCK(NULL, "mpll", mpll_clk)
+	_REGISTER_CLOCK(NULL, "spll", spll_clk)
+	_REGISTER_CLOCK(NULL, "fclk", fclk_clk)
+	_REGISTER_CLOCK(NULL, "hclk", hclk_clk)
+	_REGISTER_CLOCK(NULL, "ipg", ipg_clk)
+*/
+	_REGISTER_CLOCK(NULL, "perclk1", per_clk[0])
+	_REGISTER_CLOCK(NULL, "perclk2", per_clk[1])
+	_REGISTER_CLOCK(NULL, "perclk3", per_clk[2])
+	_REGISTER_CLOCK(NULL, "perclk4", per_clk[3])
+	_REGISTER_CLOCK(NULL, "clko", clko_clk)
+	_REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0])
+	_REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1])
+	_REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2])
+	_REGISTER_CLOCK("imx-uart.3", NULL, uart_clk[3])
+	_REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0])
+	_REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1])
+	_REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2])
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk[0])
+	_REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0])
+	_REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1])
+	_REGISTER_CLOCK(NULL, "cspi1", cspi_clk[0])
+	_REGISTER_CLOCK(NULL, "cspi2", cspi_clk[1])
+	_REGISTER_CLOCK(NULL, "cspi3", cspi_clk[2])
+	_REGISTER_CLOCK(NULL, "lcdc", lcdc_clk[0])
+	_REGISTER_CLOCK(NULL, "csi", csi_clk[0])
+	_REGISTER_CLOCK(NULL, "usb", usb_clk[0])
+	_REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0])
+	_REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1])
+	_REGISTER_CLOCK(NULL, "nfc", nfc_clk)
+	_REGISTER_CLOCK(NULL, "dma", dma_clk[0])
+	_REGISTER_CLOCK(NULL, "brom", brom_clk)
+	_REGISTER_CLOCK(NULL, "emma", emma_clk[0])
+	_REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0])
+	_REGISTER_CLOCK(NULL, "wdog", wdog_clk)
+	_REGISTER_CLOCK(NULL, "gpio", gpio_clk)
+	_REGISTER_CLOCK(NULL, "i2c", i2c_clk)
+	_REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
+	_REGISTER_CLOCK(NULL, "owire", owire_clk)
+	_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+};
+
+/*
+ * must be called very early to get information about the
+ * available clock rate when the timer framework starts
+ */
+int __init mx21_clocks_init(unsigned long lref, unsigned long href)
+{
+	int i;
+	u32 cscr;
+
+	external_low_reference = lref;
+	external_high_reference = href;
+
+	/* detect clock reference for both system PLL */
+	cscr = CSCR();
+	if (cscr & CCM_CSCR_MCU)
+		mpll_clk.parent = &ckih_clk;
+	else
+		mpll_clk.parent = &fpm_clk;
+
+	if (cscr & CCM_CSCR_SP)
+		spll_clk.parent = &ckih_clk;
+	else
+		spll_clk.parent = &fpm_clk;
+
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
+
+	/* Turn off all clock gates */
+	__raw_writel(0, CCM_PCCR0);
+	__raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1);
+
+	/* This turns of the serial PLL as well */
+	spll_clk.disable(&spll_clk);
+
+	/* This will propagate to all children and init all the clock rates. */
+	clk_enable(&per_clk[0]);
+	clk_enable(&gpio_clk);
+
+#ifdef CONFIG_DEBUG_LL_CONSOLE
+	clk_enable(&uart_clk[0]);
+#endif
+
+	mxc_timer_init(&gpt_clk[0]);
+	return 0;
+}

File diff suppressed because it is too large
+ 366 - 1238
arch/arm/mach-mx2/clock_imx27.c


+ 2 - 2
arch/arm/mach-mx2/cpu_imx27.c

@@ -26,11 +26,11 @@
 
 #include <mach/hardware.h>
 
-#include "crm_regs.h"
-
 static int cpu_silicon_rev = -1;
 static int cpu_partnumber;
 
+#define SYS_CHIP_ID             0x00    /* The offset of CHIP ID register */
+
 static void query_silicon_parameter(void)
 {
 	u32 val;

+ 149 - 164
arch/arm/mach-mx2/crm_regs.h

@@ -38,42 +38,36 @@
 #define CCM_PMCOUNT             (IO_ADDRESS(CCM_BASE_ADDR) + 0x30)
 #define CCM_WKGDCTL             (IO_ADDRESS(CCM_BASE_ADDR) + 0x34)
 
-#define CCM_CSCR_USB_OFFSET     28
-#define CCM_CSCR_USB_MASK       (0x7 << 28)
+#define CCM_CSCR_PRESC_OFFSET   29
+#define CCM_CSCR_PRESC_MASK     (0x7 << CCM_CSCR_PRESC_OFFSET)
+
+#define CCM_CSCR_USB_OFFSET     26
+#define CCM_CSCR_USB_MASK       (0x7 << CCM_CSCR_USB_OFFSET)
 #define CCM_CSCR_SD_OFFSET      24
-#define CCM_CSCR_SD_MASK        (0x3 << 24)
-#define CCM_CSCR_SSI2           (1 << 23)
-#define CCM_CSCR_SSI2_OFFSET    23
-#define CCM_CSCR_SSI1           (1 << 22)
-#define CCM_CSCR_SSI1_OFFSET    22
-#define CCM_CSCR_VPU           (1 << 21)
-#define CCM_CSCR_VPU_OFFSET    21
-#define CCM_CSCR_MSHC           (1 << 20)
-#define CCM_CSCR_SPLLRES        (1 << 19)
-#define CCM_CSCR_MPLLRES        (1 << 18)
+#define CCM_CSCR_SD_MASK        (0x3 << CCM_CSCR_SD_OFFSET)
+#define CCM_CSCR_SPLLRES        (1 << 22)
+#define CCM_CSCR_MPLLRES        (1 << 21)
+#define CCM_CSCR_SSI2_OFFSET    20
+#define CCM_CSCR_SSI2           (1 << CCM_CSCR_SSI2_OFFSET)
+#define CCM_CSCR_SSI1_OFFSET    19
+#define CCM_CSCR_SSI1           (1 << CCM_CSCR_SSI1_OFFSET)
+#define CCM_CSCR_FIR_OFFSET    	18
+#define CCM_CSCR_FIR		(1 << CCM_CSCR_FIR_OFFSET)
 #define CCM_CSCR_SP             (1 << 17)
 #define CCM_CSCR_MCU            (1 << 16)
-/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/
-#define CCM_CSCR_ARM_SRC        (1 << 15)
-#define CCM_CSCR_ARM_OFFSET     12
-#define CCM_CSCR_ARM_MASK       (0x3 << 12)
-/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/
-#define CCM_CSCR_PRESC_OFFSET   13
-#define CCM_CSCR_PRESC_MASK     (0x7 << 13)
-#define CCM_CSCR_BCLK_OFFSET    9
-#define CCM_CSCR_BCLK_MASK      (0xf << 9)
-#define CCM_CSCR_IPDIV_OFFSET   8
-#define CCM_CSCR_IPDIV          (1 << 8)
-/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/
-#define CCM_CSCR_AHB_OFFSET     8
-#define CCM_CSCR_AHB_MASK       (0x3 << 8)
-/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/
+#define CCM_CSCR_BCLK_OFFSET	10
+#define CCM_CSCR_BCLK_MASK      (0xf << CCM_CSCR_BCLK_OFFSET)
+#define CCM_CSCR_IPDIV_OFFSET   9
+#define CCM_CSCR_IPDIV          (1 << CCM_CSCR_IPDIV_OFFSET)
+
 #define CCM_CSCR_OSC26MDIV      (1 << 4)
 #define CCM_CSCR_OSC26M         (1 << 3)
 #define CCM_CSCR_FPM            (1 << 2)
 #define CCM_CSCR_SPEN           (1 << 1)
 #define CCM_CSCR_MPEN           1
 
+
+
 #define CCM_MPCTL0_CPLM         (1 << 31)
 #define CCM_MPCTL0_PD_OFFSET    26
 #define CCM_MPCTL0_PD_MASK      (0xf << 26)
@@ -109,25 +103,14 @@
 
 #define CCM_PCDR0_SSI2BAUDDIV_OFFSET    26
 #define CCM_PCDR0_SSI2BAUDDIV_MASK      (0x3f << 26)
-#define CCM_PCDR0_CLKO_EN               25
-#define CCM_PCDR0_CLKODIV_OFFSET        22
-#define CCM_PCDR0_CLKODIV_MASK          (0x7 << 22)
 #define CCM_PCDR0_SSI1BAUDDIV_OFFSET    16
 #define CCM_PCDR0_SSI1BAUDDIV_MASK      (0x3f << 16)
-/*The difinition for i.MX27 TO2*/
-#define CCM_PCDR0_VPUDIV2_OFFSET        10
-#define CCM_PCDR0_VPUDIV2_MASK          (0x3f << 10)
-#define CCM_PCDR0_NFCDIV2_OFFSET         6
-#define CCM_PCDR0_NFCDIV2_MASK           (0xf << 6)
-#define CCM_PCDR0_MSHCDIV2_MASK          0x3f
-/*The difinition for i.MX27 TO2*/
 #define CCM_PCDR0_NFCDIV_OFFSET         12
 #define CCM_PCDR0_NFCDIV_MASK           (0xf << 12)
-#define CCM_PCDR0_VPUDIV_OFFSET        8
-#define CCM_PCDR0_VPUDIV_MASK          (0xf << 8)
-#define CCM_PCDR0_MSHCDIV_OFFSET        0
-#define CCM_PCDR0_MSHCDIV_MASK          0x1f
-
+#define CCM_PCDR0_48MDIV_OFFSET		5
+#define CCM_PCDR0_48MDIV_MASK		(0x7 << CCM_PCDR0_48MDIV_OFFSET)
+#define CCM_PCDR0_FIRIDIV_OFFSET	0
+#define CCM_PCDR0_FIRIDIV_MASK		0x1f
 #define CCM_PCDR1_PERDIV4_OFFSET        24
 #define CCM_PCDR1_PERDIV4_MASK          (0x3f << 24)
 #define CCM_PCDR1_PERDIV3_OFFSET        16
@@ -137,133 +120,135 @@
 #define CCM_PCDR1_PERDIV1_OFFSET        0
 #define CCM_PCDR1_PERDIV1_MASK          0x3f
 
-#define CCM_PCCR0_CSPI1_OFFSET          31
-#define CCM_PCCR0_CSPI1_MASK            (1 << 31)
-#define CCM_PCCR0_CSPI2_OFFSET          30
-#define CCM_PCCR0_CSPI2_MASK            (1 << 30)
-#define CCM_PCCR0_CSPI3_OFFSET          29
-#define CCM_PCCR0_CSPI3_MASK            (1 << 29)
-#define CCM_PCCR0_DMA_OFFSET            28
-#define CCM_PCCR0_DMA_MASK              (1 << 28)
-#define CCM_PCCR0_EMMA_OFFSET           27
-#define CCM_PCCR0_EMMA_MASK             (1 << 27)
-#define CCM_PCCR0_FEC_OFFSET            26
-#define CCM_PCCR0_FEC_MASK              (1 << 26)
-#define CCM_PCCR0_GPIO_OFFSET           25
-#define CCM_PCCR0_GPIO_MASK             (1 << 25)
-#define CCM_PCCR0_GPT1_OFFSET           24
-#define CCM_PCCR0_GPT1_MASK             (1 << 24)
-#define CCM_PCCR0_GPT2_OFFSET           23
-#define CCM_PCCR0_GPT2_MASK             (1 << 23)
-#define CCM_PCCR0_GPT3_OFFSET           22
-#define CCM_PCCR0_GPT3_MASK             (1 << 22)
-#define CCM_PCCR0_GPT4_OFFSET           21
-#define CCM_PCCR0_GPT4_MASK             (1 << 21)
-#define CCM_PCCR0_GPT5_OFFSET           20
-#define CCM_PCCR0_GPT5_MASK             (1 << 20)
-#define CCM_PCCR0_GPT6_OFFSET           19
-#define CCM_PCCR0_GPT6_MASK             (1 << 19)
-#define CCM_PCCR0_I2C1_OFFSET           18
-#define CCM_PCCR0_I2C1_MASK             (1 << 18)
-#define CCM_PCCR0_I2C2_OFFSET           17
-#define CCM_PCCR0_I2C2_MASK             (1 << 17)
-#define CCM_PCCR0_IIM_OFFSET            16
-#define CCM_PCCR0_IIM_MASK              (1 << 16)
-#define CCM_PCCR0_KPP_OFFSET            15
-#define CCM_PCCR0_KPP_MASK              (1 << 15)
-#define CCM_PCCR0_LCDC_OFFSET           14
-#define CCM_PCCR0_LCDC_MASK             (1 << 14)
-#define CCM_PCCR0_MSHC_OFFSET           13
-#define CCM_PCCR0_MSHC_MASK             (1 << 13)
-#define CCM_PCCR0_OWIRE_OFFSET          12
-#define CCM_PCCR0_OWIRE_MASK            (1 << 12)
-#define CCM_PCCR0_PWM_OFFSET            11
-#define CCM_PCCR0_PWM_MASK              (1 << 11)
-#define CCM_PCCR0_RTC_OFFSET            9
-#define CCM_PCCR0_RTC_MASK              (1 << 9)
-#define CCM_PCCR0_RTIC_OFFSET           8
-#define CCM_PCCR0_RTIC_MASK             (1 << 8)
-#define CCM_PCCR0_SAHARA_OFFSET         7
-#define CCM_PCCR0_SAHARA_MASK           (1 << 7)
-#define CCM_PCCR0_SCC_OFFSET            6
-#define CCM_PCCR0_SCC_MASK              (1 << 6)
-#define CCM_PCCR0_SDHC1_OFFSET          5
-#define CCM_PCCR0_SDHC1_MASK            (1 << 5)
-#define CCM_PCCR0_SDHC2_OFFSET          4
-#define CCM_PCCR0_SDHC2_MASK            (1 << 4)
-#define CCM_PCCR0_SDHC3_OFFSET          3
-#define CCM_PCCR0_SDHC3_MASK            (1 << 3)
-#define CCM_PCCR0_SLCDC_OFFSET          2
-#define CCM_PCCR0_SLCDC_MASK            (1 << 2)
-#define CCM_PCCR0_SSI1_IPG_OFFSET       1
-#define CCM_PCCR0_SSI1_IPG_MASK         (1 << 1)
-#define CCM_PCCR0_SSI2_IPG_OFFSET       0
-#define CCM_PCCR0_SSI2_IPG_MASK         (1 << 0)
+#define CCM_PCCR_HCLK_CSI_OFFSET       	31
+#define CCM_PCCR_HCLK_CSI_REG	        CCM_PCCR0
+#define CCM_PCCR_HCLK_DMA_OFFSET       	30
+#define CCM_PCCR_HCLK_DMA_REG	        CCM_PCCR0
+#define CCM_PCCR_HCLK_BROM_OFFSET      	28
+#define CCM_PCCR_HCLK_BROM_REG	        CCM_PCCR0
+#define CCM_PCCR_HCLK_EMMA_OFFSET      	27
+#define CCM_PCCR_HCLK_EMMA_REG	        CCM_PCCR0
+#define CCM_PCCR_HCLK_LCDC_OFFSET      	26
+#define CCM_PCCR_HCLK_LCDC_REG	        CCM_PCCR0
+#define CCM_PCCR_HCLK_SLCDC_OFFSET     	25
+#define CCM_PCCR_HCLK_SLCDC_REG	        CCM_PCCR0
+#define CCM_PCCR_HCLK_USBOTG_OFFSET    	24
+#define CCM_PCCR_HCLK_USBOTG_REG	CCM_PCCR0
+#define CCM_PCCR_HCLK_BMI_OFFSET    	23
+#define CCM_PCCR_BMI_MASK          	(1 << CCM_PCCR_BMI_MASK)
+#define CCM_PCCR_HCLK_BMI_REG	    	CCM_PCCR0
+#define CCM_PCCR_PERCLK4_OFFSET        	22
+#define CCM_PCCR_PERCLK4_REG	    	CCM_PCCR0
+#define CCM_PCCR_SLCDC_OFFSET          	21
+#define CCM_PCCR_SLCDC_REG		CCM_PCCR0
+#define CCM_PCCR_FIRI_BAUD_OFFSET       20
+#define CCM_PCCR_FIRI_BAUD_MASK         (1 << CCM_PCCR_FIRI_BAUD_MASK)
+#define CCM_PCCR_FIRI_BAUD_REG	        CCM_PCCR0
+#define CCM_PCCR_NFC_OFFSET		19
+#define CCM_PCCR_NFC_REG		CCM_PCCR0
+#define CCM_PCCR_LCDC_OFFSET           	18
+#define CCM_PCCR_LCDC_REG		CCM_PCCR0
+#define CCM_PCCR_SSI1_BAUD_OFFSET      	17
+#define CCM_PCCR_SSI1_BAUD_REG	    	CCM_PCCR0
+#define CCM_PCCR_SSI2_BAUD_OFFSET      	16
+#define CCM_PCCR_SSI2_BAUD_REG	    	CCM_PCCR0
+#define CCM_PCCR_EMMA_OFFSET           	15
+#define CCM_PCCR_EMMA_REG		CCM_PCCR0
+#define CCM_PCCR_USBOTG_OFFSET         	14
+#define CCM_PCCR_USBOTG_REG		CCM_PCCR0
+#define CCM_PCCR_DMA_OFFSET            	13
+#define CCM_PCCR_DMA_REG            	CCM_PCCR0
+#define CCM_PCCR_I2C1_OFFSET           	12
+#define CCM_PCCR_I2C1_REG		CCM_PCCR0
+#define CCM_PCCR_GPIO_OFFSET           	11
+#define CCM_PCCR_GPIO_REG		CCM_PCCR0
+#define CCM_PCCR_SDHC2_OFFSET          	10
+#define CCM_PCCR_SDHC2_REG		CCM_PCCR0
+#define CCM_PCCR_SDHC1_OFFSET          	9
+#define CCM_PCCR_SDHC1_REG		CCM_PCCR0
+#define CCM_PCCR_FIRI_OFFSET		8
+#define CCM_PCCR_FIRI_MASK		(1 << CCM_PCCR_BAUD_MASK)
+#define CCM_PCCR_FIRI_REG		CCM_PCCR0
+#define CCM_PCCR_SSI2_IPG_OFFSET       	7
+#define CCM_PCCR_SSI2_REG		CCM_PCCR0
+#define CCM_PCCR_SSI1_IPG_OFFSET       	6
+#define CCM_PCCR_SSI1_REG		CCM_PCCR0
+#define CCM_PCCR_CSPI2_OFFSET		5
+#define	CCM_PCCR_CSPI2_REG		CCM_PCCR0
+#define CCM_PCCR_CSPI1_OFFSET		4
+#define	CCM_PCCR_CSPI1_REG		CCM_PCCR0
+#define CCM_PCCR_UART4_OFFSET          	3
+#define CCM_PCCR_UART4_REG		CCM_PCCR0
+#define CCM_PCCR_UART3_OFFSET          	2
+#define CCM_PCCR_UART3_REG		CCM_PCCR0
+#define CCM_PCCR_UART2_OFFSET          	1
+#define CCM_PCCR_UART2_REG		CCM_PCCR0
+#define CCM_PCCR_UART1_OFFSET          	0
+#define CCM_PCCR_UART1_REG		CCM_PCCR0
+
+#define CCM_PCCR_OWIRE_OFFSET          	31
+#define CCM_PCCR_OWIRE_REG		CCM_PCCR1
+#define CCM_PCCR_KPP_OFFSET            	30
+#define CCM_PCCR_KPP_REG		CCM_PCCR1
+#define CCM_PCCR_RTC_OFFSET            	29
+#define CCM_PCCR_RTC_REG		CCM_PCCR1
+#define CCM_PCCR_PWM_OFFSET            	28
+#define CCM_PCCR_PWM_REG		CCM_PCCR1
+#define CCM_PCCR_GPT3_OFFSET           	27
+#define CCM_PCCR_GPT3_REG		CCM_PCCR1
+#define CCM_PCCR_GPT2_OFFSET           	26
+#define CCM_PCCR_GPT2_REG		CCM_PCCR1
+#define CCM_PCCR_GPT1_OFFSET           	25
+#define CCM_PCCR_GPT1_REG		CCM_PCCR1
+#define CCM_PCCR_WDT_OFFSET            	24
+#define CCM_PCCR_WDT_REG		CCM_PCCR1
+#define CCM_PCCR_CSPI3_OFFSET		23
+#define	CCM_PCCR_CSPI3_REG		CCM_PCCR1
+
+#define CCM_PCCR_CSPI1_MASK            	(1 << CCM_PCCR_CSPI1_OFFSET)
+#define CCM_PCCR_CSPI2_MASK            	(1 << CCM_PCCR_CSPI2_OFFSET)
+#define CCM_PCCR_CSPI3_MASK            	(1 << CCM_PCCR_CSPI3_OFFSET)
+#define CCM_PCCR_DMA_MASK              	(1 << CCM_PCCR_DMA_OFFSET)
+#define CCM_PCCR_EMMA_MASK             	(1 << CCM_PCCR_EMMA_OFFSET)
+#define CCM_PCCR_GPIO_MASK             	(1 << CCM_PCCR_GPIO_OFFSET)
+#define CCM_PCCR_GPT1_MASK             	(1 << CCM_PCCR_GPT1_OFFSET)
+#define CCM_PCCR_GPT2_MASK             	(1 << CCM_PCCR_GPT2_OFFSET)
+#define CCM_PCCR_GPT3_MASK             	(1 << CCM_PCCR_GPT3_OFFSET)
+#define CCM_PCCR_HCLK_BROM_MASK		(1 << CCM_PCCR_HCLK_BROM_OFFSET)
+#define CCM_PCCR_HCLK_CSI_MASK         	(1 << CCM_PCCR_HCLK_CSI_OFFSET)
+#define CCM_PCCR_HCLK_DMA_MASK         	(1 << CCM_PCCR_HCLK_DMA_OFFSET)
+#define CCM_PCCR_HCLK_EMMA_MASK        	(1 << CCM_PCCR_HCLK_EMMA_OFFSET)
+#define CCM_PCCR_HCLK_LCDC_MASK        	(1 << CCM_PCCR_HCLK_LCDC_OFFSET)
+#define CCM_PCCR_HCLK_SLCDC_MASK       	(1 << CCM_PCCR_HCLK_SLCDC_OFFSET)
+#define CCM_PCCR_HCLK_USBOTG_MASK      	(1 << CCM_PCCR_HCLK_USBOTG_OFFSET)
+#define CCM_PCCR_I2C1_MASK             	(1 << CCM_PCCR_I2C1_OFFSET)
+#define CCM_PCCR_KPP_MASK              	(1 << CCM_PCCR_KPP_OFFSET)
+#define CCM_PCCR_LCDC_MASK             	(1 << CCM_PCCR_LCDC_OFFSET)
+#define CCM_PCCR_NFC_MASK		(1 << CCM_PCCR_NFC_OFFSET)
+#define CCM_PCCR_OWIRE_MASK            	(1 << CCM_PCCR_OWIRE_OFFSET)
+#define CCM_PCCR_PERCLK4_MASK          	(1 << CCM_PCCR_PERCLK4_OFFSET)
+#define CCM_PCCR_PWM_MASK              	(1 << CCM_PCCR_PWM_OFFSET)
+#define CCM_PCCR_RTC_MASK              	(1 << CCM_PCCR_RTC_OFFSET)
+#define CCM_PCCR_SDHC1_MASK            	(1 << CCM_PCCR_SDHC1_OFFSET)
+#define CCM_PCCR_SDHC2_MASK            	(1 << CCM_PCCR_SDHC2_OFFSET)
+#define CCM_PCCR_SLCDC_MASK            	(1 << CCM_PCCR_SLCDC_OFFSET)
+#define CCM_PCCR_SSI1_BAUD_MASK        	(1 << CCM_PCCR_SSI1_BAUD_OFFSET)
+#define CCM_PCCR_SSI1_IPG_MASK         	(1 << CCM_PCCR_SSI1_IPG_OFFSET)
+#define CCM_PCCR_SSI2_BAUD_MASK        	(1 << CCM_PCCR_SSI2_BAUD_OFFSET)
+#define CCM_PCCR_SSI2_IPG_MASK         	(1 << CCM_PCCR_SSI2_IPG_OFFSET)
+#define CCM_PCCR_UART1_MASK            	(1 << CCM_PCCR_UART1_OFFSET)
+#define CCM_PCCR_UART2_MASK            	(1 << CCM_PCCR_UART2_OFFSET)
+#define CCM_PCCR_UART3_MASK            	(1 << CCM_PCCR_UART3_OFFSET)
+#define CCM_PCCR_UART4_MASK            	(1 << CCM_PCCR_UART4_OFFSET)
+#define CCM_PCCR_USBOTG_MASK           	(1 << CCM_PCCR_USBOTG_OFFSET)
+#define CCM_PCCR_WDT_MASK              	(1 << CCM_PCCR_WDT_OFFSET)
 
-#define CCM_PCCR1_UART1_OFFSET          31
-#define CCM_PCCR1_UART1_MASK            (1 << 31)
-#define CCM_PCCR1_UART2_OFFSET          30
-#define CCM_PCCR1_UART2_MASK            (1 << 30)
-#define CCM_PCCR1_UART3_OFFSET          29
-#define CCM_PCCR1_UART3_MASK            (1 << 29)
-#define CCM_PCCR1_UART4_OFFSET          28
-#define CCM_PCCR1_UART4_MASK            (1 << 28)
-#define CCM_PCCR1_UART5_OFFSET          27
-#define CCM_PCCR1_UART5_MASK            (1 << 27)
-#define CCM_PCCR1_UART6_OFFSET          26
-#define CCM_PCCR1_UART6_MASK            (1 << 26)
-#define CCM_PCCR1_USBOTG_OFFSET         25
-#define CCM_PCCR1_USBOTG_MASK           (1 << 25)
-#define CCM_PCCR1_WDT_OFFSET            24
-#define CCM_PCCR1_WDT_MASK              (1 << 24)
-#define CCM_PCCR1_HCLK_ATA_OFFSET       23
-#define CCM_PCCR1_HCLK_ATA_MASK         (1 << 23)
-#define CCM_PCCR1_HCLK_BROM_OFFSET      22
-#define CCM_PCCR1_HCLK_BROM_MASK        (1 << 22)
-#define CCM_PCCR1_HCLK_CSI_OFFSET       21
-#define CCM_PCCR1_HCLK_CSI_MASK         (1 << 21)
-#define CCM_PCCR1_HCLK_DMA_OFFSET       20
-#define CCM_PCCR1_HCLK_DMA_MASK         (1 << 20)
-#define CCM_PCCR1_HCLK_EMI_OFFSET       19
-#define CCM_PCCR1_HCLK_EMI_MASK         (1 << 19)
-#define CCM_PCCR1_HCLK_EMMA_OFFSET      18
-#define CCM_PCCR1_HCLK_EMMA_MASK        (1 << 18)
-#define CCM_PCCR1_HCLK_FEC_OFFSET       17
-#define CCM_PCCR1_HCLK_FEC_MASK         (1 << 17)
-#define CCM_PCCR1_HCLK_VPU_OFFSET       16
-#define CCM_PCCR1_HCLK_VPU_MASK         (1 << 16)
-#define CCM_PCCR1_HCLK_LCDC_OFFSET      15
-#define CCM_PCCR1_HCLK_LCDC_MASK        (1 << 15)
-#define CCM_PCCR1_HCLK_RTIC_OFFSET      14
-#define CCM_PCCR1_HCLK_RTIC_MASK        (1 << 14)
-#define CCM_PCCR1_HCLK_SAHARA_OFFSET    13
-#define CCM_PCCR1_HCLK_SAHARA_MASK      (1 << 13)
-#define CCM_PCCR1_HCLK_SLCDC_OFFSET     12
-#define CCM_PCCR1_HCLK_SLCDC_MASK       (1 << 12)
-#define CCM_PCCR1_HCLK_USBOTG_OFFSET    11
-#define CCM_PCCR1_HCLK_USBOTG_MASK      (1 << 11)
-#define CCM_PCCR1_PERCLK1_OFFSET        10
-#define CCM_PCCR1_PERCLK1_MASK          (1 << 10)
-#define CCM_PCCR1_PERCLK2_OFFSET        9
-#define CCM_PCCR1_PERCLK2_MASK          (1 << 9)
-#define CCM_PCCR1_PERCLK3_OFFSET        8
-#define CCM_PCCR1_PERCLK3_MASK          (1 << 8)
-#define CCM_PCCR1_PERCLK4_OFFSET        7
-#define CCM_PCCR1_PERCLK4_MASK          (1 << 7)
-#define CCM_PCCR1_VPU_BAUD_OFFSET       6
-#define CCM_PCCR1_VPU_BAUD_MASK         (1 << 6)
-#define CCM_PCCR1_SSI1_BAUD_OFFSET      5
-#define CCM_PCCR1_SSI1_BAUD_MASK        (1 << 5)
-#define CCM_PCCR1_SSI2_BAUD_OFFSET      4
-#define CCM_PCCR1_SSI2_BAUD_MASK        (1 << 4)
-#define CCM_PCCR1_NFC_BAUD_OFFSET       3
-#define CCM_PCCR1_NFC_BAUD_MASK         (1 << 3)
-#define CCM_PCCR1_MSHC_BAUD_OFFSET      2
-#define CCM_PCCR1_MSHC_BAUD_MASK        (1 << 2)
 
 #define CCM_CCSR_32KSR          (1 << 15)
+
 #define CCM_CCSR_CLKMODE1       (1 << 9)
 #define CCM_CCSR_CLKMODE0       (1 << 8)
+
 #define CCM_CCSR_CLKOSEL_OFFSET 0
 #define CCM_CCSR_CLKOSEL_MASK   0x1f
 

+ 190 - 6
arch/arm/mach-mx2/devices.c

@@ -34,6 +34,10 @@
 
 #include <mach/irqs.h>
 #include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/mmc.h>
+
+#include "devices.h"
 
 /*
  * Resource definition for the MXC IrDA
@@ -225,37 +229,217 @@ struct platform_device mxc_nand_device = {
 	.resource = mxc_nand_resources,
 };
 
+#ifdef CONFIG_FB_IMX
+/*
+ * lcdc:
+ * - i.MX1: the basic controller
+ * - i.MX21: to be checked
+ * - i.MX27: like i.MX1, with slightly variations
+ */
+static struct resource mxc_fb[] = {
+	{
+		.start = LCDC_BASE_ADDR,
+		.end   = LCDC_BASE_ADDR + 0xFFF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = MXC_INT_LCDC,
+		.end   = MXC_INT_LCDC,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+/* mxc lcd driver */
+struct platform_device mxc_fb_device = {
+	.name = "imx-fb",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_fb),
+	.resource = mxc_fb,
+	.dev = {
+		.coherent_dma_mask = 0xFFFFFFFF,
+	},
+};
+#endif
+
+#ifdef CONFIG_MACH_MX27
+static struct resource mxc_fec_resources[] = {
+	{
+		.start	= FEC_BASE_ADDR,
+		.end	= FEC_BASE_ADDR + 0xfff,
+		.flags	= IORESOURCE_MEM
+	}, {
+		.start	= MXC_INT_FEC,
+		.end	= MXC_INT_FEC,
+		.flags	= IORESOURCE_IRQ
+	},
+};
+
+struct platform_device mxc_fec_device = {
+	.name = "fec",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_fec_resources),
+	.resource = mxc_fec_resources,
+};
+#endif
+
+static struct resource mxc_i2c_1_resources[] = {
+	[0] = {
+		.start	= I2C_BASE_ADDR,
+		.end	= I2C_BASE_ADDR + 0x0fff,
+		.flags	= IORESOURCE_MEM
+	},
+	[1] = {
+		.start	= MXC_INT_I2C,
+		.end	= MXC_INT_I2C,
+		.flags	= IORESOURCE_IRQ
+	}
+};
+
+struct platform_device mxc_i2c_device0 = {
+	.name = "imx-i2c",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
+	.resource = mxc_i2c_1_resources
+};
+
+#ifdef CONFIG_MACH_MX27
+static struct resource mxc_i2c_2_resources[] = {
+	[0] = {
+		.start	= I2C2_BASE_ADDR,
+		.end	= I2C2_BASE_ADDR + 0x0fff,
+		.flags	= IORESOURCE_MEM
+	},
+	[1] = {
+		.start	= MXC_INT_I2C2,
+		.end	= MXC_INT_I2C2,
+		.flags	= IORESOURCE_IRQ
+	}
+};
+
+struct platform_device mxc_i2c_device1 = {
+	.name = "imx-i2c",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(mxc_i2c_2_resources),
+	.resource = mxc_i2c_2_resources
+};
+#endif
+
+static struct resource mxc_pwm_resources[] = {
+	[0] = {
+		.start	= PWM_BASE_ADDR,
+		.end	= PWM_BASE_ADDR + 0x0fff,
+		.flags	= IORESOURCE_MEM
+	},
+	[1] = {
+		.start   = MXC_INT_PWM,
+		.end     = MXC_INT_PWM,
+		.flags   = IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device mxc_pwm_device = {
+	.name = "mxc_pwm",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_pwm_resources),
+	.resource = mxc_pwm_resources
+};
+
+/*
+ * Resource definition for the MXC SDHC
+ */
+static struct resource mxc_sdhc1_resources[] = {
+	[0] = {
+			.start = SDHC1_BASE_ADDR,
+			.end   = SDHC1_BASE_ADDR + SZ_4K - 1,
+			.flags = IORESOURCE_MEM,
+			},
+	[1] = {
+			.start = MXC_INT_SDHC1,
+			.end   = MXC_INT_SDHC1,
+			.flags = IORESOURCE_IRQ,
+			},
+	[2] = {
+			.start  = DMA_REQ_SDHC1,
+			.end    = DMA_REQ_SDHC1,
+			.flags  = IORESOURCE_DMA
+		},
+};
+
+static u64 mxc_sdhc1_dmamask = 0xffffffffUL;
+
+struct platform_device mxc_sdhc_device0 = {
+       .name           = "mxc-mmc",
+       .id             = 0,
+       .dev            = {
+               .dma_mask = &mxc_sdhc1_dmamask,
+               .coherent_dma_mask = 0xffffffff,
+       },
+       .num_resources  = ARRAY_SIZE(mxc_sdhc1_resources),
+       .resource       = mxc_sdhc1_resources,
+};
+
+static struct resource mxc_sdhc2_resources[] = {
+	[0] = {
+			.start = SDHC2_BASE_ADDR,
+			.end   = SDHC2_BASE_ADDR + SZ_4K - 1,
+			.flags = IORESOURCE_MEM,
+			},
+	[1] = {
+			.start = MXC_INT_SDHC2,
+			.end   = MXC_INT_SDHC2,
+			.flags = IORESOURCE_IRQ,
+			},
+	[2] = {
+			.start  = DMA_REQ_SDHC2,
+			.end    = DMA_REQ_SDHC2,
+			.flags  = IORESOURCE_DMA
+		},
+};
+
+static u64 mxc_sdhc2_dmamask = 0xffffffffUL;
+
+struct platform_device mxc_sdhc_device1 = {
+       .name           = "mxc-mmc",
+       .id             = 1,
+       .dev            = {
+               .dma_mask = &mxc_sdhc2_dmamask,
+               .coherent_dma_mask = 0xffffffff,
+       },
+       .num_resources  = ARRAY_SIZE(mxc_sdhc2_resources),
+       .resource       = mxc_sdhc2_resources,
+};
+
 /* GPIO port description */
 static struct mxc_gpio_port imx_gpio_ports[] = {
 	[0] = {
 		.chip.label = "gpio-0",
 		.irq = MXC_INT_GPIO,
-		.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 0),
+		.base = IO_ADDRESS(GPIO_BASE_ADDR),
 		.virtual_irq_start = MXC_GPIO_IRQ_START,
 	},
 	[1] = {
 		.chip.label = "gpio-1",
-		.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 1),
+		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 32,
 	},
 	[2] = {
 		.chip.label = "gpio-2",
-		.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 2),
+		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 64,
 	},
 	[3] = {
 		.chip.label = "gpio-3",
-		.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 3),
+		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 96,
 	},
 	[4] = {
 		.chip.label = "gpio-4",
-		.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 4),
+		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 128,
 	},
 	[5] = {
 		.chip.label = "gpio-5",
-		.base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 5),
+		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 160,
 	}
 };

+ 7 - 1
arch/arm/mach-mx2/devices.h

@@ -1,4 +1,3 @@
-
 extern struct platform_device mxc_gpt1;
 extern struct platform_device mxc_gpt2;
 extern struct platform_device mxc_gpt3;
@@ -14,3 +13,10 @@ extern struct platform_device mxc_uart_device4;
 extern struct platform_device mxc_uart_device5;
 extern struct platform_device mxc_w1_master_device;
 extern struct platform_device mxc_nand_device;
+extern struct platform_device mxc_fb_device;
+extern struct platform_device mxc_fec_device;
+extern struct platform_device mxc_pwm_device;
+extern struct platform_device mxc_i2c_device0;
+extern struct platform_device mxc_i2c_device1;
+extern struct platform_device mxc_sdhc_device0;
+extern struct platform_device mxc_sdhc_device1;

+ 1 - 0
arch/arm/mach-mx2/generic.c

@@ -21,6 +21,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <mach/hardware.h>
+#include <mach/common.h>
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
 

+ 7 - 12
arch/arm/mach-mx2/mx27ads.c

@@ -31,7 +31,7 @@
 #include <asm/mach/map.h>
 #include <mach/gpio.h>
 #include <mach/imx-uart.h>
-#include <mach/iomux-mx1-mx2.h>
+#include <mach/iomux.h>
 #include <mach/board-mx27ads.h>
 
 #include "devices.h"
@@ -135,6 +135,7 @@ static int uart_mxc_port3_exit(struct platform_device *pdev)
 {
 	mxc_gpio_release_multiple_pins(mxc_uart3_pins,
 			ARRAY_SIZE(mxc_uart3_pins));
+	return 0;
 }
 
 static int mxc_uart4_pins[] = {
@@ -179,6 +180,7 @@ static int uart_mxc_port5_exit(struct platform_device *pdev)
 
 static struct platform_device *platform_devices[] __initdata = {
 	&mx27ads_nor_mtd_device,
+	&mxc_fec_device,
 };
 
 static int mxc_fec_pins[] = {
@@ -196,7 +198,7 @@ static int mxc_fec_pins[] = {
 	PD11_AOUT_FEC_TX_CLK,
 	PD12_AOUT_FEC_RXD0,
 	PD13_AOUT_FEC_RX_DV,
-	PD14_AOUT_FEC_CLR,
+	PD14_AOUT_FEC_RX_CLK,
 	PD15_AOUT_FEC_COL,
 	PD16_AIN_FEC_TX_ER,
 	PF23_AIN_FEC_TX_EN
@@ -208,12 +210,6 @@ static void gpio_fec_active(void)
 			ARRAY_SIZE(mxc_fec_pins), "FEC");
 }
 
-static void gpio_fec_inactive(void)
-{
-	mxc_gpio_release_multiple_pins(mxc_fec_pins,
-			ARRAY_SIZE(mxc_fec_pins));
-}
-
 static struct imxuart_platform_data uart_pdata[] = {
 	{
 		.init = uart_mxc_port0_init,
@@ -263,11 +259,10 @@ static void __init mx27ads_timer_init(void)
 	if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0)
 		fref = 27000000;
 
-	mxc_clocks_init(fref);
-	mxc_timer_init("gpt_clk.0");
+	mx27_clocks_init(fref);
 }
 
-struct sys_timer mx27ads_timer = {
+static struct sys_timer mx27ads_timer = {
 	.init	= mx27ads_timer_init,
 };
 
@@ -280,7 +275,7 @@ static struct map_desc mx27ads_io_desc[] __initdata = {
 	},
 };
 
-void __init mx27ads_map_io(void)
+static void __init mx27ads_map_io(void)
 {
 	mxc_map_io();
 	iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc));

+ 68 - 14
arch/arm/mach-mx2/pcm038.c

@@ -20,11 +20,18 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/plat-ram.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <mach/common.h>
 #include <mach/hardware.h>
-#include <mach/iomux-mx1-mx2.h>
+#include <mach/iomux.h>
+#ifdef CONFIG_I2C_IMX
+#include <mach/i2c.h>
+#endif
 #include <asm/mach/time.h>
 #include <mach/imx-uart.h>
 #include <mach/board-pcm038.h>
@@ -121,10 +128,10 @@ static int uart_mxc_port1_exit(struct platform_device *pdev)
 	return 0;
 }
 
-static int mxc_uart2_pins[] = { PE10_PF_UART3_CTS,
+static int mxc_uart2_pins[] = { PE8_PF_UART3_TXD,
 				PE9_PF_UART3_RXD,
 				PE10_PF_UART3_CTS,
-				PE9_PF_UART3_RXD };
+				PE11_PF_UART3_RTS };
 
 static int uart_mxc_port2_init(struct platform_device *pdev)
 {
@@ -170,7 +177,7 @@ static int mxc_fec_pins[] = {
 	PD11_AOUT_FEC_TX_CLK,
 	PD12_AOUT_FEC_RXD0,
 	PD13_AOUT_FEC_RX_DV,
-	PD14_AOUT_FEC_CLR,
+	PD14_AOUT_FEC_RX_CLK,
 	PD15_AOUT_FEC_COL,
 	PD16_AIN_FEC_TX_ER,
 	PF23_AIN_FEC_TX_EN
@@ -182,12 +189,6 @@ static void gpio_fec_active(void)
 			ARRAY_SIZE(mxc_fec_pins), "FEC");
 }
 
-static void gpio_fec_inactive(void)
-{
-	mxc_gpio_release_multiple_pins(mxc_fec_pins,
-			ARRAY_SIZE(mxc_fec_pins));
-}
-
 static struct mxc_nand_platform_data pcm038_nand_board_info = {
 	.width = 1,
 	.hw_ecc = 1,
@@ -196,6 +197,7 @@ static struct mxc_nand_platform_data pcm038_nand_board_info = {
 static struct platform_device *platform_devices[] __initdata = {
 	&pcm038_nor_mtd_device,
 	&mxc_w1_master_device,
+	&mxc_fec_device,
 	&pcm038_sram_mtd_device,
 };
 
@@ -208,6 +210,51 @@ static void __init pcm038_init_sram(void)
 	__raw_writel(0x22220a00, CSCR_A(1));
 }
 
+#ifdef CONFIG_I2C_IMX
+static int mxc_i2c1_pins[] = {
+	PC5_PF_I2C2_SDA,
+	PC6_PF_I2C2_SCL
+};
+
+static int pcm038_i2c_1_init(struct device *dev)
+{
+	return mxc_gpio_setup_multiple_pins(mxc_i2c1_pins, ARRAY_SIZE(mxc_i2c1_pins),
+			"I2C1");
+}
+
+static void pcm038_i2c_1_exit(struct device *dev)
+{
+	mxc_gpio_release_multiple_pins(mxc_i2c1_pins, ARRAY_SIZE(mxc_i2c1_pins));
+}
+
+static struct imxi2c_platform_data pcm038_i2c_1_data = {
+	.bitrate = 100000,
+	.init = pcm038_i2c_1_init,
+	.exit = pcm038_i2c_1_exit,
+};
+
+static struct at24_platform_data board_eeprom = {
+	.byte_len = 4096,
+	.page_size = 32,
+	.flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pcm038_i2c_devices[] = {
+	[0] = {
+		I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+		.platform_data = &board_eeprom,
+	},
+	[1] = {
+		I2C_BOARD_INFO("rtc-pcf8563", 0x51),
+		.type = "pcf8563"
+	},
+	[2] = {
+		I2C_BOARD_INFO("lm75", 0x4a),
+		.type = "lm75"
+	}
+};
+#endif
+
 static void __init pcm038_init(void)
 {
 	gpio_fec_active();
@@ -217,9 +264,17 @@ static void __init pcm038_init(void)
 	mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
 	mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
 
-	mxc_gpio_mode(PE16_AF_RTCK); /* OWIRE */
+	mxc_gpio_mode(PE16_AF_OWIRE);
 	mxc_register_device(&mxc_nand_device, &pcm038_nand_board_info);
 
+#ifdef CONFIG_I2C_IMX
+	/* only the i2c master 1 is used on this CPU card */
+	i2c_register_board_info(1, pcm038_i2c_devices,
+				ARRAY_SIZE(pcm038_i2c_devices));
+
+	mxc_register_device(&mxc_i2c_device1, &pcm038_i2c_1_data);
+#endif
+
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 
 #ifdef CONFIG_MACH_PCM970_BASEBOARD
@@ -229,11 +284,10 @@ static void __init pcm038_init(void)
 
 static void __init pcm038_timer_init(void)
 {
-	mxc_clocks_init(26000000);
-	mxc_timer_init("gpt_clk.0");
+	mx27_clocks_init(26000000);
 }
 
-struct sys_timer pcm038_timer = {
+static struct sys_timer pcm038_timer = {
 	.init = pcm038_timer_init,
 };
 

+ 132 - 1
arch/arm/mach-mx2/pcm970-baseboard.c

@@ -17,9 +17,138 @@
  */
 
 #include <linux/platform_device.h>
-#include <mach/hardware.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
 #include <asm/mach/arch.h>
 
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/mmc.h>
+#include <mach/imxfb.h>
+#include <mach/iomux.h>
+
+#include "devices.h"
+
+static int pcm970_sdhc2_get_ro(struct device *dev)
+{
+	return gpio_get_value(GPIO_PORTC + 28);
+}
+
+static int pcm970_sdhc2_pins[] = {
+	PB4_PF_SD2_D0,
+	PB5_PF_SD2_D1,
+	PB6_PF_SD2_D2,
+	PB7_PF_SD2_D3,
+	PB8_PF_SD2_CMD,
+	PB9_PF_SD2_CLK,
+};
+
+static int pcm970_sdhc2_init(struct device *dev, irq_handler_t detect_irq, void *data)
+{
+	int ret;
+
+	ret = mxc_gpio_setup_multiple_pins(pcm970_sdhc2_pins,
+		ARRAY_SIZE(pcm970_sdhc2_pins), "sdhc2");
+	if(ret)
+		return ret;
+
+	ret = request_irq(IRQ_GPIOC(29), detect_irq, 0,
+				"imx-mmc-detect", data);
+	if (ret)
+		goto out_release_gpio;
+
+	set_irq_type(IRQ_GPIOC(29), IRQF_TRIGGER_FALLING);
+
+	ret = gpio_request(GPIO_PORTC + 28, "imx-mmc-ro");
+	if (ret)
+		goto out_release_gpio;
+
+	mxc_gpio_mode((GPIO_PORTC | 28) | GPIO_GPIO | GPIO_IN);
+	gpio_direction_input(GPIO_PORTC + 28);
+
+	return 0;
+
+out_release_gpio:
+	mxc_gpio_release_multiple_pins(pcm970_sdhc2_pins,
+			ARRAY_SIZE(pcm970_sdhc2_pins));
+	return ret;
+}
+
+static void pcm970_sdhc2_exit(struct device *dev, void *data)
+{
+	free_irq(IRQ_GPIOC(29), data);
+	gpio_free(GPIO_PORTC + 28);
+	mxc_gpio_release_multiple_pins(pcm970_sdhc2_pins,
+			ARRAY_SIZE(pcm970_sdhc2_pins));
+}
+
+static struct imxmmc_platform_data sdhc_pdata = {
+	.get_ro = pcm970_sdhc2_get_ro,
+	.init = pcm970_sdhc2_init,
+	.exit = pcm970_sdhc2_exit,
+};
+
+static int mxc_fb_pins[] = {
+	PA5_PF_LSCLK,	PA6_PF_LD0,	PA7_PF_LD1,	PA8_PF_LD2,
+	PA9_PF_LD3,	PA10_PF_LD4,	PA11_PF_LD5,	PA12_PF_LD6,
+	PA13_PF_LD7,	PA14_PF_LD8,	PA15_PF_LD9,	PA16_PF_LD10,
+	PA17_PF_LD11,	PA18_PF_LD12,	PA19_PF_LD13,	PA20_PF_LD14,
+	PA21_PF_LD15,	PA22_PF_LD16,	PA23_PF_LD17,	PA24_PF_REV,
+	PA25_PF_CLS,	PA26_PF_PS,	PA27_PF_SPL_SPR, PA28_PF_HSYNC,
+	PA29_PF_VSYNC,	PA30_PF_CONTRAST, PA31_PF_OE_ACD
+};
+
+static int pcm038_fb_init(struct platform_device *pdev)
+{
+	return mxc_gpio_setup_multiple_pins(mxc_fb_pins,
+			ARRAY_SIZE(mxc_fb_pins), "FB");
+}
+
+static int pcm038_fb_exit(struct platform_device *pdev)
+{
+	mxc_gpio_release_multiple_pins(mxc_fb_pins, ARRAY_SIZE(mxc_fb_pins));
+
+	return 0;
+}
+
+/*
+ * Connected is a portrait Sharp-QVGA display
+ * of type: LQ035Q7DH06
+ */
+static struct imx_fb_platform_data pcm038_fb_data = {
+	.pixclock	= 188679, /* in ps (5.3MHz) */
+	.xres		= 240,
+	.yres		= 320,
+
+	.bpp		= 16,
+	.hsync_len	= 7,
+	.left_margin	= 5,
+	.right_margin	= 16,
+
+	.vsync_len	= 1,
+	.upper_margin	= 7,
+	.lower_margin	= 9,
+	.fixed_screen_cpu = 0,
+
+	/*
+	 * - HSYNC active high
+	 * - VSYNC active high
+	 * - clk notenabled while idle
+	 * - clock not inverted
+	 * - data not inverted
+	 * - data enable low active
+	 * - enable sharp mode
+	 */
+	.pcr		= 0xFA0080C0,
+	.pwmr		= 0x00A903FF,
+	.lscr1		= 0x00120300,
+	.dmacr		= 0x00020010,
+
+	.init = pcm038_fb_init,
+	.exit = pcm038_fb_exit,
+};
+
 /*
  * system init for baseboard usage. Will be called by pcm038 init.
  *
@@ -28,4 +157,6 @@
  */
 void __init pcm970_baseboard_init(void)
 {
+	mxc_register_device(&mxc_fb_device, &pcm038_fb_data);
+	mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
 }

+ 3 - 0
arch/arm/mach-mx2/serial.c

@@ -22,6 +22,7 @@
 #include <linux/serial.h>
 #include <mach/hardware.h>
 #include <mach/imx-uart.h>
+#include "devices.h"
 
 static struct resource uart0[] = {
 	{
@@ -99,6 +100,7 @@ struct platform_device mxc_uart_device3 = {
 	.num_resources = ARRAY_SIZE(uart3),
 };
 
+#ifdef CONFIG_MACH_MX27
 static struct resource uart4[] = {
 	{
 		.start = UART5_BASE_ADDR,
@@ -136,3 +138,4 @@ struct platform_device mxc_uart_device5 = {
 	.resource = uart5,
 	.num_resources = ARRAY_SIZE(uart5),
 };
+#endif

+ 32 - 4
arch/arm/mach-mx3/Kconfig

@@ -1,21 +1,40 @@
-menu "MX3 Options"
-	depends on ARCH_MX3
+if ARCH_MX3
+
+config ARCH_MX31
+	bool
+
+config ARCH_MX35
+	bool
+
+comment "MX3 platforms:"
 
 config MACH_MX31ADS
 	bool "Support MX31ADS platforms"
+	select ARCH_MX31
 	default y
 	help
 	  Include support for MX31ADS platform. This includes specific
 	  configurations for the board and its peripherals.
 
+config MACH_MX31ADS_WM1133_EV1
+	bool "Support Wolfson Microelectronics 1133-EV1 module"
+	depends on MACH_MX31ADS
+	select MFD_WM8350_CONFIG_MODE_0
+	select MFD_WM8352_CONFIG_MODE_0
+	help
+	  Include support for the Wolfson Microelectronics 1133-EV1 PMU
+	  and audio module for the MX31ADS platform.
+
 config MACH_PCM037
-	bool "Support Phytec pcm037 platforms"
+	bool "Support Phytec pcm037 (i.MX31) platforms"
+	select ARCH_MX31
 	help
 	  Include support for Phytec pcm037 platform. This includes
 	  specific configurations for the board and its peripherals.
 
 config MACH_MX31LITE
 	bool "Support MX31 LITEKIT (LogicPD)"
+	select ARCH_MX31
 	default n
 	help
 	  Include support for MX31 LITEKIT platform. This includes specific
@@ -23,6 +42,7 @@ config MACH_MX31LITE
 
 config MACH_MX31_3DS
 	bool "Support MX31PDK (3DS)"
+	select ARCH_MX31
 	default n
 	help
 	  Include support for MX31PDK (3DS) platform. This includes specific
@@ -30,10 +50,18 @@ config MACH_MX31_3DS
 
 config MACH_MX31MOBOARD
 	bool "Support mx31moboard platforms (EPFL Mobots group)"
+	select ARCH_MX31
 	default n
 	help
 	  Include support for mx31moboard platform. This includes specific
 	  configurations for the board and its peripherals.
 
-endmenu
+config MACH_QONG
+	bool "Support Dave/DENX QongEVB-LITE platform"
+	select ARCH_MX31
+	default n
+	help
+	  Include support for Dave/DENX QongEVB-LITE platform. This includes
+	  specific configurations for the board and its peripherals.
 
+endif

+ 6 - 2
arch/arm/mach-mx3/Makefile

@@ -4,9 +4,13 @@
 
 # Object file lists.
 
-obj-y			:= mm.o clock.o devices.o iomux.o
+obj-y				:= mm.o devices.o
+obj-$(CONFIG_ARCH_MX31)		+= clock.o iomux.o
+obj-$(CONFIG_ARCH_MX35)		+= clock-imx35.o
 obj-$(CONFIG_MACH_MX31ADS)	+= mx31ads.o
 obj-$(CONFIG_MACH_MX31LITE)	+= mx31lite.o
 obj-$(CONFIG_MACH_PCM037)	+= pcm037.o
 obj-$(CONFIG_MACH_MX31_3DS)	+= mx31pdk.o
-obj-$(CONFIG_MACH_MX31MOBOARD)	+= mx31moboard.o
+obj-$(CONFIG_MACH_MX31MOBOARD)	+= mx31moboard.o mx31moboard-devboard.o \
+				   mx31moboard-marxbot.o
+obj-$(CONFIG_MACH_QONG)		+= qong.o

+ 487 - 0
arch/arm/mach-mx3/clock-imx35.c

@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer, Pengutronix
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define CCM_BASE	IO_ADDRESS(CCM_BASE_ADDR)
+
+#define CCM_CCMR        0x00
+#define CCM_PDR0        0x04
+#define CCM_PDR1        0x08
+#define CCM_PDR2        0x0C
+#define CCM_PDR3        0x10
+#define CCM_PDR4        0x14
+#define CCM_RCSR        0x18
+#define CCM_MPCTL       0x1C
+#define CCM_PPCTL       0x20
+#define CCM_ACMR        0x24
+#define CCM_COSR        0x28
+#define CCM_CGR0        0x2C
+#define CCM_CGR1        0x30
+#define CCM_CGR2        0x34
+#define CCM_CGR3        0x38
+
+#ifdef HAVE_SET_RATE_SUPPORT
+static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost)
+{
+	u32 min_pre, temp_pre, old_err, err;
+
+	min_pre = (div - 1) / maxpost + 1;
+	old_err = 8;
+
+	for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+		if (div > (temp_pre * maxpost))
+			break;
+
+		if (div < (temp_pre * temp_pre))
+			continue;
+
+		err = div % temp_pre;
+
+		if (err == 0) {
+			*pre = temp_pre;
+			break;
+		}
+
+		err = temp_pre - err;
+
+		if (err < old_err) {
+			old_err = err;
+			*pre = temp_pre;
+		}
+	}
+
+	*post = (div + *pre - 1) / *pre;
+}
+
+/* get the best values for a 3-bit divider combined with a 6-bit divider */
+static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post)
+{
+	if (div >= 512) {
+		*pre = 8;
+		*post = 64;
+	} else if (div >= 64) {
+		calc_dividers(div, pre, post, 64);
+	} else if (div <= 8) {
+		*pre = div;
+		*post = 1;
+	} else {
+		*pre = 1;
+		*post = div;
+	}
+}
+
+/* get the best values for two cascaded 3-bit dividers */
+static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post)
+{
+	if (div >= 64) {
+		*pre = *post = 8;
+	} else if (div > 8) {
+		calc_dividers(div, pre, post, 8);
+	} else {
+		*pre = 1;
+		*post = div;
+	}
+}
+#endif
+
+static unsigned long get_rate_mpll(void)
+{
+	ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL);
+
+	return mxc_decode_pll(mpctl, 24000000);
+}
+
+static unsigned long get_rate_ppll(void)
+{
+	ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL);
+
+	return mxc_decode_pll(ppctl, 24000000);
+}
+
+struct arm_ahb_div {
+	unsigned char arm, ahb, sel;
+};
+
+static struct arm_ahb_div clk_consumer[] = {
+	{ .arm = 1, .ahb = 4, .sel = 0},
+	{ .arm = 1, .ahb = 3, .sel = 1},
+	{ .arm = 2, .ahb = 2, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 4, .ahb = 1, .sel = 0},
+	{ .arm = 1, .ahb = 5, .sel = 0},
+	{ .arm = 1, .ahb = 8, .sel = 0},
+	{ .arm = 1, .ahb = 6, .sel = 1},
+	{ .arm = 2, .ahb = 4, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 4, .ahb = 2, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+};
+
+static struct arm_ahb_div clk_automotive[] = {
+	{ .arm = 1, .ahb = 3, .sel = 0},
+	{ .arm = 1, .ahb = 2, .sel = 1},
+	{ .arm = 2, .ahb = 1, .sel = 1},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 1, .ahb = 6, .sel = 0},
+	{ .arm = 1, .ahb = 4, .sel = 1},
+	{ .arm = 2, .ahb = 2, .sel = 1},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+};
+
+static unsigned long get_rate_arm(void)
+{
+	unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+	struct arm_ahb_div *aad;
+	unsigned long fref = get_rate_mpll();
+
+	if (pdr0 & 1) {
+		/* consumer path */
+		aad = &clk_consumer[(pdr0 >> 16) & 0xf];
+		if (aad->sel)
+			fref = fref * 2 / 3;
+	} else {
+		/* auto path */
+		aad = &clk_automotive[(pdr0 >> 9) & 0x7];
+		if (aad->sel)
+			fref = fref * 3 / 4;
+	}
+	return fref / aad->arm;
+}
+
+static unsigned long get_rate_ahb(struct clk *clk)
+{
+	unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+	struct arm_ahb_div *aad;
+	unsigned long fref = get_rate_mpll();
+
+	if (pdr0 & 1)
+		/* consumer path */
+		aad = &clk_consumer[(pdr0 >> 16) & 0xf];
+	else
+		/* auto path */
+		aad = &clk_automotive[(pdr0 >> 9) & 0x7];
+
+	return fref / aad->ahb;
+}
+
+static unsigned long get_rate_ipg(struct clk *clk)
+{
+	return get_rate_ahb(NULL) >> 1;
+}
+
+static unsigned long get_3_3_div(unsigned long in)
+{
+	return (((in >> 3) & 0x7) + 1) * ((in & 0x7) + 1);
+}
+
+static unsigned long get_rate_uart(struct clk *clk)
+{
+	unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
+	unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+	unsigned long div = get_3_3_div(pdr4 >> 10);
+
+	if (pdr3 & (1 << 14))
+		return get_rate_arm() / div;
+	else
+		return get_rate_ppll() / div;
+}
+
+static unsigned long get_rate_sdhc(struct clk *clk)
+{
+	unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
+	unsigned long div, rate;
+
+	if (pdr3 & (1 << 6))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	switch (clk->id) {
+	default:
+	case 0:
+		div = pdr3 & 0x3f;
+		break;
+	case 1:
+		div = (pdr3 >> 8) & 0x3f;
+		break;
+	case 2:
+		div = (pdr3 >> 16) & 0x3f;
+		break;
+	}
+
+	return rate / get_3_3_div(div);
+}
+
+static unsigned long get_rate_mshc(struct clk *clk)
+{
+	unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1);
+	unsigned long div1, div2, rate;
+
+	if (pdr1 & (1 << 7))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	div1 = (pdr1 >> 29) & 0x7;
+	div2 = (pdr1 >> 22) & 0x3f;
+
+	return rate / ((div1 + 1) * (div2 + 1));
+}
+
+static unsigned long get_rate_ssi(struct clk *clk)
+{
+	unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
+	unsigned long div1, div2, rate;
+
+	if (pdr2 & (1 << 6))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	switch (clk->id) {
+	default:
+	case 0:
+		div1 = pdr2 & 0x3f;
+		div2 = (pdr2 >> 24) & 0x7;
+		break;
+	case 1:
+		div1 = (pdr2 >> 8) & 0x3f;
+		div2 = (pdr2 >> 27) & 0x7;
+		break;
+	}
+
+	return rate / ((div1 + 1) * (div2 + 1));
+}
+
+static unsigned long get_rate_csi(struct clk *clk)
+{
+	unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
+	unsigned long rate;
+
+	if (pdr2 & (1 << 7))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	return rate / get_3_3_div((pdr2 >> 16) & 0x3f);
+}
+
+static unsigned long get_rate_ipg_per(struct clk *clk)
+{
+	unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+	unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+	unsigned long div1, div2;
+
+	if (pdr0 & (1 << 26)) {
+		div1 = (pdr4 >> 19) & 0x7;
+		div2 = (pdr4 >> 16) & 0x7;
+		return get_rate_arm() / ((div1 + 1) * (div2 + 1));
+	} else {
+		div1 = (pdr0 >> 12) & 0x7;
+		return get_rate_ahb(NULL) / div1;
+	}
+}
+
+static int clk_cgr_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg |= 3 << clk->enable_shift;
+	__raw_writel(reg, clk->enable_reg);
+
+	return 0;
+}
+
+static void clk_cgr_disable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg &= ~(3 << clk->enable_shift);
+	__raw_writel(reg, clk->enable_reg);
+}
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr)		\
+	static struct clk name = {			\
+		.id		= i,			\
+		.enable_reg	= CCM_BASE + er,	\
+		.enable_shift	= es,			\
+		.get_rate	= gr,			\
+		.set_rate	= sr,			\
+		.enable		= clk_cgr_enable,	\
+		.disable	= clk_cgr_disable,	\
+	}
+
+DEFINE_CLOCK(asrc_clk,   0, CCM_CGR0,  0, NULL, NULL);
+DEFINE_CLOCK(ata_clk,    0, CCM_CGR0,  2, get_rate_ipg, NULL);
+DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0,  4, NULL, NULL);
+DEFINE_CLOCK(can1_clk,   0, CCM_CGR0,  6, get_rate_ipg, NULL);
+DEFINE_CLOCK(can2_clk,   1, CCM_CGR0,  8, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi1_clk,  0, CCM_CGR0, 10, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi2_clk,  1, CCM_CGR0, 12, get_rate_ipg, NULL);
+DEFINE_CLOCK(ect_clk,    0, CCM_CGR0, 14, get_rate_ipg, NULL);
+DEFINE_CLOCK(edio_clk,   0, CCM_CGR0, 16, NULL, NULL);
+DEFINE_CLOCK(emi_clk,    0, CCM_CGR0, 18, get_rate_ipg, NULL);
+DEFINE_CLOCK(epit1_clk,  0, CCM_CGR0, 20, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(epit2_clk,  1, CCM_CGR0, 22, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(esai_clk,   0, CCM_CGR0, 24, NULL, NULL);
+DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL);
+DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL);
+DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL);
+
+DEFINE_CLOCK(fec_clk,    0, CCM_CGR1,  0, get_rate_ipg, NULL);
+DEFINE_CLOCK(gpio1_clk,  0, CCM_CGR1,  2, NULL, NULL);
+DEFINE_CLOCK(gpio2_clk,  1, CCM_CGR1,  4, NULL, NULL);
+DEFINE_CLOCK(gpio3_clk,  2, CCM_CGR1,  6, NULL, NULL);
+DEFINE_CLOCK(gpt_clk,    0, CCM_CGR1,  8, get_rate_ipg, NULL);
+DEFINE_CLOCK(i2c1_clk,   0, CCM_CGR1, 10, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(i2c2_clk,   1, CCM_CGR1, 12, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(i2c3_clk,   2, CCM_CGR1, 14, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL);
+DEFINE_CLOCK(ipu_clk,    0, CCM_CGR1, 18, NULL, NULL);
+DEFINE_CLOCK(kpp_clk,    0, CCM_CGR1, 20, get_rate_ipg, NULL);
+DEFINE_CLOCK(mlb_clk,    0, CCM_CGR1, 22, get_rate_ahb, NULL);
+DEFINE_CLOCK(mshc_clk,   0, CCM_CGR1, 24, get_rate_mshc, NULL);
+DEFINE_CLOCK(owire_clk,  0, CCM_CGR1, 26, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(pwm_clk,    0, CCM_CGR1, 28, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(rngc_clk,   0, CCM_CGR1, 30, get_rate_ipg, NULL);
+
+DEFINE_CLOCK(rtc_clk,    0, CCM_CGR2,  0, get_rate_ipg, NULL);
+DEFINE_CLOCK(rtic_clk,   0, CCM_CGR2,  2, get_rate_ahb, NULL);
+DEFINE_CLOCK(scc_clk,    0, CCM_CGR2,  4, get_rate_ipg, NULL);
+DEFINE_CLOCK(sdma_clk,   0, CCM_CGR2,  6, NULL, NULL);
+DEFINE_CLOCK(spba_clk,   0, CCM_CGR2,  8, get_rate_ipg, NULL);
+DEFINE_CLOCK(spdif_clk,  0, CCM_CGR2, 10, NULL, NULL);
+DEFINE_CLOCK(ssi1_clk,   0, CCM_CGR2, 12, get_rate_ssi, NULL);
+DEFINE_CLOCK(ssi2_clk,   1, CCM_CGR2, 14, get_rate_ssi, NULL);
+DEFINE_CLOCK(uart1_clk,  0, CCM_CGR2, 16, get_rate_uart, NULL);
+DEFINE_CLOCK(uart2_clk,  1, CCM_CGR2, 18, get_rate_uart, NULL);
+DEFINE_CLOCK(uart3_clk,  2, CCM_CGR2, 20, get_rate_uart, NULL);
+DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, NULL, NULL);
+DEFINE_CLOCK(wdog_clk,   0, CCM_CGR2, 24, NULL, NULL);
+DEFINE_CLOCK(max_clk,    0, CCM_CGR2, 26, NULL, NULL);
+DEFINE_CLOCK(admux_clk,  0, CCM_CGR2, 30, NULL, NULL);
+
+DEFINE_CLOCK(csi_clk,    0, CCM_CGR3,  0, get_rate_csi, NULL);
+DEFINE_CLOCK(iim_clk,    0, CCM_CGR3,  2, NULL, NULL);
+DEFINE_CLOCK(gpu2d_clk,  0, CCM_CGR3,  4, NULL, NULL);
+
+#define _REGISTER_CLOCK(d, n, c)	\
+	{				\
+		.dev_id = d,		\
+		.con_id = n,		\
+		.clk = &c,		\
+	},
+
+static struct clk_lookup lookups[] __initdata = {
+	_REGISTER_CLOCK(NULL, "asrc", asrc_clk)
+	_REGISTER_CLOCK(NULL, "ata", ata_clk)
+	_REGISTER_CLOCK(NULL, "audmux", audmux_clk)
+	_REGISTER_CLOCK(NULL, "can", can1_clk)
+	_REGISTER_CLOCK(NULL, "can", can2_clk)
+	_REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
+	_REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
+	_REGISTER_CLOCK(NULL, "ect", ect_clk)
+	_REGISTER_CLOCK(NULL, "edio", edio_clk)
+	_REGISTER_CLOCK(NULL, "emi", emi_clk)
+	_REGISTER_CLOCK(NULL, "epit", epit1_clk)
+	_REGISTER_CLOCK(NULL, "epit", epit2_clk)
+	_REGISTER_CLOCK(NULL, "esai", esai_clk)
+	_REGISTER_CLOCK(NULL, "sdhc", esdhc1_clk)
+	_REGISTER_CLOCK(NULL, "sdhc", esdhc2_clk)
+	_REGISTER_CLOCK(NULL, "sdhc", esdhc3_clk)
+	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+	_REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
+	_REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
+	_REGISTER_CLOCK(NULL, "gpio", gpio3_clk)
+	_REGISTER_CLOCK("gpt.0", NULL, gpt_clk)
+	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+	_REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
+	_REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk)
+	_REGISTER_CLOCK(NULL, "ipu", ipu_clk)
+	_REGISTER_CLOCK(NULL, "kpp", kpp_clk)
+	_REGISTER_CLOCK(NULL, "mlb", mlb_clk)
+	_REGISTER_CLOCK(NULL, "mshc", mshc_clk)
+	_REGISTER_CLOCK("mxc_w1", NULL, owire_clk)
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+	_REGISTER_CLOCK(NULL, "rngc", rngc_clk)
+	_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+	_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
+	_REGISTER_CLOCK(NULL, "scc", scc_clk)
+	_REGISTER_CLOCK(NULL, "sdma", sdma_clk)
+	_REGISTER_CLOCK(NULL, "spba", spba_clk)
+	_REGISTER_CLOCK(NULL, "spdif", spdif_clk)
+	_REGISTER_CLOCK(NULL, "ssi", ssi1_clk)
+	_REGISTER_CLOCK(NULL, "ssi", ssi2_clk)
+	_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+	_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+	_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+	_REGISTER_CLOCK(NULL, "usbotg", usbotg_clk)
+	_REGISTER_CLOCK("mxc_wdt.0", NULL, wdog_clk)
+	_REGISTER_CLOCK(NULL, "max", max_clk)
+	_REGISTER_CLOCK(NULL, "admux", admux_clk)
+	_REGISTER_CLOCK(NULL, "csi", csi_clk)
+	_REGISTER_CLOCK(NULL, "iim", iim_clk)
+	_REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk)
+};
+
+int __init mx35_clocks_init()
+{
+	int i;
+	unsigned int ll = 0;
+
+	mxc_set_cpu_type(MXC_CPU_MX35);
+
+#ifdef CONFIG_DEBUG_LL_CONSOLE
+	ll = (3 << 16);
+#endif
+
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
+
+	/* Turn off all clocks except the ones we need to survive, namely:
+	 * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart
+	 */
+	__raw_writel((3 << 18), CCM_BASE + CCM_CGR0);
+	__raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16),
+			CCM_BASE + CCM_CGR1);
+	__raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2);
+	__raw_writel(0, CCM_BASE + CCM_CGR3);
+
+	mxc_timer_init(&gpt_clk);
+
+	return 0;
+}
+

File diff suppressed because it is too large
+ 206 - 751
arch/arm/mach-mx3/clock.c


+ 0 - 153
arch/arm/mach-mx3/crm_regs.h

@@ -91,47 +91,6 @@
 #define MXC_CCM_PDR0_MCU_PODF_OFFSET            0
 #define MXC_CCM_PDR0_MCU_PODF_MASK              0x7
 
-#define MXC_CCM_PDR0_HSP_DIV_1                  (0x0 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_2                  (0x1 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_3                  (0x2 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_4                  (0x3 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_5                  (0x4 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_6                  (0x5 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_7                  (0x6 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_8                  (0x7 << 11)
-
-#define MXC_CCM_PDR0_IPG_DIV_1                  (0x0 << 6)
-#define MXC_CCM_PDR0_IPG_DIV_2                  (0x1 << 6)
-#define MXC_CCM_PDR0_IPG_DIV_3                  (0x2 << 6)
-#define MXC_CCM_PDR0_IPG_DIV_4                  (0x3 << 6)
-
-#define MXC_CCM_PDR0_MAX_DIV_1                  (0x0 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_2                  (0x1 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_3                  (0x2 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_4                  (0x3 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_5                  (0x4 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_6                  (0x5 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_7                  (0x6 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_8                  (0x7 << 3)
-
-#define MXC_CCM_PDR0_NFC_DIV_1                  (0x0 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_2                  (0x1 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_3                  (0x2 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_4                  (0x3 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_5                  (0x4 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_6                  (0x5 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_7                  (0x6 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_8                  (0x7 << 8)
-
-#define MXC_CCM_PDR0_MCU_DIV_1                  0x0
-#define MXC_CCM_PDR0_MCU_DIV_2                  0x1
-#define MXC_CCM_PDR0_MCU_DIV_3                  0x2
-#define MXC_CCM_PDR0_MCU_DIV_4                  0x3
-#define MXC_CCM_PDR0_MCU_DIV_5                  0x4
-#define MXC_CCM_PDR0_MCU_DIV_6                  0x5
-#define MXC_CCM_PDR0_MCU_DIV_7                  0x6
-#define MXC_CCM_PDR0_MCU_DIV_8                  0x7
-
 #define MXC_CCM_PDR1_USB_PRDF_OFFSET            30
 #define MXC_CCM_PDR1_USB_PRDF_MASK              (0x3 << 30)
 #define MXC_CCM_PDR1_USB_PODF_OFFSET            27
@@ -152,118 +111,6 @@
 /* Bit definitions for RCSR */
 #define MXC_CCM_RCSR_NF16B			0x80000000
 
-/* Bit definitions for both MCU, USB and SR PLL control registers */
-#define MXC_CCM_PCTL_BRM                        0x80000000
-#define MXC_CCM_PCTL_PD_OFFSET                  26
-#define MXC_CCM_PCTL_PD_MASK                    (0xF << 26)
-#define MXC_CCM_PCTL_MFD_OFFSET                 16
-#define MXC_CCM_PCTL_MFD_MASK                   (0x3FF << 16)
-#define MXC_CCM_PCTL_MFI_OFFSET                 10
-#define MXC_CCM_PCTL_MFI_MASK                   (0xF << 10)
-#define MXC_CCM_PCTL_MFN_OFFSET                 0
-#define MXC_CCM_PCTL_MFN_MASK                   0x3FF
-
-#define MXC_CCM_CGR0_SD_MMC1_OFFSET             0
-#define MXC_CCM_CGR0_SD_MMC1_MASK               (0x3 << 0)
-#define MXC_CCM_CGR0_SD_MMC2_OFFSET             2
-#define MXC_CCM_CGR0_SD_MMC2_MASK               (0x3 << 2)
-#define MXC_CCM_CGR0_GPT_OFFSET                 4
-#define MXC_CCM_CGR0_GPT_MASK                   (0x3 << 4)
-#define MXC_CCM_CGR0_EPIT1_OFFSET               6
-#define MXC_CCM_CGR0_EPIT1_MASK                 (0x3 << 6)
-#define MXC_CCM_CGR0_EPIT2_OFFSET               8
-#define MXC_CCM_CGR0_EPIT2_MASK                 (0x3 << 8)
-#define MXC_CCM_CGR0_IIM_OFFSET                 10
-#define MXC_CCM_CGR0_IIM_MASK                   (0x3 << 10)
-#define MXC_CCM_CGR0_ATA_OFFSET                 12
-#define MXC_CCM_CGR0_ATA_MASK                   (0x3 << 12)
-#define MXC_CCM_CGR0_SDMA_OFFSET                14
-#define MXC_CCM_CGR0_SDMA_MASK                  (0x3 << 14)
-#define MXC_CCM_CGR0_CSPI3_OFFSET               16
-#define MXC_CCM_CGR0_CSPI3_MASK                 (0x3 << 16)
-#define MXC_CCM_CGR0_RNG_OFFSET                 18
-#define MXC_CCM_CGR0_RNG_MASK                   (0x3 << 18)
-#define MXC_CCM_CGR0_UART1_OFFSET               20
-#define MXC_CCM_CGR0_UART1_MASK                 (0x3 << 20)
-#define MXC_CCM_CGR0_UART2_OFFSET               22
-#define MXC_CCM_CGR0_UART2_MASK                 (0x3 << 22)
-#define MXC_CCM_CGR0_SSI1_OFFSET                24
-#define MXC_CCM_CGR0_SSI1_MASK                  (0x3 << 24)
-#define MXC_CCM_CGR0_I2C1_OFFSET                26
-#define MXC_CCM_CGR0_I2C1_MASK                  (0x3 << 26)
-#define MXC_CCM_CGR0_I2C2_OFFSET                28
-#define MXC_CCM_CGR0_I2C2_MASK                  (0x3 << 28)
-#define MXC_CCM_CGR0_I2C3_OFFSET                30
-#define MXC_CCM_CGR0_I2C3_MASK                  (0x3 << 30)
-
-#define MXC_CCM_CGR1_HANTRO_OFFSET              0
-#define MXC_CCM_CGR1_HANTRO_MASK                (0x3 << 0)
-#define MXC_CCM_CGR1_MEMSTICK1_OFFSET           2
-#define MXC_CCM_CGR1_MEMSTICK1_MASK             (0x3 << 2)
-#define MXC_CCM_CGR1_MEMSTICK2_OFFSET           4
-#define MXC_CCM_CGR1_MEMSTICK2_MASK             (0x3 << 4)
-#define MXC_CCM_CGR1_CSI_OFFSET                 6
-#define MXC_CCM_CGR1_CSI_MASK                   (0x3 << 6)
-#define MXC_CCM_CGR1_RTC_OFFSET                 8
-#define MXC_CCM_CGR1_RTC_MASK                   (0x3 << 8)
-#define MXC_CCM_CGR1_WDOG_OFFSET                10
-#define MXC_CCM_CGR1_WDOG_MASK                  (0x3 << 10)
-#define MXC_CCM_CGR1_PWM_OFFSET                 12
-#define MXC_CCM_CGR1_PWM_MASK                   (0x3 << 12)
-#define MXC_CCM_CGR1_SIM_OFFSET                 14
-#define MXC_CCM_CGR1_SIM_MASK                   (0x3 << 14)
-#define MXC_CCM_CGR1_ECT_OFFSET                 16
-#define MXC_CCM_CGR1_ECT_MASK                   (0x3 << 16)
-#define MXC_CCM_CGR1_USBOTG_OFFSET              18
-#define MXC_CCM_CGR1_USBOTG_MASK                (0x3 << 18)
-#define MXC_CCM_CGR1_KPP_OFFSET                 20
-#define MXC_CCM_CGR1_KPP_MASK                   (0x3 << 20)
-#define MXC_CCM_CGR1_IPU_OFFSET                 22
-#define MXC_CCM_CGR1_IPU_MASK                   (0x3 << 22)
-#define MXC_CCM_CGR1_UART3_OFFSET               24
-#define MXC_CCM_CGR1_UART3_MASK                 (0x3 << 24)
-#define MXC_CCM_CGR1_UART4_OFFSET               26
-#define MXC_CCM_CGR1_UART4_MASK                 (0x3 << 26)
-#define MXC_CCM_CGR1_UART5_OFFSET               28
-#define MXC_CCM_CGR1_UART5_MASK                 (0x3 << 28)
-#define MXC_CCM_CGR1_OWIRE_OFFSET               30
-#define MXC_CCM_CGR1_OWIRE_MASK                 (0x3 << 30)
-
-#define MXC_CCM_CGR2_SSI2_OFFSET                0
-#define MXC_CCM_CGR2_SSI2_MASK                  (0x3 << 0)
-#define MXC_CCM_CGR2_CSPI1_OFFSET               2
-#define MXC_CCM_CGR2_CSPI1_MASK                 (0x3 << 2)
-#define MXC_CCM_CGR2_CSPI2_OFFSET               4
-#define MXC_CCM_CGR2_CSPI2_MASK                 (0x3 << 4)
-#define MXC_CCM_CGR2_GACC_OFFSET                6
-#define MXC_CCM_CGR2_GACC_MASK                  (0x3 << 6)
-#define MXC_CCM_CGR2_EMI_OFFSET                 8
-#define MXC_CCM_CGR2_EMI_MASK                   (0x3 << 8)
-#define MXC_CCM_CGR2_RTIC_OFFSET                10
-#define MXC_CCM_CGR2_RTIC_MASK                  (0x3 << 10)
-#define MXC_CCM_CGR2_FIRI_OFFSET                12
-#define MXC_CCM_CGR2_FIRI_MASK                  (0x3 << 12)
-#define MXC_CCM_CGR2_IPMUX1_OFFSET              14
-#define MXC_CCM_CGR2_IPMUX1_MASK                (0x3 << 14)
-#define MXC_CCM_CGR2_IPMUX2_OFFSET              16
-#define MXC_CCM_CGR2_IPMUX2_MASK                (0x3 << 16)
-
-/* These new CGR2 bits are added in MX32 */
-#define MXC_CCM_CGR2_APMSYSCLKSEL_OFFSET	18
-#define MXC_CCM_CGR2_APMSYSCLKSEL_MASK		(0x3 << 18)
-#define MXC_CCM_CGR2_APMSSICLKSEL_OFFSET	20
-#define MXC_CCM_CGR2_APMSSICLKSEL_MASK		(0x3 << 20)
-#define MXC_CCM_CGR2_APMPERCLKSEL_OFFSET	22
-#define MXC_CCM_CGR2_APMPERCLKSEL_MASK		(0x3 << 22)
-#define MXC_CCM_CGR2_MXCCLKENSEL_OFFSET		24
-#define MXC_CCM_CGR2_MXCCLKENSEL_MASK		(0x1 << 24)
-#define MXC_CCM_CGR2_CHIKCAMPEN_OFFSET		25
-#define MXC_CCM_CGR2_CHIKCAMPEN_MASK		(0x1 << 25)
-#define MXC_CCM_CGR2_OVRVPUBUSY_OFFSET		26
-#define MXC_CCM_CGR2_OVRVPUBUSY_MASK		(0x1 << 26)
-#define MXC_CCM_CGR2_APMENA_OFFSET		30
-#define MXC_CCM_CGR2_AOMENA_MASK		(0x1 << 30)
-
 /*
  * LTR0 register offsets
  */

+ 191 - 2
arch/arm/mach-mx3/devices.c

@@ -25,6 +25,8 @@
 #include <mach/irqs.h>
 #include <mach/imx-uart.h>
 
+#include "devices.h"
+
 static struct resource uart0[] = {
 	{
 		.start = UART1_BASE_ADDR,
@@ -82,6 +84,7 @@ struct platform_device mxc_uart_device2 = {
 	.num_resources = ARRAY_SIZE(uart2),
 };
 
+#ifdef CONFIG_ARCH_MX31
 static struct resource uart3[] = {
 	{
 		.start = UART4_BASE_ADDR,
@@ -119,6 +122,7 @@ struct platform_device mxc_uart_device4 = {
 	.resource = uart4,
 	.num_resources = ARRAY_SIZE(uart4),
 };
+#endif /* CONFIG_ARCH_MX31 */
 
 /* GPIO port description */
 static struct mxc_gpio_port imx_gpio_ports[] = {
@@ -164,8 +168,8 @@ struct platform_device mxc_w1_master_device = {
 
 static struct resource mxc_nand_resources[] = {
 	{
-		.start	= NFC_BASE_ADDR,
-		.end	= NFC_BASE_ADDR + 0xfff,
+		.start	= 0, /* runtime dependent */
+		.end	= 0,
 		.flags	= IORESOURCE_MEM
 	}, {
 		.start	= MXC_INT_NANDFC,
@@ -180,3 +184,188 @@ struct platform_device mxc_nand_device = {
 	.num_resources = ARRAY_SIZE(mxc_nand_resources),
 	.resource = mxc_nand_resources,
 };
+
+static struct resource mxc_i2c0_resources[] = {
+	{
+		.start = I2C_BASE_ADDR,
+		.end = I2C_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = MXC_INT_I2C,
+		.end = MXC_INT_I2C,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_i2c_device0 = {
+	.name = "imx-i2c",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_i2c0_resources),
+	.resource = mxc_i2c0_resources,
+};
+
+static struct resource mxc_i2c1_resources[] = {
+	{
+		.start = I2C2_BASE_ADDR,
+		.end = I2C2_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = MXC_INT_I2C2,
+		.end = MXC_INT_I2C2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_i2c_device1 = {
+	.name = "imx-i2c",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(mxc_i2c1_resources),
+	.resource = mxc_i2c1_resources,
+};
+
+static struct resource mxc_i2c2_resources[] = {
+	{
+		.start = I2C3_BASE_ADDR,
+		.end = I2C3_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = MXC_INT_I2C3,
+		.end = MXC_INT_I2C3,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_i2c_device2 = {
+	.name = "imx-i2c",
+	.id = 2,
+	.num_resources = ARRAY_SIZE(mxc_i2c2_resources),
+	.resource = mxc_i2c2_resources,
+};
+
+#ifdef CONFIG_ARCH_MX31
+static struct resource mxcsdhc0_resources[] = {
+	{
+		.start = MMC_SDHC1_BASE_ADDR,
+		.end = MMC_SDHC1_BASE_ADDR + SZ_16K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_MMC_SDHC1,
+		.end = MXC_INT_MMC_SDHC1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource mxcsdhc1_resources[] = {
+	{
+		.start = MMC_SDHC2_BASE_ADDR,
+		.end = MMC_SDHC2_BASE_ADDR + SZ_16K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_MMC_SDHC2,
+		.end = MXC_INT_MMC_SDHC2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxcsdhc_device0 = {
+	.name = "mxc-mmc",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxcsdhc0_resources),
+	.resource = mxcsdhc0_resources,
+};
+
+struct platform_device mxcsdhc_device1 = {
+	.name = "mxc-mmc",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(mxcsdhc1_resources),
+	.resource = mxcsdhc1_resources,
+};
+#endif /* CONFIG_ARCH_MX31 */
+
+/* i.MX31 Image Processing Unit */
+
+/* The resource order is important! */
+static struct resource mx3_ipu_rsrc[] = {
+	{
+		.start = IPU_CTRL_BASE_ADDR,
+		.end = IPU_CTRL_BASE_ADDR + 0x5F,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IPU_CTRL_BASE_ADDR + 0x88,
+		.end = IPU_CTRL_BASE_ADDR + 0xB3,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_IPU_SYN,
+		.end = MXC_INT_IPU_SYN,
+		.flags = IORESOURCE_IRQ,
+	}, {
+		.start = MXC_INT_IPU_ERR,
+		.end = MXC_INT_IPU_ERR,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mx3_ipu = {
+	.name = "ipu-core",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(mx3_ipu_rsrc),
+	.resource = mx3_ipu_rsrc,
+};
+
+static struct resource fb_resources[] = {
+	{
+		.start	= IPU_CTRL_BASE_ADDR + 0xB4,
+		.end	= IPU_CTRL_BASE_ADDR + 0x1BF,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+struct platform_device mx3_fb = {
+	.name		= "mx3_sdc_fb",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(fb_resources),
+	.resource	= fb_resources,
+	.dev		= {
+		.coherent_dma_mask = 0xffffffff,
+       },
+};
+
+#ifdef CONFIG_ARCH_MX35
+static struct resource mxc_fec_resources[] = {
+	{
+		.start	= MXC_FEC_BASE_ADDR,
+		.end	= MXC_FEC_BASE_ADDR + 0xfff,
+		.flags	= IORESOURCE_MEM
+	}, {
+		.start	= MXC_INT_FEC,
+		.end	= MXC_INT_FEC,
+		.flags	= IORESOURCE_IRQ
+	},
+};
+
+struct platform_device mxc_fec_device = {
+	.name = "fec",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_fec_resources),
+	.resource = mxc_fec_resources,
+};
+#endif
+
+static int mx3_devices_init(void)
+{
+	if (cpu_is_mx31()) {
+		mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR;
+		mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff;
+	}
+	if (cpu_is_mx35()) {
+		mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR;
+		mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0xfff;
+	}
+
+	return 0;
+}
+
+subsys_initcall(mx3_devices_init);

+ 8 - 0
arch/arm/mach-mx3/devices.h

@@ -6,3 +6,11 @@ extern struct platform_device mxc_uart_device3;
 extern struct platform_device mxc_uart_device4;
 extern struct platform_device mxc_w1_master_device;
 extern struct platform_device mxc_nand_device;
+extern struct platform_device mxc_i2c_device0;
+extern struct platform_device mxc_i2c_device1;
+extern struct platform_device mxc_i2c_device2;
+extern struct platform_device mx3_ipu;
+extern struct platform_device mx3_fb;
+extern struct platform_device mxc_fec_device;
+extern struct platform_device mxcsdhc_device0;
+extern struct platform_device mxcsdhc_device1;

+ 84 - 4
arch/arm/mach-mx3/iomux.c

@@ -1,6 +1,7 @@
 /*
  * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
  * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -21,6 +22,7 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/kernel.h>
 #include <mach/hardware.h>
 #include <mach/gpio.h>
 #include <mach/iomux-mx3.h>
@@ -38,6 +40,8 @@
 static DEFINE_SPINLOCK(gpio_mux_lock);
 
 #define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3)
+
+unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
 /*
  * set the mode for a IOMUX pin.
  */
@@ -50,9 +54,6 @@ int mxc_iomux_mode(unsigned int pin_mode)
 	field = pin_mode & 0x3;
 	mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT;
 
-	pr_debug("%s: reg offset = 0x%x field = %d mode = 0x%02x\n",
-			__func__, (pin_mode & IOMUX_REG_MASK), field, mode);
-
 	spin_lock(&gpio_mux_lock);
 
 	l = __raw_readl(reg);
@@ -92,6 +93,86 @@ void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
 }
 EXPORT_SYMBOL(mxc_iomux_set_pad);
 
+/*
+ * setups a single pin:
+ * 	- reserves the pin so that it is not claimed by another driver
+ * 	- setups the iomux according to the configuration
+ * 	- if the pin is configured as a GPIO, we claim it through kernel gpiolib
+ */
+int mxc_iomux_setup_pin(const unsigned int pin, const char *label)
+{
+	unsigned pad = pin & IOMUX_PADNUM_MASK;
+	unsigned gpio;
+
+	if (pad >= (PIN_MAX + 1)) {
+		printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n",
+			pad, label ? label : "?");
+		return -EINVAL;
+	}
+
+	if (test_and_set_bit(pad, mxc_pin_alloc_map)) {
+		printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n",
+			pad, label ? label : "?");
+		return -EINVAL;
+	}
+	mxc_iomux_mode(pin);
+
+	/* if we have a gpio, we can allocate it */
+	gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT;
+	if (gpio < (GPIO_PORT_MAX + 1) * 32)
+		if (gpio_request(gpio, label))
+			return -EINVAL;
+
+	return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_setup_pin);
+
+int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
+		const char *label)
+{
+	unsigned int *p = pin_list;
+	int i;
+	int ret = -EINVAL;
+
+	for (i = 0; i < count; i++) {
+		if (mxc_iomux_setup_pin(*p, label))
+			goto setup_error;
+		p++;
+	}
+	return 0;
+
+setup_error:
+	mxc_iomux_release_multiple_pins(pin_list, i);
+	return ret;
+}
+EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins);
+
+void mxc_iomux_release_pin(const unsigned int pin)
+{
+	unsigned pad = pin & IOMUX_PADNUM_MASK;
+	unsigned gpio;
+
+	if (pad < (PIN_MAX + 1))
+		clear_bit(pad, mxc_pin_alloc_map);
+
+	gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT;
+	if (gpio < (GPIO_PORT_MAX + 1) * 32)
+		gpio_free(gpio);
+}
+EXPORT_SYMBOL(mxc_iomux_release_pin);
+
+void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count)
+{
+	unsigned int *p = pin_list;
+	int i;
+
+	for (i = 0; i < count; i++) {
+		mxc_iomux_release_pin(*p);
+		p++;
+	}
+}
+EXPORT_SYMBOL(mxc_iomux_release_multiple_pins);
+
 /*
  * This function enables/disables the general purpose function for a particular
  * signal.
@@ -111,4 +192,3 @@ void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en)
 	spin_unlock(&gpio_mux_lock);
 }
 EXPORT_SYMBOL(mxc_iomux_set_gpr);
-

+ 36 - 1
arch/arm/mach-mx3/mm.c

@@ -22,10 +22,14 @@
 
 #include <linux/mm.h>
 #include <linux/init.h>
-#include <mach/hardware.h>
+#include <linux/err.h>
+
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
+#include <asm/hardware/cache-l2x0.h>
+
 #include <mach/common.h>
+#include <mach/hardware.h>
 
 /*!
  * @file mm.c
@@ -50,6 +54,16 @@ static struct map_desc mxc_io_desc[] __initdata = {
 		.pfn		= __phys_to_pfn(AVIC_BASE_ADDR),
 		.length		= AVIC_SIZE,
 		.type		= MT_DEVICE_NONSHARED
+	}, {
+		.virtual	= AIPS1_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(AIPS1_BASE_ADDR),
+		.length		= AIPS1_SIZE,
+		.type		= MT_DEVICE_NONSHARED
+	}, {
+		.virtual	= AIPS2_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(AIPS2_BASE_ADDR),
+		.length		= AIPS2_SIZE,
+		.type		= MT_DEVICE_NONSHARED
 	},
 };
 
@@ -62,3 +76,24 @@ void __init mxc_map_io(void)
 {
 	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
 }
+
+#ifdef CONFIG_CACHE_L2X0
+static int mxc_init_l2x0(void)
+{
+	void __iomem *l2x0_base;
+
+	l2x0_base = ioremap(L2CC_BASE_ADDR, 4096);
+	if (IS_ERR(l2x0_base)) {
+		printk(KERN_ERR "remapping L2 cache area failed with %ld\n",
+				PTR_ERR(l2x0_base));
+		return 0;
+	}
+
+	l2x0_init(l2x0_base, 0x00030024, 0x00000000);
+
+	return 0;
+}
+
+arch_initcall(mxc_init_l2x0);
+#endif
+

+ 307 - 21
arch/arm/mach-mx3/mx31ads.c

@@ -22,6 +22,8 @@
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/serial_8250.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
 #include <linux/irq.h>
 
 #include <mach/hardware.h>
@@ -35,6 +37,12 @@
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx3.h>
 
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+#include <linux/mfd/wm8350/audio.h>
+#include <linux/mfd/wm8350/core.h>
+#include <linux/mfd/wm8350/pmic.h>
+#endif
+
 #include "devices.h"
 
 /*!
@@ -94,13 +102,16 @@ static struct imxuart_platform_data uart_pdata = {
 	.flags = IMXUART_HAVE_RTSCTS,
 };
 
+static int uart_pins[] = {
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1
+};
+
 static inline void mxc_init_imx_uart(void)
 {
-	mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
-	mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
-	mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
-	mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
-
+	mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0");
 	mxc_register_device(&mxc_uart_device0, &uart_pdata);
 }
 #else /* !SERIAL_IMX */
@@ -176,7 +187,7 @@ static void __init mx31ads_init_expio(void)
 	/*
 	 * Configure INT line as GPIO input
 	 */
-	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO));
+	mxc_iomux_setup_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio");
 
 	/* disable the interrupt and clear the status */
 	__raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG);
@@ -191,25 +202,300 @@ static void __init mx31ads_init_expio(void)
 	set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler);
 }
 
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+/* This section defines setup for the Wolfson Microelectronics
+ * 1133-EV1 PMU/audio board.  When other PMU boards are supported the
+ * regulator definitions may be shared with them, but for now they can
+ * only be used with this board so would generate warnings about
+ * unused statics and some of the configuration is specific to this
+ * module.
+ */
+
+/* CPU */
+static struct regulator_consumer_supply sw1a_consumers[] = {
+	{
+		.supply = "cpu_vcc",
+	}
+};
+
+static struct regulator_init_data sw1a_data = {
+	.constraints = {
+		.name = "SW1A",
+		.min_uV = 1275000,
+		.max_uV = 1600000,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+				  REGULATOR_CHANGE_MODE,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL |
+				    REGULATOR_MODE_FAST,
+		.state_mem = {
+			 .uV = 1400000,
+			 .mode = REGULATOR_MODE_NORMAL,
+			 .enabled = 1,
+		 },
+		.initial_state = PM_SUSPEND_MEM,
+		.always_on = 1,
+		.boot_on = 1,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(sw1a_consumers),
+	.consumer_supplies = sw1a_consumers,
+};
+
+/* System IO - High */
+static struct regulator_init_data viohi_data = {
+	.constraints = {
+		.name = "VIOHO",
+		.min_uV = 2800000,
+		.max_uV = 2800000,
+		.state_mem = {
+			 .uV = 2800000,
+			 .mode = REGULATOR_MODE_NORMAL,
+			 .enabled = 1,
+		 },
+		.initial_state = PM_SUSPEND_MEM,
+		.always_on = 1,
+		.boot_on = 1,
+	},
+};
+
+/* System IO - Low */
+static struct regulator_init_data violo_data = {
+	.constraints = {
+		.name = "VIOLO",
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+		.state_mem = {
+			 .uV = 1800000,
+			 .mode = REGULATOR_MODE_NORMAL,
+			 .enabled = 1,
+		 },
+		.initial_state = PM_SUSPEND_MEM,
+		.always_on = 1,
+		.boot_on = 1,
+	},
+};
+
+/* DDR RAM */
+static struct regulator_init_data sw2a_data = {
+	.constraints = {
+		.name = "SW2A",
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL,
+		.state_mem = {
+			 .uV = 1800000,
+			 .mode = REGULATOR_MODE_NORMAL,
+			 .enabled = 1,
+		 },
+		.state_disk = {
+			 .mode = REGULATOR_MODE_NORMAL,
+			 .enabled = 0,
+		 },
+		.always_on = 1,
+		.boot_on = 1,
+		.initial_state = PM_SUSPEND_MEM,
+	},
+};
+
+static struct regulator_init_data ldo1_data = {
+	.constraints = {
+		.name = "VCAM/VMMC1/VMMC2",
+		.min_uV = 2800000,
+		.max_uV = 2800000,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL,
+		.apply_uV = 1,
+	},
+};
+
+static struct regulator_consumer_supply ldo2_consumers[] = {
+	{
+		.supply = "AVDD",
+	},
+	{
+		.supply = "HPVDD",
+	},
+};
+
+/* CODEC and SIM */
+static struct regulator_init_data ldo2_data = {
+	.constraints = {
+		.name = "VESIM/VSIM/AVDD",
+		.min_uV = 3300000,
+		.max_uV = 3300000,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL,
+		.apply_uV = 1,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(ldo2_consumers),
+	.consumer_supplies = ldo2_consumers,
+};
+
+/* General */
+static struct regulator_init_data vdig_data = {
+	.constraints = {
+		.name = "VDIG",
+		.min_uV = 1500000,
+		.max_uV = 1500000,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL,
+		.apply_uV = 1,
+		.always_on = 1,
+		.boot_on = 1,
+	},
+};
+
+/* Tranceivers */
+static struct regulator_init_data ldo4_data = {
+	.constraints = {
+		.name = "VRF1/CVDD_2.775",
+		.min_uV = 2500000,
+		.max_uV = 2500000,
+		.valid_modes_mask = REGULATOR_MODE_NORMAL,
+		.apply_uV = 1,
+		.always_on = 1,
+		.boot_on = 1,
+	},
+};
+
+static struct wm8350_led_platform_data wm8350_led_data = {
+	.name            = "wm8350:white",
+	.default_trigger = "heartbeat",
+	.max_uA          = 27899,
+};
+
+static struct wm8350_audio_platform_data imx32ads_wm8350_setup = {
+	.vmid_discharge_msecs = 1000,
+	.drain_msecs = 30,
+	.cap_discharge_msecs = 700,
+	.vmid_charge_msecs = 700,
+	.vmid_s_curve = WM8350_S_CURVE_SLOW,
+	.dis_out4 = WM8350_DISCHARGE_SLOW,
+	.dis_out3 = WM8350_DISCHARGE_SLOW,
+	.dis_out2 = WM8350_DISCHARGE_SLOW,
+	.dis_out1 = WM8350_DISCHARGE_SLOW,
+	.vroi_out4 = WM8350_TIE_OFF_500R,
+	.vroi_out3 = WM8350_TIE_OFF_500R,
+	.vroi_out2 = WM8350_TIE_OFF_500R,
+	.vroi_out1 = WM8350_TIE_OFF_500R,
+	.vroi_enable = 0,
+	.codec_current_on = WM8350_CODEC_ISEL_1_0,
+	.codec_current_standby = WM8350_CODEC_ISEL_0_5,
+	.codec_current_charge = WM8350_CODEC_ISEL_1_5,
+};
+
+static int mx31_wm8350_init(struct wm8350 *wm8350)
+{
+	int i;
+
+	wm8350_gpio_config(wm8350, 0, WM8350_GPIO_DIR_IN,
+			   WM8350_GPIO0_PWR_ON_IN, WM8350_GPIO_ACTIVE_LOW,
+			   WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_ON);
+
+	wm8350_gpio_config(wm8350, 3, WM8350_GPIO_DIR_IN,
+			   WM8350_GPIO3_PWR_OFF_IN, WM8350_GPIO_ACTIVE_HIGH,
+			   WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_ON);
+
+	wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN,
+			   WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH,
+			   WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_OFF);
+
+	wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN,
+			   WM8350_GPIO7_HIBERNATE_IN, WM8350_GPIO_ACTIVE_HIGH,
+			   WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_OFF);
+
+	wm8350_gpio_config(wm8350, 6, WM8350_GPIO_DIR_OUT,
+			   WM8350_GPIO6_SDOUT_OUT, WM8350_GPIO_ACTIVE_HIGH,
+			   WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_OFF);
+
+	wm8350_gpio_config(wm8350, 8, WM8350_GPIO_DIR_OUT,
+			   WM8350_GPIO8_VCC_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
+			   WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_OFF);
+
+	wm8350_gpio_config(wm8350, 9, WM8350_GPIO_DIR_OUT,
+			   WM8350_GPIO9_BATT_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
+			   WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+			   WM8350_GPIO_DEBOUNCE_OFF);
+
+	/* Fix up for our own supplies. */
+	for (i = 0; i < ARRAY_SIZE(ldo2_consumers); i++)
+		ldo2_consumers[i].dev = wm8350->dev;
+
+	wm8350_register_regulator(wm8350, WM8350_DCDC_1, &sw1a_data);
+	wm8350_register_regulator(wm8350, WM8350_DCDC_3, &viohi_data);
+	wm8350_register_regulator(wm8350, WM8350_DCDC_4, &violo_data);
+	wm8350_register_regulator(wm8350, WM8350_DCDC_6, &sw2a_data);
+	wm8350_register_regulator(wm8350, WM8350_LDO_1, &ldo1_data);
+	wm8350_register_regulator(wm8350, WM8350_LDO_2, &ldo2_data);
+	wm8350_register_regulator(wm8350, WM8350_LDO_3, &vdig_data);
+	wm8350_register_regulator(wm8350, WM8350_LDO_4, &ldo4_data);
+
+	/* LEDs */
+	wm8350_dcdc_set_slot(wm8350, WM8350_DCDC_5, 1, 1,
+			     WM8350_DC5_ERRACT_SHUTDOWN_CONV);
+	wm8350_isink_set_flash(wm8350, WM8350_ISINK_A,
+			       WM8350_ISINK_FLASH_DISABLE,
+			       WM8350_ISINK_FLASH_TRIG_BIT,
+			       WM8350_ISINK_FLASH_DUR_32MS,
+			       WM8350_ISINK_FLASH_ON_INSTANT,
+			       WM8350_ISINK_FLASH_OFF_INSTANT,
+			       WM8350_ISINK_FLASH_MODE_EN);
+	wm8350_dcdc25_set_mode(wm8350, WM8350_DCDC_5,
+			       WM8350_ISINK_MODE_BOOST,
+			       WM8350_ISINK_ILIM_NORMAL,
+			       WM8350_DC5_RMP_20V,
+			       WM8350_DC5_FBSRC_ISINKA);
+	wm8350_register_led(wm8350, 0, WM8350_DCDC_5, WM8350_ISINK_A,
+			    &wm8350_led_data);
+
+	wm8350->codec.platform_data = &imx32ads_wm8350_setup;
+
+	return 0;
+}
+
+static struct wm8350_platform_data __initdata mx31_wm8350_pdata = {
+	.init = mx31_wm8350_init,
+};
+#endif
+
+#if defined(CONFIG_I2C_IMX) || defined(CONFIG_I2C_IMX_MODULE)
+static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = {
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+	{
+		I2C_BOARD_INFO("wm8350", 0x1a),
+		.platform_data = &mx31_wm8350_pdata,
+		.irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+	},
+#endif
+};
+
+static void mxc_init_i2c(void)
+{
+	i2c_register_board_info(1, mx31ads_i2c1_devices,
+				ARRAY_SIZE(mx31ads_i2c1_devices));
+
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1));
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1));
+
+	mxc_register_device(&mxc_i2c_device1, NULL);
+}
+#else
+static void mxc_init_i2c(void)
+{
+}
+#endif
+
 /*!
  * This structure defines static mappings for the i.MX31ADS board.
  */
 static struct map_desc mx31ads_io_desc[] __initdata = {
 	{
-		.virtual	= AIPS1_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS1_BASE_ADDR),
-		.length		= AIPS1_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	}, {
 		.virtual	= SPBA0_BASE_ADDR_VIRT,
 		.pfn		= __phys_to_pfn(SPBA0_BASE_ADDR),
 		.length		= SPBA0_SIZE,
 		.type		= MT_DEVICE_NONSHARED
-	}, {
-		.virtual	= AIPS2_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS2_BASE_ADDR),
-		.length		= AIPS2_SIZE,
-		.type		= MT_DEVICE_NONSHARED
 	}, {
 		.virtual	= CS4_BASE_ADDR_VIRT,
 		.pfn		= __phys_to_pfn(CS4_BASE_ADDR),
@@ -221,13 +507,13 @@ static struct map_desc mx31ads_io_desc[] __initdata = {
 /*!
  * Set up static virtual mappings.
  */
-void __init mx31ads_map_io(void)
+static void __init mx31ads_map_io(void)
 {
 	mxc_map_io();
 	iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
 }
 
-void __init mx31ads_init_irq(void)
+static void __init mx31ads_init_irq(void)
 {
 	mxc_init_irq();
 	mx31ads_init_expio();
@@ -240,15 +526,15 @@ static void __init mxc_board_init(void)
 {
 	mxc_init_extuart();
 	mxc_init_imx_uart();
+	mxc_init_i2c();
 }
 
 static void __init mx31ads_timer_init(void)
 {
-	mxc_clocks_init(26000000);
-	mxc_timer_init("ipg_clk.0");
+	mx31_clocks_init(26000000);
 }
 
-struct sys_timer mx31ads_timer = {
+static struct sys_timer mx31ads_timer = {
 	.init	= mx31ads_timer_init,
 };
 

+ 1 - 12
arch/arm/mach-mx3/mx31lite.c

@@ -42,20 +42,10 @@
  */
 static struct map_desc mx31lite_io_desc[] __initdata = {
 	{
-		.virtual = AIPS1_BASE_ADDR_VIRT,
-		.pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
-		.length = AIPS1_SIZE,
-		.type = MT_DEVICE_NONSHARED
-	}, {
 		.virtual = SPBA0_BASE_ADDR_VIRT,
 		.pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
 		.length = SPBA0_SIZE,
 		.type = MT_DEVICE_NONSHARED
-	}, {
-		.virtual = AIPS2_BASE_ADDR_VIRT,
-		.pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
-		.length = AIPS2_SIZE,
-		.type = MT_DEVICE_NONSHARED
 	}, {
 		.virtual = CS4_BASE_ADDR_VIRT,
 		.pfn = __phys_to_pfn(CS4_BASE_ADDR),
@@ -82,8 +72,7 @@ static void __init mxc_board_init(void)
 
 static void __init mx31lite_timer_init(void)
 {
-	mxc_clocks_init(26000000);
-	mxc_timer_init("ipg_clk.0");
+	mx31_clocks_init(26000000);
 }
 
 struct sys_timer mx31lite_timer = {

+ 48 - 0
arch/arm/mach-mx3/mx31moboard-devboard.c

@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+
+#include "devices.h"
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static int mxc_uart1_pins[] = {
+	MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2,
+	MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2,
+};
+
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_devboard_init(void)
+{
+	printk(KERN_INFO "Initializing mx31devboard peripherals\n");
+	mxc_iomux_setup_multiple_pins(mxc_uart1_pins, ARRAY_SIZE(mxc_uart1_pins), "uart1");
+	mxc_register_device(&mxc_uart_device1, &uart_pdata);
+}

+ 37 - 0
arch/arm/mach-mx3/mx31moboard-marxbot.c

@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+
+#include "devices.h"
+
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_marxbot_init(void)
+{
+	printk(KERN_INFO "Initializing mx31marxbot peripherals\n");
+}

+ 29 - 45
arch/arm/mach-mx3/mx31moboard.c

@@ -32,6 +32,7 @@
 #include <mach/common.h>
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx3.h>
+#include <mach/board-mx31moboard.h>
 
 #include "devices.h"
 
@@ -63,6 +64,18 @@ static struct platform_device *devices[] __initdata = {
 	&mx31moboard_flash,
 };
 
+static int mxc_uart0_pins[] = {
+	MX31_PIN_CTS1__CTS1, MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1,
+};
+static int mxc_uart4_pins[] = {
+	MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5,
+	MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5,
+};
+
+static int mx31moboard_baseboard;
+core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
+
 /*
  * Board specific initialization.
  */
@@ -70,58 +83,29 @@ static void __init mxc_board_init(void)
 {
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 
-	mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
-	mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
-	mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
-	mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
-
+	mxc_iomux_setup_multiple_pins(mxc_uart0_pins, ARRAY_SIZE(mxc_uart0_pins), "uart0");
 	mxc_register_device(&mxc_uart_device0, &uart_pdata);
 
-	mxc_iomux_mode(MX31_PIN_CTS2__CTS2);
-	mxc_iomux_mode(MX31_PIN_RTS2__RTS2);
-	mxc_iomux_mode(MX31_PIN_TXD2__TXD2);
-	mxc_iomux_mode(MX31_PIN_RXD2__RXD2);
-
-	mxc_register_device(&mxc_uart_device1, &uart_pdata);
-
-	mxc_iomux_mode(MX31_PIN_PC_RST__CTS5);
-	mxc_iomux_mode(MX31_PIN_PC_VS2__RTS5);
-	mxc_iomux_mode(MX31_PIN_PC_BVD2__TXD5);
-	mxc_iomux_mode(MX31_PIN_PC_BVD1__RXD5);
-
+	mxc_iomux_setup_multiple_pins(mxc_uart4_pins, ARRAY_SIZE(mxc_uart4_pins), "uart4");
 	mxc_register_device(&mxc_uart_device4, &uart_pdata);
-}
 
-/*
- * This structure defines static mappings for the mx31moboard.
- */
-static struct map_desc mx31moboard_io_desc[] __initdata = {
-	{
-		.virtual	= AIPS1_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS1_BASE_ADDR),
-		.length		= AIPS1_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	}, {
-		.virtual	= AIPS2_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS2_BASE_ADDR),
-		.length		= AIPS2_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	},
-};
-
-/*
- * Set up static virtual mappings.
- */
-void __init mx31moboard_map_io(void)
-{
-	mxc_map_io();
-	iotable_init(mx31moboard_io_desc, ARRAY_SIZE(mx31moboard_io_desc));
+	switch (mx31moboard_baseboard) {
+	case MX31NOBOARD:
+		break;
+	case MX31DEVBOARD:
+		mx31moboard_devboard_init();
+		break;
+	case MX31MARXBOT:
+		mx31moboard_marxbot_init();
+		break;
+	default:
+		printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n", mx31moboard_baseboard);
+	}
 }
 
 static void __init mx31moboard_timer_init(void)
 {
-	mxc_clocks_init(26000000);
-	mxc_timer_init("ipg_clk.0");
+	mx31_clocks_init(26000000);
 }
 
 struct sys_timer mx31moboard_timer = {
@@ -133,7 +117,7 @@ MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
 	.phys_io	= AIPS1_BASE_ADDR,
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx31moboard_map_io,
+	.map_io         = mxc_map_io,
 	.init_irq       = mxc_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &mx31moboard_timer,

+ 10 - 34
arch/arm/mach-mx3/mx31pdk.c

@@ -45,40 +45,17 @@ static struct imxuart_platform_data uart_pdata = {
 	.flags = IMXUART_HAVE_RTSCTS,
 };
 
-static inline void mxc_init_imx_uart(void)
-{
-	mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
-	mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
-	mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
-	mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
-
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-}
-
-/*!
- * This structure defines static mappings for the i.MX31PDK board.
- */
-static struct map_desc mx31pdk_io_desc[] __initdata = {
-	{
-		.virtual	= AIPS1_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS1_BASE_ADDR),
-		.length		= AIPS1_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	}, {
-		.virtual	= AIPS2_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS2_BASE_ADDR),
-		.length		= AIPS2_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	},
+static int uart_pins[] = {
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1
 };
 
-/*!
- * Set up static virtual mappings.
- */
-static void __init mx31pdk_map_io(void)
+static inline void mxc_init_imx_uart(void)
 {
-	mxc_map_io();
-	iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc));
+	mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0");
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
 }
 
 /*!
@@ -91,8 +68,7 @@ static void __init mxc_board_init(void)
 
 static void __init mx31pdk_timer_init(void)
 {
-	mxc_clocks_init(26000000);
-	mxc_timer_init("ipg_clk.0");
+	mx31_clocks_init(26000000);
 }
 
 static struct sys_timer mx31pdk_timer = {
@@ -108,7 +84,7 @@ MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
 	.phys_io	= AIPS1_BASE_ADDR,
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = mx31pdk_map_io,
+	.map_io         = mxc_map_io,
 	.init_irq       = mxc_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &mx31pdk_timer,

+ 98 - 40
arch/arm/mach-mx3/pcm037.c

@@ -26,6 +26,8 @@
 #include <linux/gpio.h>
 #include <linux/smc911x.h>
 #include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -37,6 +39,10 @@
 #include <mach/iomux-mx3.h>
 #include <mach/board-pcm037.h>
 #include <mach/mxc_nand.h>
+#include <mach/mmc.h>
+#ifdef CONFIG_I2C_IMX
+#include <mach/i2c.h>
+#endif
 
 #include "devices.h"
 
@@ -117,12 +123,90 @@ static struct mxc_nand_platform_data pcm037_nand_board_info = {
 	.hw_ecc = 1,
 };
 
+#ifdef CONFIG_I2C_IMX
+static int i2c_1_pins[] = {
+	MX31_PIN_CSPI2_MOSI__SCL,
+	MX31_PIN_CSPI2_MISO__SDA,
+};
+
+static int pcm037_i2c_1_init(struct device *dev)
+{
+	return mxc_iomux_setup_multiple_pins(i2c_1_pins, ARRAY_SIZE(i2c_1_pins),
+			"i2c-1");
+}
+
+static void pcm037_i2c_1_exit(struct device *dev)
+{
+	mxc_iomux_release_multiple_pins(i2c_1_pins, ARRAY_SIZE(i2c_1_pins));
+}
+
+static struct imxi2c_platform_data pcm037_i2c_1_data = {
+	.bitrate = 100000,
+	.init = pcm037_i2c_1_init,
+	.exit = pcm037_i2c_1_exit,
+};
+
+static struct at24_platform_data board_eeprom = {
+	.byte_len = 4096,
+	.page_size = 32,
+	.flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pcm037_i2c_devices[] = {
+       {
+		I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+		.platform_data = &board_eeprom,
+	}, {
+		I2C_BOARD_INFO("rtc-pcf8563", 0x51),
+		.type = "pcf8563",
+	}
+};
+#endif
+
+static int sdhc1_pins[] = {
+	MX31_PIN_SD1_DATA3__SD1_DATA3,
+	MX31_PIN_SD1_DATA2__SD1_DATA2,
+	MX31_PIN_SD1_DATA1__SD1_DATA1,
+	MX31_PIN_SD1_DATA0__SD1_DATA0,
+	MX31_PIN_SD1_CLK__SD1_CLK,
+	MX31_PIN_SD1_CMD__SD1_CMD,
+};
+
+static int pcm970_sdhc1_init(struct device *dev, irq_handler_t h, void *data)
+{
+	return mxc_iomux_setup_multiple_pins(sdhc1_pins, ARRAY_SIZE(sdhc1_pins),
+				"sdhc-1");
+}
+
+static void pcm970_sdhc1_exit(struct device *dev, void *data)
+{
+	mxc_iomux_release_multiple_pins(sdhc1_pins, ARRAY_SIZE(sdhc1_pins));
+}
+
+/* No card and rw detection at the moment */
+static struct imxmmc_platform_data sdhc_pdata = {
+	.init = pcm970_sdhc1_init,
+	.exit = pcm970_sdhc1_exit,
+};
+
 static struct platform_device *devices[] __initdata = {
 	&pcm037_flash,
 	&pcm037_eth,
 	&pcm037_sram_device,
 };
 
+static int uart0_pins[] = {
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1
+};
+
+static int uart2_pins[] = {
+	MX31_PIN_CSPI3_MOSI__RXD3,
+	MX31_PIN_CSPI3_MISO__TXD3
+};
+
 /*
  * Board specific initialization.
  */
@@ -130,59 +214,33 @@ static void __init mxc_board_init(void)
 {
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 
-	mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
-	mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
-	mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
-	mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
-
+	mxc_iomux_setup_multiple_pins(uart0_pins, ARRAY_SIZE(uart0_pins), "uart-0");
 	mxc_register_device(&mxc_uart_device0, &uart_pdata);
 
-	mxc_iomux_mode(MX31_PIN_CSPI3_MOSI__RXD3);
-	mxc_iomux_mode(MX31_PIN_CSPI3_MISO__TXD3);
-
+	mxc_iomux_setup_multiple_pins(uart2_pins, ARRAY_SIZE(uart2_pins), "uart-2");
 	mxc_register_device(&mxc_uart_device2, &uart_pdata);
 
-	mxc_iomux_mode(MX31_PIN_BATT_LINE__OWIRE);
+	mxc_iomux_setup_pin(MX31_PIN_BATT_LINE__OWIRE, "batt-0wire");
 	mxc_register_device(&mxc_w1_master_device, NULL);
 
 	/* SMSC9215 IRQ pin */
-	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO));
-	if (!gpio_request(MX31_PIN_GPIO3_1, "pcm037-eth"))
+	if (!mxc_iomux_setup_pin(IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO),
+				"pcm037-eth"))
 		gpio_direction_input(MX31_PIN_GPIO3_1);
 
-	mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
-}
+#ifdef CONFIG_I2C_IMX
+	i2c_register_board_info(1, pcm037_i2c_devices,
+			ARRAY_SIZE(pcm037_i2c_devices));
 
-/*
- * This structure defines static mappings for the pcm037 board.
- */
-static struct map_desc pcm037_io_desc[] __initdata = {
-	{
-		.virtual	= AIPS1_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS1_BASE_ADDR),
-		.length		= AIPS1_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	}, {
-		.virtual	= AIPS2_BASE_ADDR_VIRT,
-		.pfn		= __phys_to_pfn(AIPS2_BASE_ADDR),
-		.length		= AIPS2_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	},
-};
-
-/*
- * Set up static virtual mappings.
- */
-void __init pcm037_map_io(void)
-{
-	mxc_map_io();
-	iotable_init(pcm037_io_desc, ARRAY_SIZE(pcm037_io_desc));
+	mxc_register_device(&mxc_i2c_device1, &pcm037_i2c_1_data);
+#endif
+	mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
+	mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
 }
 
 static void __init pcm037_timer_init(void)
 {
-	mxc_clocks_init(26000000);
-	mxc_timer_init("ipg_clk.0");
+	mx31_clocks_init(26000000);
 }
 
 struct sys_timer pcm037_timer = {
@@ -194,7 +252,7 @@ MACHINE_START(PCM037, "Phytec Phycore pcm037")
 	.phys_io	= AIPS1_BASE_ADDR,
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
-	.map_io         = pcm037_map_io,
+	.map_io         = mxc_map_io,
 	.init_irq       = mxc_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &pcm037_timer,

+ 312 - 0
arch/arm/mach-mx3/qong.c

@@ -0,0 +1,312 @@
+/*
+ *  Copyright (C) 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.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/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <mach/board-qong.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include "devices.h"
+
+/* FPGA defines */
+#define QONG_FPGA_VERSION(major, minor, rev)	\
+	(((major & 0xF) << 12) | ((minor & 0xF) << 8) | (rev & 0xFF))
+
+#define QONG_FPGA_BASEADDR 		CS1_BASE_ADDR
+#define QONG_FPGA_PERIPH_SIZE 		(1 << 24)
+
+#define QONG_FPGA_CTRL_BASEADDR		QONG_FPGA_BASEADDR
+#define QONG_FPGA_CTRL_SIZE 		0x10
+/* FPGA control registers */
+#define QONG_FPGA_CTRL_VERSION		0x00
+
+#define QONG_DNET_ID		1
+#define QONG_DNET_BASEADDR	\
+	(QONG_FPGA_BASEADDR + QONG_DNET_ID * QONG_FPGA_PERIPH_SIZE)
+#define QONG_DNET_SIZE 		0x00001000
+
+#define QONG_FPGA_IRQ		IOMUX_TO_IRQ(MX31_PIN_DTR_DCE1)
+
+/*
+ * This file contains the board-specific initialization routines.
+ */
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static int uart_pins[] = {
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1
+};
+
+static inline void mxc_init_imx_uart(void)
+{
+	mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins),
+			"uart-0");
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+}
+
+static struct resource dnet_resources[] = {
+	[0] = {
+		.name	= "dnet-memory",
+		.start	= QONG_DNET_BASEADDR,
+		.end	= QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= QONG_FPGA_IRQ,
+		.end	= QONG_FPGA_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dnet_device = {
+	.name			= "dnet",
+	.id			= -1,
+	.num_resources		= ARRAY_SIZE(dnet_resources),
+	.resource		= dnet_resources,
+};
+
+static int __init qong_init_dnet(void)
+{
+	int ret;
+
+	ret = platform_device_register(&dnet_device);
+	return ret;
+}
+
+/* MTD NOR flash */
+
+static struct physmap_flash_data qong_flash_data = {
+	.width = 2,
+};
+
+static struct resource qong_flash_resource = {
+	.start = CS0_BASE_ADDR,
+	.end = CS0_BASE_ADDR + QONG_NOR_SIZE - 1,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device qong_nor_mtd_device = {
+	.name = "physmap-flash",
+	.id = 0,
+	.dev = {
+		.platform_data = &qong_flash_data,
+		},
+	.resource = &qong_flash_resource,
+	.num_resources = 1,
+};
+
+static void qong_init_nor_mtd(void)
+{
+	(void)platform_device_register(&qong_nor_mtd_device);
+}
+
+/*
+ * Hardware specific access to control-lines
+ */
+static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+
+	if (cmd == NAND_CMD_NONE)
+		return;
+
+	if (ctrl & NAND_CLE)
+		writeb(cmd, nand_chip->IO_ADDR_W + (1 << 24));
+	else
+		writeb(cmd, nand_chip->IO_ADDR_W + (1 << 23));
+}
+
+/*
+ * Read the Device Ready pin.
+ */
+static int qong_nand_device_ready(struct mtd_info *mtd)
+{
+	return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB));
+}
+
+static void qong_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+	if (chip >= 0)
+		gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
+	else
+		gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1);
+}
+
+static struct platform_nand_data qong_nand_data = {
+	.chip = {
+		.chip_delay		= 20,
+		.options		= 0,
+	},
+	.ctrl = {
+		.cmd_ctrl 		= qong_nand_cmd_ctrl,
+		.dev_ready		= qong_nand_device_ready,
+		.select_chip		= qong_nand_select_chip,
+	}
+};
+
+static struct resource qong_nand_resource = {
+	.start  	= CS3_BASE_ADDR,
+	.end    	= CS3_BASE_ADDR + SZ_32M - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device qong_nand_device = {
+	.name		= "gen_nand",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &qong_nand_data,
+	},
+	.num_resources	= 1,
+	.resource	= &qong_nand_resource,
+};
+
+static void __init qong_init_nand_mtd(void)
+{
+	/* init CS */
+	__raw_writel(0x00004f00, CSCR_U(3));
+	__raw_writel(0x20013b31, CSCR_L(3));
+	__raw_writel(0x00020800, CSCR_A(3));
+	mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true);
+
+	/* enable pin */
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFCE_B, IOMUX_CONFIG_GPIO));
+	if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), "nand_enable"))
+		gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
+
+	/* ready/busy pin */
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFRB, IOMUX_CONFIG_GPIO));
+	if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFRB), "nand_rdy"))
+		gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFRB));
+
+	/* write protect pin */
+	mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFWP_B, IOMUX_CONFIG_GPIO));
+	if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFWP_B), "nand_wp"))
+		gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFWP_B));
+
+	platform_device_register(&qong_nand_device);
+}
+
+static void __init qong_init_fpga(void)
+{
+	void __iomem *regs;
+	u32 fpga_ver;
+
+	regs = ioremap(QONG_FPGA_CTRL_BASEADDR, QONG_FPGA_CTRL_SIZE);
+	if (!regs) {
+		printk(KERN_ERR "%s: failed to map registers, aborting.\n",
+				__func__);
+		return;
+	}
+
+	fpga_ver = readl(regs + QONG_FPGA_CTRL_VERSION);
+	iounmap(regs);
+	printk(KERN_INFO "Qong FPGA version %d.%d.%d\n",
+			(fpga_ver & 0xF000) >> 12,
+			(fpga_ver & 0x0F00) >> 8, fpga_ver & 0x00FF);
+	if (fpga_ver < QONG_FPGA_VERSION(0, 8, 7)) {
+		printk(KERN_ERR "qong: Unexpected FPGA version, FPGA-based "
+				"devices won't be registered!\n");
+		return;
+	}
+
+	/* register FPGA-based devices */
+	qong_init_nand_mtd();
+	qong_init_dnet();
+}
+
+/*
+ * This structure defines the MX31 memory map.
+ */
+static struct map_desc qong_io_desc[] __initdata = {
+	{
+		.virtual = AIPS1_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
+		.length = AIPS1_SIZE,
+		.type = MT_DEVICE_NONSHARED
+	}, {
+		.virtual = AIPS2_BASE_ADDR_VIRT,
+		.pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
+		.length = AIPS2_SIZE,
+		.type = MT_DEVICE_NONSHARED
+	}
+};
+
+/*
+ * Set up static virtual mappings.
+ */
+static void __init qong_map_io(void)
+{
+	mxc_map_io();
+	iotable_init(qong_io_desc, ARRAY_SIZE(qong_io_desc));
+}
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+	mxc_init_imx_uart();
+	qong_init_nor_mtd();
+	qong_init_fpga();
+}
+
+static void __init qong_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+static struct sys_timer qong_timer = {
+	.init	= qong_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros defined in arch.h in order to
+ * initialize __mach_desc_QONG data structure.
+ */
+
+MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
+	/* Maintainer: DENX Software Engineering GmbH */
+	.phys_io        = AIPS1_BASE_ADDR,
+	.io_pg_offst    = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = PHYS_OFFSET + 0x100,
+	.map_io         = qong_map_io,
+	.init_irq       = mxc_init_irq,
+	.init_machine   = mxc_board_init,
+	.timer          = &qong_timer,
+MACHINE_END

+ 1 - 1
arch/arm/mach-omap2/board-ldp.c

@@ -81,7 +81,7 @@ static inline void __init ldp_init_smc911x(void)
 	}
 
 	ldp_smc911x_resources[0].start = cs_mem_base + 0x0;
-	ldp_smc911x_resources[0].end   = cs_mem_base + 0xf;
+	ldp_smc911x_resources[0].end   = cs_mem_base + 0xff;
 	udelay(100);
 
 	eth_gpio = LDP_SMC911X_GPIO;

+ 8 - 8
arch/arm/mach-omap2/clock.c

@@ -565,7 +565,7 @@ u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
  *
  * Given a struct clk of a rate-selectable clksel clock, and a clock divisor,
  * find the corresponding register field value.  The return register value is
- * the value before left-shifting.  Returns 0xffffffff on error
+ * the value before left-shifting.  Returns ~0 on error
  */
 u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
 {
@@ -577,7 +577,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
 
 	clks = omap2_get_clksel_by_parent(clk, clk->parent);
 	if (clks == NULL)
-		return 0;
+		return ~0;
 
 	for (clkr = clks->rates; clkr->div; clkr++) {
 		if ((clkr->flags & cpu_mask) && (clkr->div == div))
@@ -588,7 +588,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
 		printk(KERN_ERR "clock: Could not find divisor %d for "
 		       "clock %s parent %s\n", div, clk->name,
 		       clk->parent->name);
-		return 0;
+		return ~0;
 	}
 
 	return clkr->val;
@@ -708,7 +708,7 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
 		return 0;
 
 	for (clkr = clks->rates; clkr->div; clkr++) {
-		if (clkr->flags & (cpu_mask | DEFAULT_RATE))
+		if (clkr->flags & cpu_mask && clkr->flags & DEFAULT_RATE)
 			break; /* Found the default rate for this platform */
 	}
 
@@ -746,7 +746,7 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
 		return -EINVAL;
 
 	if (clk->usecount > 0)
-		_omap2_clk_disable(clk);
+		omap2_clk_disable(clk);
 
 	/* Set new source value (previous dividers if any in effect) */
 	reg_val = __raw_readl(src_addr) & ~field_mask;
@@ -759,11 +759,11 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
 		wmb();
 	}
 
-	if (clk->usecount > 0)
-		_omap2_clk_enable(clk);
-
 	clk->parent = new_parent;
 
+	if (clk->usecount > 0)
+		omap2_clk_enable(clk);
+
 	/* CLKSEL clocks follow their parents' rates, divided by a divisor */
 	clk->rate = new_parent->rate;
 

+ 1 - 1
arch/arm/mach-orion5x/irq.c

@@ -44,7 +44,7 @@ void __init orion5x_init_irq(void)
 	 * User can use set_type() if he wants to use edge types handlers.
 	 */
 	for (i = IRQ_ORION5X_GPIO_START; i < NR_IRQS; i++) {
-		set_irq_chip(i, &orion_gpio_irq_level_chip);
+		set_irq_chip(i, &orion_gpio_irq_chip);
 		set_irq_handler(i, handle_level_irq);
 		irq_desc[i].status |= IRQ_LEVEL;
 		set_irq_flags(i, IRQF_VALID);

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

@@ -19,6 +19,7 @@
 #include <linux/serial_8250.h>
 #include <linux/ata_platform.h>
 #include <linux/io.h>
+#include <linux/i2c.h>
 
 #include <asm/elf.h>
 #include <asm/mach-types.h>
@@ -201,8 +202,13 @@ static struct platform_device *devs[] __initdata = {
 	&pata_device,
 };
 
+static struct i2c_board_info i2c_rtc = {
+	I2C_BOARD_INFO("pcf8583", 0x50)
+};
+
 static int __init rpc_init(void)
 {
+	i2c_register_board_info(0, &i2c_rtc, 1);
 	return platform_add_devices(devs, ARRAY_SIZE(devs));
 }
 

+ 2 - 1
arch/arm/mm/Kconfig

@@ -704,7 +704,8 @@ config CACHE_FEROCEON_L2_WRITETHROUGH
 
 config CACHE_L2X0
 	bool "Enable the L2x0 outer cache controller"
-	depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || REALVIEW_EB_A9MP
+	depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
+		   REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31
 	default y
 	select OUTER_CACHE
 	help

+ 2 - 1
arch/arm/mm/abort-ev6.S

@@ -23,7 +23,8 @@ ENTRY(v6_early_abort)
 #ifdef CONFIG_CPU_32v6K
 	clrex
 #else
-	strex	r0, r1, [sp]			@ Clear the exclusive monitor
+	sub	r1, sp, #4			@ Get unused stack location
+	strex	r0, r1, [r1]			@ Clear the exclusive monitor
 #endif
 	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR

+ 2 - 1
arch/arm/mm/mmu.c

@@ -716,7 +716,8 @@ static void __init sanity_check_meminfo(void)
 		 * Check whether this memory bank would entirely overlap
 		 * the vmalloc area.
 		 */
-		if (__va(bank->start) >= VMALLOC_MIN) {
+		if (__va(bank->start) >= VMALLOC_MIN ||
+		    __va(bank->start) < PAGE_OFFSET) {
 			printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
 			       "(vmalloc region overlap).\n",
 			       bank->start, bank->start + bank->size - 1);

+ 9 - 1
arch/arm/plat-mxc/Kconfig

@@ -3,7 +3,7 @@ if ARCH_MXC
 menu "Freescale MXC Implementations"
 
 choice
-	prompt "MXC/iMX Base Type"
+	prompt "Freescale CPU family:"
 	default ARCH_MX3
 
 config ARCH_MX1
@@ -15,12 +15,14 @@ config ARCH_MX1
 config ARCH_MX2
 	bool "MX2-based"
 	select CPU_ARM926T
+	select COMMON_CLKDEV
 	help
 	  This enables support for systems based on the Freescale i.MX2 family
 
 config ARCH_MX3
 	bool "MX3-based"
 	select CPU_V6
+	select COMMON_CLKDEV
 	help
 	  This enables support for systems based on the Freescale i.MX3 family
 
@@ -43,4 +45,10 @@ config MXC_IRQ_PRIOR
 	  requirements for timing.
 	  Say N here, unless you have a specialized requirement.
 
+config MXC_PWM
+	tristate "Enable PWM driver"
+	depends on ARCH_MXC
+	help
+	  Enable support for the i.MX PWM controller(s).
+
 endif

+ 2 - 1
arch/arm/plat-mxc/Makefile

@@ -3,7 +3,8 @@
 #
 
 # Common support
-obj-y := irq.o clock.o gpio.o time.o devices.o
+obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o
 
 obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o
 obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
+obj-$(CONFIG_MXC_PWM)  += pwm.o

Some files were not shown because too many files changed in this diff