- 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:
Linus Torvalds 2015-02-12 08:58:43 -08:00
Родитель 42cf0f203e 3c3c8e3618
Коммит cdd305454e
36 изменённых файлов: 766 добавлений и 172 удалений

Просмотреть файл

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

Просмотреть файл

@ -1,7 +1,10 @@
NVIDIA Tegra AHB
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)
Example:

Просмотреть файл

@ -6,7 +6,11 @@ modes. It provides power-gating controllers for SoC and CPU power-islands.
Required properties:
- 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
- clocks : Must contain an entry for each entry in clock-names.
See ../clocks/clock-bindings.txt for details.

Просмотреть файл

@ -1,7 +1,9 @@
Tegra124 SoC SATA AHCI controller
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:
- AHCI register set (SATA BAR5)
- 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.
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:
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

Просмотреть файл

@ -197,7 +197,9 @@ of the following host1x client modules:
- sor: serial output resource
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.
- interrupts: The interrupt outputs from the controller.
- 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
- 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.
- interrupts: The interrupt outputs from the controller.
- clocks: Must contain an entry for each entry in clock-names.

Просмотреть файл

@ -1,11 +1,11 @@
NVIDIA Tegra20/Tegra30/Tegra114 I2C controller driver.
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:
nvidia,tegra20-i2c-dvc: Tegra20 has specific I2C controller called as DVC I2C
controller. This only support master mode of I2C communication. Register

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -1,11 +1,10 @@
NVIDIA Tegra20/Tegra30/Tegr114/Tegra124 apbmisc block
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
and length of the registers which contain revision and debug features.
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.
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.
See ../clocks/clock-bindings.txt for details.
- resets : Must contain an entry for each entry in reset-names.

Просмотреть файл

@ -1,10 +1,10 @@
NVIDIA Tegra PCIe controller
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"
- 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.

Просмотреть файл

@ -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.
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:
-- first entry - the drive strength and pad control registers.
-- second entry - the pinmux registers

Просмотреть файл

@ -13,7 +13,9 @@ how to describe and reference PHYs in device trees.
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.
- resets: Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.

Просмотреть файл

@ -1,9 +1,10 @@
Tegra SoC PWFM controller
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
- #pwm-cells: should be 2. See pwm.txt in this directory for a description of
the cells format.

Просмотреть файл

@ -6,7 +6,9 @@ state.
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.
- interrupts : A single interrupt specifier.
- clocks : Must contain one entry, for the module clock.

Просмотреть файл

@ -8,7 +8,10 @@ Required properties:
- "ns16550"
- "ns16750"
- "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"
- "ralink,rt2880-uart"
- "ibm,qpace-nwp-serial"

Просмотреть файл

@ -1,7 +1,10 @@
NVIDIA Tegra30 AHUB (Audio Hub)
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
the AHUB's register blocks.
- Tegra30 requires 2 entries, for the APBIF and AHUB/AUDIO register blocks.

Просмотреть файл

@ -1,7 +1,9 @@
NVIDIA Tegra30 HDA controller
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.
- interrupts : The interrupt from the HDA controller.
- clocks : Must contain an entry for each required entry in clock-names.

Просмотреть файл

@ -1,7 +1,10 @@
NVIDIA Tegra30 I2S controller
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
- clocks : Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.

Просмотреть файл

@ -1,7 +1,9 @@
NVIDIA Tegra114 SPI controller.
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.
- interrupts: Should contain SPI interrupts.
- 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
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
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.
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:
- SOCTHERM register set
- interrupts : Defines the interrupt used by SOCTHERM

Просмотреть файл

@ -6,7 +6,9 @@ trigger a legacy watchdog reset.
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.
- 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.

Просмотреть файл

@ -1,4 +1,4 @@
* OF selftest platform device
1) OF selftest platform device
** selftest
@ -12,3 +12,60 @@ Example:
compatible = "selftest";
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 :
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.
- clocks : Must contain one entry, for the module clock.
See ../clocks/clock-bindings.txt for details.

