Browse Source

Merge tag 'devicetree-for-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux

Pull DeviceTree changes from Rob Herring:

 - DT unittests for I2C probing and overlays from Pantelis Antoniou

 - Remove DT unittest dependency on OF_DYNAMIC from Gaurav Minocha

 - Add Tegra compatible strings missing for newer parts from Paul
   Walmsley

 - Various vendor prefix additions

* tag 'devicetree-for-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux:
  of: Add vendor prefix for OmniVision Technologies
  of: Use ovti for Omnivision
  of: Add vendor prefix for Truly Semiconductors Limited
  of: Add vendor prefix for Himax Technologies Inc.
  of/fdt: fix sparse warning
  of: unitest: Add I2C overlay unit tests.
  Documentation: DT: document compatible string existence requirement
  Documentation: DT bindings: add nvidia, tegra132-denver compatible string
  Documentation: DT bindings: add more Tegra chip compatible strings
  of: EXPORT_SYMBOL_GPL of_property_read_u64_array
  of: Fix brace position for struct of_device_id definition
  of/unittest: Remove obsolete code
  dt-bindings: use isil prefix for Intersil in vendor-prefixes.txt
  Add AD Holdings Plc. to vendor-prefixes.
  dt-bindings: Add Silicon Mitus vendor prefix
  Removes OF_UNITTEST dependency on OF_DYNAMIC config symbol
  pinctrl: fix up device tree bindings
  DT: Vendors: Add Everspin
  doc: add bindings document for altera fpga manager
  drivers: of: Export of_reserved_mem_device_{init,release}
Linus Torvalds 10 years ago
parent
commit
cdd305454e
36 changed files with 766 additions and 172 deletions
  1. 1 0
      Documentation/devicetree/bindings/arm/cpus.txt
  2. 4 1
      Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-ahb.txt
  3. 5 1
      Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
  4. 3 1
      Documentation/devicetree/bindings/ata/tegra-sata.txt
  5. 17 0
      Documentation/devicetree/bindings/fpga/altera-socfpga-fpga-mgr.txt
  6. 5 5
      Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.txt
  7. 6 2
      Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt
  8. 5 5
      Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt
  9. 1 1
      Documentation/devicetree/bindings/media/atmel-isi.txt
  10. 1 1
      Documentation/devicetree/bindings/media/video-interfaces.txt
  11. 4 5
      Documentation/devicetree/bindings/misc/nvidia,tegra20-apbmisc.txt
  12. 5 1
      Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
  13. 4 4
      Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
  14. 2 1
      Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-pinmux.txt
  15. 3 1
      Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-xusb-padctl.txt
  16. 4 3
      Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt
  17. 3 1
      Documentation/devicetree/bindings/rtc/nvidia,tegra20-rtc.txt
  18. 4 1
      Documentation/devicetree/bindings/serial/of-serial.txt
  19. 4 1
      Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt
  20. 3 1
      Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.txt
  21. 4 1
      Documentation/devicetree/bindings/sound/nvidia,tegra30-i2s.txt
  22. 3 1
      Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt
  23. 23 0
      Documentation/devicetree/bindings/submitting-patches.txt
  24. 3 1
      Documentation/devicetree/bindings/thermal/tegra-soctherm.txt
  25. 3 1
      Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt
  26. 58 1
      Documentation/devicetree/bindings/unittest.txt
  27. 4 1
      Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt
  28. 4 1
      Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt
  29. 7 2
      Documentation/devicetree/bindings/vendor-prefixes.txt
  30. 0 1
      drivers/of/Kconfig
  31. 1 0
      drivers/of/base.c
  32. 1 1
      drivers/of/fdt.c
  33. 2 0
      drivers/of/of_reserved_mem.c
  34. 94 0
      drivers/of/unittest-data/tests-overlay.dtsi
  35. 474 123
      drivers/of/unittest.c
  36. 1 2
      include/linux/mod_devicetable.h

+ 1 - 0
Documentation/devicetree/bindings/arm/cpus.txt

@@ -175,6 +175,7 @@ nodes to be present and contain the properties described below.
 			    "marvell,pj4a"
 			    "marvell,pj4a"
 			    "marvell,pj4b"
 			    "marvell,pj4b"
 			    "marvell,sheeva-v5"
 			    "marvell,sheeva-v5"
+			    "nvidia,tegra132-denver"
 			    "qcom,krait"
 			    "qcom,krait"
 			    "qcom,scorpion"
 			    "qcom,scorpion"
 	- enable-method
 	- enable-method

+ 4 - 1
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-ahb.txt

@@ -1,7 +1,10 @@
 NVIDIA Tegra AHB
 NVIDIA Tegra AHB
 
 
 Required properties:
 Required properties:
-- compatible : "nvidia,tegra20-ahb" or "nvidia,tegra30-ahb"
+- compatible : For Tegra20, must contain "nvidia,tegra20-ahb".  For
+  Tegra30, must contain "nvidia,tegra30-ahb".  Otherwise, must contain
+  '"nvidia,<chip>-ahb", "nvidia,tegra30-ahb"' where <chip> is tegra124,
+  tegra132, or tegra210.
 - reg : Should contain 1 register ranges(address and length)
 - reg : Should contain 1 register ranges(address and length)
 
 
 Example:
 Example:

+ 5 - 1
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt

@@ -6,7 +6,11 @@ modes. It provides power-gating controllers for SoC and CPU power-islands.
 
 
 Required properties:
 Required properties:
 - name : Should be pmc
 - name : Should be pmc
-- compatible : Should contain "nvidia,tegra<chip>-pmc".
+- compatible : For Tegra20, must contain "nvidia,tegra20-pmc".  For Tegra30,
+  must contain "nvidia,tegra30-pmc".  For Tegra114, must contain
+  "nvidia,tegra114-pmc".  For Tegra124, must contain "nvidia,tegra124-pmc".
+  Otherwise, must contain "nvidia,<chip>-pmc", plus at least one of the
+  above, where <chip> is tegra132.
 - reg : Offset and length of the register set for the device
 - reg : Offset and length of the register set for the device
 - clocks : Must contain an entry for each entry in clock-names.
 - clocks : Must contain an entry for each entry in clock-names.
   See ../clocks/clock-bindings.txt for details.
   See ../clocks/clock-bindings.txt for details.

+ 3 - 1
Documentation/devicetree/bindings/ata/tegra-sata.txt

@@ -1,7 +1,9 @@
 Tegra124 SoC SATA AHCI controller
 Tegra124 SoC SATA AHCI controller
 
 
 Required properties :
 Required properties :
-- compatible : "nvidia,tegra124-ahci".
+- compatible : For Tegra124, must contain "nvidia,tegra124-ahci".  Otherwise,
+  must contain '"nvidia,<chip>-ahci", "nvidia,tegra124-ahci"', where <chip>
+  is tegra132.
 - reg : Should contain 2 entries:
 - reg : Should contain 2 entries:
   - AHCI register set (SATA BAR5)
   - AHCI register set (SATA BAR5)
   - SATA register set
   - SATA register set

+ 17 - 0
Documentation/devicetree/bindings/fpga/altera-socfpga-fpga-mgr.txt

@@ -0,0 +1,17 @@
+Altera SOCFPGA FPGA Manager
+
+Required properties:
+- compatible : should contain "altr,socfpga-fpga-mgr"
+- reg        : base address and size for memory mapped io.
+               - The first index is for FPGA manager register access.
+               - The second index is for writing FPGA configuration data.
+- interrupts : interrupt for the FPGA Manager device.
+
+Example:
+
+	hps_0_fpgamgr: fpgamgr@0xff706000 {
+		compatible = "altr,socfpga-fpga-mgr";
+		reg = <0xFF706000 0x1000
+		       0xFFB90000 0x1000>;
+		interrupts = <0 175 4>;
+	};

+ 5 - 5
Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.txt

@@ -1,11 +1,11 @@
 NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 fuse block.
 NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 fuse block.
 
 
 Required properties:
 Required properties:
-- compatible : should be:
-	"nvidia,tegra20-efuse"
-	"nvidia,tegra30-efuse"
-	"nvidia,tegra114-efuse"
-	"nvidia,tegra124-efuse"
+- compatible : For Tegra20, must contain "nvidia,tegra20-efuse".  For Tegra30,
+  must contain "nvidia,tegra30-efuse".  For Tegra114, must contain
+  "nvidia,tegra114-efuse".  For Tegra124, must contain "nvidia,tegra124-efuse".
+  Otherwise, must contain "nvidia,<chip>-efuse", plus one of the above, where
+  <chip> is tegra132.
   Details:
   Details:
   nvidia,tegra20-efuse: Tegra20 requires using APB DMA to read the fuse data
   nvidia,tegra20-efuse: Tegra20 requires using APB DMA to read the fuse data
 	due to a hardware bug. Tegra20 also lacks certain information which is
 	due to a hardware bug. Tegra20 also lacks certain information which is

+ 6 - 2
Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt

@@ -197,7 +197,9 @@ of the following host1x client modules:
 - sor: serial output resource
 - sor: serial output resource
 
 
   Required properties:
   Required properties:
