Merge branch 'next/dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 30 Jul 2011 06:32:02 +0000 (23:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 30 Jul 2011 06:32:02 +0000 (23:32 -0700)
* 'next/dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/linux-arm-soc: (21 commits)
  arm/dt: tegra devicetree support
  arm/versatile: Add device tree support
  dt/irq: add irq_domain_generate_simple() helper
  irq: add irq_domain translation infrastructure
  dmaengine: imx-sdma: add device tree probe support
  dmaengine: imx-sdma: sdma_get_firmware does not need to copy fw_name
  dmaengine: imx-sdma: use platform_device_id to identify sdma version
  mmc: sdhci-esdhc-imx: add device tree probe support
  mmc: sdhci-pltfm: dt device does not pass parent to sdhci_alloc_host
  mmc: sdhci-esdhc-imx: get rid of the uses of cpu_is_mx()
  mmc: sdhci-esdhc-imx: do not reference platform data after probe
  mmc: sdhci-esdhc-imx: extend card_detect and write_protect support for mx5
  net/fec: add device tree probe support
  net: ibm_newemac: convert it to use of_get_phy_mode
  dt/net: add helper function of_get_phy_mode
  net/fec: gasket needs to be enabled for some i.mx
  serial/imx: add device tree probe support
  serial/imx: get rid of the uses of cpu_is_mx1()
  arm/dt: Add dtb make rule
  arm/dt: Add skeleton dtsi file
  ...

72 files changed:
Documentation/devicetree/bindings/arm/arm-boards [new file with mode: 0644]
Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/arm-versatile.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mtd/arm-versatile.txt [new file with mode: 0644]
Documentation/devicetree/bindings/net/fsl-fec.txt [new file with mode: 0644]
Documentation/devicetree/bindings/net/smsc-lan91c111.txt [new file with mode: 0644]
Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt [new file with mode: 0644]
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/boot/Makefile
arch/arm/boot/dts/skeleton.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tegra-harmony.dts [new file with mode: 0644]
arch/arm/boot/dts/tegra-seaboard.dts [new file with mode: 0644]
arch/arm/boot/dts/tegra20.dtsi [new file with mode: 0644]
arch/arm/boot/dts/versatile-ab.dts [new file with mode: 0644]
arch/arm/boot/dts/versatile-pb.dts [new file with mode: 0644]
arch/arm/include/asm/mach/arch.h
arch/arm/include/asm/prom.h
arch/arm/kernel/devtree.c
arch/arm/mach-imx/clock-imx1.c
arch/arm/mach-imx/clock-imx21.c
arch/arm/mach-imx/clock-imx25.c
arch/arm/mach-imx/clock-imx27.c
arch/arm/mach-imx/clock-imx31.c
arch/arm/mach-imx/clock-imx35.c
arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
arch/arm/mach-imx/mach-mx25_3ds.c
arch/arm/mach-imx/mach-pcm043.c
arch/arm/mach-imx/mm-imx25.c
arch/arm/mach-imx/mm-imx31.c
arch/arm/mach-imx/mm-imx35.c
arch/arm/mach-mx5/board-mx51_babbage.c
arch/arm/mach-mx5/board-mx53_loco.c
arch/arm/mach-mx5/clock-mx51-mx53.c
arch/arm/mach-mx5/mm.c
arch/arm/mach-mx5/mx51_efika.c
arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/Makefile.boot
arch/arm/mach-tegra/board-dt.c [new file with mode: 0644]
arch/arm/mach-versatile/Kconfig
arch/arm/mach-versatile/Makefile
arch/arm/mach-versatile/core.c
arch/arm/mach-versatile/core.h
arch/arm/mach-versatile/versatile_dt.c [new file with mode: 0644]
arch/arm/plat-mxc/devices/platform-fec.c
arch/arm/plat-mxc/devices/platform-imx-dma.c
arch/arm/plat-mxc/devices/platform-imx-uart.c
arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c
arch/arm/plat-mxc/include/mach/devices-common.h
arch/arm/plat-mxc/include/mach/dma.h
arch/arm/plat-mxc/include/mach/esdhc.h
arch/arm/plat-mxc/include/mach/sdma.h
drivers/dma/imx-sdma.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci-pltfm.c
drivers/net/fec.c
drivers/net/ibm_newemac/core.c
drivers/net/ibm_newemac/emac.h
drivers/net/ibm_newemac/phy.c
drivers/of/of_net.c
drivers/tty/serial/imx.c
include/linux/irq.h
include/linux/irqdomain.h [new file with mode: 0644]
include/linux/of_irq.h
include/linux/of_net.h
include/linux/phy.h
kernel/irq/Kconfig
kernel/irq/Makefile
kernel/irq/irqdomain.c [new file with mode: 0644]

diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards
new file mode 100644 (file)
index 0000000..91f2614
--- /dev/null
@@ -0,0 +1,20 @@
+ARM Versatile Application and Platform Baseboards
+-------------------------------------------------
+ARM's development hardware platform with connectors for customizable
+core tiles.  The hardware configuration of the Versatile boards is
+highly customizable.
+
+Required properties (in root node):
+       compatible = "arm,versatile-ab";  /* Application baseboard */
+       compatible = "arm,versatile-pb";  /* Platform baseboard */
+
+Interrupt controllers:
+- VIC required properties:
+       compatible = "arm,versatile-vic";
+       interrupt-controller;
+       #interrupt-cells = <1>;
+
+- SIC required properties:
+       compatible = "arm,versatile-sic";
+       interrupt-controller;
+       #interrupt-cells = <1>;
diff --git a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
new file mode 100644 (file)
index 0000000..d1e3f44
--- /dev/null
@@ -0,0 +1,17 @@
+* Freescale Smart Direct Memory Access (SDMA) Controller for i.MX
+
+Required properties:
+- compatible : Should be "fsl,<chip>-sdma"
+- reg : Should contain SDMA registers location and length
+- interrupts : Should contain SDMA interrupt
+- fsl,sdma-ram-script-name : Should contain the full path of SDMA RAM
+  scripts firmware
+
+Examples:
+
+sdma@83fb0000 {
+       compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
+       reg = <0x83fb0000 0x4000>;
+       interrupts = <6>;
+       fsl,sdma-ram-script-name = "sdma-imx51.bin";
+};
diff --git a/Documentation/devicetree/bindings/i2c/arm-versatile.txt b/Documentation/devicetree/bindings/i2c/arm-versatile.txt
new file mode 100644 (file)
index 0000000..361d31c
--- /dev/null
@@ -0,0 +1,10 @@
+i2c Controller on ARM Versatile platform:
+
+Required properties:
+- compatible : Must be "arm,versatile-i2c";
+- reg
+- #address-cells = <1>;
+- #size-cells = <0>;
+
+Optional properties:
+- Child nodes conforming to i2c bus binding
diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
new file mode 100644 (file)
index 0000000..ab22fe6
--- /dev/null
@@ -0,0 +1,34 @@
+* Freescale Enhanced Secure Digital Host Controller (eSDHC) for i.MX
+
+The Enhanced Secure Digital Host Controller on Freescale i.MX family
+provides an interface for MMC, SD, and SDIO types of memory cards.
+
+Required properties:
+- compatible : Should be "fsl,<chip>-esdhc"
+- reg : Should contain eSDHC registers location and length
+- interrupts : Should contain eSDHC interrupt
+
+Optional properties:
+- fsl,card-wired : Indicate the card is wired to host permanently
+- fsl,cd-internal : Indicate to use controller internal card detection
+- fsl,wp-internal : Indicate to use controller internal write protection
+- cd-gpios : Specify GPIOs for card detection
+- wp-gpios : Specify GPIOs for write protection
+
+Examples:
+
+esdhc@70004000 {
+       compatible = "fsl,imx51-esdhc";
+       reg = <0x70004000 0x4000>;
+       interrupts = <1>;
+       fsl,cd-internal;
+       fsl,wp-internal;
+};
+
+esdhc@70008000 {
+       compatible = "fsl,imx51-esdhc";
+       reg = <0x70008000 0x4000>;
+       interrupts = <2>;
+       cd-gpios = <&gpio0 6 0>; /* GPIO1_6 */
+       wp-gpios = <&gpio0 5 0>; /* GPIO1_5 */
+};
diff --git a/Documentation/devicetree/bindings/mtd/arm-versatile.txt b/Documentation/devicetree/bindings/mtd/arm-versatile.txt
new file mode 100644 (file)
index 0000000..476845d
--- /dev/null
@@ -0,0 +1,8 @@
+Flash device on ARM Versatile board
+
+Required properties:
+- compatible : must be "arm,versatile-flash";
+- bank-width : width in bytes of flash interface.
+
+Optional properties:
+- Subnode partition map from mtd flash binding
diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt
new file mode 100644 (file)
index 0000000..de43951
--- /dev/null
@@ -0,0 +1,24 @@
+* Freescale Fast Ethernet Controller (FEC)
+
+Required properties:
+- compatible : Should be "fsl,<soc>-fec"
+- reg : Address and length of the register set for the device
+- interrupts : Should contain fec interrupt
+- phy-mode : String, operation mode of the PHY interface.
+  Supported values are: "mii", "gmii", "sgmii", "tbi", "rmii",
+  "rgmii", "rgmii-id", "rgmii-rxid", "rgmii-txid", "rtbi", "smii".
+- phy-reset-gpios : Should specify the gpio for phy reset
+
+Optional properties:
+- local-mac-address : 6 bytes, mac address
+
+Example:
+
+fec@83fec000 {
+       compatible = "fsl,imx51-fec", "fsl,imx27-fec";
+       reg = <0x83fec000 0x4000>;
+       interrupts = <87>;
+       phy-mode = "mii";
+       phy-reset-gpios = <&gpio1 14 0>; /* GPIO2_14 */
+       local-mac-address = [00 04 9F 01 1B B9];
+};
diff --git a/Documentation/devicetree/bindings/net/smsc-lan91c111.txt b/Documentation/devicetree/bindings/net/smsc-lan91c111.txt
new file mode 100644 (file)
index 0000000..953049b
--- /dev/null
@@ -0,0 +1,10 @@
+SMSC LAN91c111 Ethernet mac
+
+Required properties:
+- compatible = "smsc,lan91c111";
+- reg : physical address and size of registers
+- interrupts : interrupt connection
+
+Optional properties:
+- phy-device : phandle to Ethernet phy
+- local-mac-address : Ethernet mac address to use
diff --git a/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt b/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
new file mode 100644 (file)
index 0000000..a9c0406
--- /dev/null
@@ -0,0 +1,19 @@
+* Freescale i.MX Universal Asynchronous Receiver/Transmitter (UART)
+
+Required properties:
+- compatible : Should be "fsl,<soc>-uart"
+- reg : Address and length of the register set for the device
+- interrupts : Should contain uart interrupt
+
+Optional properties:
+- fsl,uart-has-rtscts : Indicate the uart has rts and cts
+- fsl,irda-mode : Indicate the uart supports irda mode
+
+Example:
+
+uart@73fbc000 {
+       compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+       reg = <0x73fbc000 0x4000>;
+       interrupts = <31>;
+       fsl,uart-has-rtscts;
+};
index 09ebf0b..2c71a8f 100644 (file)
@@ -1716,6 +1716,7 @@ config USE_OF
        bool "Flattened Device Tree support"
        select OF
        select OF_EARLY_FLATTREE
+       select IRQ_DOMAIN
        help
          Include support for flattened device tree machine descriptions.
 
index 3a4a04b..70c424e 100644 (file)
@@ -282,6 +282,12 @@ zImage Image xipImage bootpImage uImage: vmlinux
 zinstall uinstall install: vmlinux
        $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
 
+%.dtb:
+       $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+
+dtbs:
+       $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+
 # We use MRPROPER_FILES and CLEAN_FILES now
 archclean:
        $(Q)$(MAKE) $(clean)=$(boot)
@@ -298,6 +304,7 @@ define archhelp
   echo  '  uImage        - U-Boot wrapped zImage'
   echo  '  bootpImage    - Combined zImage and initial RAM disk' 
   echo  '                  (supply initrd image via make variable INITRD=<path>)'
+  echo  '  dtbs          - Build device tree blobs for enabled boards'
   echo  '  install       - Install uncompressed kernel'
   echo  '  zinstall      - Install compressed kernel'
   echo  '  uinstall      - Install U-Boot wrapped compressed kernel'
index 9128fdd..a1edfd5 100644 (file)
@@ -59,6 +59,12 @@ $(obj)/zImage:       $(obj)/compressed/vmlinux FORCE
 
 endif
 
+# Rule to build device tree blobs
+$(obj)/%.dtb: $(src)/dts/%.dts
+       $(call cmd,dtc)
+
+$(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y))
+
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
                   -C none -a $(LOADADDR) -e $(STARTADDR) \
