DeviceTree changes for 3.20:
- 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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJU3CJVAAoJEMhvYp4jgsXieMgIAKlpr8gcMq/ORRRbVJ9jrL64 A0gPZZEBBVJ0BX7b6mvz15/6Zt70naoE23tMgaCQpR620ox9xFshmwhzHct9npiQ KRode+9QhFRvA3Pc5LXhfD+bnyJ3Z4pWPrbY6sDDL9txqolpUhU4fz8Y3InwN5YB GSD6NG3UKDmrTOvkR1j2WrCIkSeXYAEKtnuQlN/+eZXM6kzZYDcdskHv6o18mf4b Ys6mwkfJdN3UZVQE8ZxUSi3wdC9U7mErNOZuc2rgL9Qb+q0RHtgE2GTI2Zxw0Sj1 BlCO1Fs0sYhOunZIazLJht7cenGbBMf+ed2DB4VLNiEmPhavqdv9wjNt9jOjh5k= =Aviy -----END PGP SIGNATURE----- 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}
This commit is contained in:
commit
cdd305454e
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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>;
|
||||||
|
};
|
@ -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:
|
- compatible : For Tegra20, must contain "nvidia,tegra20-efuse". For Tegra30,
|
||||||
"nvidia,tegra20-efuse"
|
must contain "nvidia,tegra30-efuse". For Tegra114, must contain
|
||||||
"nvidia,tegra30-efuse"
|
"nvidia,tegra114-efuse". For Tegra124, must contain "nvidia,tegra124-efuse".
|
||||||
"nvidia,tegra114-efuse"
|
Otherwise, must contain "nvidia,<chip>-efuse", plus one of the above, where
|
||||||
"nvidia,tegra124-efuse"
|
<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
|
||||||
|
@ -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.
|
||||||
|
@ -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:
|
- compatible : For Tegra20, must be one of "nvidia,tegra20-i2c-dvc" or
|
||||||
"nvidia,tegra114-i2c"
|
"nvidia,tegra20-i2c". For Tegra30, must be "nvidia,tegra30-i2c".
|
||||||
"nvidia,tegra30-i2c"
|
For Tegra114, must be "nvidia,tegra114-i2c". Otherwise, must be
|
||||||
"nvidia,tegra20-i2c"
|
"nvidia,<chip>-i2c", plus at least one of the above, where <chip> is
|
||||||
"nvidia,tegra20-i2c-dvc"
|
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
|
||||||
|
@ -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 {
|
||||||
|
@ -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 = <®ulator1>;
|
vddio-supply = <®ulator1>;
|
||||||
vddcore-supply = <®ulator2>;
|
vddcore-supply = <®ulator2>;
|
||||||
|
@ -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:
|
- compatible : For Tegra20, must be "nvidia,tegra20-apbmisc". For Tegra30,
|
||||||
"nvidia,tegra20-apbmisc"
|
must be "nvidia,tegra30-apbmisc". Otherwise, must contain
|
||||||
"nvidia,tegra30-apbmisc"
|
"nvidia,<chip>-apbmisc", plus one of the above, where <chip> is tegra114,
|
||||||
"nvidia,tegra114-apbmisc"
|
tegra124, tegra132.
|
||||||
"nvidia,tegra124-apbmisc"
|
|
||||||
- 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
|
||||||
|
@ -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.
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
NVIDIA Tegra PCIe controller
|
NVIDIA Tegra PCIe controller
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible: Must be one of:
|
- compatible: For Tegra20, must contain "nvidia,tegra20-pcie". For Tegra30,
|
||||||
- "nvidia,tegra20-pcie"
|
"nvidia,tegra30-pcie". For Tegra124, must contain "nvidia,tegra124-pcie".
|
||||||
- "nvidia,tegra30-pcie"
|
Otherwise, must contain "nvidia,<chip>-pcie", plus one of the above, where
|
||||||
- "nvidia,tegra124-pcie"
|
<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.
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
Tegra SoC PWFM controller
|
Tegra SoC PWFM controller
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible: should be one of:
|
- compatible: For Tegra20, must contain "nvidia,tegra20-pwm". For Tegra30,
|
||||||
- "nvidia,tegra20-pwm"
|
must contain "nvidia,tegra30-pwm". Otherwise, must contain
|
||||||
- "nvidia,tegra30-pwm"
|
"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.
|
||||||
|
@ -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.
|
||||||
|
@ -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"
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -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.
|
||||||
|
@ -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,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)
|
isil Intersil
|
||||||
isl 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.
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -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,
|
switch (ovtype) {
|
||||||
"/testcase-data/overlay-node/test-bus/test-selftest%d", nr);
|
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))
|
if (of_selftest_device_exists(selftest_nr, ovtype) != before) {
|
||||||
!= 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))
|
if (of_selftest_device_exists(selftest_nr, ovtype) != after) {
|
||||||
!= 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))
|
if (of_selftest_device_exists(selftest_nr, ovtype) != before) {
|
||||||
!= 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))
|
if (of_selftest_device_exists(selftest_nr, ovtype) != after) {
|
||||||
!= 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))
|
if (of_selftest_device_exists(selftest_nr, 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),
|
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(
|
if (of_selftest_device_exists(selftest_nr + i, PDEV_OVERLAY)
|
||||||
selftest_path(selftest_nr + i))
|
|
||||||
!= 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(
|
if (of_selftest_device_exists(selftest_nr + i, PDEV_OVERLAY)
|
||||||
selftest_path(selftest_nr + i))
|
|
||||||
!= 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(
|
if (of_selftest_device_exists(selftest_nr + i, PDEV_OVERLAY)
|
||||||
selftest_path(selftest_nr + i))
|
|
||||||
!= 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);
|
ret = of_selftest_apply_overlay_check(10, 10, 0, 1, PDEV_OVERLAY);
|
||||||
if (selftest(ret == 0, "overlay test %d failed; overlay application\n", 10))
|
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);
|
ret = of_selftest_apply_revert_overlay_check(11, 11, 0, 1,
|
||||||
if (selftest(ret == 0, "overlay test %d failed; overlay application\n", 11))
|
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", ®);
|
||||||
|
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();
|
||||||
|
|
||||||
|
@ -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];
|
||||||
|
Loading…
Reference in New Issue
Block a user