-  - compatible: "nvidia,tegra124-sor"
+  - compatible: For Tegra124, must contain "nvidia,tegra124-sor".  Otherwise,
+    must contain '"nvidia,<chip>-sor", "nvidia,tegra124-sor"', where <chip>
+    is tegra132.
   - reg: Physical base address and length of the controller's registers.
   - reg: Physical base address and length of the controller's registers.
   - interrupts: The interrupt outputs from the controller.
   - interrupts: The interrupt outputs from the controller.
   - clocks: Must contain an entry for each entry in clock-names.
   - clocks: Must contain an entry for each entry in clock-names.
@@ -222,7 +224,9 @@ of the following host1x client modules:
   - nvidia,dpaux: phandle to a DispayPort AUX interface
   - nvidia,dpaux: phandle to a DispayPort AUX interface
 
 
 - dpaux: DisplayPort AUX interface
 - dpaux: DisplayPort AUX interface
-  - compatible: "nvidia,tegra124-dpaux"
+  - compatible: For Tegra124, must contain "nvidia,tegra124-dpaux".  Otherwise,
+    must contain '"nvidia,<chip>-dpaux", "nvidia,tegra124-dpaux"', where
+    <chip> is tegra132.
   - reg: Physical base address and length of the controller's registers.
   - reg: Physical base address and length of the controller's registers.
   - interrupts: The interrupt outputs from the controller.
   - interrupts: The interrupt outputs from the controller.
   - clocks: Must contain an entry for each entry in clock-names.
   - clocks: Must contain an entry for each entry in clock-names.

+ 5 - 5
Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt

@@ -1,11 +1,11 @@
 NVIDIA Tegra20/Tegra30/Tegra114 I2C controller driver.
 NVIDIA Tegra20/Tegra30/Tegra114 I2C controller driver.
 
 
 Required properties:
 Required properties:
-- compatible : should be:
-	"nvidia,tegra114-i2c"
-	"nvidia,tegra30-i2c"
-	"nvidia,tegra20-i2c"
-	"nvidia,tegra20-i2c-dvc"
+- compatible : For Tegra20, must be one of "nvidia,tegra20-i2c-dvc" or
+  "nvidia,tegra20-i2c".  For Tegra30, must be "nvidia,tegra30-i2c".
+  For Tegra114, must be "nvidia,tegra114-i2c".  Otherwise, must be
+  "nvidia,<chip>-i2c", plus at least one of the above, where <chip> is
+  tegra124, tegra132, or tegra210.
   Details of compatible are as follows:
   Details of compatible are as follows:
   nvidia,tegra20-i2c-dvc: Tegra20 has specific I2C controller called as DVC I2C
   nvidia,tegra20-i2c-dvc: Tegra20 has specific I2C controller called as DVC I2C
 	controller. This only support master mode of I2C communication. Register
 	controller. This only support master mode of I2C communication. Register

+ 1 - 1
Documentation/devicetree/bindings/media/atmel-isi.txt