diff --git a/arch/arm/boot/dts/skeleton.dtsi b/arch/arm/boot/dts/skeleton.dtsi
new file mode 100644 (file)
index 0000000..b41d241
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Skeleton device tree; the bare minimum needed to boot; just include and
+ * add a compatible value.  The bootloader will typically populate the memory
+ * node.
+ */
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       chosen { };
+       aliases { };
+       memory { device_type = "memory"; reg = <0 0>; };
+};
diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
new file mode 100644 (file)
index 0000000..4c05334
--- /dev/null
@@ -0,0 +1,70 @@
+/dts-v1/;
+
+/memreserve/ 0x1c000000 0x04000000;
+/include/ "tegra20.dtsi"
+
+/ {
+       model = "NVIDIA Tegra2 Harmony evaluation board";
+       compatible = "nvidia,harmony", "nvidia,tegra20";
+
+       chosen {
+               bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk0p2 rw rootwait";
+       };
+
+       memory@0 {
+               reg = < 0x00000000 0x40000000 >;
+       };
+
+       i2c@7000c000 {
+               clock-frequency = <400000>;
+
+               codec: wm8903@1a {
+                       compatible = "wlf,wm8903";
+                       reg = <0x1a>;
+                       interrupts = < 347 >;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       /* 0x8000 = Not configured */
+                       gpio-cfg = < 0x8000 0x8000 0 0x8000 0x8000 >;
+               };
+       };
+
+       i2c@7000c400 {
+               clock-frequency = <400000>;
+       };
+
+       i2c@7000c500 {
+               clock-frequency = <400000>;
+       };
+
+       i2c@7000d000 {
+               clock-frequency = <400000>;
+       };
+
+       sound {
+               compatible = "nvidia,harmony-sound", "nvidia,tegra-wm8903";
+
+               spkr-en-gpios = <&codec 2 0>;
+               hp-det-gpios = <&gpio 178 0>;
+               int-mic-en-gpios = <&gpio 184 0>;
+               ext-mic-en-gpios = <&gpio 185 0>;
+       };
+
+       serial@70006300 {
+               clock-frequency = < 216000000 >;
+       };
+
+       sdhci@c8000200 {
+               gpios = <&gpio 69 0>, /* cd, gpio PI5 */
+                       <&gpio 57 0>, /* wp, gpio PH1 */
+                       <&gpio 155 0>; /* power, gpio PT3 */
+       };
+
+       sdhci@c8000600 {
+               gpios = <&gpio 58 0>, /* cd, gpio PH2 */
+                       <&gpio 59 0>, /* wp, gpio PH3 */
+                       <&gpio 70 0>; /* power, gpio PI6 */
+       };
+};
diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts
new file mode 100644 (file)
index 0000000..1940cae
--- /dev/null
@@ -0,0 +1,28 @@
+/dts-v1/;
+
+/memreserve/ 0x1c000000 0x04000000;
+/include/ "tegra20.dtsi"
+
+/ {
+       model = "NVIDIA Seaboard";
+       compatible = "nvidia,seaboard", "nvidia,tegra20";
+
+       chosen {
+               bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/mmcblk1p3 rw rootwait";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = < 0x00000000 0x40000000 >;
+       };
+
+       serial@70006300 {
+               clock-frequency = < 216000000 >;
+       };
+
+       sdhci@c8000400 {
+               gpios = <&gpio 69 0>, /* cd, gpio PI5 */
+                       <&gpio 57 0>, /* wp, gpio PH1 */
+                       <&gpio 70 0>; /* power, gpio PI6 */
+       };
+};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
new file mode 100644 (file)
index 0000000..5727595
--- /dev/null
@@ -0,0 +1,139 @@
+/include/ "skeleton.dtsi"
+
+/ {
+       compatible = "nvidia,tegra20";
+       interrupt-parent = <&intc>;
+
+       intc: interrupt-controller@50041000 {
+               compatible = "nvidia,tegra20-gic";
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               reg = < 0x50041000 0x1000 >,
+                     < 0x50040100 0x0100 >;
+       };
+
+       i2c@7000c000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "nvidia,tegra20-i2c";
+               reg = <0x7000C000 0x100>;
+               interrupts = < 70 >;
+       };
+
+       i2c@7000c400 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "nvidia,tegra20-i2c";
+               reg = <0x7000C400 0x100>;
+               interrupts = < 116 >;
+       };
+
+       i2c@7000c500 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "nvidia,tegra20-i2c";
+               reg = <0x7000C500 0x100>;
+               interrupts = < 124 >;
+       };
+
+       i2c@7000d000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "nvidia,tegra20-i2c";
+               reg = <0x7000D000 0x200>;
+               interrupts = < 85 >;
+       };
+
+       i2s@70002800 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "nvidia,tegra20-i2s";
+               reg = <0x70002800 0x200>;
+               interrupts = < 45 >;
+               dma-channel = < 2 >;
+       };
+
+       i2s@70002a00 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "nvidia,tegra20-i2s";
+               reg = <0x70002a00 0x200>;
+               interrupts = < 35 >;
+               dma-channel = < 1 >;
+       };
+
+       das@70000c00 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "nvidia,tegra20-das";
+               reg = <0x70000c00 0x80>;
+       };
+
+       gpio: gpio@6000d000 {
+               compatible = "nvidia,tegra20-gpio";
+               reg = < 0x6000d000 0x1000 >;
+               interrupts = < 64 65 66 67 87 119 121 >;
+               #gpio-cells = <2>;
+               gpio-controller;
+       };
+
+       serial@70006000 {
+               compatible = "nvidia,tegra20-uart";
+               reg = <0x70006000 0x40>;
+               reg-shift = <2>;
+               interrupts = < 68 >;
+       };
+
+       serial@70006040 {
+               compatible = "nvidia,tegra20-uart";
+               reg = <0x70006040 0x40>;
+               reg-shift = <2>;
+               interrupts = < 69 >;
+       };
+
+       serial@70006200 {
+               compatible = "nvidia,tegra20-uart";
+               reg = <0x70006200 0x100>;
+               reg-shift = <2>;
+               interrupts = < 78 >;
+       };
+
+       serial@70006300 {
+               compatible = "nvidia,tegra20-uart";
+               reg = <0x70006300 0x100>;
+               reg-shift = <2>;
+               interrupts = < 122 >;
+       };
+
+       serial@70006400 {
+               compatible = "nvidia,tegra20-uart";
+               reg = <0x70006400 0x100>;
+               reg-shift = <2>;
+               interrupts = < 123 >;
+       };
+
+       sdhci@c8000000 {
+               compatible = "nvidia,tegra20-sdhci";
+               reg = <0xc8000000 0x200>;
+               interrupts = < 46 >;
+       };
+
+       sdhci@c8000200 {
+               compatible = "nvidia,tegra20-sdhci";
+               reg = <0xc8000200 0x200>;
+               interrupts = < 47 >;
+       };
+
+       sdhci@c8000400 {
+               compatible = "nvidia,tegra20-sdhci";
+               reg = <0xc8000400 0x200>;
+               interrupts = < 51 >;
+       };
+
+       sdhci@c8000600 {
+               compatible = "nvidia,tegra20-sdhci";
+               reg = <0xc8000600 0x200>;
+               interrupts = < 63 >;
+       };
+};
+
diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts
new file mode 100644 (file)
index 0000000..0b32925
--- /dev/null
@@ -0,0 +1,192 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+       model = "ARM Versatile AB";
+       compatible = "arm,versatile-ab";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       interrupt-parent = <&vic>;
+
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+               serial2 = &uart2;
+               i2c0 = &i2c0;
+       };
+
+       memory {
+               reg = <0x0 0x08000000>;
+       };
+
+       flash@34000000 {
+               compatible = "arm,versatile-flash";
+               reg = <0x34000000 0x4000000>;
+               bank-width = <4>;
+       };
+
+       i2c0: i2c@10002000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "arm,versatile-i2c";
+               reg = <0x10002000 0x1000>;
+
+               rtc@68 {
+                       compatible = "dallas,ds1338";
+                       reg = <0x68>;
+               };
+       };
+
+       net@10010000 {
+               compatible = "smsc,lan91c111";
+               reg = <0x10010000 0x10000>;
+               interrupts = <25>;
+       };
+
+       lcd@10008000 {
+               compatible = "arm,versatile-lcd";
+               reg = <0x10008000 0x1000>;
+       };
+
+       amba {
+               compatible = "arm,amba-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               vic: intc@10140000 {
+                       compatible = "arm,versatile-vic";
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+                       reg = <0x10140000 0x1000>;
+               };
+
+               sic: intc@10003000 {
+                       compatible = "arm,versatile-sic";
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+                       reg = <0x10003000 0x1000>;
+                       interrupt-parent = <&vic>;
+                       interrupts = <31>; /* Cascaded to vic */
+               };
+
+               dma@10130000 {
+                       compatible = "arm,pl081", "arm,primecell";
+                       reg = <0x10130000 0x1000>;
+                       interrupts = <17>;
+               };
+
+               uart0: uart@101f1000 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x101f1000 0x1000>;
+                       interrupts = <12>;
+               };
+
+               uart1: uart@101f2000 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x101f2000 0x1000>;
+                       interrupts = <13>;
+               };
+
+               uart2: uart@101f3000 {
+                       compatible = "arm,pl011", "arm,primecell";
+                       reg = <0x101f3000 0x1000>;
+                       interrupts = <14>;
+               };
+
+               smc@10100000 {
+                       compatible = "arm,primecell";
+                       reg = <0x10100000 0x1000>;
+               };
+
+               mpmc@10110000 {
+                       compatible = "arm,primecell";
+                       reg = <0x10110000 0x1000>;
+               };
+
+               display@10120000 {
+                       compatible = "arm,pl110", "arm,primecell";
+                       reg = <0x10120000 0x1000>;
+                       interrupts = <16>;
+               };
+
+               sctl@101e0000 {
+                       compatible = "arm,primecell";
+                       reg = <0x101e0000 0x1000>;
+               };
+
+               watchdog@101e1000 {
+                       compatible = "arm,primecell";
+                       reg = <0x101e1000 0x1000>;
+                       interrupts = <0>;
+               };
+
+               gpio0: gpio@101e4000 {
+                       compatible = "arm,pl061", "arm,primecell";
+                       reg = <0x101e4000 0x1000>;
+                       gpio-controller;
+                       interrupts = <6>;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio1: gpio@101e5000 {
+                       compatible = "arm,pl061", "arm,primecell";
+                       reg = <0x101e5000 0x1000>;
+                       interrupts = <7>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               rtc@101e8000 {
+                       compatible = "arm,pl030", "arm,primecell";
+                       reg = <0x101e8000 0x1000>;
+                       interrupts = <10>;
+               };
+
+               sci@101f0000 {
+                       compatible = "arm,primecell";
+                       reg = <0x101f0000 0x1000>;
+                       interrupts = <15>;
+               };
+
+               ssp@101f4000 {
+                       compatible = "arm,pl022", "arm,primecell";
+                       reg = <0x101f4000 0x1000>;
+                       interrupts = <11>;
+               };
+
+               fpga {
+                       compatible = "arm,versatile-fpga", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x10000000 0x10000>;
+
+                       aaci@4000 {
+                               compatible = "arm,primecell";
+                               reg = <0x4000 0x1000>;
+                               interrupts = <24>;
+                       };
+                       mmc@5000 {
+                               compatible = "arm,primecell";
+                               reg = < 0x5000 0x1000>;
+                               interrupts = <22>;
+                       };
+                       kmi@6000 {
+                               compatible = "arm,pl050", "arm,primecell";
+                               reg = <0x6000 0x1000>;
+                               interrupt-parent = <&sic>;
+                               interrupts = <3>;
+                       };
+                       kmi@7000 {
+                               compatible = "arm,pl050", "arm,primecell";
+                               reg = <0x7000 0x1000>;
+                               interrupt-parent = <&sic>;
+                               interrupts = <4>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts
new file mode 100644 (file)
index 0000000..8a614e3
--- /dev/null
@@ -0,0 +1,48 @@
+/include/ "versatile-ab.dts"
+
+/ {
+       model = "ARM Versatile PB";
+       compatible = "arm,versatile-pb";
+
+       amba {
+               gpio2: gpio@101e6000 {
+                       compatible = "arm,pl061", "arm,primecell";
+                       reg = <0x101e6000 0x1000>;
+                       interrupts = <8>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpio3: gpio@101e7000 {
+                       compatible = "arm,pl061", "arm,primecell";
+                       reg = <0x101e7000 0x1000>;
+                       interrupts = <9>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               fpga {
+                       uart@9000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0x9000 0x1000>;
+                               interrupt-parent = <&sic>;
+                               interrupts = <6>;
+                       };
+                       sci@a000 {
+                               compatible = "arm,primecell";
+                               reg = <0xa000 0x1000>;
+                               interrupt-parent = <&sic>;
+                               interrupts = <5>;
+                       };
+                       mmc@b000 {
+                               compatible = "arm,primecell";
+                               reg = <0xb000 0x1000>;
+                               interrupts = <23>;
+                       };
+               };
+       };
+};
index 3281fb4..217aa19 100644 (file)
@@ -74,4 +74,11 @@ static const struct machine_desc __mach_desc_##_type \
 #define MACHINE_END                            \
 };
 
+#define DT_MACHINE_START(_name, _namestr)              \
+static const struct machine_desc __mach_desc_##_name   \
+ __used                                                        \
+ __attribute__((__section__(".arch.info.init"))) = {   \
+       .nr             = ~0,                           \
+       .name           = _namestr,
+
 #endif
index 11b8708..6f65ca8 100644 (file)
 #include <asm/setup.h>
 #include <asm/irq.h>
 
-static inline void irq_dispose_mapping(unsigned int virq)
-{
-       return;
-}
-
 extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
 extern void arm_dt_memblock_reserve(void);
 
index 0cdd7b4..1a33e9d 100644 (file)
@@ -132,17 +132,3 @@ struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
 
        return mdesc_best;
 }
-
-/**
- * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
- *
- * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
- * mapped 1:1 onto Linux irq numbers.  Cascaded irq controllers are not
- * supported.
- */
-unsigned int irq_create_of_mapping(struct device_node *controller,
-                                  const u32 *intspec, unsigned int intsize)
-{
-       return intspec[0];
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
index dcc4172..4aabeb2 100644 (file)
@@ -587,9 +587,9 @@ static struct clk_lookup lookups[] __initdata = {
        _REGISTER_CLOCK(NULL, "mma", mma_clk)
        _REGISTER_CLOCK("imx_udc.0", NULL, usbd_clk)
        _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
-       _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk)
-       _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk)
-       _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk)
+       _REGISTER_CLOCK("imx1-uart.0", NULL, uart_clk)
+       _REGISTER_CLOCK("imx1-uart.1", NULL, uart_clk)
+       _REGISTER_CLOCK("imx1-uart.2", NULL, uart_clk)
        _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
        _REGISTER_CLOCK("imx1-cspi.0", NULL, spi_clk)
        _REGISTER_CLOCK("imx1-cspi.1", NULL, spi_clk)
index bf30a8c..ee15d8c 100644 (file)
@@ -1162,10 +1162,10 @@ static struct clk_lookup lookups[] = {
        _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("imx21-uart.0", NULL, uart_clk[0])
+       _REGISTER_CLOCK("imx21-uart.1", NULL, uart_clk[1])
+       _REGISTER_CLOCK("imx21-uart.2", NULL, uart_clk[2])
+       _REGISTER_CLOCK("imx21-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])
index af1c580..0fc7ba5 100644 (file)
@@ -272,11 +272,12 @@ DEFINE_CLOCK(can2_clk,     1, CCM_CGCR1,  3, get_rate_ipg, NULL, NULL);
        },
 
 static struct clk_lookup lookups[] = {
-       _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("imx-uart.3", NULL, uart4_clk)
-       _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+       /* i.mx25 has the i.mx21 type uart */
+       _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
+       _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
+       _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
+       _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
+       _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
        _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
        _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
        _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
@@ -295,19 +296,20 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
        _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
        _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
-       _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+       _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk)
        _REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
        _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
        _REGISTER_CLOCK("imx2-wdt.0", NULL, wdt_clk)
        _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
        _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
-       _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
-       _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx25.0", NULL, esdhc1_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx25.1", NULL, esdhc2_clk)
        _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
        _REGISTER_CLOCK(NULL, "audmux", audmux_clk)
        _REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
        _REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
-       _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
+       /* i.mx25 has the i.mx35 type sdma */
+       _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
 };
 
 int __init mx25_clocks_init(void)
index 583f251..6912b82 100644 (file)
@@ -624,12 +624,13 @@ DEFINE_CLOCK1(csi_clk,     0, NULL,   0, parent, &csi_clk1, &per4_clk);
        },
 
 static struct clk_lookup lookups[] = {
-       _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("imx-uart.3", NULL, uart4_clk)
-       _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
-       _REGISTER_CLOCK("imx-uart.5", NULL, uart6_clk)
+       /* i.mx27 has the i.mx21 type uart */
+       _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
+       _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
+       _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
+       _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
+       _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
+       _REGISTER_CLOCK("imx21-uart.5", NULL, uart6_clk)
        _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk)
        _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk)
        _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk)
@@ -662,7 +663,7 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK(NULL, "brom", brom_clk)
        _REGISTER_CLOCK(NULL, "emma", emma_clk)
        _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk)
-       _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+       _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
        _REGISTER_CLOCK(NULL, "emi", emi_clk)
        _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
        _REGISTER_CLOCK(NULL, "ata", ata_clk)
index 25f343f..d973770 100644 (file)
@@ -547,11 +547,12 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1)
        _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2)
        _REGISTER_CLOCK("mx3-camera.0", NULL, csi_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("imx-uart.3", NULL, uart4_clk)
-       _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+       /* i.mx31 has the i.mx21 type uart */
+       _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
+       _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
+       _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
+       _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
+       _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_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)
@@ -564,7 +565,7 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK(NULL, "ata", ata_clk)
        _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
        _REGISTER_CLOCK(NULL, "rng", rng_clk)
-       _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk1)
+       _REGISTER_CLOCK("imx31-sdma", NULL, sdma_clk1)
        _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2)
        _REGISTER_CLOCK(NULL, "mstick", mstick1_clk)
        _REGISTER_CLOCK(NULL, "mstick", mstick2_clk)
index 5a4cc1e..88b62a0 100644 (file)
@@ -458,10 +458,11 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk)
        _REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk)
        _REGISTER_CLOCK(NULL, "esai", esai_clk)
-       _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
-       _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
-       _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk)
-       _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx35.0", NULL, esdhc1_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx35.1", NULL, esdhc2_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx35.2", NULL, esdhc3_clk)
+       /* i.mx35 has the i.mx27 type fec */
+       _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
        _REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
        _REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
        _REGISTER_CLOCK(NULL, "gpio", gpio3_clk)