Просмотреть файл

@ -3,7 +3,10 @@ Tegra SOC USB PHY
The device node for Tegra SOC USB PHY:
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:
- The PHY's own register set.
Always present.

Просмотреть файл

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

Просмотреть файл

@ -10,7 +10,6 @@ menu "Device Tree and Open Firmware support"
config OF_UNITTEST
bool "Device Tree runtime unit tests"
depends on OF_IRQ && OF_EARLY_FLATTREE
select OF_DYNAMIC
select OF_RESOLVE
help
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;
}
EXPORT_SYMBOL_GPL(of_property_read_u64_array);
/**
* 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
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;
const char *p;

Просмотреть файл

@ -265,6 +265,7 @@ int of_reserved_mem_device_init(struct device *dev)
return ret;
}
EXPORT_SYMBOL_GPL(of_reserved_mem_device_init);
/**
* 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);
}
EXPORT_SYMBOL_GPL(of_reserved_mem_device_release);

Просмотреть файл

@ -68,6 +68,48 @@
status = "disabled";
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/of_platform.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include "of_private.h"
static struct selftest_results {
@ -27,11 +30,6 @@ static struct selftest_results {
int failed;
} 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, ...) ({ \
bool failed = !(result); \
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)
{
struct device_node *next, *dup, *child;
unsigned long flags;
dup = of_find_node_by_path(np->full_name);
if (dup) {
@ -829,17 +828,19 @@ static int attach_node_and_children(struct device_node *np)
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;
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) {
next = child->sibling;
attach_node_and_children(child);
@ -889,10 +890,7 @@ static int __init selftest_data_add(void)
}
if (!of_root) {
/* enabling flag for removing nodes */
selftest_live_tree = true;
of_root = selftest_data_node;
for_each_of_allnodes(np)
__of_attach_node_sysfs(np);
of_aliases = of_find_node_by_path("/aliases");
@ -911,59 +909,6 @@ static int __init selftest_data_add(void)
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
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;
}
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];
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';
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 char buf[256];
@ -1093,16 +1115,15 @@ out:
/* apply an overlay while checking before and after states */
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;
/* 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",
overlay_path(overlay_nr),
selftest_path(selftest_nr),
selftest_path(selftest_nr, ovtype),
!before ? "enabled" : "disabled");
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 */
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",
overlay_path(overlay_nr),
selftest_path(selftest_nr),
selftest_path(selftest_nr, ovtype),
!after ? "enabled" : "disabled");
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 */
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;
/* 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",
overlay_path(overlay_nr),
selftest_path(selftest_nr),
selftest_path(selftest_nr, ovtype),
!before ? "enabled" : "disabled");
return -EINVAL;
}
@ -1150,11 +1170,10 @@ static int of_selftest_apply_revert_overlay_check(int overlay_nr,
}
/* 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",
overlay_path(overlay_nr),
selftest_path(selftest_nr),
selftest_path(selftest_nr, ovtype),
!after ? "enabled" : "disabled");
return -EINVAL;
}
@ -1163,16 +1182,15 @@ static int of_selftest_apply_revert_overlay_check(int overlay_nr,
if (ret != 0) {
selftest(0, "overlay @\"%s\" failed to be destroyed @\"%s\"\n",
overlay_path(overlay_nr),
selftest_path(selftest_nr));
selftest_path(selftest_nr, ovtype));
return ret;
}
/* 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",
overlay_path(overlay_nr),
selftest_path(selftest_nr),
selftest_path(selftest_nr, ovtype),
!before ? "enabled" : "disabled");
return -EINVAL;
}
@ -1186,7 +1204,7 @@ static void of_selftest_overlay_0(void)
int ret;
/* 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)
return;
@ -1199,7 +1217,7 @@ static void of_selftest_overlay_1(void)
int ret;
/* 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)
return;
@ -1212,7 +1230,7 @@ static void of_selftest_overlay_2(void)
int ret;
/* 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)
return;
@ -1225,7 +1243,7 @@ static void of_selftest_overlay_3(void)
int ret;
/* 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)
return;
@ -1238,7 +1256,7 @@ static void of_selftest_overlay_4(void)
int ret;
/* 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)
return;
@ -1251,7 +1269,7 @@ static void of_selftest_overlay_5(void)
int ret;
/* 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)
return;
@ -1268,12 +1286,12 @@ static void of_selftest_overlay_6(void)
/* selftest device must be in before state */
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) {
selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
overlay_path(overlay_nr + i),
selftest_path(selftest_nr + i),
selftest_path(selftest_nr + i,
PDEV_OVERLAY),
!before ? "enabled" : "disabled");
return;
}
@ -1300,12 +1318,12 @@ static void of_selftest_overlay_6(void)
for (i = 0; i < 2; i++) {
/* 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) {
selftest(0, "overlay @\"%s\" failed @\"%s\" %s\n",
overlay_path(overlay_nr + i),
selftest_path(selftest_nr + i),
selftest_path(selftest_nr + i,
PDEV_OVERLAY),
!after ? "enabled" : "disabled");
return;
}
@ -1316,19 +1334,20 @@ static void of_selftest_overlay_6(void)
if (ret != 0) {
selftest(0, "overlay @\"%s\" failed destroy @\"%s\"\n",
overlay_path(overlay_nr + i),
selftest_path(selftest_nr + i));
selftest_path(selftest_nr + i,
PDEV_OVERLAY));
return;
}
}
for (i = 0; i < 2; i++) {
/* 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) {
selftest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
overlay_path(overlay_nr + i),
selftest_path(selftest_nr + i),
selftest_path(selftest_nr + i,
PDEV_OVERLAY),
!before ? "enabled" : "disabled");
return;
}
@ -1370,7 +1389,8 @@ static void of_selftest_overlay_8(void)
if (ret == 0) {
selftest(0, "overlay @\"%s\" was destroyed @\"%s\"\n",
overlay_path(overlay_nr + 0),
selftest_path(selftest_nr));
selftest_path(selftest_nr,
PDEV_OVERLAY));
return;
}
@ -1380,7 +1400,8 @@ static void of_selftest_overlay_8(void)
if (ret != 0) {
selftest(0, "overlay @\"%s\" not destroyed @\"%s\"\n",
overlay_path(overlay_nr + i),
selftest_path(selftest_nr));
selftest_path(selftest_nr,
PDEV_OVERLAY));
return;
}
}
@ -1395,16 +1416,17 @@ static void of_selftest_overlay_10(void)
char *child_path;
/* 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;
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))
return;
ret = of_path_platform_device_exists(child_path);
ret = of_path_device_type_exists(child_path, PDEV_OVERLAY);
kfree(child_path);
if (selftest(ret, "overlay test %d failed; no child device\n", 10))
return;
@ -1416,11 +1438,331 @@ static void of_selftest_overlay_11(void)
int ret;
/* 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;
}
#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)
{
struct device_node *bus_np = NULL;
@ -1445,15 +1787,15 @@ static void __init of_selftest_overlay(void)
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_path(100));
selftest_path(100, PDEV_OVERLAY));
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_path(101));
selftest_path(101, PDEV_OVERLAY));
goto out;
}
@ -1472,6 +1814,18 @@ static void __init of_selftest_overlay(void)
of_selftest_overlay_10();
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:
of_node_put(bus_np);
}
@ -1514,9 +1868,6 @@ static int __init of_selftest(void)
of_selftest_platform_populate();
of_selftest_overlay();
/* removing selftest data from live tree */
selftest_data_remove();
/* Double check linkage after removing testcase data */
of_selftest_check_tree_linkage();

Просмотреть файл

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