@@ -38,7 +38,7 @@ Example:
 
 
 	i2c1: i2c@f0018000 {
 	i2c1: i2c@f0018000 {
 		ov2640: camera@0x30 {
 		ov2640: camera@0x30 {
-			compatible = "omnivision,ov2640";
+			compatible = "ovti,ov2640";
 			reg = <0x30>;
 			reg = <0x30>;
 
 
 			port {
 			port {

+ 1 - 1
Documentation/devicetree/bindings/media/video-interfaces.txt

@@ -162,7 +162,7 @@ pipelines can be active: ov772x -> ceu0 or imx074 -> csi2 -> ceu0.
 	i2c0: i2c@0xfff20000 {
 	i2c0: i2c@0xfff20000 {
 		...
 		...
 		ov772x_1: camera@0x21 {
 		ov772x_1: camera@0x21 {
-			compatible = "omnivision,ov772x";
+			compatible = "ovti,ov772x";
 			reg = <0x21>;
 			reg = <0x21>;
 			vddio-supply = <&regulator1>;
 			vddio-supply = <&regulator1>;
 			vddcore-supply = <&regulator2>;
 			vddcore-supply = <&regulator2>;

+ 4 - 5
Documentation/devicetree/bindings/misc/nvidia,tegra20-apbmisc.txt

@@ -1,11 +1,10 @@
 NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 apbmisc block
 NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 apbmisc block
 
 
 Required properties:
 Required properties:
-- compatible : should be:
-       "nvidia,tegra20-apbmisc"
-       "nvidia,tegra30-apbmisc"
-       "nvidia,tegra114-apbmisc"
-       "nvidia,tegra124-apbmisc"
+- compatible : For Tegra20, must be "nvidia,tegra20-apbmisc".  For Tegra30,
+  must be "nvidia,tegra30-apbmisc".  Otherwise, must contain
+  "nvidia,<chip>-apbmisc", plus one of the above, where <chip> is tegra114,
+  tegra124, tegra132.
 - reg: Should contain 2 entries: the first entry gives the physical address
 - reg: Should contain 2 entries: the first entry gives the physical address
        and length of the registers which contain revision and debug features.
        and length of the registers which contain revision and debug features.
        The second entry gives the physical address and length of the
        The second entry gives the physical address and length of the

+ 5 - 1
Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt

@@ -7,7 +7,11 @@ This file documents differences between the core properties described
 by mmc.txt and the properties used by the sdhci-tegra driver.
 by mmc.txt and the properties used by the sdhci-tegra driver.
 
 
 Required properties:
 Required properties:
-- compatible : Should be "nvidia,<chip>-sdhci"
+- compatible : For Tegra20, must contain "nvidia,tegra20-sdhci".
+  For Tegra30, must contain "nvidia,tegra30-sdhci".  For Tegra114,
+  must contain "nvidia,tegra114-sdhci".  For Tegra124, must contain
+  "nvidia,tegra124-sdhci".  Otherwise, must contain "nvidia,<chip>-sdhci",
+  plus one of the above, where <chip> is tegra132 or tegra210.
 - clocks : Must contain one entry, for the module clock.
 - clocks : Must contain one entry, for the module clock.
   See ../clocks/clock-bindings.txt for details.
   See ../clocks/clock-bindings.txt for details.
 - resets : Must contain an entry for each entry in reset-names.
 - resets : Must contain an entry for each entry in reset-names.

+ 4 - 4
Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt

@@ -1,10 +1,10 @@
 NVIDIA Tegra PCIe controller
 NVIDIA Tegra PCIe controller
 
 
 Required properties:
 Required properties:
-- compatible: Must be one of:
-  - "nvidia,tegra20-pcie"
-  - "nvidia,tegra30-pcie"
-  - "nvidia,tegra124-pcie"
+- compatible: For Tegra20, must contain "nvidia,tegra20-pcie".  For Tegra30,
+  "nvidia,tegra30-pcie".  For Tegra124, must contain "nvidia,tegra124-pcie".
+  Otherwise, must contain "nvidia,<chip>-pcie", plus one of the above, where
+  <chip> is tegra132 or tegra210.
 - device_type: Must be "pci"
 - device_type: Must be "pci"
 - reg: A list of physical base address and length for each set of controller
 - reg: A list of physical base address and length for each set of controller
   registers. Must contain an entry for each entry in the reg-names property.
   registers. Must contain an entry for each entry in the reg-names property.

+ 2 - 1
Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-pinmux.txt

@@ -6,7 +6,8 @@ nvidia,tegra30-pinmux.txt. In fact, this document assumes that binding as
 a baseline, and only documents the differences between the two bindings.
 a baseline, and only documents the differences between the two bindings.
 
 
 Required properties:
 Required properties:
-- compatible: "nvidia,tegra124-pinmux"
+- compatible: For Tegra124, must contain "nvidia,tegra124-pinmux".  For
+  Tegra132, must contain '"nvidia,tegra132-pinmux", "nvidia-tegra124-pinmux"'.
 - reg: Should contain a list of base address and size pairs for:
 - reg: Should contain a list of base address and size pairs for:
     -- first entry - the drive strength and pad control registers.
     -- first entry - the drive strength and pad control registers.
     -- second entry - the pinmux registers
     -- second entry - the pinmux registers

+ 3 - 1
Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-xusb-padctl.txt

@@ -13,7 +13,9 @@ how to describe and reference PHYs in device trees.
 
 
 Required properties:
 Required properties:
 --------------------
 --------------------
-- compatible: should be "nvidia,tegra124-xusb-padctl"
+- compatible: For Tegra124, must contain "nvidia,tegra124-xusb-padctl".
+  Otherwise, must contain '"nvidia,<chip>-xusb-padctl",
+  "nvidia-tegra124-xusb-padctl"', where <chip> is tegra132 or tegra210.
 - reg: Physical base address and length of the controller's registers.
 - reg: Physical base address and length of the controller's registers.
 - resets: Must contain an entry for each entry in reset-names.
 - resets: Must contain an entry for each entry in reset-names.
   See ../reset/reset.txt for details.
   See ../reset/reset.txt for details.

+ 4 - 3
Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt

@@ -1,9 +1,10 @@
 Tegra SoC PWFM controller
 Tegra SoC PWFM controller
 
 
 Required properties:
 Required properties:
-- compatible: should be one of:
-  - "nvidia,tegra20-pwm"
-  - "nvidia,tegra30-pwm"
+- compatible: For Tegra20, must contain "nvidia,tegra20-pwm".  For Tegra30,
+  must contain "nvidia,tegra30-pwm".  Otherwise, must contain
+  "nvidia,<chip>-pwm", plus one of the above, where <chip> is tegra114,
+  tegra124, tegra132, or tegra210.
 - reg: physical base address and length of the controller's registers
 - reg: physical base address and length of the controller's registers
 - #pwm-cells: should be 2. See pwm.txt in this directory for a description of
 - #pwm-cells: should be 2. See pwm.txt in this directory for a description of
   the cells format.
   the cells format.

+ 3 - 1
Documentation/devicetree/bindings/rtc/nvidia,tegra20-rtc.txt

@@ -6,7 +6,9 @@ state.
 
 
 Required properties:
 Required properties:
 
 
-- compatible : should be "nvidia,tegra20-rtc".
+- compatible : For Tegra20, must contain "nvidia,tegra20-rtc".  Otherwise,
+  must contain '"nvidia,<chip>-rtc", "nvidia,tegra20-rtc"', where <chip>
+  can be tegra30, tegra114, tegra124, or tegra132.
 - reg : Specifies base physical address and size of the registers.
 - reg : Specifies base physical address and size of the registers.
 - interrupts : A single interrupt specifier.
 - interrupts : A single interrupt specifier.
 - clocks : Must contain one entry, for the module clock.
 - clocks : Must contain one entry, for the module clock.

+ 4 - 1
Documentation/devicetree/bindings/serial/of-serial.txt

@@ -8,7 +8,10 @@ Required properties:
 	- "ns16550"
 	- "ns16550"
 	- "ns16750"
 	- "ns16750"
 	- "ns16850"
 	- "ns16850"
-	- "nvidia,tegra20-uart"
+	- For Tegra20, must contain "nvidia,tegra20-uart"
+	- For other Tegra, must contain '"nvidia,<chip>-uart",
+	  "nvidia,tegra20-uart"' where <chip> is tegra30, tegra114, tegra124,
+	  tegra132, or tegra210.
 	- "nxp,lpc3220-uart"
 	- "nxp,lpc3220-uart"
 	- "ralink,rt2880-uart"
 	- "ralink,rt2880-uart"
 	- "ibm,qpace-nwp-serial"
 	- "ibm,qpace-nwp-serial"

+ 4 - 1
Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt

@@ -1,7 +1,10 @@
 NVIDIA Tegra30 AHUB (Audio Hub)
 NVIDIA Tegra30 AHUB (Audio Hub)
 
 
 Required properties:
 Required properties:
-- compatible : "nvidia,tegra30-ahub", "nvidia,tegra114-ahub", etc.
+- compatible : For Tegra30, must contain "nvidia,tegra30-ahub".  For Tegra114,
+  must contain "nvidia,tegra114-ahub".  For Tegra124, must contain
+  "nvidia,tegra124-ahub".  Otherwise, must contain "nvidia,<chip>-ahub",
+  plus at least one of the above, where <chip> is tegra132.
 - reg : Should contain the register physical address and length for each of
 - reg : Should contain the register physical address and length for each of
   the AHUB's register blocks.
   the AHUB's register blocks.
   - Tegra30 requires 2 entries, for the APBIF and AHUB/AUDIO register blocks.
   - Tegra30 requires 2 entries, for the APBIF and AHUB/AUDIO register blocks.

+ 3 - 1
Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.txt

@@ -1,7 +1,9 @@
 NVIDIA Tegra30 HDA controller
 NVIDIA Tegra30 HDA controller
 
 
 Required properties:
 Required properties:
-- compatible : "nvidia,tegra30-hda"
+- compatible : For Tegra30, must contain "nvidia,tegra30-hda".  Otherwise,
+  must contain '"nvidia,<chip>-hda", "nvidia,tegra30-hda"', where <chip> is
+  tegra114, tegra124, or tegra132.
 - reg : Should contain the HDA registers location and length.
 - reg : Should contain the HDA registers location and length.
 - interrupts : The interrupt from the HDA controller.
 - interrupts : The interrupt from the HDA controller.
 - clocks : Must contain an entry for each required entry in clock-names.
 - clocks : Must contain an entry for each required entry in clock-names.

+ 4 - 1
Documentation/devicetree/bindings/sound/nvidia,tegra30-i2s.txt

@@ -1,7 +1,10 @@
 NVIDIA Tegra30 I2S controller
 NVIDIA Tegra30 I2S controller
 
 
 Required properties:
 Required properties:
-- compatible : "nvidia,tegra30-i2s"
+- compatible : For Tegra30, must contain "nvidia,tegra30-i2s".  For Tegra124,
+  must contain "nvidia,tegra124-i2s".  Otherwise, must contain
+  "nvidia,<chip>-i2s" plus at least one of the above, where <chip> is
+  tegra114 or tegra132.
 - reg : Should contain I2S registers location and length
 - reg : Should contain I2S registers location and length
 - clocks : Must contain one entry, for the module clock.
 - clocks : Must contain one entry, for the module clock.
   See ../clocks/clock-bindings.txt for details.
   See ../clocks/clock-bindings.txt for details.

+ 3 - 1
Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt

@@ -1,7 +1,9 @@
 NVIDIA Tegra114 SPI controller.
 NVIDIA Tegra114 SPI controller.
 
 
 Required properties:
 Required properties:
-- compatible : should be "nvidia,tegra114-spi".
+- compatible : For Tegra114, must contain "nvidia,tegra114-spi".
+  Otherwise, must contain '"nvidia,<chip>-spi", "nvidia,tegra114-spi"' where
+  <chip> is tegra124, tegra132, or tegra210.
 - reg: Should contain SPI registers location and length.
 - reg: Should contain SPI registers location and length.
 - interrupts: Should contain SPI interrupts.
 - interrupts: Should contain SPI interrupts.
 - clock-names : Must include the following entries:
 - clock-names : Must include the following entries:

+ 23 - 0
Documentation/devicetree/bindings/submitting-patches.txt

@@ -15,6 +15,29 @@ I. For patch submitters
   3) The Documentation/ portion of the patch should come in the series before
   3) The Documentation/ portion of the patch should come in the series before
      the code implementing the binding.
      the code implementing the binding.
 
 
+  4) Any compatible strings used in a chip or board DTS file must be
+     previously documented in the corresponding DT binding text file
+     in Documentation/devicetree/bindings.  This rule applies even if
+     the Linux device driver does not yet match on the compatible
+     string.  [ checkpatch will emit warnings if this step is not
+     followed as of commit bff5da4335256513497cc8c79f9a9d1665e09864
+     ("checkpatch: add DT compatible string documentation checks"). ]
+
+  5) The wildcard "<chip>" may be used in compatible strings, as in
+     the following example:
+
+         - compatible: Must contain '"nvidia,<chip>-pcie",
+           "nvidia,tegra20-pcie"' where <chip> is tegra30, tegra132, ...
+
+     As in the above example, the known values of "<chip>" should be
+     documented if it is used.
+
+  6) If a documented compatible string is not yet matched by the
+     driver, the documentation should also include a compatible
+     string that is matched by the driver (as in the "nvidia,tegra20-pcie"
+     example above).
+
+
 II. For kernel maintainers
 II. For kernel maintainers
 
 
   1) If you aren't comfortable reviewing a given binding, reply to it and ask
   1) If you aren't comfortable reviewing a given binding, reply to it and ask

+ 3 - 1
Documentation/devicetree/bindings/thermal/tegra-soctherm.txt

@@ -7,7 +7,9 @@ notifications. It is also used to manage emergency shutdown in an
 overheating situation.
 overheating situation.
 
 
 Required properties :
 Required properties :
-- compatible : "nvidia,tegra124-soctherm".
+- compatible : For Tegra124, must contain "nvidia,tegra124-soctherm".
+  For Tegra132, must contain "nvidia,tegra132-soctherm".
+  For Tegra210, must contain "nvidia,tegra210-soctherm".
 - reg : Should contain 1 entry:
 - reg : Should contain 1 entry:
   - SOCTHERM register set
   - SOCTHERM register set
 - interrupts : Defines the interrupt used by SOCTHERM
 - interrupts : Defines the interrupt used by SOCTHERM

+ 3 - 1
Documentation/devicetree/bindings/timer/nvidia,tegra30-timer.txt

@@ -6,7 +6,9 @@ trigger a legacy watchdog reset.
 
 
 Required properties:
 Required properties:
 
 
-- compatible : should be "nvidia,tegra30-timer", "nvidia,tegra20-timer".
+- compatible : For Tegra30, must contain "nvidia,tegra30-timer".  Otherwise,
+  must contain '"nvidia,<chip>-timer", "nvidia,tegra30-timer"' where
+  <chip> is tegra124 or tegra132.
 - reg : Specifies base physical address and size of the registers.
 - reg : Specifies base physical address and size of the registers.
 - interrupts : A list of 6 interrupts; one per each of timer channels 1
 - interrupts : A list of 6 interrupts; one per each of timer channels 1
     through 5, and one for the shared interrupt for the remaining channels.
     through 5, and one for the shared interrupt for the remaining channels.

+ 58 - 1
Documentation/devicetree/bindings/unittest.txt

@@ -1,4 +1,4 @@
-* OF selftest platform device
+1) OF selftest platform device
 
 
 ** selftest
 ** selftest
 
 
@@ -12,3 +12,60 @@ Example:
 		compatible = "selftest";
 		compatible = "selftest";
 		status = "okay";
 		status = "okay";
 	};
 	};