@@ -481,14 +482,15 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
        _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
        _REGISTER_CLOCK(NULL, "scc", scc_clk)
-       _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
+       _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
        _REGISTER_CLOCK(NULL, "spba", spba_clk)
        _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
        _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
        _REGISTER_CLOCK("imx-ssi.1", NULL, 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)
+       /* i.mx35 has the i.mx21 type uart */
+       _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
+       _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
+       _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
        _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
        _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
        _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
index 01ebcb3..66e8726 100644 (file)
@@ -225,7 +225,8 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
 
 static struct esdhc_platform_data sd1_pdata = {
        .cd_gpio = GPIO_SD1CD,
-       .wp_gpio = -EINVAL,
+       .cd_type = ESDHC_CD_GPIO,
+       .wp_type = ESDHC_WP_NONE,
 };
 
 /*
index 558eb52..0f0af02 100644 (file)
@@ -236,7 +236,8 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
 
 static struct esdhc_platform_data sd1_pdata = {
        .cd_gpio = GPIO_SD1CD,
-       .wp_gpio = -EINVAL,
+       .cd_type = ESDHC_CD_GPIO,
+       .wp_type = ESDHC_WP_NONE,
 };
 
 /*
index 01534bb..7f66a91 100644 (file)
@@ -215,6 +215,8 @@ static const struct imxi2c_platform_data mx25_3ds_i2c0_data __initconst = {
 static const struct esdhc_platform_data mx25pdk_esdhc_pdata __initconst = {
        .wp_gpio = SD1_GPIO_WP,
        .cd_gpio = SD1_GPIO_CD,
+       .wp_type = ESDHC_WP_GPIO,
+       .cd_type = ESDHC_CD_GPIO,
 };
 
 static void __init mx25pdk_init(void)
index 163cc31..660ec3e 100644 (file)
@@ -349,6 +349,8 @@ __setup("otg_mode=", pcm043_otg_mode);
 static struct esdhc_platform_data sd1_pdata = {
        .wp_gpio = SD1_GPIO_WP,
        .cd_gpio = SD1_GPIO_CD,
+       .wp_type = ESDHC_WP_GPIO,
+       .cd_type = ESDHC_CD_GPIO,
 };
 
 /*
index 8bf0291..cc4d152 100644 (file)
@@ -79,7 +79,6 @@ static struct sdma_script_start_addrs imx25_sdma_script __initdata = {
 };
 
 static struct sdma_platform_data imx25_sdma_pdata __initdata = {
-       .sdma_version = 2,
        .fw_name = "sdma-imx25.bin",
        .script_addrs = &imx25_sdma_script,
 };
@@ -92,5 +91,6 @@ void __init imx25_soc_init(void)
        mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
        mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
 
-       imx_add_imx_sdma(MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata);
+       /* i.mx25 has the i.mx35 type sdma */
+       imx_add_imx_sdma("imx35-sdma", MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata);
 }
index 61bff38..b7c55e7 100644 (file)
@@ -69,7 +69,6 @@ static struct sdma_script_start_addrs imx31_to2_sdma_script __initdata = {
 };
 
 static struct sdma_platform_data imx31_sdma_pdata __initdata = {
-       .sdma_version = 1,
        .fw_name = "sdma-imx31-to2.bin",
        .script_addrs = &imx31_to2_sdma_script,
 };
@@ -88,5 +87,5 @@ void __init imx31_soc_init(void)
                imx31_sdma_pdata.script_addrs = &imx31_to1_sdma_script;
        }
 
-       imx_add_imx_sdma(MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata);
+       imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata);
 }
index 98769ae..f49bac7 100644 (file)
@@ -86,7 +86,6 @@ static struct sdma_script_start_addrs imx35_to2_sdma_script __initdata = {
 };
 
 static struct sdma_platform_data imx35_sdma_pdata __initdata = {
-       .sdma_version = 2,
        .fw_name = "sdma-imx35-to2.bin",
        .script_addrs = &imx35_to2_sdma_script,
 };
@@ -106,5 +105,5 @@ void __init imx35_soc_init(void)
                imx35_sdma_pdata.script_addrs = &imx35_to1_sdma_script;
        }
 
-       imx_add_imx_sdma(MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata);
+       imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata);
 }
index 15c6000..e400b09 100644 (file)
@@ -41,8 +41,6 @@
 #define BABBAGE_POWER_KEY      IMX_GPIO_NR(2, 21)
 #define BABBAGE_ECSPI1_CS0     IMX_GPIO_NR(4, 24)
 #define BABBAGE_ECSPI1_CS1     IMX_GPIO_NR(4, 25)
-#define BABBAGE_SD1_CD         IMX_GPIO_NR(1, 0)
-#define BABBAGE_SD1_WP         IMX_GPIO_NR(1, 1)
 #define BABBAGE_SD2_CD         IMX_GPIO_NR(1, 6)
 #define BABBAGE_SD2_WP         IMX_GPIO_NR(1, 5)
 
@@ -146,8 +144,9 @@ static iomux_v3_cfg_t mx51babbage_pads[] = {
        MX51_PAD_SD1_DATA1__SD1_DATA1,
        MX51_PAD_SD1_DATA2__SD1_DATA2,
        MX51_PAD_SD1_DATA3__SD1_DATA3,
-       MX51_PAD_GPIO1_0__GPIO1_0,
-       MX51_PAD_GPIO1_1__GPIO1_1,
+       /* CD/WP from controller */
+       MX51_PAD_GPIO1_0__SD1_CD,
+       MX51_PAD_GPIO1_1__SD1_WP,
 
        /* SD 2 */
        MX51_PAD_SD2_CMD__SD2_CMD,
@@ -156,6 +155,7 @@ static iomux_v3_cfg_t mx51babbage_pads[] = {
        MX51_PAD_SD2_DATA1__SD2_DATA1,
        MX51_PAD_SD2_DATA2__SD2_DATA2,
        MX51_PAD_SD2_DATA3__SD2_DATA3,
+       /* CD/WP gpio */
        MX51_PAD_GPIO1_6__GPIO1_6,
        MX51_PAD_GPIO1_5__GPIO1_5,
 
@@ -340,13 +340,15 @@ static const struct spi_imx_master mx51_babbage_spi_pdata __initconst = {
 };
 
 static const struct esdhc_platform_data mx51_babbage_sd1_data __initconst = {
-       .cd_gpio = BABBAGE_SD1_CD,
-       .wp_gpio = BABBAGE_SD1_WP,
+       .cd_type = ESDHC_CD_CONTROLLER,
+       .wp_type = ESDHC_WP_CONTROLLER,
 };
 
 static const struct esdhc_platform_data mx51_babbage_sd2_data __initconst = {
        .cd_gpio = BABBAGE_SD2_CD,
        .wp_gpio = BABBAGE_SD2_WP,
+       .cd_type = ESDHC_CD_GPIO,
+       .wp_type = ESDHC_WP_GPIO,
 };
 
 /*
index 54be525..4e1d51d 100644 (file)
@@ -210,11 +210,15 @@ static const struct gpio_keys_platform_data loco_button_data __initconst = {
 
 static const struct esdhc_platform_data mx53_loco_sd1_data __initconst = {
        .cd_gpio = LOCO_SD1_CD,
+       .cd_type = ESDHC_CD_GPIO,
+       .wp_type = ESDHC_WP_NONE,
 };
 
 static const struct esdhc_platform_data mx53_loco_sd3_data __initconst = {
        .cd_gpio = LOCO_SD3_CD,
        .wp_gpio = LOCO_SD3_WP,
+       .cd_type = ESDHC_CD_GPIO,
+       .wp_type = ESDHC_WP_GPIO,
 };
 
 static inline void mx53_loco_fec_reset(void)
index 23cd809..7f20308 100644 (file)
@@ -1422,11 +1422,13 @@ DEFINE_CLOCK(ipu_di1_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG6_OFFSET,
        },
 
 static struct clk_lookup mx51_lookups[] = {
-       _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
-       _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
-       _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+       /* i.mx51 has the i.mx21 type uart */
+       _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
+       _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
+       _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
        _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
-       _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+       /* i.mx51 has the i.mx27 type fec */
+       _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
        _REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk)
        _REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk)
        _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
@@ -1446,7 +1448,8 @@ static struct clk_lookup mx51_lookups[] = {
        _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
        _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
        _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
-       _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
+       /* i.mx51 has the i.mx35 type sdma */
+       _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
        _REGISTER_CLOCK(NULL, "ckih", ckih_clk)
        _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk)
        _REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk)
@@ -1454,10 +1457,10 @@ static struct clk_lookup mx51_lookups[] = {
        _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk)
        /* i.mx51 has the i.mx35 type cspi */
        _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk)
-       _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
-       _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
-       _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk)
-       _REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, esdhc4_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx51.0", NULL, esdhc1_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx51.1", NULL, esdhc2_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx51.2", NULL, esdhc3_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx51.3", NULL, esdhc4_clk)
        _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk)
        _REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
        _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
@@ -1470,29 +1473,32 @@ static struct clk_lookup mx51_lookups[] = {
 };
 
 static struct clk_lookup mx53_lookups[] = {
-       _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("imx-uart.3", NULL, uart4_clk)
-       _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+       /* i.mx53 has the i.mx21 type uart */
+       _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
+       _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
+       _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
+       _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
+       _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
        _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
-       _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+       /* i.mx53 has the i.mx25 type fec */
+       _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk)
        _REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
        _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
        _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
        _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_mx53_clk)
-       _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
-       _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_mx53_clk)
-       _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_mx53_clk)
-       _REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, esdhc4_mx53_clk)
        /* i.mx53 has the i.mx51 type ecspi */
        _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk)
        _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk)
        /* i.mx53 has the i.mx25 type cspi */
        _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx53.0", NULL, esdhc1_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx53.1", NULL, esdhc2_mx53_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx53.2", NULL, esdhc3_mx53_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx53.3", NULL, esdhc4_mx53_clk)
        _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
        _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk)
-       _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
+       /* i.mx53 has the i.mx35 type sdma */
+       _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
        _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
        _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
        _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
index ef8aec9..baea6e5 100644 (file)
@@ -115,7 +115,6 @@ static struct sdma_script_start_addrs imx51_sdma_script __initdata = {
 };
 
 static struct sdma_platform_data imx51_sdma_pdata __initdata = {
-       .sdma_version = 2,
        .fw_name = "sdma-imx51.bin",
        .script_addrs = &imx51_sdma_script,
 };
@@ -135,7 +134,6 @@ static struct sdma_script_start_addrs imx53_sdma_script __initdata = {
 };
 
 static struct sdma_platform_data imx53_sdma_pdata __initdata = {
-       .sdma_version = 2,
        .fw_name = "sdma-imx53.bin",
        .script_addrs = &imx53_sdma_script,
 };
@@ -148,7 +146,8 @@ void __init imx51_soc_init(void)
        mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH);
        mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH);
 
-       imx_add_imx_sdma(MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata);
+       /* i.mx51 has the i.mx35 type sdma */
+       imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata);
 }
 
 void __init imx53_soc_init(void)
@@ -162,5 +161,6 @@ void __init imx53_soc_init(void)
        mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
        mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
 
-       imx_add_imx_sdma(MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata);
+       /* i.mx53 has the i.mx35 type sdma */
+       imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata);
 }
index 56739c2..4435e03 100644 (file)
@@ -260,8 +260,8 @@ static struct regulator_consumer_supply vvideo_consumers[] = {
 };
 
 static struct regulator_consumer_supply vsd_consumers[] = {
-       REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.0"),
-       REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"),
+       REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx51.0"),
+       REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx51.1"),
 };
 
 static struct regulator_consumer_supply pwgt1_consumer[] = {
index fec64f3..d82ebab 100644 (file)
@@ -51,6 +51,12 @@ config MACH_SEABOARD
         also be included for some of the derivative boards that
         have large similarities with the seaboard design.
 
+config MACH_TEGRA_DT
+       bool "Generic Tegra board (FDT support)"
+       select USE_OF
+       help
+         Support for generic nVidia Tegra boards using Flattened Device Tree
+
 config MACH_TRIMSLICE
        bool "TrimSlice board"
        select TEGRA_PCI
index ed58ef9..f11b910 100644 (file)
@@ -29,5 +29,8 @@ obj-${CONFIG_MACH_PAZ00}              += board-paz00-pinmux.o
 obj-${CONFIG_MACH_SEABOARD}             += board-seaboard.o
 obj-${CONFIG_MACH_SEABOARD}             += board-seaboard-pinmux.o
 
+obj-${CONFIG_MACH_TEGRA_DT}             += board-dt.o
+obj-${CONFIG_MACH_TEGRA_DT}             += board-harmony-pinmux.o
+
 obj-${CONFIG_MACH_TRIMSLICE}            += board-trimslice.o
 obj-${CONFIG_MACH_TRIMSLICE}            += board-trimslice-pinmux.o
index db52d61..428ad12 100644 (file)
@@ -1,3 +1,6 @@
 zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC)   := 0x00008000
 params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC)        := 0x00000100
 initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC)        := 0x00800000
+
+dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb
+dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb
diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c
new file mode 100644 (file)
index 0000000..9f47e04
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * nVidia Tegra device tree board support
+ *
+ * Copyright (C) 2010 Secret Lab Technologies, Ltd.
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/pda_power.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c-tegra.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/setup.h>
+
+#include <mach/iomap.h>
+#include <mach/irqs.h>
+
+#include "board.h"
+#include "board-harmony.h"
+#include "clock.h"
+#include "devices.h"
+
+void harmony_pinmux_init(void);
+void seaboard_pinmux_init(void);
+
+
+struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC2_BASE, "sdhci-tegra.1", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC3_BASE, "sdhci-tegra.2", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC4_BASE, "sdhci-tegra.3", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C_BASE, "tegra-i2c.0", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C2_BASE, "tegra-i2c.1", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_I2C3_BASE, "tegra-i2c.2", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-i2c", TEGRA_DVC_BASE, "tegra-i2c.3", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.0", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-i2s", TEGRA_I2S1_BASE, "tegra-i2s.1", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra20-das", TEGRA_APB_MISC_DAS_BASE, "tegra-das", NULL),
+       {}
+};
+
+static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
+       /* name         parent          rate            enabled */
+       { "uartd",      "pll_p",        216000000,      true },
+       { NULL,         NULL,           0,              0},
+};
+
+static struct of_device_id tegra_dt_match_table[] __initdata = {
+       { .compatible = "simple-bus", },
+       {}
+};
+
+static struct of_device_id tegra_dt_gic_match[] __initdata = {
+       { .compatible = "nvidia,tegra20-gic", },
+       {}
+};
+
+static void __init tegra_dt_init(void)
+{
+       struct device_node *node;
+
+       node = of_find_matching_node_by_address(NULL, tegra_dt_gic_match,
+                                               TEGRA_ARM_INT_DIST_BASE);
+       if (node)
+               irq_domain_add_simple(node, INT_GIC_BASE);
+
+       tegra_clk_init_from_table(tegra_dt_clk_init_table);
+
+       if (of_machine_is_compatible("nvidia,harmony"))
+               harmony_pinmux_init();
+       else if (of_machine_is_compatible("nvidia,seaboard"))
+               seaboard_pinmux_init();
+
+       /*
+        * Finished with the static registrations now; fill in the missing
+        * devices
+        */
+       of_platform_populate(NULL, tegra_dt_match_table, tegra20_auxdata_lookup, NULL);
+}
+
+static const char * tegra_dt_board_compat[] = {
+       "nvidia,harmony",
+       "nvidia,seaboard",
+       NULL
+};
+
+DT_MACHINE_START(TEGRA_DT, "nVidia Tegra (Flattened Device Tree)")
+       .map_io         = tegra_map_common_io,
+       .init_early     = tegra_init_early,
+       .init_irq       = tegra_init_irq,
+       .timer          = &tegra_timer,
+       .init_machine   = tegra_dt_init,
+       .dt_compat      = tegra_dt_board_compat,
+MACHINE_END
index 9cdec5a..c1f38f6 100644 (file)
@@ -17,4 +17,12 @@ config MACH_VERSATILE_AB
          Include support for the ARM(R) Versatile Application Baseboard
          for the ARM926EJ-S.
 
+config MACH_VERSATILE_DT
+       bool "Support Versatile platform from device tree"
+       select USE_OF
+       select CPU_ARM926T
+       help
+         Include support for the ARM(R) Versatile/PB platform,
+         using the device tree for discovery
+
 endmenu
index 97cf4d8..81fa3fe 100644 (file)
@@ -5,4 +5,5 @@
 obj-y                                  := core.o
 obj-$(CONFIG_ARCH_VERSATILE_PB)                += versatile_pb.o
 obj-$(CONFIG_MACH_VERSATILE_AB)                += versatile_ab.o
+obj-$(CONFIG_MACH_VERSATILE_DT)                += versatile_dt.o
 obj-$(CONFIG_PCI)                      += pci.o
index 0c99cf0..e340a54 100644 (file)
@@ -24,6 +24,9 @@
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
 #include <linux/amba/pl061.h>
@@ -83,13 +86,26 @@ static struct fpga_irq_data sic_irq = {
 #define PIC_MASK       0
 #endif
 
+/* Lookup table for finding a DT node that represents the vic instance */
+static const struct of_device_id vic_of_match[] __initconst = {
+       { .compatible = "arm,versatile-vic", },
+       {}
+};
+
+static const struct of_device_id sic_of_match[] __initconst = {
+       { .compatible = "arm,versatile-sic", },
+       {}
+};
+
 void __init versatile_init_irq(void)
 {
        vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0);
+       irq_domain_generate_simple(vic_of_match, VERSATILE_VIC_BASE, IRQ_VIC_START);
 
        writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
 
        fpga_irq_init(IRQ_VICSOURCE31, ~PIC_MASK, &sic_irq);
+       irq_domain_generate_simple(sic_of_match, VERSATILE_SIC_BASE, IRQ_SIC_START);
 
        /*
         * Interrupts on secondary controller from 0 to 8 are routed to
@@ -646,6 +662,52 @@ static struct amba_device *amba_devs[] __initdata = {
        &kmi1_device,
 };
 
+#ifdef CONFIG_OF
+/*
+ * Lookup table for attaching a specific name and platform_data pointer to
+ * devices as they get created by of_platform_populate().  Ideally this table
+ * would not exist, but the current clock implementation depends on some devices
+ * having a specific name.
+ */
+struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI0_BASE, "fpga:05", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI0_BASE, "fpga:06", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_KMI1_BASE, "fpga:07", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART3_BASE, "fpga:09", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI1_BASE, "fpga:0b", NULL),
+
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_CLCD_BASE, "dev:20", &clcd_plat_data),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART0_BASE, "dev:f1", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART1_BASE, "dev:f2", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_UART2_BASE, "dev:f3", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_SSP_BASE, "dev:f4", NULL),
+
+#if 0
+       /*
+        * These entries are unnecessary because no clocks referencing
+        * them.  I've left them in for now as place holders in case
+        * any of them need to be added back, but they should be
+        * removed before actually committing this patch.  --gcl
+        */
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_AACI_BASE, "fpga:04", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCI1_BASE, "fpga:0a", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_SMC_BASE, "dev:00", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_MPMC_BASE, "dev:10", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_DMAC_BASE, "dev:30", NULL),
+
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCTL_BASE, "dev:e0", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_WATCHDOG_BASE, "dev:e1", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO0_BASE, "dev:e4", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO1_BASE, "dev:e5", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO2_BASE, "dev:e6", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_GPIO3_BASE, "dev:e7", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_RTC_BASE, "dev:e8", NULL),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_SCI_BASE, "dev:f0", NULL),
+#endif
+       {}
+};
+#endif
+
 #ifdef CONFIG_LEDS
 #define VA_LEDS_BASE (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
 
index fd6404e..e014227 100644 (file)
@@ -23,6 +23,7 @@
 #define __ASM_ARCH_VERSATILE_H
 
 #include <linux/amba/bus.h>
+#include <linux/of_platform.h>
 
 extern void __init versatile_init(void);
 extern void __init versatile_init_early(void);
@@ -30,6 +31,9 @@ extern void __init versatile_init_irq(void);
 extern void __init versatile_map_io(void);
 extern struct sys_timer versatile_timer;
 extern unsigned int mmc_status(struct device *dev);
+#ifdef CONFIG_OF
+extern struct of_dev_auxdata versatile_auxdata_lookup[];
+#endif
 
 #define AMBA_DEVICE(name,busid,base,plat)                      \
 static struct amba_device name##_device = {                    \
diff --git a/arch/arm/mach-versatile/versatile_dt.c b/arch/arm/mach-versatile/versatile_dt.c
new file mode 100644 (file)
index 0000000..54e037c
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Versatile board support using the device tree
+ *
+ *  Copyright (C) 2010 Secret Lab Technologies Ltd.
+ *  Copyright (C) 2009 Jeremy Kerr <jeremy.kerr@canonical.com>
+ *  Copyright (C) 2004 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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/init.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "core.h"
+
+static void __init versatile_dt_init(void)
+{
+       of_platform_populate(NULL, of_default_bus_match_table,
+                            versatile_auxdata_lookup, NULL);
+}
+
+static const char *versatile_dt_match[] __initconst = {
+       "arm,versatile-ab",
+       "arm,versatile-pb",
+       NULL,
+};
+
+DT_MACHINE_START(VERSATILE_PB, "ARM-Versatile (Device Tree Support)")
+       .map_io         = versatile_map_io,
+       .init_early     = versatile_init_early,
+       .init_irq       = versatile_init_irq,
+       .timer          = &versatile_timer,
+       .init_machine   = versatile_dt_init,
+       .dt_compat      = versatile_dt_match,
+MACHINE_END
index 4fc6ffc..0bae44e 100644 (file)
 #include <mach/hardware.h>
 #include <mach/devices-common.h>
 
-#define imx_fec_data_entry_single(soc)                                 \
+#define imx_fec_data_entry_single(soc, _devid)                         \
        {                                                               \
+               .devid = _devid,                                        \
                .iobase = soc ## _FEC_BASE_ADDR,                        \
                .irq = soc ## _INT_FEC,                                 \
        }
 
 #ifdef CONFIG_SOC_IMX25
 const struct imx_fec_data imx25_fec_data __initconst =
-       imx_fec_data_entry_single(MX25);
+       imx_fec_data_entry_single(MX25, "imx25-fec");
 #endif /* ifdef CONFIG_SOC_IMX25 */
 
 #ifdef CONFIG_SOC_IMX27
 const struct imx_fec_data imx27_fec_data __initconst =
-       imx_fec_data_entry_single(MX27);
+       imx_fec_data_entry_single(MX27, "imx27-fec");
 #endif /* ifdef CONFIG_SOC_IMX27 */
 
 #ifdef CONFIG_SOC_IMX35
+/* i.mx35 has the i.mx27 type fec */
 const struct imx_fec_data imx35_fec_data __initconst =
-       imx_fec_data_entry_single(MX35);
+       imx_fec_data_entry_single(MX35, "imx27-fec");
 #endif
 
 #ifdef CONFIG_SOC_IMX50
+/* i.mx50 has the i.mx25 type fec */
 const struct imx_fec_data imx50_fec_data __initconst =
-       imx_fec_data_entry_single(MX50);
+       imx_fec_data_entry_single(MX50, "imx25-fec");
 #endif
 
 #ifdef CONFIG_SOC_IMX51
+/* i.mx51 has the i.mx27 type fec */
 const struct imx_fec_data imx51_fec_data __initconst =
-       imx_fec_data_entry_single(MX51);
+       imx_fec_data_entry_single(MX51, "imx27-fec");
 #endif
 
 #ifdef CONFIG_SOC_IMX53
+/* i.mx53 has the i.mx25 type fec */
 const struct imx_fec_data imx53_fec_data __initconst =
-       imx_fec_data_entry_single(MX53);
+       imx_fec_data_entry_single(MX53, "imx25-fec");
 #endif
 
 struct platform_device *__init imx_add_fec(
@@ -63,7 +68,7 @@ struct platform_device *__init imx_add_fec(
                },
        };
 
-       return imx_add_platform_device_dmamask("fec", 0,
+       return imx_add_platform_device_dmamask(data->devid, 0,
                        res, ARRAY_SIZE(res),
                        pdata, sizeof(*pdata), DMA_BIT_MASK(32));
 }
index 2b0fdb2..7fa7e9c 100644 (file)
@@ -14,7 +14,7 @@ struct platform_device __init __maybe_unused *imx_add_imx_dma(void)
                        "imx-dma", -1, NULL, 0, NULL, 0);
 }
 