+
+2) OF selftest i2c adapter platform device
+
+** platform device unittest adapter
+
+Required properties:
+- compatible: must be selftest-i2c-bus
+
+Children nodes contain selftest i2c devices.
+
+Example:
+	selftest-i2c-bus {
+		compatible = "selftest-i2c-bus";
+		status = "okay";
+	};
+
+3) OF selftest i2c device
+
+** I2C selftest device
+
+Required properties:
+- compatible: must be selftest-i2c-dev
+
+All other properties are optional
+
+Example:
+	selftest-i2c-dev {
+		compatible = "selftest-i2c-dev";
+		status = "okay";
+	};
+
+4) OF selftest i2c mux device
+
+** I2C selftest mux
+
+Required properties:
+- compatible: must be selftest-i2c-mux
+
+Children nodes contain selftest i2c bus nodes per channel.
+
+Example:
+	selftest-i2c-mux {
+		compatible = "selftest-i2c-mux";
+		status = "okay";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		channel-0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			i2c-dev {
+				reg = <8>;
+				compatible = "selftest-i2c-dev";
+				status = "okay";
+			};
+		};
+	};

+ 4 - 1
Documentation/devicetree/bindings/usb/nvidia,tegra20-ehci.txt

@@ -6,7 +6,10 @@ Practice : Universal Serial Bus" with the following modifications
 and additions :
 and additions :
 
 
 Required properties :
 Required properties :
- - compatible : Should be "nvidia,tegra20-ehci".
+ - compatible : For Tegra20, must contain "nvidia,tegra20-ehci".
+   For Tegra30, must contain "nvidia,tegra30-ehci".  Otherwise, must contain
+   "nvidia,<chip>-ehci" plus at least one of the above, where <chip> is
+   tegra114, tegra124, tegra132, or tegra210.
  - nvidia,phy : phandle of the PHY that the controller is connected to.
  - nvidia,phy : phandle of the PHY that the controller is connected to.
  - clocks : Must contain one entry, for the module clock.
  - clocks : Must contain one entry, for the module clock.
    See ../clocks/clock-bindings.txt for details.
    See ../clocks/clock-bindings.txt for details.

+ 4 - 1
Documentation/devicetree/bindings/usb/nvidia,tegra20-usb-phy.txt

@@ -3,7 +3,10 @@ Tegra SOC USB PHY
 The device node for Tegra SOC USB PHY:
 The device node for Tegra SOC USB PHY:
 
 
 Required properties :
 Required properties :
- - compatible : Should be "nvidia,tegra<chip>-usb-phy".
+ - compatible : For Tegra20, must contain "nvidia,tegra20-usb-phy".
+   For Tegra30, must contain "nvidia,tegra30-usb-phy".  Otherwise, must contain
+   "nvidia,<chip>-usb-phy" plus at least one of the above, where <chip> is
+   tegra114, tegra124, tegra132, or tegra210.
  - reg : Defines the following set of registers, in the order listed:
  - reg : Defines the following set of registers, in the order listed:
    - The PHY's own register set.
    - The PHY's own register set.
      Always present.
      Always present.

+ 7 - 2
Documentation/devicetree/bindings/vendor-prefixes.txt

@@ -7,6 +7,7 @@ abilis	Abilis Systems
 active-semi	Active-Semi International Inc
 active-semi	Active-Semi International Inc
 ad	Avionic Design GmbH
 ad	Avionic Design GmbH
 adapteva	Adapteva, Inc.
 adapteva	Adapteva, Inc.
+adh	AD Holdings Plc.
 adi	Analog Devices, Inc.
 adi	Analog Devices, Inc.
 aeroflexgaisler	Aeroflex Gaisler AB
 aeroflexgaisler	Aeroflex Gaisler AB
 allwinner	Allwinner Technology Co., Ltd.
 allwinner	Allwinner Technology Co., Ltd.
@@ -57,6 +58,7 @@ est	ESTeem Wireless Modems
 ettus	NI Ettus Research
 ettus	NI Ettus Research
 eukrea  Eukréa Electromatique
 eukrea  Eukréa Electromatique
 everest	Everest Semiconductor Co. Ltd.
 everest	Everest Semiconductor Co. Ltd.
+everspin	Everspin Technologies, Inc.
 excito	Excito
 excito	Excito
 fcs	Fairchild Semiconductor
 fcs	Fairchild Semiconductor
 fsl	Freescale Semiconductor
 fsl	Freescale Semiconductor
@@ -70,6 +72,7 @@ gumstix	Gumstix, Inc.
 gw	Gateworks Corporation
 gw	Gateworks Corporation
 hannstar	HannStar Display Corporation
 hannstar	HannStar Display Corporation
 haoyu	Haoyu Microelectronic Co. Ltd.
 haoyu	Haoyu Microelectronic Co. Ltd.
+himax	Himax Technologies, Inc.
 hisilicon	Hisilicon Limited.
 hisilicon	Hisilicon Limited.
 hit	Hitachi Ltd.
 hit	Hitachi Ltd.
 honeywell	Honeywell
 honeywell	Honeywell
@@ -83,8 +86,7 @@ innolux	Innolux Corporation
 intel	Intel Corporation
 intel	Intel Corporation
 intercontrol	Inter Control Group
 intercontrol	Inter Control Group
 isee	ISEE 2007 S.L.
 isee	ISEE 2007 S.L.
-isil    Intersil (deprecated, use isl)
-isl	Intersil
+isil	Intersil
 karo	Ka-Ro electronics GmbH
 karo	Ka-Ro electronics GmbH
 keymile	Keymile GmbH
 keymile	Keymile GmbH
 lacie	LaCie
 lacie	LaCie
@@ -119,6 +121,7 @@ nvidia	NVIDIA
 nxp	NXP Semiconductors
 nxp	NXP Semiconductors
 onnn	ON Semiconductor Corp.
 onnn	ON Semiconductor Corp.
 opencores	OpenCores.org
 opencores	OpenCores.org
+ovti	OmniVision Technologies
 panasonic	Panasonic Corporation
 panasonic	Panasonic Corporation
 pericom	Pericom Technology Inc.
 pericom	Pericom Technology Inc.
 phytec	PHYTEC Messtechnik GmbH
 phytec	PHYTEC Messtechnik GmbH
@@ -146,6 +149,7 @@ seagate	Seagate Technology PLC
 semtech	Semtech Corporation
 semtech	Semtech Corporation
 sil	Silicon Image
 sil	Silicon Image
 silabs	Silicon Laboratories
 silabs	Silicon Laboratories
+siliconmitus	Silicon Mitus, Inc.
 simtek
 simtek
 sii	Seiko Instruments, Inc.
 sii	Seiko Instruments, Inc.
 silergy	Silergy Corp.
 silergy	Silergy Corp.
@@ -167,6 +171,7 @@ tlm	Trusted Logic Mobility
 toradex	Toradex AG
 toradex	Toradex AG
 toshiba	Toshiba Corporation
 toshiba	Toshiba Corporation
 toumaz	Toumaz
 toumaz	Toumaz
+truly	Truly Semiconductors Limited
 usi	Universal Scientific Industrial Co., Ltd.
 usi	Universal Scientific Industrial Co., Ltd.
 v3	V3 Semiconductor
 v3	V3 Semiconductor
 variscite	Variscite Ltd.
 variscite	Variscite Ltd.

+ 0 - 1
drivers/of/Kconfig

@@ -10,7 +10,6 @@ menu "Device Tree and Open Firmware support"
 config OF_UNITTEST
 config OF_UNITTEST
 	bool "Device Tree runtime unit tests"
 	bool "Device Tree runtime unit tests"
 	depends on OF_IRQ && OF_EARLY_FLATTREE
 	depends on OF_IRQ && OF_EARLY_FLATTREE
-	select OF_DYNAMIC
 	select OF_RESOLVE
 	select OF_RESOLVE
 	help
 	help
 	  This option builds in test cases for the device tree infrastructure
 	  This option builds in test cases for the device tree infrastructure

+ 1 - 0
drivers/of/base.c

@@ -1303,6 +1303,7 @@ int of_property_read_u64_array(const struct device_node *np,
 	}
 	}
 	return 0;
 	return 0;
 }
 }