-struct platform_device __init __maybe_unused *imx_add_imx_sdma(
+struct platform_device __init __maybe_unused *imx_add_imx_sdma(char *name,
        resource_size_t iobase, int irq, struct sdma_platform_data *pdata)
 {
        struct resource res[] = {
@@ -29,6 +29,6 @@ struct platform_device __init __maybe_unused *imx_add_imx_sdma(
                },
        };
 
-       return platform_device_register_resndata(&mxc_ahb_bus, "imx-sdma",
+       return platform_device_register_resndata(&mxc_ahb_bus, name,
                        -1, res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
 }
index cfce8c9..2020d84 100644 (file)
@@ -152,7 +152,7 @@ struct platform_device *__init imx_add_imx_uart_3irq(
                },
        };
 
-       return imx_add_platform_device("imx-uart", data->id, res,
+       return imx_add_platform_device("imx1-uart", data->id, res,
                        ARRAY_SIZE(res), pdata, sizeof(*pdata));
 }
 
@@ -172,6 +172,7 @@ struct platform_device *__init imx_add_imx_uart_1irq(
                },
        };
 
-       return imx_add_platform_device("imx-uart", data->id, res, ARRAY_SIZE(res),
-                       pdata, sizeof(*pdata));
+       /* i.mx21 type uart runs on all i.mx except i.mx1 */
+       return imx_add_platform_device("imx21-uart", data->id,
+                       res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
 }
index 6b2940b..5955f5d 100644 (file)
 #include <mach/devices-common.h>
 #include <mach/esdhc.h>
 
-#define imx_sdhci_esdhc_imx_data_entry_single(soc, _id, hwid) \
+#define imx_sdhci_esdhc_imx_data_entry_single(soc, _devid, _id, hwid) \
        {                                                               \
+               .devid = _devid,                                        \
                .id = _id,                                              \
                .iobase = soc ## _ESDHC ## hwid ## _BASE_ADDR,  \
                .irq = soc ## _INT_ESDHC ## hwid,                       \
        }
 
-#define imx_sdhci_esdhc_imx_data_entry(soc, id, hwid)  \
-       [id] = imx_sdhci_esdhc_imx_data_entry_single(soc, id, hwid)
+#define imx_sdhci_esdhc_imx_data_entry(soc, devid, id, hwid)   \
+       [id] = imx_sdhci_esdhc_imx_data_entry_single(soc, devid, id, hwid)
 
 #ifdef CONFIG_SOC_IMX25
 const struct imx_sdhci_esdhc_imx_data
 imx25_sdhci_esdhc_imx_data[] __initconst = {
 #define imx25_sdhci_esdhc_imx_data_entry(_id, _hwid)                   \
-       imx_sdhci_esdhc_imx_data_entry(MX25, _id, _hwid)
+       imx_sdhci_esdhc_imx_data_entry(MX25, "sdhci-esdhc-imx25", _id, _hwid)
        imx25_sdhci_esdhc_imx_data_entry(0, 1),
        imx25_sdhci_esdhc_imx_data_entry(1, 2),
 };
@@ -34,7 +35,7 @@ imx25_sdhci_esdhc_imx_data[] __initconst = {
 const struct imx_sdhci_esdhc_imx_data
 imx35_sdhci_esdhc_imx_data[] __initconst = {
 #define imx35_sdhci_esdhc_imx_data_entry(_id, _hwid)                   \
-       imx_sdhci_esdhc_imx_data_entry(MX35, _id, _hwid)
+       imx_sdhci_esdhc_imx_data_entry(MX35, "sdhci-esdhc-imx35", _id, _hwid)
        imx35_sdhci_esdhc_imx_data_entry(0, 1),
        imx35_sdhci_esdhc_imx_data_entry(1, 2),
        imx35_sdhci_esdhc_imx_data_entry(2, 3),
@@ -45,7 +46,7 @@ imx35_sdhci_esdhc_imx_data[] __initconst = {
 const struct imx_sdhci_esdhc_imx_data
 imx51_sdhci_esdhc_imx_data[] __initconst = {
 #define imx51_sdhci_esdhc_imx_data_entry(_id, _hwid)                   \
-       imx_sdhci_esdhc_imx_data_entry(MX51, _id, _hwid)
+       imx_sdhci_esdhc_imx_data_entry(MX51, "sdhci-esdhc-imx51", _id, _hwid)
        imx51_sdhci_esdhc_imx_data_entry(0, 1),
        imx51_sdhci_esdhc_imx_data_entry(1, 2),
        imx51_sdhci_esdhc_imx_data_entry(2, 3),
@@ -57,7 +58,7 @@ imx51_sdhci_esdhc_imx_data[] __initconst = {
 const struct imx_sdhci_esdhc_imx_data
 imx53_sdhci_esdhc_imx_data[] __initconst = {
 #define imx53_sdhci_esdhc_imx_data_entry(_id, _hwid)                   \
-       imx_sdhci_esdhc_imx_data_entry(MX53, _id, _hwid)
+       imx_sdhci_esdhc_imx_data_entry(MX53, "sdhci-esdhc-imx53", _id, _hwid)
        imx53_sdhci_esdhc_imx_data_entry(0, 1),
        imx53_sdhci_esdhc_imx_data_entry(1, 2),
        imx53_sdhci_esdhc_imx_data_entry(2, 3),
@@ -65,6 +66,11 @@ imx53_sdhci_esdhc_imx_data[] __initconst = {
 };
 #endif /* ifdef CONFIG_SOC_IMX53 */
 
+static const struct esdhc_platform_data default_esdhc_pdata __initconst = {
+       .wp_type = ESDHC_WP_NONE,
+       .cd_type = ESDHC_CD_NONE,
+};
+
 struct platform_device *__init imx_add_sdhci_esdhc_imx(
                const struct imx_sdhci_esdhc_imx_data *data,
                const struct esdhc_platform_data *pdata)
@@ -81,6 +87,13 @@ struct platform_device *__init imx_add_sdhci_esdhc_imx(
                },
        };
 
-       return imx_add_platform_device("sdhci-esdhc-imx", data->id, res,
+       /*
+        * If machine does not provide pdata, use the default one
+        * which means no WP/CD support
+        */
+       if (!pdata)
+               pdata = &default_esdhc_pdata;
+
+       return imx_add_platform_device(data->devid, data->id, res,
                        ARRAY_SIZE(res), pdata, sizeof(*pdata));
 }
index bf93820..524538a 100644 (file)
@@ -30,6 +30,7 @@ static inline struct platform_device *imx_add_platform_device(
 
 #include <linux/fec.h>
 struct imx_fec_data {
+       const char *devid;
        resource_size_t iobase;
        resource_size_t irq;
 };
@@ -276,6 +277,7 @@ struct platform_device *__init imx_add_mxc_w1(
 
 #include <mach/esdhc.h>
 struct imx_sdhci_esdhc_imx_data {
+       const char *devid;
        int id;
        resource_size_t iobase;
        resource_size_t irq;
@@ -297,5 +299,5 @@ struct platform_device *__init imx_add_spi_imx(
                const struct spi_imx_master *pdata);
 
 struct platform_device *imx_add_imx_dma(void);
-struct platform_device *imx_add_imx_sdma(
+struct platform_device *imx_add_imx_sdma(char *name,
        resource_size_t iobase, int irq, struct sdma_platform_data *pdata);
index ef77515..233d0a5 100644 (file)
@@ -60,7 +60,8 @@ static inline int imx_dma_is_ipu(struct dma_chan *chan)
 
 static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
 {
-       return !strcmp(dev_name(chan->device->dev), "imx-sdma") ||
+       return !strcmp(dev_name(chan->device->dev), "imx31-sdma") ||
+               !strcmp(dev_name(chan->device->dev), "imx35-sdma") ||
                !strcmp(dev_name(chan->device->dev), "imx-dma");
 }
 
index 86003f4..aaf9748 100644 (file)
 #ifndef __ASM_ARCH_IMX_ESDHC_H
 #define __ASM_ARCH_IMX_ESDHC_H
 
+enum wp_types {
+       ESDHC_WP_NONE,          /* no WP, neither controller nor gpio */
+       ESDHC_WP_CONTROLLER,    /* mmc controller internal WP */
+       ESDHC_WP_GPIO,          /* external gpio pin for WP */
+};
+
+enum cd_types {
+       ESDHC_CD_NONE,          /* no CD, neither controller nor gpio */
+       ESDHC_CD_CONTROLLER,    /* mmc controller internal CD */
+       ESDHC_CD_GPIO,          /* external gpio pin for CD */
+       ESDHC_CD_PERMANENT,     /* no CD, card permanently wired to host */
+};
+
 /**
- * struct esdhc_platform_data - optional platform data for esdhc on i.MX
+ * struct esdhc_platform_data - platform data for esdhc on i.MX
  *
- * strongly recommended for i.MX25/35, not needed for other variants
+ * ESDHC_WP(CD)_CONTROLLER type is not available on i.MX25/35.
  *
- * @wp_gpio:   gpio for write_protect (-EINVAL if unused)
- * @cd_gpio:   gpio for card_detect interrupt (-EINVAL if unused)
+ * @wp_gpio:   gpio for write_protect
+ * @cd_gpio:   gpio for card_detect interrupt
+ * @wp_type:   type of write_protect method (see wp_types enum above)
+ * @cd_type:   type of card_detect method (see cd_types enum above)
  */
 
 struct esdhc_platform_data {
        unsigned int wp_gpio;
        unsigned int cd_gpio;
+       enum wp_types wp_type;
+       enum cd_types cd_type;
 };
 #endif /* __ASM_ARCH_IMX_ESDHC_H */
index f495c87..3a39428 100644 (file)
@@ -48,12 +48,10 @@ struct sdma_script_start_addrs {
 /**
  * struct sdma_platform_data - platform specific data for SDMA engine
  *
- * @sdma_version       The version of this SDMA engine
  * @fw_name            The firmware name
  * @script_addrs       SDMA scripts addresses in SDMA ROM
  */
 struct sdma_platform_data {
-       int sdma_version;
        char *fw_name;
        struct sdma_script_start_addrs *script_addrs;
 };
index 1ea47db..1eb60de 100644 (file)
@@ -32,6 +32,8 @@
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/dmaengine.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/irq.h>
 #include <mach/sdma.h>
@@ -65,8 +67,8 @@
 #define SDMA_ONCE_RTB          0x060
 #define SDMA_XTRIG_CONF1       0x070
 #define SDMA_XTRIG_CONF2       0x074
-#define SDMA_CHNENBL0_V2       0x200
-#define SDMA_CHNENBL0_V1       0x080
+#define SDMA_CHNENBL0_IMX35    0x200
+#define SDMA_CHNENBL0_IMX31    0x080
 #define SDMA_CHNPRI_0          0x100
 
 /*
@@ -299,13 +301,18 @@ struct sdma_firmware_header {
        u32     ram_code_size;
 };
 
+enum sdma_devtype {
+       IMX31_SDMA,     /* runs on i.mx31 */
+       IMX35_SDMA,     /* runs on i.mx35 and later */
+};
+
 struct sdma_engine {
        struct device                   *dev;
        struct device_dma_parameters    dma_parms;
        struct sdma_channel             channel[MAX_DMA_CHANNELS];
        struct sdma_channel_control     *channel_control;
        void __iomem                    *regs;
-       unsigned int                    version;
+       enum sdma_devtype               devtype;
        unsigned int                    num_events;
        struct sdma_context_data        *context;
        dma_addr_t                      context_phys;
@@ -314,6 +321,26 @@ struct sdma_engine {
        struct sdma_script_start_addrs  *script_addrs;
 };
 
+static struct platform_device_id sdma_devtypes[] = {
+       {
+               .name = "imx31-sdma",
+               .driver_data = IMX31_SDMA,
+       }, {
+               .name = "imx35-sdma",
+               .driver_data = IMX35_SDMA,
+       }, {
+               /* sentinel */
+       }
+};
+MODULE_DEVICE_TABLE(platform, sdma_devtypes);
+
+static const struct of_device_id sdma_dt_ids[] = {
+       { .compatible = "fsl,imx31-sdma", .data = &sdma_devtypes[IMX31_SDMA], },
+       { .compatible = "fsl,imx35-sdma", .data = &sdma_devtypes[IMX35_SDMA], },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sdma_dt_ids);
+
 #define SDMA_H_CONFIG_DSPDMA   (1 << 12) /* indicates if the DSPDMA is used */
 #define SDMA_H_CONFIG_RTD_PINS (1 << 11) /* indicates if Real-Time Debug pins are enabled */
 #define SDMA_H_CONFIG_ACR      (1 << 4)  /* indicates if AHB freq /core freq = 2 or 1 */
@@ -321,8 +348,8 @@ struct sdma_engine {
 
 static inline u32 chnenbl_ofs(struct sdma_engine *sdma, unsigned int event)
 {
-       u32 chnenbl0 = (sdma->version == 2 ? SDMA_CHNENBL0_V2 : SDMA_CHNENBL0_V1);
-
+       u32 chnenbl0 = (sdma->devtype == IMX31_SDMA ? SDMA_CHNENBL0_IMX31 :
+                                                     SDMA_CHNENBL0_IMX35);
        return chnenbl0 + event * 4;
 }
 
@@ -1108,22 +1135,14 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma,
                const char *fw_name)
 {
        const struct firmware *fw;
-       char *fwname;
        const struct sdma_firmware_header *header;
        int ret;
        const struct sdma_script_start_addrs *addr;
        unsigned short *ram_code;
 
-       fwname = kasprintf(GFP_KERNEL, "%s", fw_name);
-       if (!fwname)
-               return -ENOMEM;
-
-       ret = request_firmware(&fw, fwname, sdma->dev);
-       if (ret) {
-               kfree(fwname);
+       ret = request_firmware(&fw, fw_name, sdma->dev);
+       if (ret)
                return ret;
-       }
-       kfree(fwname);
 
        if (fw->size < sizeof(*header))
                goto err_firmware;
@@ -1162,15 +1181,16 @@ static int __init sdma_init(struct sdma_engine *sdma)
        int i, ret;
        dma_addr_t ccb_phys;
 
-       switch (sdma->version) {
-       case 1:
+       switch (sdma->devtype) {
+       case IMX31_SDMA:
                sdma->num_events = 32;
                break;
-       case 2:
+       case IMX35_SDMA:
                sdma->num_events = 48;
                break;
        default:
-               dev_err(sdma->dev, "Unknown version %d. aborting\n", sdma->version);
+               dev_err(sdma->dev, "Unknown sdma type %d. aborting\n",
+                       sdma->devtype);
                return -ENODEV;
        }
 
@@ -1239,6 +1259,10 @@ err_dma_alloc:
 
 static int __init sdma_probe(struct platform_device *pdev)
 {
+       const struct of_device_id *of_id =
+                       of_match_device(sdma_dt_ids, &pdev->dev);
+       struct device_node *np = pdev->dev.of_node;
+       const char *fw_name;
        int ret;
        int irq;
        struct resource *iores;
@@ -1254,7 +1278,7 @@ static int __init sdma_probe(struct platform_device *pdev)
 
        iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq = platform_get_irq(pdev, 0);
-       if (!iores || irq < 0 || !pdata) {
+       if (!iores || irq < 0) {
                ret = -EINVAL;
                goto err_irq;
        }
@@ -1284,7 +1308,9 @@ static int __init sdma_probe(struct platform_device *pdev)
        if (!sdma->script_addrs)
                goto err_alloc;
 
-       sdma->version = pdata->sdma_version;
+       if (of_id)
+               pdev->id_entry = of_id->data;
+       sdma->devtype = pdev->id_entry->driver_data;
 
        dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask);
        dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask);
@@ -1314,10 +1340,30 @@ static int __init sdma_probe(struct platform_device *pdev)
        if (ret)
                goto err_init;
 
-       if (pdata->script_addrs)
+       if (pdata && pdata->script_addrs)
                sdma_add_scripts(sdma, pdata->script_addrs);
 
-       sdma_get_firmware(sdma, pdata->fw_name);
+       if (pdata) {
+               sdma_get_firmware(sdma, pdata->fw_name);
+       } else {
+               /*
+                * Because that device tree does not encode ROM script address,
+                * the RAM script in firmware is mandatory for device tree
+                * probe, otherwise it fails.
+                */
+               ret = of_property_read_string(np, "fsl,sdma-ram-script-name",
+                                             &fw_name);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to get firmware name\n");
+                       goto err_init;
+               }
+
+               ret = sdma_get_firmware(sdma, fw_name);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to get firmware\n");
+                       goto err_init;
+               }
+       }
 
        sdma->dma_device.dev = &pdev->dev;
 
@@ -1365,7 +1411,9 @@ static int __exit sdma_remove(struct platform_device *pdev)
 static struct platform_driver sdma_driver = {
        .driver         = {
                .name   = "imx-sdma",
+               .of_match_table = sdma_dt_ids,
        },
+       .id_table       = sdma_devtypes,
        .remove         = __exit_p(sdma_remove),
 };
 
index 710b706..9ebfb4b 100644 (file)
@@ -20,7 +20,9 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/sdio.h>
-#include <mach/hardware.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <mach/esdhc.h>
 #include "sdhci-pltfm.h"
 #include "sdhci-esdhc.h"
@@ -29,7 +31,6 @@
 #define SDHCI_VENDOR_SPEC              0xC0
 #define  SDHCI_VENDOR_SPEC_SDIO_QUIRK  0x00000002
 
-#define ESDHC_FLAG_GPIO_FOR_CD         (1 << 0)
 /*
  * The CMDTYPE of the CMD register (offset 0xE) should be set to
  * "11" when the STOP CMD12 is issued on imx53 to abort one
  */
 #define ESDHC_FLAG_MULTIBLK_NO_INT     (1 << 1)
 
+enum imx_esdhc_type {
+       IMX25_ESDHC,
+       IMX35_ESDHC,
+       IMX51_ESDHC,
+       IMX53_ESDHC,
+};
+
 struct pltfm_imx_data {
        int flags;
        u32 scratchpad;
+       enum imx_esdhc_type devtype;
+       struct esdhc_platform_data boarddata;
+};
+
+static struct platform_device_id imx_esdhc_devtype[] = {
+       {
+               .name = "sdhci-esdhc-imx25",
+               .driver_data = IMX25_ESDHC,
+       }, {
+               .name = "sdhci-esdhc-imx35",
+               .driver_data = IMX35_ESDHC,
+       }, {
+               .name = "sdhci-esdhc-imx51",
+               .driver_data = IMX51_ESDHC,
+       }, {
+               .name = "sdhci-esdhc-imx53",
+               .driver_data = IMX53_ESDHC,
+       }, {
+               /* sentinel */
+       }
 };
+MODULE_DEVICE_TABLE(platform, imx_esdhc_devtype);
+
+static const struct of_device_id imx_esdhc_dt_ids[] = {
+       { .compatible = "fsl,imx25-esdhc", .data = &imx_esdhc_devtype[IMX25_ESDHC], },
+       { .compatible = "fsl,imx35-esdhc", .data = &imx_esdhc_devtype[IMX35_ESDHC], },
+       { .compatible = "fsl,imx51-esdhc", .data = &imx_esdhc_devtype[IMX51_ESDHC], },
+       { .compatible = "fsl,imx53-esdhc", .data = &imx_esdhc_devtype[IMX53_ESDHC], },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);
+
+static inline int is_imx25_esdhc(struct pltfm_imx_data *data)
+{
+       return data->devtype == IMX25_ESDHC;
+}
+
+static inline int is_imx35_esdhc(struct pltfm_imx_data *data)
+{
+       return data->devtype == IMX35_ESDHC;
+}
+
+static inline int is_imx51_esdhc(struct pltfm_imx_data *data)
+{
+       return data->devtype == IMX51_ESDHC;
+}
+
+static inline int is_imx53_esdhc(struct pltfm_imx_data *data)
+{
+       return data->devtype == IMX53_ESDHC;
+}
 
 static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg)
 {
@@ -60,17 +118,14 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
 {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
        struct pltfm_imx_data *imx_data = pltfm_host->priv;
+       struct esdhc_platform_data *boarddata = &imx_data->boarddata;
 
-       /* fake CARD_PRESENT flag on mx25/35 */
+       /* fake CARD_PRESENT flag */
        u32 val = readl(host->ioaddr + reg);
 
        if (unlikely((reg == SDHCI_PRESENT_STATE)
-                       && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD))) {
-               struct esdhc_platform_data *boarddata =
-                               host->mmc->parent->platform_data;
-
-               if (boarddata && gpio_is_valid(boarddata->cd_gpio)
-                               && gpio_get_value(boarddata->cd_gpio))
+                       && gpio_is_valid(boarddata->cd_gpio))) {
+               if (gpio_get_value(boarddata->cd_gpio))
                        /* no card, if a valid gpio says so... */
                        val &= ~SDHCI_CARD_PRESENT;
                else
@@ -85,12 +140,12 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
 {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
        struct pltfm_imx_data *imx_data = pltfm_host->priv;
+       struct esdhc_platform_data *boarddata = &imx_data->boarddata;
 
        if (unlikely((reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)
-                       && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD)))
+                       && (boarddata->cd_type == ESDHC_CD_GPIO)))
                /*
                 * these interrupts won't work with a custom card_detect gpio
-                * (only applied to mx25/35)
                 */
                val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
 
@@ -173,6 +228,17 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
                return;
        }
        esdhc_clrset_le(host, 0xff, val, reg);
+
+       /*
+        * The esdhc has a design violation to SDHC spec which tells
+        * that software reset should not affect card detection circuit.
+        * But esdhc clears its SYSCTL register bits [0..2] during the
+        * software reset.  This will stop those clocks that card detection
+        * circuit relies on.  To work around it, we turn the clocks on back
+        * to keep card detection circuit functional.
+        */
+       if ((reg == SDHCI_SOFTWARE_RESET) && (val & 1))
+               esdhc_clrset_le(host, 0x7, 0x7, ESDHC_SYSTEM_CONTROL);
 }
 
 static unsigned int esdhc_pltfm_get_max_clock(struct sdhci_host *host)
@@ -189,6 +255,26 @@ static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host)
        return clk_get_rate(pltfm_host->clk) / 256 / 16;
 }
 
+static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
+{
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct pltfm_imx_data *imx_data = pltfm_host->priv;
+       struct esdhc_platform_data *boarddata = &imx_data->boarddata;
+
+       switch (boarddata->wp_type) {
+       case ESDHC_WP_GPIO:
+               if (gpio_is_valid(boarddata->wp_gpio))
+                       return gpio_get_value(boarddata->wp_gpio);
+       case ESDHC_WP_CONTROLLER:
+               return !(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
+                              SDHCI_WRITE_PROTECT);
+       case ESDHC_WP_NONE:
+               break;
+       }
+
+       return -ENOSYS;
+}
+
 static struct sdhci_ops sdhci_esdhc_ops = {
        .read_l = esdhc_readl_le,
        .read_w = esdhc_readw_le,
@@ -198,6 +284,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
        .set_clock = esdhc_set_clock,
        .get_max_clock = esdhc_pltfm_get_max_clock,
        .get_min_clock = esdhc_pltfm_get_min_clock,
+       .get_ro = esdhc_pltfm_get_ro,
 };
 
 static struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
@@ -207,17 +294,6 @@ static struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
        .ops = &sdhci_esdhc_ops,
 };
 
-static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
-{
-       struct esdhc_platform_data *boarddata =
-                       host->mmc->parent->platform_data;
-
-       if (boarddata && gpio_is_valid(boarddata->wp_gpio))
-               return gpio_get_value(boarddata->wp_gpio);
-       else
-               return -ENOSYS;
-}
-
 static irqreturn_t cd_irq(int irq, void *data)
 {
        struct sdhci_host *sdhost = (struct sdhci_host *)data;
@@ -226,8 +302,48 @@ static irqreturn_t cd_irq(int irq, void *data)
        return IRQ_HANDLED;
 };
 
+#ifdef CONFIG_OF
+static int __devinit
+sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
+                        struct esdhc_platform_data *boarddata)
+{
+       struct device_node *np = pdev->dev.of_node;
+
+       if (!np)
+               return -ENODEV;
+
+       if (of_get_property(np, "fsl,card-wired", NULL))
+               boarddata->cd_type = ESDHC_CD_PERMANENT;
+
+       if (of_get_property(np, "fsl,cd-controller", NULL))
+               boarddata->cd_type = ESDHC_CD_CONTROLLER;
+
+       if (of_get_property(np, "fsl,wp-controller", NULL))
+               boarddata->wp_type = ESDHC_WP_CONTROLLER;
+
+       boarddata->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
+       if (gpio_is_valid(boarddata->cd_gpio))
+               boarddata->cd_type = ESDHC_CD_GPIO;
+
+       boarddata->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
+       if (gpio_is_valid(boarddata->wp_gpio))
+               boarddata->wp_type = ESDHC_WP_GPIO;
+
+       return 0;
+}
+#else
+static inline int
+sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
+                        struct esdhc_platform_data *boarddata)
+{
+       return -ENODEV;
+}
+#endif
+
 static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
 {
+       const struct of_device_id *of_id =
+                       of_match_device(imx_esdhc_dt_ids, &pdev->dev);
        struct sdhci_pltfm_host *pltfm_host;
        struct sdhci_host *host;
        struct esdhc_platform_data *boarddata;
@@ -242,8 +358,14 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
        pltfm_host = sdhci_priv(host);
 
        imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
-       if (!imx_data)
-               return -ENOMEM;
+       if (!imx_data) {
+               err = -ENOMEM;
+               goto err_imx_data;
+       }
+
+       if (of_id)
+               pdev->id_entry = of_id->data;
+       imx_data->devtype = pdev->id_entry->driver_data;
        pltfm_host->priv = imx_data;
 
        clk = clk_get(mmc_dev(host->mmc), NULL);
@@ -255,50 +377,72 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
        clk_enable(clk);
        pltfm_host->clk = clk;
 
-       if (!cpu_is_mx25())
+       if (!is_imx25_esdhc(imx_data))
                host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 
-       if (cpu_is_mx25() || cpu_is_mx35()) {
+       if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
                /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
                host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK;
-               /* write_protect can't be routed to controller, use gpio */
-               sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro;
-       }
 
-       if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51()))
+       if (is_imx53_esdhc(imx_data))
                imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
 
-       boarddata = host->mmc->parent->platform_data;
-       if (boarddata) {
+       boarddata = &imx_data->boarddata;
+       if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {
+               if (!host->mmc->parent->platform_data) {
+                       dev_err(mmc_dev(host->mmc), "no board data!\n");
+                       err = -EINVAL;
+                       goto no_board_data;
+               }
+               imx_data->boarddata = *((struct esdhc_platform_data *)
+                                       host->mmc->parent->platform_data);
+       }
+
+       /* write_protect */
+       if (boarddata->wp_type == ESDHC_WP_GPIO) {
                err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP");
                if (err) {
                        dev_warn(mmc_dev(host->mmc),
-                               "no write-protect pin available!\n");
-                       boarddata->wp_gpio = err;
+                                "no write-protect pin available!\n");
+                       boarddata->wp_gpio = -EINVAL;
                }
+       } else {
+               boarddata->wp_gpio = -EINVAL;
+       }
+
+       /* card_detect */
+       if (boarddata->cd_type != ESDHC_CD_GPIO)
+               boarddata->cd_gpio = -EINVAL;
 
+       switch (boarddata->cd_type) {
+       case ESDHC_CD_GPIO:
                err = gpio_request_one(boarddata->cd_gpio, GPIOF_IN, "ESDHC_CD");
                if (err) {
-                       dev_warn(mmc_dev(host->mmc),
+                       dev_err(mmc_dev(host->mmc),
                                "no card-detect pin available!\n");
                        goto no_card_detect_pin;
                }
 
-               /* i.MX5x has issues to be researched */
-               if (!cpu_is_mx25() && !cpu_is_mx35())
-                       goto not_supported;
-
                err = request_irq(gpio_to_irq(boarddata->cd_gpio), cd_irq,
                                 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
                                 mmc_hostname(host->mmc), host);
                if (err) {
-                       dev_warn(mmc_dev(host->mmc), "request irq error\n");
+                       dev_err(mmc_dev(host->mmc), "request irq error\n");
                        goto no_card_detect_irq;
                }
+               /* fall through */
 
-               imx_data->flags |= ESDHC_FLAG_GPIO_FOR_CD;
-               /* Now we have a working card_detect again */
+       case ESDHC_CD_CONTROLLER:
+               /* we have a working card_detect back */
                host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+               break;
+
+       case ESDHC_CD_PERMANENT:
+               host->mmc->caps = MMC_CAP_NONREMOVABLE;
+               break;
+
+       case ESDHC_CD_NONE:
+               break;
        }
 
        err = sdhci_add_host(host);
@@ -307,16 +451,21 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
 
        return 0;
 
- no_card_detect_irq:
-       gpio_free(boarddata->cd_gpio);
- no_card_detect_pin:
-       boarddata->cd_gpio = err;
- not_supported:
-       kfree(imx_data);
- err_add_host:
+err_add_host:
+       if (gpio_is_valid(boarddata->cd_gpio))
+               free_irq(gpio_to_irq(boarddata->cd_gpio), host);
+no_card_detect_irq:
+       if (gpio_is_valid(boarddata->cd_gpio))
+               gpio_free(boarddata->cd_gpio);
+       if (gpio_is_valid(boarddata->wp_gpio))
+               gpio_free(boarddata->wp_gpio);
+no_card_detect_pin:
+no_board_data:
        clk_disable(pltfm_host->clk);
        clk_put(pltfm_host->clk);
- err_clk_get:
+err_clk_get:
+       kfree(imx_data);
+err_imx_data:
        sdhci_pltfm_free(pdev);
        return err;
 }
@@ -325,20 +474,18 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
 {
        struct sdhci_host *host = platform_get_drvdata(pdev);
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-       struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
        struct pltfm_imx_data *imx_data = pltfm_host->priv;
+       struct esdhc_platform_data *boarddata = &imx_data->boarddata;
        int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
 
        sdhci_remove_host(host, dead);
 
-       if (boarddata && gpio_is_valid(boarddata->wp_gpio))
+       if (gpio_is_valid(boarddata->wp_gpio))
                gpio_free(boarddata->wp_gpio);
 
-       if (boarddata && gpio_is_valid(boarddata->cd_gpio)) {
+       if (gpio_is_valid(boarddata->cd_gpio)) {
+               free_irq(gpio_to_irq(boarddata->cd_gpio), host);
                gpio_free(boarddata->cd_gpio);
-
-               if (!(host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION))
-                       free_irq(gpio_to_irq(boarddata->cd_gpio), host);
        }
 
        clk_disable(pltfm_host->clk);
@@ -354,7 +501,9 @@ static struct platform_driver sdhci_esdhc_imx_driver = {
        .driver         = {
                .name   = "sdhci-esdhc-imx",
                .owner  = THIS_MODULE,
+               .of_match_table = imx_esdhc_dt_ids,
        },
+       .id_table       = imx_esdhc_devtype,
        .probe          = sdhci_esdhc_imx_probe,
        .remove         = __devexit_p(sdhci_esdhc_imx_remove),
 #ifdef CONFIG_PM
index 71c0ce1..6414efe 100644 (file)
@@ -85,6 +85,7 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
 {
        struct sdhci_host *host;
        struct sdhci_pltfm_host *pltfm_host;
+       struct device_node *np = pdev->dev.of_node;
        struct resource *iomem;
        int ret;
 
@@ -98,7 +99,7 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev,
                dev_err(&pdev->dev, "Invalid iomem size!\n");
 
        /* Some PCI-based MFD need the parent here */
-       if (pdev->dev.parent != &platform_bus)
+       if (pdev->dev.parent != &platform_bus && !np)
                host = sdhci_alloc_host(pdev->dev.parent, sizeof(*pltfm_host));
        else
                host = sdhci_alloc_host(&pdev->dev, sizeof(*pltfm_host));
index 5b631fe..e8266cc 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <linux/fec.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_net.h>
 
 #include <asm/cacheflush.h>
 
 #define FEC_QUIRK_ENET_MAC             (1 << 0)
 /* Controller needs driver to swap frame */
 #define FEC_QUIRK_SWAP_FRAME           (1 << 1)
+/* Controller uses gasket */
+#define FEC_QUIRK_USE_GASKET           (1 << 2)
 
 static struct platform_device_id fec_devtype[] = {
        {
+               /* keep it for coldfire */
                .name = DRIVER_NAME,
                .driver_data = 0,
        }, {
+               .name = "imx25-fec",
+               .driver_data = FEC_QUIRK_USE_GASKET,
+       }, {
+               .name = "imx27-fec",
+               .driver_data = 0,
+       }, {
                .name = "imx28-fec",
                .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME,
-       },
-       { }
+       }, {
+               /* sentinel */
+       }
 };
+MODULE_DEVICE_TABLE(platform, fec_devtype);
+
+enum imx_fec_type {
+       IMX25_FEC = 1,  /* runs on i.mx25/50/53 */
+       IMX27_FEC,      /* runs on i.mx27/35/51 */
+       IMX28_FEC,
+};
+
+static const struct of_device_id fec_dt_ids[] = {
+       { .compatible = "fsl,imx25-fec", .data = &fec_devtype[IMX25_FEC], },
+       { .compatible = "fsl,imx27-fec", .data = &fec_devtype[IMX27_FEC], },
+       { .compatible = "fsl,imx28-fec", .data = &fec_devtype[IMX28_FEC], },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fec_dt_ids);
 
 static unsigned char macaddr[ETH_ALEN];
 module_param_array(macaddr, byte, NULL, 0);
@@ -427,7 +456,7 @@ fec_restart(struct net_device *ndev, int duplex)
 
        } else {
 #ifdef FEC_MIIGSK_ENR
-               if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
+               if (id_entry->driver_data & FEC_QUIRK_USE_GASKET) {
                        /* disable the gasket and wait */
                        writel(0, fep->hwp + FEC_MIIGSK_ENR);
                        while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
@@ -436,8 +465,11 @@ fec_restart(struct net_device *ndev, int duplex)
                        /*
                         * configure the gasket:
                         *   RMII, 50 MHz, no loopback, no echo
+                        *   MII, 25 MHz, no loopback, no echo
                         */
-                       writel(1, fep->hwp + FEC_MIIGSK_CFGR);
+                       writel((fep->phy_interface == PHY_INTERFACE_MODE_RMII) ?
+                                       1 : 0, fep->hwp + FEC_MIIGSK_CFGR);
+
 
                        /* re-enable the gasket */
                        writel(2, fep->hwp + FEC_MIIGSK_ENR);
@@ -734,8 +766,22 @@ static void __inline__ fec_get_mac(struct net_device *ndev)
         */
        iap = macaddr;
 
+#ifdef CONFIG_OF
        /*
-        * 2) from flash or fuse (via platform data)
+        * 2) from device tree data
+        */
+       if (!is_valid_ether_addr(iap)) {
+               struct device_node *np = fep->pdev->dev.of_node;
+               if (np) {
+                       const char *mac = of_get_mac_address(np);
+                       if (mac)
+                               iap = (unsigned char *) mac;
+               }
+       }
+#endif
+
+       /*
+        * 3) from flash or fuse (via platform data)
         */
        if (!is_valid_ether_addr(iap)) {
 #ifdef CONFIG_M5272
@@ -748,7 +794,7 @@ static void __inline__ fec_get_mac(struct net_device *ndev)
        }
 
        /*
-        * 3) FEC mac registers set by bootloader
+        * 4) FEC mac registers set by bootloader
         */
        if (!is_valid_ether_addr(iap)) {
                *((unsigned long *) &tmpaddr[0]) =
@@ -1354,6 +1400,52 @@ static int fec_enet_init(struct net_device *ndev)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static int __devinit fec_get_phy_mode_dt(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+
+       if (np)
+               return of_get_phy_mode(np);
+
+       return -ENODEV;
+}
+
+static int __devinit fec_reset_phy(struct platform_device *pdev)
+{
+       int err, phy_reset;
+       struct device_node *np = pdev->dev.of_node;
+
+       if (!np)
+               return -ENODEV;
+
+       phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
+       err = gpio_request_one(phy_reset, GPIOF_OUT_INIT_LOW, "phy-reset");
+       if (err) {
+               pr_warn("FEC: failed to get gpio phy-reset: %d\n", err);
+               return err;
+       }
+       msleep(1);
+       gpio_set_value(phy_reset, 1);
+
+       return 0;
+}
+#else /* CONFIG_OF */
+static inline int fec_get_phy_mode_dt(struct platform_device *pdev)
+{
+       return -ENODEV;
+}
+
+static inline int fec_reset_phy(struct platform_device *pdev)
+{
+       /*
+        * In case of platform probe, the reset has been done
+        * by machine code.
+        */
+       return 0;
+}
+#endif /* CONFIG_OF */
+
 static int __devinit
 fec_probe(struct platform_device *pdev)
 {
@@ -1362,6 +1454,11 @@ fec_probe(struct platform_device *pdev)
        struct net_device *ndev;
        int i, irq, ret = 0;
        struct resource *r;
+       const struct of_device_id *of_id;
+
+       of_id = of_match_device(fec_dt_ids, &pdev->dev);
+       if (of_id)
+               pdev->id_entry = of_id->data;
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!r)
@@ -1393,9 +1490,18 @@ fec_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, ndev);
 
-       pdata = pdev->dev.platform_data;
-       if (pdata)
-               fep->phy_interface = pdata->phy;
+       ret = fec_get_phy_mode_dt(pdev);
+       if (ret < 0) {
+               pdata = pdev->dev.platform_data;
+               if (pdata)
+                       fep->phy_interface = pdata->phy;
+               else
+                       fep->phy_interface = PHY_INTERFACE_MODE_MII;
+       } else {
+               fep->phy_interface = ret;
+       }
+
+       fec_reset_phy(pdev);
 
        /* This device has up to three irqs on some platforms */
        for (i = 0; i < 3; i++) {
@@ -1530,6 +1636,7 @@ static struct platform_driver fec_driver = {
 #ifdef CONFIG_PM
                .pm     = &fec_pm_ops,
 #endif
+               .of_match_table = fec_dt_ids,
        },
        .id_table = fec_devtype,
        .probe  = fec_probe,
index 725399e..70cb7d8 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/bitops.h>
 #include <linux/workqueue.h>
 #include <linux/of.h>
+#include <linux/of_net.h>
 #include <linux/slab.h>
 
 #include <asm/processor.h>
@@ -2506,18 +2507,6 @@ static int __devinit emac_init_config(struct emac_instance *dev)
 {
        struct device_node *np = dev->ofdev->dev.of_node;
        const void *p;
-       unsigned int plen;
-       const char *pm, *phy_modes[] = {
-               [PHY_MODE_NA] = "",
-               [PHY_MODE_MII] = "mii",
-               [PHY_MODE_RMII] = "rmii",
-               [PHY_MODE_SMII] = "smii",
-               [PHY_MODE_RGMII] = "rgmii",
-               [PHY_MODE_TBI] = "tbi",
-               [PHY_MODE_GMII] = "gmii",
-               [PHY_MODE_RTBI] = "rtbi",
-               [PHY_MODE_SGMII] = "sgmii",
-       };
 
        /* Read config from device-tree */
        if (emac_read_uint_prop(np, "mal-device", &dev->mal_ph, 1))
@@ -2566,23 +2555,9 @@ static int __devinit emac_init_config(struct emac_instance *dev)
                dev->mal_burst_size = 256;
 
        /* PHY mode needs some decoding */
-       dev->phy_mode = PHY_MODE_NA;
-       pm = of_get_property(np, "phy-mode", &plen);
-       if (pm != NULL) {
-               int i;
-               for (i = 0; i < ARRAY_SIZE(phy_modes); i++)
-                       if (!strcasecmp(pm, phy_modes[i])) {
-                               dev->phy_mode = i;
-                               break;
-                       }
-       }
-
-       /* Backward compat with non-final DT */
-       if (dev->phy_mode == PHY_MODE_NA && pm != NULL && plen == 4) {
-               u32 nmode = *(const u32 *)pm;
-               if (nmode > PHY_MODE_NA && nmode <= PHY_MODE_SGMII)
-                       dev->phy_mode = nmode;
-       }
+       dev->phy_mode = of_get_phy_mode(np);
+       if (dev->phy_mode < 0)
+               dev->phy_mode = PHY_MODE_NA;
 
        /* Check EMAC version */
        if (of_device_is_compatible(np, "ibm,emac4sync")) {
index 8a61b59..1568278 100644 (file)
@@ -26,6 +26,7 @@
 #define __IBM_NEWEMAC_H
 
 #include <linux/types.h>
+#include <linux/phy.h>
 
 /* EMAC registers                      Write Access rules */
 struct emac_regs {
@@ -106,15 +107,15 @@ struct emac_regs {
 /*
  * PHY mode settings (EMAC <-> ZMII/RGMII bridge <-> PHY)
  */
-#define PHY_MODE_NA    0
-#define PHY_MODE_MII   1
-#define PHY_MODE_RMII  2
-#define PHY_MODE_SMII  3
-#define PHY_MODE_RGMII 4
-#define PHY_MODE_TBI   5
-#define PHY_MODE_GMII  6
-#define PHY_MODE_RTBI  7
-#define PHY_MODE_SGMII 8
+#define PHY_MODE_NA    PHY_INTERFACE_MODE_NA
+#define PHY_MODE_MII   PHY_INTERFACE_MODE_MII
+#define PHY_MODE_RMII  PHY_INTERFACE_MODE_RMII
+#define PHY_MODE_SMII  PHY_INTERFACE_MODE_SMII
+#define PHY_MODE_RGMII PHY_INTERFACE_MODE_RGMII
+#define PHY_MODE_TBI   PHY_INTERFACE_MODE_TBI
+#define PHY_MODE_GMII  PHY_INTERFACE_MODE_GMII
+#define PHY_MODE_RTBI  PHY_INTERFACE_MODE_RTBI
+#define PHY_MODE_SGMII PHY_INTERFACE_MODE_SGMII
 
 /* EMACx_MR0 */
 #define EMAC_MR0_RXI                   0x80000000
index ac9d964..ab4e596 100644 (file)
 #include "emac.h"
 #include "phy.h"
 
-static inline int phy_read(struct mii_phy *phy, int reg)
+#define phy_read _phy_read
+#define phy_write _phy_write
+
+static inline int _phy_read(struct mii_phy *phy, int reg)
 {
        return phy->mdio_read(phy->dev, phy->address, reg);
 }
 
-static inline void phy_write(struct mii_phy *phy, int reg, int val)
+static inline void _phy_write(struct mii_phy *phy, int reg, int val)
 {
        phy->mdio_write(phy->dev, phy->address, reg, val);
 }
index 86f334a..bb18471 100644 (file)
@@ -8,6 +8,51 @@
 #include <linux/etherdevice.h>
 #include <linux/kernel.h>
 #include <linux/of_net.h>
+#include <linux/phy.h>
+
+/**
+ * It maps 'enum phy_interface_t' found in include/linux/phy.h
+ * into the device tree binding of 'phy-mode', so that Ethernet
+ * device driver can get phy interface from device tree.
+ */
+static const char *phy_modes[] = {
+       [PHY_INTERFACE_MODE_NA]         = "",
+       [PHY_INTERFACE_MODE_MII]        = "mii",
+       [PHY_INTERFACE_MODE_GMII]       = "gmii",
+       [PHY_INTERFACE_MODE_SGMII]      = "sgmii",
+       [PHY_INTERFACE_MODE_TBI]        = "tbi",
+       [PHY_INTERFACE_MODE_RMII]       = "rmii",
+       [PHY_INTERFACE_MODE_RGMII]      = "rgmii",
+       [PHY_INTERFACE_MODE_RGMII_ID]   = "rgmii-id",
+       [PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid",
+       [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
+       [PHY_INTERFACE_MODE_RTBI]       = "rtbi",
+       [PHY_INTERFACE_MODE_SMII]       = "smii",
+};
+
+/**
+ * of_get_phy_mode - Get phy mode for given device_node
+ * @np:        Pointer to the given device_node
+ *
+ * The function gets phy interface string from property 'phy-mode',
+ * and return its index in phy_modes table, or errno in error case.
+ */
+const int of_get_phy_mode(struct device_node *np)
+{
+       const char *pm;
+       int err, i;
+
+       err = of_property_read_string(np, "phy-mode", &pm);
+       if (err < 0)
+               return err;
+
+       for (i = 0; i < ARRAY_SIZE(phy_modes); i++)
+               if (!strcasecmp(pm, phy_modes[i]))
+                       return i;
+
+       return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(of_get_phy_mode);
 
 /**
  * Search the device tree for the best MAC address to use.  'mac-address' is
index 22fe801..827db76 100644 (file)
 #include <linux/delay.h>
 #include <linux/rational.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <mach/hardware.h>
 #include <mach/imx-uart.h>
 
 /* Register definitions */
@@ -66,8 +67,9 @@
 #define UBIR  0xa4 /* BRM Incremental Register */
 #define UBMR  0xa8 /* BRM Modulator Register */
 #define UBRC  0xac /* Baud Rate Count Register */
-#define MX2_ONEMS 0xb0 /* One Millisecond register */
-#define UTS (cpu_is_mx1() ? 0xd0 : 0xb4) /* UART Test Register */
+#define IMX21_ONEMS 0xb0 /* One Millisecond register */
+#define IMX1_UTS 0xd0 /* UART Test Register on i.mx1 */
+#define IMX21_UTS 0xb4 /* UART Test Register on all other i.mx*/
 
 /* UART Control Register Bit Fields.*/
 #define  URXD_CHARRDY    (1<<15)
@@ -87,7 +89,7 @@
 #define  UCR1_RTSDEN     (1<<5)         /* RTS delta interrupt enable */
 #define  UCR1_SNDBRK     (1<<4)         /* Send break */
 #define  UCR1_TDMAEN     (1<<3)         /* Transmitter ready DMA enable */
-#define  MX1_UCR1_UARTCLKEN  (1<<2)     /* UART clock enabled, mx1 only */
+#define  IMX1_UCR1_UARTCLKEN  (1<<2)  /* UART clock enabled, i.mx1 only */
 #define  UCR1_DOZE       (1<<1)         /* Doze */
 #define  UCR1_UARTEN     (1<<0)         /* UART enabled */
 #define  UCR2_ESCI              (1<<15) /* Escape seq interrupt enable */
 #define  UCR3_RXDSEN    (1<<6)  /* Receive status interrupt enable */
 #define  UCR3_AIRINTEN   (1<<5)  /* Async IR wake interrupt enable */
 #define  UCR3_AWAKEN    (1<<4)  /* Async wake interrupt enable */
-#define  MX1_UCR3_REF25         (1<<3)  /* Ref freq 25 MHz, only on mx1 */
-#define  MX1_UCR3_REF30         (1<<2)  /* Ref Freq 30 MHz, only on mx1 */
-#define  MX2_UCR3_RXDMUXSEL     (1<<2)  /* RXD Muxed Input Select, on mx2/mx3 */
+#define  IMX21_UCR3_RXDMUXSEL   (1<<2)  /* RXD Muxed Input Select */
 #define  UCR3_INVT      (1<<1)  /* Inverted Infrared transmission */
 #define  UCR3_BPEN      (1<<0)  /* Preset registers enable */
 #define  UCR4_CTSTL_SHF  10      /* CTS trigger level shift */
 
 #define UART_NR 8
 
+/* i.mx21 type uart runs on all i.mx except i.mx1 */
+enum imx_uart_type {
+       IMX1_UART,
+       IMX21_UART,
+};
+
+/* device type dependent stuff */
+struct imx_uart_data {
+       unsigned uts_reg;
+       enum imx_uart_type devtype;
+};
+
 struct imx_port {
        struct uart_port        port;
        struct timer_list       timer;
@@ -192,6 +204,7 @@ struct imx_port {
        unsigned int            irda_inv_tx:1;
        unsigned short          trcv_delay; /* transceiver delay */
        struct clk              *clk;
+       struct imx_uart_data    *devdata;
 };
 
 #ifdef CONFIG_IRDA
@@ -200,6 +213,52 @@ struct imx_port {
 #define USE_IRDA(sport)        (0)
 #endif
 
+static struct imx_uart_data imx_uart_devdata[] = {
+       [IMX1_UART] = {
+               .uts_reg = IMX1_UTS,
+               .devtype = IMX1_UART,
+       },
+       [IMX21_UART] = {
+               .uts_reg = IMX21_UTS,
+               .devtype = IMX21_UART,
+       },
+};
+
+static struct platform_device_id imx_uart_devtype[] = {
+       {
+               .name = "imx1-uart",
+               .driver_data = (kernel_ulong_t) &imx_uart_devdata[IMX1_UART],
+       }, {
+               .name = "imx21-uart",
+               .driver_data = (kernel_ulong_t) &imx_uart_devdata[IMX21_UART],
+       }, {
+               /* sentinel */
+       }
+};
+MODULE_DEVICE_TABLE(platform, imx_uart_devtype);
+
+static struct of_device_id imx_uart_dt_ids[] = {
+       { .compatible = "fsl,imx1-uart", .data = &imx_uart_devdata[IMX1_UART], },
+       { .compatible = "fsl,imx21-uart", .data = &imx_uart_devdata[IMX21_UART], },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_uart_dt_ids);
+
+static inline unsigned uts_reg(struct imx_port *sport)
+{
+       return sport->devdata->uts_reg;
+}
+
+static inline int is_imx1_uart(struct imx_port *sport)
+{
+       return sport->devdata->devtype == IMX1_UART;
+}
+
+static inline int is_imx21_uart(struct imx_port *sport)
+{
+       return sport->devdata->devtype == IMX21_UART;
+}
+
 /*
  * Handle any change of modem status signal since we were last called.
  */
@@ -326,7 +385,8 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
        struct circ_buf *xmit = &sport->port.state->xmit;
 
        while (!uart_circ_empty(xmit) &&
-                       !(readl(sport->port.membase + UTS) & UTS_TXFULL)) {
+                       !(readl(sport->port.membase + uts_reg(sport))
+                               & UTS_TXFULL)) {
                /* send xmit->buf[xmit->tail]
                 * out the port here */
                writel(xmit->buf[xmit->tail], sport->port.membase + URTX0);
@@ -373,7 +433,7 @@ static void imx_start_tx(struct uart_port *port)
                writel(temp, sport->port.membase + UCR4);
        }
 
-       if (readl(sport->port.membase + UTS) & UTS_TXEMPTY)
+       if (readl(sport->port.membase + uts_reg(sport)) & UTS_TXEMPTY)
                imx_transmit_buffer(sport);
 }
 
@@ -689,9 +749,9 @@ static int imx_startup(struct uart_port *port)
                }
        }
 
-       if (!cpu_is_mx1()) {
+       if (is_imx21_uart(sport)) {
                temp = readl(sport->port.membase + UCR3);
-               temp |= MX2_UCR3_RXDMUXSEL;
+               temp |= IMX21_UCR3_RXDMUXSEL;
                writel(temp, sport->port.membase + UCR3);
        }
 
@@ -923,9 +983,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
        writel(num, sport->port.membase + UBIR);
        writel(denom, sport->port.membase + UBMR);
 
-       if (!cpu_is_mx1())
+       if (is_imx21_uart(sport))
                writel(sport->port.uartclk / div / 1000,
-                               sport->port.membase + MX2_ONEMS);
+                               sport->port.membase + IMX21_ONEMS);
 
        writel(old_ucr1, sport->port.membase + UCR1);
 
@@ -1041,7 +1101,7 @@ static void imx_console_putchar(struct uart_port *port, int ch)
 {
        struct imx_port *sport = (struct imx_port *)port;
 
-       while (readl(sport->port.membase + UTS) & UTS_TXFULL)
+       while (readl(sport->port.membase + uts_reg(sport)) & UTS_TXFULL)
                barrier();
 
        writel(ch, sport->port.membase + URTX0);
@@ -1062,8 +1122,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
        ucr1 = old_ucr1 = readl(sport->port.membase + UCR1);
        old_ucr2 = readl(sport->port.membase + UCR2);
 
-       if (cpu_is_mx1())
-               ucr1 |= MX1_UCR1_UARTCLKEN;
+       if (is_imx1_uart(sport))
+               ucr1 |= IMX1_UCR1_UARTCLKEN;
        ucr1 |= UCR1_UARTEN;
        ucr1 &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
 
@@ -1222,6 +1282,63 @@ static int serial_imx_resume(struct platform_device *dev)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static int serial_imx_probe_dt(struct imx_port *sport,
+               struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       const struct of_device_id *of_id =
+                       of_match_device(imx_uart_dt_ids, &pdev->dev);
+       int ret;
+
+       if (!np)
+               return -ENODEV;
+
+       ret = of_alias_get_id(np, "serial");
+       if (ret < 0) {
+               pr_err("%s: failed to get alias id, errno %d\n",
+                       __func__, ret);
+               return -ENODEV;
+       } else {
+               sport->port.line = ret;
+       }
+
+       if (of_get_property(np, "fsl,uart-has-rtscts", NULL))
+               sport->have_rtscts = 1;
+
+       if (of_get_property(np, "fsl,irda-mode", NULL))
+               sport->use_irda = 1;
+
+       sport->devdata = of_id->data;
+
+       return 0;
+}
+#else
+static inline int serial_imx_probe_dt(struct imx_port *sport,
+               struct platform_device *pdev)
+{
+       return -ENODEV;
+}
+#endif
+
+static void serial_imx_probe_pdata(struct imx_port *sport,
+               struct platform_device *pdev)
+{
+       struct imxuart_platform_data *pdata = pdev->dev.platform_data;
+
+       sport->port.line = pdev->id;
+       sport->devdata = (struct imx_uart_data  *) pdev->id_entry->driver_data;
+
+       if (!pdata)
+               return;
+
+       if (pdata->flags & IMXUART_HAVE_RTSCTS)
+               sport->have_rtscts = 1;
+
+       if (pdata->flags & IMXUART_IRDA)
+               sport->use_irda = 1;
+}
+
 static int serial_imx_probe(struct platform_device *pdev)
 {
        struct imx_port *sport;
@@ -1234,6 +1351,10 @@ static int serial_imx_probe(struct platform_device *pdev)
        if (!sport)
                return -ENOMEM;
 
+       ret = serial_imx_probe_dt(sport, pdev);
+       if (ret == -ENODEV)
+               serial_imx_probe_pdata(sport, pdev);
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                ret = -ENODEV;
@@ -1258,7 +1379,6 @@ static int serial_imx_probe(struct platform_device *pdev)
        sport->port.fifosize = 32;
        sport->port.ops = &imx_pops;
        sport->port.flags = UPF_BOOT_AUTOCONF;
-       sport->port.line = pdev->id;
        init_timer(&sport->timer);
        sport->timer.function = imx_timeout;
        sport->timer.data     = (unsigned long)sport;
@@ -1272,17 +1392,9 @@ static int serial_imx_probe(struct platform_device *pdev)
 
        sport->port.uartclk = clk_get_rate(sport->clk);
 
-       imx_ports[pdev->id] = sport;
+       imx_ports[sport->port.line] = sport;
 
        pdata = pdev->dev.platform_data;
-       if (pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
-               sport->have_rtscts = 1;
-
-#ifdef CONFIG_IRDA
-       if (pdata && (pdata->flags & IMXUART_IRDA))
-               sport->use_irda = 1;
-#endif
-
        if (pdata && pdata->init) {
                ret = pdata->init(pdev);
                if (ret)
@@ -1340,9 +1452,11 @@ static struct platform_driver serial_imx_driver = {
 
        .suspend        = serial_imx_suspend,
        .resume         = serial_imx_resume,
+       .id_table       = imx_uart_devtype,
        .driver         = {
                .name   = "imx-uart",
                .owner  = THIS_MODULE,
+               .of_match_table = imx_uart_dt_ids,
        },
 };
 
index 5f69504..87a06f3 100644 (file)
@@ -108,14 +108,18 @@ enum {
 };
 
 struct msi_desc;
+struct irq_domain;
 
 /**
  * struct irq_data - per irq and irq chip data passed down to chip functions
  * @irq:               interrupt number
+ * @hwirq:             hardware interrupt number, local to the interrupt domain
  * @node:              node index useful for balancing
  * @state_use_accessors: status information for irq chip functions.
  *                     Use accessor functions to deal with it
  * @chip:              low level interrupt hardware access
+ * @domain:            Interrupt translation domain; responsible for mapping
+ *                     between hwirq number and linux irq number.
  * @handler_data:      per-IRQ data for the irq_chip methods
  * @chip_data:         platform-specific per-chip private data for the chip
  *                     methods, to allow shared chip implementations
@@ -128,9 +132,11 @@ struct msi_desc;
  */
 struct irq_data {
        unsigned int            irq;
+       unsigned long           hwirq;
        unsigned int            node;
        unsigned int            state_use_accessors;
        struct irq_chip         *chip;
+       struct irq_domain       *domain;
        void                    *handler_data;
        void                    *chip_data;
        struct msi_desc         *msi_desc;
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
new file mode 100644 (file)
index 0000000..e807ad6
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * irq_domain - IRQ translation domains
+ *
+ * Translation infrastructure between hw and linux irq numbers.  This is
+ * helpful for interrupt controllers to implement mapping between hardware
+ * irq numbers and the Linux irq number space.
+ *
+ * irq_domains also have a hook for translating device tree interrupt
+ * representation into a hardware irq number that can be mapped back to a
+ * Linux irq number without any extra platform support code.
+ *
+ * irq_domain is expected to be embedded in an interrupt controller's private
+ * data structure.
+ */
+#ifndef _LINUX_IRQDOMAIN_H
+#define _LINUX_IRQDOMAIN_H
+
+#include <linux/irq.h>
+#include <linux/mod_devicetable.h>
+
+#ifdef CONFIG_IRQ_DOMAIN
+struct device_node;
+struct irq_domain;
+
+/**
+ * struct irq_domain_ops - Methods for irq_domain objects
+ * @to_irq: (optional) given a local hardware irq number, return the linux
+ *          irq number.  If to_irq is not implemented, then the irq_domain
+ *          will use this translation: irq = (domain->irq_base + hwirq)
+ * @dt_translate: Given a device tree node and interrupt specifier, decode
+ *                the hardware irq number and linux irq type value.
+ */
+struct irq_domain_ops {
+       unsigned int (*to_irq)(struct irq_domain *d, unsigned long hwirq);
+
+#ifdef CONFIG_OF
+       int (*dt_translate)(struct irq_domain *d, struct device_node *node,
+                           const u32 *intspec, unsigned int intsize,
+                           unsigned long *out_hwirq, unsigned int *out_type);
+#endif /* CONFIG_OF */
+};
+
+/**
+ * struct irq_domain - Hardware interrupt number translation object
+ * @list: Element in global irq_domain list.
+ * @irq_base: Start of irq_desc range assigned to the irq_domain.  The creator
+ *            of the irq_domain is responsible for allocating the array of
+ *            irq_desc structures.
+ * @nr_irq: Number of irqs managed by the irq domain
+ * @ops: pointer to irq_domain methods
+ * @priv: private data pointer for use by owner.  Not touched by irq_domain
+ *        core code.
+ * @of_node: (optional) Pointer to device tree nodes associated with the
+ *           irq_domain.  Used when decoding device tree interrupt specifiers.
+ */
+struct irq_domain {
+       struct list_head list;
+       unsigned int irq_base;
+       unsigned int nr_irq;
+       const struct irq_domain_ops *ops;
+       void *priv;
+       struct device_node *of_node;
+};
+
+/**
+ * irq_domain_to_irq() - Translate from a hardware irq to a linux irq number
+ *
+ * Returns the linux irq number associated with a hardware irq.  By default,
+ * the mapping is irq == domain->irq_base + hwirq, but this mapping can
+ * be overridden if the irq_domain implements a .to_irq() hook.
+ */
+static inline unsigned int irq_domain_to_irq(struct irq_domain *d,
+                                            unsigned long hwirq)
+{
+       return d->ops->to_irq ? d->ops->to_irq(d, hwirq) : d->irq_base + hwirq;
+}
+
+extern void irq_domain_add(struct irq_domain *domain);
+extern void irq_domain_del(struct irq_domain *domain);
+#endif /* CONFIG_IRQ_DOMAIN */
+
+#if defined(CONFIG_IRQ_DOMAIN) && defined(CONFIG_OF_IRQ)
+extern void irq_domain_add_simple(struct device_node *controller, int irq_base);
+extern void irq_domain_generate_simple(const struct of_device_id *match,
+                                       u64 phys_base, unsigned int irq_start);
+#else /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */
+static inline void irq_domain_generate_simple(const struct of_device_id *match,
+                                       u64 phys_base, unsigned int irq_start) { }
+#endif /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */
+
+#endif /* _LINUX_IRQDOMAIN_H */
index e6955f5..cd2e61c 100644 (file)
@@ -63,6 +63,9 @@ extern int of_irq_map_one(struct device_node *device, int index,
 extern unsigned int irq_create_of_mapping(struct device_node *controller,
                                          const u32 *intspec,
                                          unsigned int intsize);
+#ifdef CONFIG_IRQ_DOMAIN
+extern void irq_dispose_mapping(unsigned int irq);
+#endif
 extern int of_irq_to_resource(struct device_node *dev, int index,
                              struct resource *r);
 extern int of_irq_count(struct device_node *dev);
@@ -70,6 +73,7 @@ extern int of_irq_to_resource_table(struct device_node *dev,
                struct resource *res, int nr_irqs);
 extern struct device_node *of_irq_find_parent(struct device_node *child);
 
+
 #endif /* CONFIG_OF_IRQ */
 #endif /* CONFIG_OF */
 #endif /* __OF_IRQ_H */
index e913081..f474641 100644 (file)
@@ -9,6 +9,7 @@
 
 #ifdef CONFIG_OF_NET
 #include <linux/of.h>
+extern const int of_get_phy_mode(struct device_node *np);
 extern const void *of_get_mac_address(struct device_node *np);
 #endif
 
index ad51863..54fc413 100644 (file)
@@ -53,6 +53,7 @@
 
 /* Interface Mode definitions */
 typedef enum {
+       PHY_INTERFACE_MODE_NA,
        PHY_INTERFACE_MODE_MII,
        PHY_INTERFACE_MODE_GMII,
        PHY_INTERFACE_MODE_SGMII,
@@ -62,7 +63,8 @@ typedef enum {
        PHY_INTERFACE_MODE_RGMII_ID,
        PHY_INTERFACE_MODE_RGMII_RXID,
        PHY_INTERFACE_MODE_RGMII_TXID,
-       PHY_INTERFACE_MODE_RTBI
+       PHY_INTERFACE_MODE_RTBI,
+       PHY_INTERFACE_MODE_SMII,
 } phy_interface_t;
 
 
index d1d051b..5a38bf4 100644 (file)
@@ -52,6 +52,10 @@ config IRQ_EDGE_EOI_HANDLER
 config GENERIC_IRQ_CHIP
        bool
 
+# Generic irq_domain hw <--> linux irq number translation
+config IRQ_DOMAIN
+       bool
+
 # Support forced irq threading
 config IRQ_FORCED_THREADING
        bool
index 7329005..fff1738 100644 (file)
@@ -2,6 +2,7 @@
 obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o
 obj-$(CONFIG_GENERIC_IRQ_CHIP) += generic-chip.o
 obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
+obj-$(CONFIG_IRQ_DOMAIN) += irqdomain.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
 obj-$(CONFIG_PM_SLEEP) += pm.o
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
new file mode 100644 (file)
index 0000000..d5828da
--- /dev/null
@@ -0,0 +1,180 @@
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+static LIST_HEAD(irq_domain_list);
+static DEFINE_MUTEX(irq_domain_mutex);
+
+/**
+ * irq_domain_add() - Register an irq_domain
+ * @domain: ptr to initialized irq_domain structure
+ *
+ * Registers an irq_domain structure.  The irq_domain must at a minimum be
+ * initialized with an ops structure pointer, and either a ->to_irq hook or
+ * a valid irq_base value.  Everything else is optional.
+ */
+void irq_domain_add(struct irq_domain *domain)
+{
+       struct irq_data *d;
+       int hwirq;
+
+       /*
+        * This assumes that the irq_domain owner has already allocated
+        * the irq_descs.  This block will be removed when support for dynamic
+        * allocation of irq_descs is added to irq_domain.
+        */
+       for (hwirq = 0; hwirq < domain->nr_irq; hwirq++) {
+               d = irq_get_irq_data(irq_domain_to_irq(domain, hwirq));
+               if (d || d->domain) {
+                       /* things are broken; just report, don't clean up */
+                       WARN(1, "error: irq_desc already assigned to a domain");
+                       return;
+               }
+               d->domain = domain;
+               d->hwirq = hwirq;
+       }
+
+       mutex_lock(&irq_domain_mutex);
+       list_add(&domain->list, &irq_domain_list);
+       mutex_unlock(&irq_domain_mutex);
+}
+
+/**
+ * irq_domain_del() - Unregister an irq_domain
+ * @domain: ptr to registered irq_domain.
+ */
+void irq_domain_del(struct irq_domain *domain)
+{
+       struct irq_data *d;
+       int hwirq;
+
+       mutex_lock(&irq_domain_mutex);
+       list_del(&domain->list);
+       mutex_unlock(&irq_domain_mutex);
+
+       /* Clear the irq_domain assignments */
+       for (hwirq = 0; hwirq < domain->nr_irq; hwirq++) {
+               d = irq_get_irq_data(irq_domain_to_irq(domain, hwirq));
+               d->domain = NULL;
+       }
+}
+
+#if defined(CONFIG_OF_IRQ)
+/**
+ * irq_create_of_mapping() - Map a linux irq number from a DT interrupt spec
+ *
+ * Used by the device tree interrupt mapping code to translate a device tree
+ * interrupt specifier to a valid linux irq number.  Returns either a valid
+ * linux IRQ number or 0.
+ *
+ * When the caller no longer need the irq number returned by this function it
+ * should arrange to call irq_dispose_mapping().
+ */
+unsigned int irq_create_of_mapping(struct device_node *controller,
+                                  const u32 *intspec, unsigned int intsize)
+{
+       struct irq_domain *domain;
+       unsigned long hwirq;
+       unsigned int irq, type;
+       int rc = -EINVAL;
+
+       /* Find a domain which can translate the irq spec */
+       mutex_lock(&irq_domain_mutex);
+       list_for_each_entry(domain, &irq_domain_list, list) {
+               if (!domain->ops->dt_translate)
+                       continue;
+               rc = domain->ops->dt_translate(domain, controller,
+                                       intspec, intsize, &hwirq, &type);
+               if (rc == 0)
+                       break;
+       }
+       mutex_unlock(&irq_domain_mutex);
+
+       if (rc != 0)
+               return 0;
+
+       irq = irq_domain_to_irq(domain, hwirq);
+       if (type != IRQ_TYPE_NONE)
+               irq_set_irq_type(irq, type);
+       pr_debug("%s: mapped hwirq=%i to irq=%i, flags=%x\n",
+                controller->full_name, (int)hwirq, irq, type);
+       return irq;
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
+
+/**
+ * irq_dispose_mapping() - Discard a mapping created by irq_create_of_mapping()
+ * @irq: linux irq number to be discarded
+ *
+ * Calling this function indicates the caller no longer needs a reference to
+ * the linux irq number returned by a prior call to irq_create_of_mapping().
+ */
+void irq_dispose_mapping(unsigned int irq)
+{
+       /*
+        * nothing yet; will be filled when support for dynamic allocation of
+        * irq_descs is added to irq_domain
+        */
+}
+EXPORT_SYMBOL_GPL(irq_dispose_mapping);
+
+int irq_domain_simple_dt_translate(struct irq_domain *d,
+                           struct device_node *controller,
+                           const u32 *intspec, unsigned int intsize,
+                           unsigned long *out_hwirq, unsigned int *out_type)
+{
+       if (d->of_node != controller)
+               return -EINVAL;
+       if (intsize < 1)
+               return -EINVAL;
+
+       *out_hwirq = intspec[0];
+       *out_type = IRQ_TYPE_NONE;
+       if (intsize > 1)
+               *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
+       return 0;
+}
+
+struct irq_domain_ops irq_domain_simple_ops = {
+       .dt_translate = irq_domain_simple_dt_translate,
+};
+EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
+
+/**
+ * irq_domain_create_simple() - Set up a 'simple' translation range
+ */
+void irq_domain_add_simple(struct device_node *controller, int irq_base)
+{
+       struct irq_domain *domain;
+
+       domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+       if (!domain) {
+               WARN_ON(1);
+               return;
+       }
+
+       domain->irq_base = irq_base;
+       domain->of_node = of_node_get(controller);
+       domain->ops = &irq_domain_simple_ops;
+       irq_domain_add(domain);
+}
+EXPORT_SYMBOL_GPL(irq_domain_add_simple);
+
+void irq_domain_generate_simple(const struct of_device_id *match,
+                               u64 phys_base, unsigned int irq_start)
+{
+       struct device_node *node;
+       pr_info("looking for phys_base=%llx, irq_start=%i\n",
+               (unsigned long long) phys_base, (int) irq_start);
+       node = of_find_matching_node_by_address(NULL, match, phys_base);
+       if (node)
+               irq_domain_add_simple(node, irq_start);
+       else
+               pr_info("no node found\n");
+}
+EXPORT_SYMBOL_GPL(irq_domain_generate_simple);
+#endif /* CONFIG_OF_IRQ */