+EXPORT_SYMBOL_GPL(of_property_read_u64_array);
 
 
 /**
 /**
  * of_property_read_string - Find and read a string from a property
  * of_property_read_string - Find and read a string from a property

+ 1 - 1
drivers/of/fdt.c

@@ -762,7 +762,7 @@ static inline void early_init_dt_check_for_initrd(unsigned long node)
 #ifdef CONFIG_SERIAL_EARLYCON
 #ifdef CONFIG_SERIAL_EARLYCON
 extern struct of_device_id __earlycon_of_table[];
 extern struct of_device_id __earlycon_of_table[];
 
 
-int __init early_init_dt_scan_chosen_serial(void)
+static int __init early_init_dt_scan_chosen_serial(void)
 {
 {
 	int offset;
 	int offset;
 	const char *p;
 	const char *p;

+ 2 - 0
drivers/of/of_reserved_mem.c

@@ -265,6 +265,7 @@ int of_reserved_mem_device_init(struct device *dev)
 
 
 	return ret;
 	return ret;
 }
 }
+EXPORT_SYMBOL_GPL(of_reserved_mem_device_init);
 
 
 /**
 /**
  * of_reserved_mem_device_release() - release reserved memory device structures
  * of_reserved_mem_device_release() - release reserved memory device structures
@@ -289,3 +290,4 @@ void of_reserved_mem_device_release(struct device *dev)
 
 
 	rmem->ops->device_release(rmem, dev);
 	rmem->ops->device_release(rmem, dev);
 }
 }
+EXPORT_SYMBOL_GPL(of_reserved_mem_device_release);

+ 94 - 0
drivers/of/unittest-data/tests-overlay.dtsi

@@ -68,6 +68,48 @@
 					status = "disabled";
 					status = "disabled";
 					reg = <8>;
 					reg = <8>;
 				};
 				};
+
+				i2c-test-bus {
+					compatible = "selftest-i2c-bus";
+					status = "okay";
+					reg = <50>;
+
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					test-selftest12 {
+						reg = <8>;
+						compatible = "selftest-i2c-dev";
+						status = "disabled";
+					};
+
+					test-selftest13 {
+						reg = <9>;
+						compatible = "selftest-i2c-dev";
+						status = "okay";
+					};
+
+					test-selftest14 {
+						reg = <10>;
+						compatible = "selftest-i2c-mux";
+						status = "okay";
+
+						#address-cells = <1>;
+						#size-cells = <0>;
+
+						i2c@0 {
+							#address-cells = <1>;
+							#size-cells = <0>;
+							reg = <0>;
+
+							test-mux-dev {
+								reg = <32>;
+								compatible = "selftest-i2c-dev";
+								status = "okay";
+							};
+						};
+					};
+				};
 			};
 			};
 		};
 		};
 
 
@@ -231,5 +273,57 @@
 				};
 				};
 			};
 			};
 		};
 		};
+
+		/* test enable using absolute target path (i2c) */
+		overlay12 {
+			fragment@0 {
+				target-path = "/testcase-data/overlay-node/test-bus/i2c-test-bus/test-selftest12";
+				__overlay__ {
+					status = "okay";
+				};
+			};
+		};
+
+		/* test disable using absolute target path (i2c) */
+		overlay13 {
+			fragment@0 {
+				target-path = "/testcase-data/overlay-node/test-bus/i2c-test-bus/test-selftest13";
+				__overlay__ {
+					status = "disabled";
+				};
+			};
+		};
+
+		/* test mux overlay */
+		overlay15 {
+			fragment@0 {
+				target-path = "/testcase-data/overlay-node/test-bus/i2c-test-bus";
+				__overlay__ {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					test-selftest15 {
+						reg = <11>;
+						compatible = "selftest-i2c-mux";
+						status = "okay";
+
+						#address-cells = <1>;
+						#size-cells = <0>;
+
+						i2c@0 {
+							#address-cells = <1>;
+							#size-cells = <0>;
+							reg = <0>;
+
+							test-mux-dev {
+								reg = <32>;
+								compatible = "selftest-i2c-dev";
+								status = "okay";
+							};
+						};
+					};
+				};
+			};
+		};
+
 	};
 	};
 };
 };

+ 474 - 123
drivers/of/unittest.c

@@ -20,6 +20,9 @@
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/of_platform.h>
 #include <linux/of_platform.h>
 
 
+#include <linux/i2c.h>
+#include <linux/i2c-mux.h>
+
 #include "of_private.h"
 #include "of_private.h"
 
 
 static struct selftest_results {
 static struct selftest_results {
@@ -27,11 +30,6 @@ static struct selftest_results {
 	int failed;
 	int failed;
 } selftest_results;
 } selftest_results;
 
 
-#define NO_OF_NODES 3
-static struct device_node *nodes[NO_OF_NODES];
-static int last_node_index;
-static bool selftest_live_tree;
-
 #define selftest(result, fmt, ...) ({ \
 #define selftest(result, fmt, ...) ({ \
 	bool failed = !(result); \
 	bool failed = !(result); \
 	if (failed) { \
 	if (failed) { \
@@ -822,6 +820,7 @@ static void update_node_properties(struct device_node *np,
 static int attach_node_and_children(struct device_node *np)
 static int attach_node_and_children(struct device_node *np)
 {
 {
 	struct device_node *next, *dup, *child;
 	struct device_node *next, *dup, *child;
+	unsigned long flags;
 
 
 	dup = of_find_node_by_path(np->full_name);
 	dup = of_find_node_by_path(np->full_name);
 	if (dup) {
 	if (dup) {
@@ -829,17 +828,19 @@ static int attach_node_and_children(struct device_node *np)
 		return 0;
 		return 0;
 	}
 	}
 
 
-	/* Children of the root need to be remembered for removal */
-	if (np->parent == of_root) {
-		if (WARN_ON(last_node_index >= NO_OF_NODES))
-			return -EINVAL;
-		nodes[last_node_index++] = np;
-	}
-
 	child = np->child;
 	child = np->child;
 	np->child = NULL;
 	np->child = NULL;
-	np->sibling = NULL;
-	of_attach_node(np);
+
+	mutex_lock(&of_mutex);
+	raw_spin_lock_irqsave(&devtree_lock, flags);
+	np->sibling = np->parent->child;
+	np->parent->child = np;
+	of_node_clear_flag(np, OF_DETACHED);
+	raw_spin_unlock_irqrestore(&devtree_lock, flags);
+
+	__of_attach_node_sysfs(np);
+	mutex_unlock(&of_mutex);
+
 	while (child) {
 	while (child) {
 		next = child->sibling;
 		next = child->sibling;
 		attach_node_and_children(child);
 		attach_node_and_children(child);
@@ -889,10 +890,7 @@ static int __init selftest_data_add(void)
 	}
 	}
 
 
 	if (!of_root) {
 	if (!of_root) {
-		/* enabling flag for removing nodes */
-		selftest_live_tree = true;
 		of_root = selftest_data_node;
 		of_root = selftest_data_node;
-
 		for_each_of_allnodes(np)
 		for_each_of_allnodes(np)
 			__of_attach_node_sysfs(np);
 			__of_attach_node_sysfs(np);
 		of_aliases = of_find_node_by_path("/aliases");
 		of_aliases = of_find_node_by_path("/aliases");
@@ -911,59 +909,6 @@ static int __init selftest_data_add(void)
 	return 0;
 	return 0;
 }
 }
 
 
-/**
- *	detach_node_and_children - detaches node
- *	and its children from live tree
- *
- *	@np:	Node to detach from live tree
- */
-static void detach_node_and_children(struct device_node *np)
-{
-	while (np->child)
-		detach_node_and_children(np->child);
-	of_detach_node(np);
-}
-
-/**
- *	selftest_data_remove - removes the selftest data
- *	nodes from the live tree
- */
-static void selftest_data_remove(void)
-{
-	struct device_node *np;
-	struct property *prop;
-
-	if (selftest_live_tree) {
-		of_node_put(of_aliases);
-		of_node_put(of_chosen);
-		of_aliases = NULL;
-		of_chosen = NULL;
-		for_each_child_of_node(of_root, np)
-			detach_node_and_children(np);
-		__of_detach_node_sysfs(of_root);
-		of_root = NULL;
-		return;
-	}
-
-	while (last_node_index-- > 0) {
-		if (nodes[last_node_index]) {
-			np = of_find_node_by_path(nodes[last_node_index]->full_name);
-			if (np == nodes[last_node_index]) {
-				if (of_aliases == np) {
-					of_node_put(of_aliases);
-					of_aliases = NULL;
-				}
-				detach_node_and_children(np);
-			} else {
-				for_each_property_of_node(np, prop) {
-					if (strcmp(prop->name, "testcase-alias") == 0)
-						of_remove_property(np, prop);
-				}
-			}
-		}
-	}
-}
-
 #ifdef CONFIG_OF_OVERLAY
 #ifdef CONFIG_OF_OVERLAY
 
 
 static int selftest_probe(struct platform_device *pdev)
 static int selftest_probe(struct platform_device *pdev)
@@ -1034,17 +979,94 @@ static int of_path_platform_device_exists(const char *path)
 	return pdev != NULL;
 	return pdev != NULL;
 }
 }
 
 
-static const char *selftest_path(int nr)
+#if IS_ENABLED(CONFIG_I2C)
+
+/* get the i2c client device instantiated at the path */
+static struct i2c_client *of_path_to_i2c_client(const char *path)
 {
 {
+	struct device_node *np;
+	struct i2c_client *client;
+
+	np = of_find_node_by_path(path);
+	if (np == NULL)
+		return NULL;
+
+	client = of_find_i2c_device_by_node(np);
+	of_node_put(np);
+
+	return client;
+}
+
+/* find out if a i2c client device exists at that path */
+static int of_path_i2c_client_exists(const char *path)
+{
+	struct i2c_client *client;
+
+	client = of_path_to_i2c_client(path);
+	if (client)
+		put_device(&client->dev);
+	return client != NULL;
+}
+#else
+static int of_path_i2c_client_exists(const char *path)
+{
+	return 0;
+}
+#endif
+
+enum overlay_type {
+	PDEV_OVERLAY,
+	I2C_OVERLAY
+};
+
+static int of_path_device_type_exists(const char *path,
+		enum overlay_type ovtype)
+{
+	switch (ovtype) {
+	case PDEV_OVERLAY:
+		return of_path_platform_device_exists(path);
+	case I2C_OVERLAY:
+		return of_path_i2c_client_exists(path);
+	}
+	return 0;
+}
+
+static const char *selftest_path(int nr, enum overlay_type ovtype)
+{
+	const char *base;
 	static char buf[256];
 	static char buf[256];
 
 
-	snprintf(buf, sizeof(buf) - 1,
-		"/testcase-data/overlay-node/test-bus/test-selftest%d", nr);
+	switch (ovtype) {
+	case PDEV_OVERLAY:
+		base = "/testcase-data/overlay-node/test-bus";
+		break;
+	case I2C_OVERLAY:
+		base = "/testcase-data/overlay-node/test-bus/i2c-test-bus";
+		break;
+	default:
+		buf[0] = '\0';
+		return buf;
+	}
+	snprintf(buf, sizeof(buf) - 1, "%s/test-selftest%d", base, nr);
 	buf[sizeof(buf) - 1] = '\0';
 	buf[sizeof(buf) - 1] = '\0';
-
 	return buf;
 	return buf;
 }
 }
 
 
+static int of_selftest_device_exists(int selftest_nr, enum overlay_type ovtype)
+{
+	const char *path;
+
+	path = selftest_path(selftest_nr, ovtype);
+
+	switch (ovtype) {
+	case PDEV_OVERLAY:
+		return of_path_platform_device_exists(path);
+	case I2C_OVERLAY:
+		return of_path_i2c_client_exists(path);
+	}
+	return 0;
+}
+
 static const char *overlay_path(int nr)
 static const char *overlay_path(int nr)
 {
 {
 	static char buf[256];
 	static char buf[256];
@@ -1093,16 +1115,15 @@ out:
 
 
 /* apply an overlay while checking before and after states */
 /* apply an overlay while checking before and after states */
 static int of_selftest_apply_overlay_check(int overlay_nr, int selftest_nr,
 static int of_selftest_apply_overlay_check(int overlay_nr, int selftest_nr,
-		int before, int after)
+		int before, int after, enum overlay_type ovtype)
 {
 {
 	int ret;
 	int ret;
 
 
 	/* selftest device must not be in before state */
 	/* selftest device must not be in before state */
-	if (of_path_platform_device_exists(selftest_path(selftest_nr))
-			!= before) {
+	if (of_selftest_device_exists(selftest_nr, ovtype) != before) {
 		selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
 		selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
 				overlay_path(overlay_nr),
 				overlay_path(overlay_nr),
-				selftest_path(selftest_nr),
+				selftest_path(selftest_nr, ovtype),
 				!before ? "enabled" : "disabled");
 				!before ? "enabled" : "disabled");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
@@ -1114,11 +1135,10 @@ static int of_selftest_apply_overlay_check(int overlay_nr, int selftest_nr,
 	}
 	}
 
 
 	/* selftest device must be to set to after state */
 	/* selftest device must be to set to after state */
-	if (of_path_platform_device_exists(selftest_path(selftest_nr))
-			!= after) {
+	if (of_selftest_device_exists(selftest_nr, ovtype) != after) {
 		selftest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n",
 		selftest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n",
 				overlay_path(overlay_nr),
 				overlay_path(overlay_nr),
-				selftest_path(selftest_nr),
+				selftest_path(selftest_nr, ovtype),
 				!after ? "enabled" : "disabled");
 				!after ? "enabled" : "disabled");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
@@ -1128,16 +1148,16 @@ static int of_selftest_apply_overlay_check(int overlay_nr, int selftest_nr,
 
 
 /* apply an overlay and then revert it while checking before, after states */
 /* apply an overlay and then revert it while checking before, after states */
 static int of_selftest_apply_revert_overlay_check(int overlay_nr,
 static int of_selftest_apply_revert_overlay_check(int overlay_nr,
-		int selftest_nr, int before, int after)
+		int selftest_nr, int before, int after,
+		enum overlay_type ovtype)
 {
 {
 	int ret, ov_id;
 	int ret, ov_id;
 
 
 	/* selftest device must be in before state */
 	/* selftest device must be in before state */
-	if (of_path_platform_device_exists(selftest_path(selftest_nr))
-			!= before) {
+	if (of_selftest_device_exists(selftest_nr, ovtype) != before) {
 		selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
 		selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
 				overlay_path(overlay_nr),
 				overlay_path(overlay_nr),
-				selftest_path(selftest_nr),
+				selftest_path(selftest_nr, ovtype),
 				!before ? "enabled" : "disabled");
 				!before ? "enabled" : "disabled");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
@@ -1150,11 +1170,10 @@ static int of_selftest_apply_revert_overlay_check(int overlay_nr,
 	}
 	}
 
 
 	/* selftest device must be in after state */
 	/* selftest device must be in after state */
-	if (of_path_platform_device_exists(selftest_path(selftest_nr))
-			!= after) {
+	if (of_selftest_device_exists(selftest_nr, ovtype) != after) {
 		selftest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n",
 		selftest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n",
 				overlay_path(overlay_nr),
 				overlay_path(overlay_nr),
-				selftest_path(selftest_nr),
+				selftest_path(selftest_nr, ovtype),
 				!after ? "enabled" : "disabled");
 				!after ? "enabled" : "disabled");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
@@ -1163,16 +1182,15 @@ static int of_selftest_apply_revert_overlay_check(int overlay_nr,
 	if (ret != 0) {
 	if (ret != 0) {
 		selftest(0, "overlay @\"%s\" failed to be destroyed @\"%s\"\n",
 		selftest(0, "overlay @\"%s\" failed to be destroyed @\"%s\"\n",
 				overlay_path(overlay_nr),
 				overlay_path(overlay_nr),
-				selftest_path(selftest_nr));
+				selftest_path(selftest_nr, ovtype));
 		return ret;
 		return ret;
 	}
 	}
 
 
 	/* selftest device must be again in before state */
 	/* selftest device must be again in before state */
-	if (of_path_platform_device_exists(selftest_path(selftest_nr))
-			!= before) {
+	if (of_selftest_device_exists(selftest_nr, PDEV_OVERLAY) != before) {
 		selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
 		selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
 				overlay_path(overlay_nr),
 				overlay_path(overlay_nr),
-				selftest_path(selftest_nr),
+				selftest_path(selftest_nr, ovtype),
 				!before ? "enabled" : "disabled");
 				!before ? "enabled" : "disabled");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
@@ -1186,7 +1204,7 @@ static void of_selftest_overlay_0(void)
 	int ret;
 	int ret;
 
 
 	/* device should enable */
 	/* device should enable */
-	ret = of_selftest_apply_overlay_check(0, 0, 0, 1);
+	ret = of_selftest_apply_overlay_check(0, 0, 0, 1, PDEV_OVERLAY);
 	if (ret != 0)
 	if (ret != 0)
 		return;
 		return;
 
 
@@ -1199,7 +1217,7 @@ static void of_selftest_overlay_1(void)
 	int ret;
 	int ret;
 
 
 	/* device should disable */
 	/* device should disable */
-	ret = of_selftest_apply_overlay_check(1, 1, 1, 0);
+	ret = of_selftest_apply_overlay_check(1, 1, 1, 0, PDEV_OVERLAY);
 	if (ret != 0)
 	if (ret != 0)
 		return;
 		return;
 
 
@@ -1212,7 +1230,7 @@ static void of_selftest_overlay_2(void)
 	int ret;
 	int ret;
 
 
 	/* device should enable */
 	/* device should enable */
-	ret = of_selftest_apply_overlay_check(2, 2, 0, 1);
+	ret = of_selftest_apply_overlay_check(2, 2, 0, 1, PDEV_OVERLAY);
 	if (ret != 0)
 	if (ret != 0)
 		return;
 		return;
 
 
@@ -1225,7 +1243,7 @@ static void of_selftest_overlay_3(void)
 	int ret;
 	int ret;
 
 
 	/* device should disable */
 	/* device should disable */
-	ret = of_selftest_apply_overlay_check(3, 3, 1, 0);
+	ret = of_selftest_apply_overlay_check(3, 3, 1, 0, PDEV_OVERLAY);
 	if (ret != 0)
 	if (ret != 0)
 		return;
 		return;
 
 
@@ -1238,7 +1256,7 @@ static void of_selftest_overlay_4(void)
 	int ret;
 	int ret;
 
 
 	/* device should disable */
 	/* device should disable */
-	ret = of_selftest_apply_overlay_check(4, 4, 0, 1);
+	ret = of_selftest_apply_overlay_check(4, 4, 0, 1, PDEV_OVERLAY);
 	if (ret != 0)
 	if (ret != 0)
 		return;
 		return;
 
 
@@ -1251,7 +1269,7 @@ static void of_selftest_overlay_5(void)
 	int ret;
 	int ret;
 
 
 	/* device should disable */
 	/* device should disable */
-	ret = of_selftest_apply_revert_overlay_check(5, 5, 0, 1);
+	ret = of_selftest_apply_revert_overlay_check(5, 5, 0, 1, PDEV_OVERLAY);
 	if (ret != 0)
 	if (ret != 0)
 		return;
 		return;
 
 
@@ -1268,12 +1286,12 @@ static void of_selftest_overlay_6(void)
 
 
 	/* selftest device must be in before state */
 	/* selftest device must be in before state */
 	for (i = 0; i < 2; i++) {
 	for (i = 0; i < 2; i++) {
-		if (of_path_platform_device_exists(
-					selftest_path(selftest_nr + i))
+		if (of_selftest_device_exists(selftest_nr + i, PDEV_OVERLAY)
 				!= before) {
 				!= before) {
 			selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
 			selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
 					overlay_path(overlay_nr + i),
 					overlay_path(overlay_nr + i),
-					selftest_path(selftest_nr + i),
+					selftest_path(selftest_nr + i,
+						PDEV_OVERLAY),
 					!before ? "enabled" : "disabled");
 					!before ? "enabled" : "disabled");
 			return;
 			return;
 		}
 		}
@@ -1300,12 +1318,12 @@ static void of_selftest_overlay_6(void)
 
 
 	for (i = 0; i < 2; i++) {
 	for (i = 0; i < 2; i++) {
 		/* selftest device must be in after state */
 		/* selftest device must be in after state */
-		if (of_path_platform_device_exists(
-					selftest_path(selftest_nr + i))
+		if (of_selftest_device_exists(selftest_nr + i, PDEV_OVERLAY)
 				!= after) {
 				!= after) {
 			selftest(0, "overlay @\"%s\" failed @\"%s\" %s\n",
 			selftest(0, "overlay @\"%s\" failed @\"%s\" %s\n",
 					overlay_path(overlay_nr + i),
 					overlay_path(overlay_nr + i),
-					selftest_path(selftest_nr + i),
+					selftest_path(selftest_nr + i,
+						PDEV_OVERLAY),
 					!after ? "enabled" : "disabled");
 					!after ? "enabled" : "disabled");
 			return;
 			return;
 		}
 		}
@@ -1316,19 +1334,20 @@ static void of_selftest_overlay_6(void)
 		if (ret != 0) {
 		if (ret != 0) {
 			selftest(0, "overlay @\"%s\" failed destroy @\"%s\"\n",
 			selftest(0, "overlay @\"%s\" failed destroy @\"%s\"\n",
 					overlay_path(overlay_nr + i),
 					overlay_path(overlay_nr + i),
-					selftest_path(selftest_nr + i));
+					selftest_path(selftest_nr + i,
+						PDEV_OVERLAY));
 			return;
 			return;
 		}
 		}
 	}
 	}
 
 
 	for (i = 0; i < 2; i++) {
 	for (i = 0; i < 2; i++) {
 		/* selftest device must be again in before state */
 		/* selftest device must be again in before state */
-		if (of_path_platform_device_exists(
-					selftest_path(selftest_nr + i))
+		if (of_selftest_device_exists(selftest_nr + i, PDEV_OVERLAY)
 				!= before) {
 				!= before) {
 			selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
 			selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
 					overlay_path(overlay_nr + i),
 					overlay_path(overlay_nr + i),
-					selftest_path(selftest_nr + i),
+					selftest_path(selftest_nr + i,
+						PDEV_OVERLAY),
 					!before ? "enabled" : "disabled");
 					!before ? "enabled" : "disabled");
 			return;
 			return;
 		}
 		}
@@ -1370,7 +1389,8 @@ static void of_selftest_overlay_8(void)
 	if (ret == 0) {
 	if (ret == 0) {
 		selftest(0, "overlay @\"%s\" was destroyed @\"%s\"\n",
 		selftest(0, "overlay @\"%s\" was destroyed @\"%s\"\n",
 				overlay_path(overlay_nr + 0),
 				overlay_path(overlay_nr + 0),
-				selftest_path(selftest_nr));
+				selftest_path(selftest_nr,
+					PDEV_OVERLAY));
 		return;
 		return;
 	}
 	}
 
 
@@ -1380,7 +1400,8 @@ static void of_selftest_overlay_8(void)
 		if (ret != 0) {
 		if (ret != 0) {
 			selftest(0, "overlay @\"%s\" not destroyed @\"%s\"\n",
 			selftest(0, "overlay @\"%s\" not destroyed @\"%s\"\n",
 					overlay_path(overlay_nr + i),
 					overlay_path(overlay_nr + i),
-					selftest_path(selftest_nr));
+					selftest_path(selftest_nr,
+						PDEV_OVERLAY));
 			return;
 			return;
 		}
 		}
 	}
 	}
@@ -1395,16 +1416,17 @@ static void of_selftest_overlay_10(void)
 	char *child_path;
 	char *child_path;
 
 
 	/* device should disable */
 	/* device should disable */
-	ret = of_selftest_apply_overlay_check(10, 10, 0, 1);
-	if (selftest(ret == 0, "overlay test %d failed; overlay application\n", 10))
+	ret = of_selftest_apply_overlay_check(10, 10, 0, 1, PDEV_OVERLAY);
+	if (selftest(ret == 0,
+			"overlay test %d failed; overlay application\n", 10))
 		return;
 		return;
 
 
 	child_path = kasprintf(GFP_KERNEL, "%s/test-selftest101",
 	child_path = kasprintf(GFP_KERNEL, "%s/test-selftest101",
-			selftest_path(10));
+			selftest_path(10, PDEV_OVERLAY));
 	if (selftest(child_path, "overlay test %d failed; kasprintf\n", 10))
 	if (selftest(child_path, "overlay test %d failed; kasprintf\n", 10))
 		return;
 		return;
 
 
-	ret = of_path_platform_device_exists(child_path);
+	ret = of_path_device_type_exists(child_path, PDEV_OVERLAY);
 	kfree(child_path);
 	kfree(child_path);
 	if (selftest(ret, "overlay test %d failed; no child device\n", 10))
 	if (selftest(ret, "overlay test %d failed; no child device\n", 10))
 		return;
 		return;
@@ -1416,11 +1438,331 @@ static void of_selftest_overlay_11(void)
 	int ret;
 	int ret;
 
 
 	/* device should disable */
 	/* device should disable */
-	ret = of_selftest_apply_revert_overlay_check(11, 11, 0, 1);
-	if (selftest(ret == 0, "overlay test %d failed; overlay application\n", 11))
+	ret = of_selftest_apply_revert_overlay_check(11, 11, 0, 1,
+			PDEV_OVERLAY);
+	if (selftest(ret == 0,
+			"overlay test %d failed; overlay application\n", 11))
 		return;
 		return;
 }
 }
 
 
+#if IS_ENABLED(CONFIG_I2C) && IS_ENABLED(CONFIG_OF_OVERLAY)
+
+struct selftest_i2c_bus_data {
+	struct platform_device	*pdev;
+	struct i2c_adapter	adap;
+};
+
+static int selftest_i2c_master_xfer(struct i2c_adapter *adap,
+		struct i2c_msg *msgs, int num)
+{
+	struct selftest_i2c_bus_data *std = i2c_get_adapdata(adap);
+
+	(void)std;
+
+	return num;
+}
+
+static u32 selftest_i2c_functionality(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm selftest_i2c_algo = {
+	.master_xfer	= selftest_i2c_master_xfer,
+	.functionality	= selftest_i2c_functionality,
+};
+
+static int selftest_i2c_bus_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct selftest_i2c_bus_data *std;
+	struct i2c_adapter *adap;
+	int ret;
+
+	if (np == NULL) {
+		dev_err(dev, "No OF data for device\n");
+		return -EINVAL;
+
+	}
+
+	dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name);
+
+	std = devm_kzalloc(dev, sizeof(*std), GFP_KERNEL);
+	if (!std) {
+		dev_err(dev, "Failed to allocate selftest i2c data\n");
+		return -ENOMEM;
+	}
+
+	/* link them together */
+	std->pdev = pdev;
+	platform_set_drvdata(pdev, std);
+
+	adap = &std->adap;
+	i2c_set_adapdata(adap, std);
+	adap->nr = -1;
+	strlcpy(adap->name, pdev->name, sizeof(adap->name));
+	adap->class = I2C_CLASS_DEPRECATED;
+	adap->algo = &selftest_i2c_algo;
+	adap->dev.parent = dev;
+	adap->dev.of_node = dev->of_node;
+	adap->timeout = 5 * HZ;
+	adap->retries = 3;
+
+	ret = i2c_add_numbered_adapter(adap);
+	if (ret != 0) {
+		dev_err(dev, "Failed to add I2C adapter\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int selftest_i2c_bus_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct selftest_i2c_bus_data *std = platform_get_drvdata(pdev);
+
+	dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name);
+	i2c_del_adapter(&std->adap);
+
+	return 0;
+}
+
+static struct of_device_id selftest_i2c_bus_match[] = {
+	{ .compatible = "selftest-i2c-bus", },
+	{},
+};
+
+static struct platform_driver selftest_i2c_bus_driver = {
+	.probe			= selftest_i2c_bus_probe,
+	.remove			= selftest_i2c_bus_remove,
+	.driver = {
+		.name		= "selftest-i2c-bus",
+		.of_match_table	= of_match_ptr(selftest_i2c_bus_match),
+	},
+};
+
+static int selftest_i2c_dev_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device_node *np = client->dev.of_node;
+
+	if (!np) {
+		dev_err(dev, "No OF node\n");
+		return -EINVAL;
+	}
+
+	dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name);
+
+	return 0;
+};
+
+static int selftest_i2c_dev_remove(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct device_node *np = client->dev.of_node;
+
+	dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name);
+	return 0;
+}
+
+static const struct i2c_device_id selftest_i2c_dev_id[] = {
+	{ .name = "selftest-i2c-dev" },
+	{ }
+};
+
+static struct i2c_driver selftest_i2c_dev_driver = {
+	.driver = {
+		.name = "selftest-i2c-dev",
+		.owner = THIS_MODULE,
+	},
+	.probe = selftest_i2c_dev_probe,
+	.remove = selftest_i2c_dev_remove,
+	.id_table = selftest_i2c_dev_id,
+};
+
+#if IS_ENABLED(CONFIG_I2C_MUX)
+
+struct selftest_i2c_mux_data {
+	int nchans;
+	struct i2c_adapter *adap[];
+};
+
+static int selftest_i2c_mux_select_chan(struct i2c_adapter *adap,
+			       void *client, u32 chan)
+{
+	return 0;
+}
+
+static int selftest_i2c_mux_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	int ret, i, nchans, size;
+	struct device *dev = &client->dev;
+	struct i2c_adapter *adap = to_i2c_adapter(dev->parent);
+	struct device_node *np = client->dev.of_node, *child;
+	struct selftest_i2c_mux_data *stm;
+	u32 reg, max_reg;
+
+	dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name);
+
+	if (!np) {
+		dev_err(dev, "No OF node\n");
+		return -EINVAL;
+	}
+
+	max_reg = (u32)-1;
+	for_each_child_of_node(np, child) {
+		ret = of_property_read_u32(child, "reg", &reg);
+		if (ret)
+			continue;
+		if (max_reg == (u32)-1 || reg > max_reg)
+			max_reg = reg;
+	}
+	nchans = max_reg == (u32)-1 ? 0 : max_reg + 1;
+	if (nchans == 0) {
+		dev_err(dev, "No channels\n");
+		return -EINVAL;
+	}
+
+	size = offsetof(struct selftest_i2c_mux_data, adap[nchans]);
+	stm = devm_kzalloc(dev, size, GFP_KERNEL);
+	if (!stm) {
+		dev_err(dev, "Out of memory\n");
+		return -ENOMEM;
+	}
+	stm->nchans = nchans;
+	for (i = 0; i < nchans; i++) {
+		stm->adap[i] = i2c_add_mux_adapter(adap, dev, client,
+				0, i, 0, selftest_i2c_mux_select_chan, NULL);
+		if (!stm->adap[i]) {
+			dev_err(dev, "Failed to register mux #%d\n", i);
+			for (i--; i >= 0; i--)
+				i2c_del_mux_adapter(stm->adap[i]);
+			return -ENODEV;
+		}
+	}
+
+	i2c_set_clientdata(client, stm);
+
+	return 0;
+};
+
+static int selftest_i2c_mux_remove(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct device_node *np = client->dev.of_node;
+	struct selftest_i2c_mux_data *stm = i2c_get_clientdata(client);
+	int i;
+
+	dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name);
+	for (i = stm->nchans - 1; i >= 0; i--)
+		i2c_del_mux_adapter(stm->adap[i]);
+	return 0;
+}
+
+static const struct i2c_device_id selftest_i2c_mux_id[] = {
+	{ .name = "selftest-i2c-mux" },
+	{ }
+};
+
+static struct i2c_driver selftest_i2c_mux_driver = {
+	.driver = {
+		.name = "selftest-i2c-mux",
+		.owner = THIS_MODULE,
+	},
+	.probe = selftest_i2c_mux_probe,
+	.remove = selftest_i2c_mux_remove,
+	.id_table = selftest_i2c_mux_id,
+};
+
+#endif
+
+static int of_selftest_overlay_i2c_init(void)
+{
+	int ret;
+
+	ret = i2c_add_driver(&selftest_i2c_dev_driver);
+	if (selftest(ret == 0,
+			"could not register selftest i2c device driver\n"))
+		return ret;
+
+	ret = platform_driver_register(&selftest_i2c_bus_driver);
+	if (selftest(ret == 0,
+			"could not register selftest i2c bus driver\n"))
+		return ret;
+
+#if IS_ENABLED(CONFIG_I2C_MUX)
+	ret = i2c_add_driver(&selftest_i2c_mux_driver);
+	if (selftest(ret == 0,
+			"could not register selftest i2c mux driver\n"))
+		return ret;
+#endif
+
+	return 0;
+}
+
+static void of_selftest_overlay_i2c_cleanup(void)
+{
+#if IS_ENABLED(CONFIG_I2C_MUX)
+	i2c_del_driver(&selftest_i2c_mux_driver);
+#endif
+	platform_driver_unregister(&selftest_i2c_bus_driver);
+	i2c_del_driver(&selftest_i2c_dev_driver);
+}
+
+static void of_selftest_overlay_i2c_12(void)
+{
+	int ret;
+
+	/* device should enable */
+	ret = of_selftest_apply_overlay_check(12, 12, 0, 1, I2C_OVERLAY);
+	if (ret != 0)
+		return;
+
+	selftest(1, "overlay test %d passed\n", 12);
+}
+
+/* test deactivation of device */
+static void of_selftest_overlay_i2c_13(void)
+{
+	int ret;
+
+	/* device should disable */
+	ret = of_selftest_apply_overlay_check(13, 13, 1, 0, I2C_OVERLAY);
+	if (ret != 0)
+		return;
+
+	selftest(1, "overlay test %d passed\n", 13);
+}
+
+/* just check for i2c mux existence */
+static void of_selftest_overlay_i2c_14(void)
+{
+}
+
+static void of_selftest_overlay_i2c_15(void)
+{
+	int ret;
+
+	/* device should enable */
+	ret = of_selftest_apply_overlay_check(16, 15, 0, 1, I2C_OVERLAY);
+	if (ret != 0)
+		return;
+
+	selftest(1, "overlay test %d passed\n", 15);
+}
+
+#else
+
+static inline void of_selftest_overlay_i2c_14(void) { }
+static inline void of_selftest_overlay_i2c_15(void) { }
+
+#endif
+
 static void __init of_selftest_overlay(void)
 static void __init of_selftest_overlay(void)
 {
 {
 	struct device_node *bus_np = NULL;
 	struct device_node *bus_np = NULL;
@@ -1445,15 +1787,15 @@ static void __init of_selftest_overlay(void)
 		goto out;
 		goto out;
 	}
 	}
 
 
-	if (!of_path_platform_device_exists(selftest_path(100))) {
+	if (!of_selftest_device_exists(100, PDEV_OVERLAY)) {
 		selftest(0, "could not find selftest0 @ \"%s\"\n",
 		selftest(0, "could not find selftest0 @ \"%s\"\n",
-				selftest_path(100));
+				selftest_path(100, PDEV_OVERLAY));
 		goto out;
 		goto out;
 	}
 	}
 
 
-	if (of_path_platform_device_exists(selftest_path(101))) {
+	if (of_selftest_device_exists(101, PDEV_OVERLAY)) {
 		selftest(0, "selftest1 @ \"%s\" should not exist\n",
 		selftest(0, "selftest1 @ \"%s\" should not exist\n",
-				selftest_path(101));
+				selftest_path(101, PDEV_OVERLAY));
 		goto out;
 		goto out;
 	}
 	}
 
 
@@ -1472,6 +1814,18 @@ static void __init of_selftest_overlay(void)
 	of_selftest_overlay_10();
 	of_selftest_overlay_10();
 	of_selftest_overlay_11();
 	of_selftest_overlay_11();
 
 
+#if IS_ENABLED(CONFIG_I2C)
+	if (selftest(of_selftest_overlay_i2c_init() == 0, "i2c init failed\n"))
+		goto out;
+
+	of_selftest_overlay_i2c_12();
+	of_selftest_overlay_i2c_13();
+	of_selftest_overlay_i2c_14();
+	of_selftest_overlay_i2c_15();
+
+	of_selftest_overlay_i2c_cleanup();
+#endif
+
 out:
 out:
 	of_node_put(bus_np);
 	of_node_put(bus_np);
 }
 }
@@ -1514,9 +1868,6 @@ static int __init of_selftest(void)
 	of_selftest_platform_populate();
 	of_selftest_platform_populate();
 	of_selftest_overlay();
 	of_selftest_overlay();
 
 
-	/* removing selftest data from live tree */
-	selftest_data_remove();
-
 	/* Double check linkage after removing testcase data */
 	/* Double check linkage after removing testcase data */
 	of_selftest_check_tree_linkage();
 	of_selftest_check_tree_linkage();
 
 

+ 1 - 2
include/linux/mod_devicetable.h

@@ -220,8 +220,7 @@ struct serio_device_id {
 /*
 /*
  * Struct used for matching a device
  * Struct used for matching a device
  */
  */
-struct of_device_id
-{
+struct of_device_id {
 	char	name[32];
 	char	name[32];
 	char	type[32];
 	char	type[32];
 	char	compatible[128];
 	char	compatible[128];