mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 12:52:30 +00:00
DeviceTree updates for v4.18:
- Sync dtc with upstream version v1.4.6-21-g84e414b0b5bc. This adds new warnings which are either fixed or disabled by default (enabled with W=1). - Validate an untrusted offset in DT overlay function update_usages_of_a_phandle_reference - Fix a use after free error of_platform_device_destroy - Fix an off by 1 string errors in unittest - Avoid creating a struct device for OPP nodes - Update DT specific submitting-patches.txt with patch content and subject requirements. - Move some bindings to their proper subsystem locations - Add vendor prefixes for Kaohsiung, SiFive, Avnet, Wi2Wi, Logic PD, and ArcherMind - Add documentation for "no-gpio-delays" property in FSI bus GPIO master - Add compatible for r8a77990 SoC ravb ethernet block - More wack-a-mole removal of 'status' property in examples -----BEGIN PGP SIGNATURE----- iQJEBAABCgAuFiEEktVUI4SxYhzZyEuo+vtdtY28YcMFAlsX7EMQHHJvYmhAa2Vy bmVsLm9yZwAKCRD6+121jbxhwymLD/0b71t4fwg2n/vkrKHXp/NyGNv2mcDjl2Yo VEFKvRrUEVQNQHfUAgo9aaI71+prr7a4MB9o3GE4NBO+IsY5YpK+TYpVj2M2cVqW giIjivOw8+sxJFnAGpYoxqwHtdm9fkdQEnLl/x90QBw0ZicDXC9MAnIaLUqVqoM9 6GbFODyb6Z2lzw73d5Gvg/fvxdlANWvOMLwz6w6Xd8/bN9+FCEjhxSIyNJO2ASCb dAju6EFqqvJvRs2WYjnDABOW/ujl95RuP0NVuZ0b+FfHQSNzKk9IxCFHAFUaw5Md SqbqkKkhJamnAtETIV5r//bMBpiLO8a9BwJexXo+E1ftR8isbQMhLmD9kBsLDL8A s4wDfAeqKSqH9RAsCaWb50POafe4LwCzKQGMiZUXsGeiHv/lIS2t5ybwmJ+LrDiL nIIcX2fDAgjG1FPH3sMKNiwYhJQwsBFmgB4qvCNcGhDhi587gM6TehcBznX/tscQ o4AY/qTmsCcabI9/3V6JEMelHZ5WfARGBSID4QEFqWIxKXDDIhH4JCjRdyCJIK0M zKaE0uqlrDsVOPLHqAphoc0ebuCgU6SxcI1EXX2fMaaAJSmrr7G1N2abTJSHSJ03 ApYHPn5AJGq/xIpE4955h9CRKN4ftu+sTfkPx9KmnRysf5DntuRRQtuSuFXcJ9mO vtKp3kWFWQ== =2b7G -----END PGP SIGNATURE----- Merge tag 'devicetree-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux Pull DeviceTree updates from Rob Herring: - Sync dtc with upstream version v1.4.6-21-g84e414b0b5bc. This adds new warnings which are either fixed or disabled by default (enabled with W=1). - Validate an untrusted offset in DT overlay function update_usages_of_a_phandle_reference - Fix a use after free error of_platform_device_destroy - Fix an off by 1 string errors in unittest - Avoid creating a struct device for OPP nodes - Update DT specific submitting-patches.txt with patch content and subject requirements. - Move some bindings to their proper subsystem locations - Add vendor prefixes for Kaohsiung, SiFive, Avnet, Wi2Wi, Logic PD, and ArcherMind - Add documentation for "no-gpio-delays" property in FSI bus GPIO master - Add compatible for r8a77990 SoC ravb ethernet block - More wack-a-mole removal of 'status' property in examples * tag 'devicetree-for-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (25 commits) dt-bindings: submitting-patches: add guidance on patch content and subject of: platform: stop accessing invalid dev in of_platform_device_destroy dt-bindings: net: ravb: Add support for r8a77990 SoC dt-bindings: Add vendor prefix for ArcherMind dt-bindings: fsi-master-gpio: Document "no-gpio-delays" property dt-bindings: Add vendor prefix for Logic PD of: overlay: validate offset from property fixups of: unittest: for strings, account for trailing \0 in property length field drm: rcar-du: disable dtc graph-endpoint warnings on DT overlays kbuild: disable new dtc graph and unit-address warnings scripts/dtc: Update to upstream version v1.4.6-21-g84e414b0b5bc MAINTAINERS: add keyword for devicetree overlay notifiers dt-bindings: define vendor prefix for Wi2Wi, Inc. dt-bindings: Add vendor prefix for Avnet, Inc. dt-bindings: Relocate Tegra20 memory controller bindings dt-bindings: Add "sifive" vendor prefix dt-bindings: exynos: move ADC binding to iio/adc/ directory dt-bindings: powerpc/4xx: move 4xx NDFC and EMAC bindings to subsystem directories dt-bindings: move various RNG bindings to rng/ directory dt-bindings: move various timer bindings to timer/ directory ...
This commit is contained in:
commit
289cf155d9
@ -26,7 +26,7 @@ interrupt-controller:
|
||||
see binding for interrupt-controller/arm,gic.txt
|
||||
|
||||
timer:
|
||||
see binding for arm/twd.txt
|
||||
see binding for timer/arm,twd.txt
|
||||
|
||||
clocks:
|
||||
see binding for clocks/ux500.txt
|
||||
|
@ -23,7 +23,6 @@ Controller:
|
||||
dma-requests = <27>;
|
||||
interrupts = <0 12 4>;
|
||||
clocks = <&pclk>;
|
||||
status = "disable";
|
||||
};
|
||||
|
||||
Client:
|
||||
|
@ -190,7 +190,6 @@ mmc0: mmc@23000000 {
|
||||
power-domains = <&k2g_pds 0xb>;
|
||||
clocks = <&k2g_clks 0xb 1>, <&k2g_clks 0xb 2>;
|
||||
clock-names = "fck", "mmchsdb_fck";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
@ -11,6 +11,10 @@ Optional properties:
|
||||
- trans-gpios = <gpio-descriptor>; : GPIO for voltage translator enable
|
||||
- mux-gpios = <gpio-descriptor>; : GPIO for pin multiplexing with other
|
||||
functions (eg, external FSI masters)
|
||||
- no-gpio-delays; : Don't add extra delays between GPIO
|
||||
accesses. This is useful when the HW
|
||||
GPIO block is running at a low enough
|
||||
frequency.
|
||||
|
||||
Examples:
|
||||
|
||||
|
@ -61,7 +61,6 @@ Example of the RCU bindings on a xRX200 SoC:
|
||||
usb_phy0: usb2-phy@18 {
|
||||
compatible = "lantiq,xrx200-usb2-phy";
|
||||
reg = <0x18 4>, <0x38 4>;
|
||||
status = "disabled";
|
||||
|
||||
resets = <&reset1 4 4>, <&reset0 4 4>;
|
||||
reset-names = "phy", "ctrl";
|
||||
@ -71,7 +70,6 @@ Example of the RCU bindings on a xRX200 SoC:
|
||||
usb_phy1: usb2-phy@34 {
|
||||
compatible = "lantiq,xrx200-usb2-phy";
|
||||
reg = <0x34 4>, <0x3C 4>;
|
||||
status = "disabled";
|
||||
|
||||
resets = <&reset1 5 4>, <&reset0 4 4>;
|
||||
reset-names = "phy", "ctrl";
|
||||
|
@ -69,7 +69,6 @@ Example: R8A7790 (R-Car H2) SDHI controller nodes
|
||||
max-frequency = <195000000>;
|
||||
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
|
||||
resets = <&cpg 314>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
sdhi1: sd@ee120000 {
|
||||
@ -83,7 +82,6 @@ Example: R8A7790 (R-Car H2) SDHI controller nodes
|
||||
max-frequency = <195000000>;
|
||||
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
|
||||
resets = <&cpg 313>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
sdhi2: sd@ee140000 {
|
||||
@ -97,7 +95,6 @@ Example: R8A7790 (R-Car H2) SDHI controller nodes
|
||||
max-frequency = <97500000>;
|
||||
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
|
||||
resets = <&cpg 312>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
sdhi3: sd@ee160000 {
|
||||
@ -111,5 +108,4 @@ Example: R8A7790 (R-Car H2) SDHI controller nodes
|
||||
max-frequency = <97500000>;
|
||||
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
|
||||
resets = <&cpg 311>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -20,7 +20,6 @@ Required NFI properties:
|
||||
- interrupts: Interrupts of NFI.
|
||||
- clocks: NFI required clocks.
|
||||
- clock-names: NFI clocks internal name.
|
||||
- status: Disabled default. Then set "okay" by platform.
|
||||
- ecc-engine: Required ECC Engine node.
|
||||
- #address-cells: NAND chip index, should be 1.
|
||||
- #size-cells: Should be 0.
|
||||
@ -34,7 +33,6 @@ Example:
|
||||
clocks = <&pericfg CLK_PERI_NFI>,
|
||||
<&pericfg CLK_PERI_NFI_PAD>;
|
||||
clock-names = "nfi_clk", "pad_clk";
|
||||
status = "disabled";
|
||||
ecc-engine = <&bch>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@ -152,7 +150,6 @@ Required BCH properties:
|
||||
- interrupts: Interrupts of ECC.
|
||||
- clocks: ECC required clocks.
|
||||
- clock-names: ECC clocks internal name.
|
||||
- status: Disabled default. Then set "okay" by platform.
|
||||
|
||||
Example:
|
||||
|
||||
@ -162,5 +159,4 @@ Example:
|
||||
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&pericfg CLK_PERI_NFI_ECC>;
|
||||
clock-names = "nfiecc_clk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
@ -21,6 +21,7 @@ Required properties:
|
||||
- "renesas,etheravb-r8a77965" for the R8A77965 SoC.
|
||||
- "renesas,etheravb-r8a77970" for the R8A77970 SoC.
|
||||
- "renesas,etheravb-r8a77980" for the R8A77980 SoC.
|
||||
- "renesas,etheravb-r8a77990" for the R8A77990 SoC.
|
||||
- "renesas,etheravb-r8a77995" for the R8A77995 SoC.
|
||||
- "renesas,etheravb-rcar-gen3" as a fallback for the above
|
||||
R-Car Gen3 devices.
|
||||
|
@ -25,8 +25,6 @@ Optional properties:
|
||||
|
||||
Example:
|
||||
|
||||
SoC-specific DT Entry:
|
||||
|
||||
pcie0: pcie@1f2b0000 {
|
||||
status = "disabled";
|
||||
device_type = "pci";
|
||||
@ -50,8 +48,3 @@ SoC-specific DT Entry:
|
||||
clocks = <&pcie0clk 0>;
|
||||
};
|
||||
|
||||
|
||||
Board-specific DT Entry:
|
||||
&pcie0 {
|
||||
status = "ok";
|
||||
};
|
||||
|
@ -20,5 +20,4 @@ Example:
|
||||
assert-falling-edge;
|
||||
|
||||
compatible = "pps-gpio";
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
Required properties:
|
||||
- compatible: Shall contain "ti,omap-dmtimer-pwm".
|
||||
- ti,timers: phandle to PWM capable OMAP timer. See arm/omap/timer.txt for info
|
||||
- ti,timers: phandle to PWM capable OMAP timer. See timer/ti,timer.txt for info
|
||||
about these timers.
|
||||
- #pwm-cells: Should be 3. See pwm.txt in this directory for a description of
|
||||
the cells format.
|
||||
|
@ -6,7 +6,14 @@ I. For patch submitters
|
||||
0) Normal patch submission rules from Documentation/process/submitting-patches.rst
|
||||
applies.
|
||||
|
||||
1) The Documentation/ portion of the patch should be a separate patch.
|
||||
1) The Documentation/ and include/dt-bindings/ portion of the patch should
|
||||
be a separate patch. The preferred subject prefix for binding patches is:
|
||||
|
||||
"dt-bindings: <binding dir>: ..."
|
||||
|
||||
The 80 characters of the subject are precious. It is recommended to not
|
||||
use "Documentation" or "doc" because that is implied. All bindings are
|
||||
docs. Repeating "binding" again should also be avoided.
|
||||
|
||||
2) Submit the entire series to the devicetree mailinglist at
|
||||
|
||||
|
@ -27,9 +27,9 @@ Example:
|
||||
|
||||
tsc: thermal@e6198000 {
|
||||
compatible = "renesas,r8a7795-thermal";
|
||||
reg = <0 0xe6198000 0 0x68>,
|
||||
<0 0xe61a0000 0 0x5c>,
|
||||
<0 0xe61a8000 0 0x5c>;
|
||||
reg = <0 0xe6198000 0 0x100>,
|
||||
<0 0xe61a0000 0 0x100>,
|
||||
<0 0xe61a8000 0 0x100>;
|
||||
interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
@ -32,6 +32,7 @@ andestech Andes Technology Corporation
|
||||
apm Applied Micro Circuits Corporation (APM)
|
||||
aptina Aptina Imaging
|
||||
arasan Arasan Chip Systems
|
||||
archermind ArcherMind Technology (Nanjing) Co., Ltd.
|
||||
arctic Arctic Sand
|
||||
aries Aries Embedded GmbH
|
||||
arm ARM Ltd.
|
||||
@ -47,6 +48,7 @@ auvidea Auvidea GmbH
|
||||
avago Avago Technologies
|
||||
avia avia semiconductor
|
||||
avic Shanghai AVIC Optoelectronics Co., Ltd.
|
||||
avnet Avnet, Inc.
|
||||
axentia Axentia Technologies AB
|
||||
axis Axis Communications AB
|
||||
bananapi BIPAI KEJI LIMITED
|
||||
@ -186,6 +188,7 @@ khadas Khadas
|
||||
kiebackpeter Kieback & Peter GmbH
|
||||
kinetic Kinetic Technologies
|
||||
kingnovel Kingnovel Technology Co., Ltd.
|
||||
koe Kaohsiung Opto-Electronics Inc.
|
||||
kosagi Sutajio Ko-Usagi PTE Ltd.
|
||||
kyo Kyocera Corporation
|
||||
lacie LaCie
|
||||
@ -200,6 +203,7 @@ linaro Linaro Limited
|
||||
linksys Belkin International, Inc. (Linksys)
|
||||
linux Linux-specific binding
|
||||
lltc Linear Technology Corporation
|
||||
logicpd Logic PD, Inc.
|
||||
lsi LSI Corp. (LSI Logic)
|
||||
lwn Liebherr-Werk Nenzing GmbH
|
||||
macnica Macnica Americas
|
||||
@ -320,6 +324,7 @@ sgx SGX Sensortech
|
||||
sharp Sharp Corporation
|
||||
shimafuji Shimafuji Electric, Inc.
|
||||
si-en Si-En Technology Ltd.
|
||||
sifive SiFive, Inc.
|
||||
sigma Sigma Designs, Inc.
|
||||
sii Seiko Instruments, Inc.
|
||||
sil Silicon Image
|
||||
@ -395,6 +400,7 @@ vot Vision Optical Technology Co., Ltd.
|
||||
wd Western Digital Corp.
|
||||
wetek WeTek Electronics, limited.
|
||||
wexler Wexler
|
||||
wi2wi Wi2Wi, Inc.
|
||||
winbond Winbond Electronics corp.
|
||||
winstar Winstar Display Corp.
|
||||
wlf Wolfson Microelectronics
|
||||
|
@ -10510,12 +10510,14 @@ F: drivers/infiniband/ulp/opa_vnic
|
||||
|
||||
OPEN FIRMWARE AND DEVICE TREE OVERLAYS
|
||||
M: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
|
||||
M: Frank Rowand <frowand.list@gmail.com>
|
||||
L: devicetree@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/dynamic-resolution-notes.txt
|
||||
F: Documentation/devicetree/overlay-notes.txt
|
||||
F: drivers/of/overlay.c
|
||||
F: drivers/of/resolver.c
|
||||
K: of_overlay_notifier_
|
||||
|
||||
OPEN FIRMWARE AND FLATTENED DEVICE TREE
|
||||
M: Rob Herring <robh+dt@kernel.org>
|
||||
|
@ -17,3 +17,10 @@ rcar-du-drm-$(CONFIG_DRM_RCAR_VSP) += rcar_du_vsp.o
|
||||
obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o
|
||||
obj-$(CONFIG_DRM_RCAR_DW_HDMI) += rcar_dw_hdmi.o
|
||||
obj-$(CONFIG_DRM_RCAR_LVDS) += rcar_lvds.o
|
||||
|
||||
# 'remote-endpoint' is fixed up at run-time
|
||||
DTC_FLAGS_rcar_du_of_lvds_r8a7790 += -Wno-graph_endpoint
|
||||
DTC_FLAGS_rcar_du_of_lvds_r8a7791 += -Wno-graph_endpoint
|
||||
DTC_FLAGS_rcar_du_of_lvds_r8a7793 += -Wno-graph_endpoint
|
||||
DTC_FLAGS_rcar_du_of_lvds_r8a7795 += -Wno-graph_endpoint
|
||||
DTC_FLAGS_rcar_du_of_lvds_r8a7796 += -Wno-graph_endpoint
|
||||
|
@ -177,7 +177,6 @@ int of_node_to_nid(struct device_node *device)
|
||||
|
||||
return NUMA_NO_NODE;
|
||||
}
|
||||
EXPORT_SYMBOL(of_node_to_nid);
|
||||
|
||||
int __init of_numa_init(void)
|
||||
{
|
||||
|
@ -32,6 +32,11 @@ const struct of_device_id of_default_bus_match_table[] = {
|
||||
{} /* Empty terminated list */
|
||||
};
|
||||
|
||||
static const struct of_device_id of_skipped_node_table[] = {
|
||||
{ .compatible = "operating-points-v2", },
|
||||
{} /* Empty terminated list */
|
||||
};
|
||||
|
||||
static int of_dev_node_match(struct device *dev, void *data)
|
||||
{
|
||||
return dev->of_node == data;
|
||||
@ -356,6 +361,12 @@ static int of_platform_bus_create(struct device_node *bus,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Skip nodes for which we don't want to create devices */
|
||||
if (unlikely(of_match_node(of_skipped_node_table, bus))) {
|
||||
pr_debug("%s() - skipping %pOF node\n", __func__, bus);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (of_node_check_flag(bus, OF_POPULATED_BUS)) {
|
||||
pr_debug("%s() - skipping %pOF, already populated\n",
|
||||
__func__, bus);
|
||||
@ -537,6 +548,9 @@ int of_platform_device_destroy(struct device *dev, void *data)
|
||||
if (of_node_check_flag(dev->of_node, OF_POPULATED_BUS))
|
||||
device_for_each_child(dev, NULL, of_platform_device_destroy);
|
||||
|
||||
of_node_clear_flag(dev->of_node, OF_POPULATED);
|
||||
of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
|
||||
|
||||
if (dev->bus == &platform_bus_type)
|
||||
platform_device_unregister(to_platform_device(dev));
|
||||
#ifdef CONFIG_ARM_AMBA
|
||||
@ -544,8 +558,6 @@ int of_platform_device_destroy(struct device *dev, void *data)
|
||||
amba_device_unregister(to_amba_device(dev));
|
||||
#endif
|
||||
|
||||
of_node_clear_flag(dev->of_node, OF_POPULATED);
|
||||
of_node_clear_flag(dev->of_node, OF_POPULATED_BUS);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_platform_device_destroy);
|
||||
|
@ -122,6 +122,11 @@ static int update_usages_of_a_phandle_reference(struct device_node *overlay,
|
||||
goto err_fail;
|
||||
}
|
||||
|
||||
if (offset < 0 || offset + sizeof(__be32) > prop->length) {
|
||||
err = -EINVAL;
|
||||
goto err_fail;
|
||||
}
|
||||
|
||||
*(__be32 *)(prop->value + offset) = cpu_to_be32(phandle);
|
||||
}
|
||||
|
||||
|
@ -165,20 +165,20 @@ static void __init of_unittest_dynamic(void)
|
||||
/* Add a new property - should pass*/
|
||||
prop->name = "new-property";
|
||||
prop->value = "new-property-data";
|
||||
prop->length = strlen(prop->value);
|
||||
prop->length = strlen(prop->value) + 1;
|
||||
unittest(of_add_property(np, prop) == 0, "Adding a new property failed\n");
|
||||
|
||||
/* Try to add an existing property - should fail */
|
||||
prop++;
|
||||
prop->name = "new-property";
|
||||
prop->value = "new-property-data-should-fail";
|
||||
prop->length = strlen(prop->value);
|
||||
prop->length = strlen(prop->value) + 1;
|
||||
unittest(of_add_property(np, prop) != 0,
|
||||
"Adding an existing property should have failed\n");
|
||||
|
||||
/* Try to modify an existing property - should pass */
|
||||
prop->value = "modify-property-data-should-pass";
|
||||
prop->length = strlen(prop->value);
|
||||
prop->length = strlen(prop->value) + 1;
|
||||
unittest(of_update_property(np, prop) == 0,
|
||||
"Updating an existing property should have passed\n");
|
||||
|
||||
@ -186,7 +186,7 @@ static void __init of_unittest_dynamic(void)
|
||||
prop++;
|
||||
prop->name = "modify-property";
|
||||
prop->value = "modify-missing-property-data-should-pass";
|
||||
prop->length = strlen(prop->value);
|
||||
prop->length = strlen(prop->value) + 1;
|
||||
unittest(of_update_property(np, prop) == 0,
|
||||
"Updating a missing property should have passed\n");
|
||||
|
||||
|
@ -251,6 +251,9 @@ DTC_FLAGS += -Wno-unit_address_vs_reg \
|
||||
-Wno-unit_address_format \
|
||||
-Wno-avoid_unnecessary_addr_size \
|
||||
-Wno-alias_paths \
|
||||
-Wno-graph_child_address \
|
||||
-Wno-graph_port \
|
||||
-Wno-unique_unit_address \
|
||||
-Wno-pci_device_reg
|
||||
endif
|
||||
|
||||
|
@ -255,7 +255,7 @@ static void check_duplicate_node_names(struct check *c, struct dt_info *dti,
|
||||
child2;
|
||||
child2 = child2->next_sibling)
|
||||
if (streq(child->name, child2->name))
|
||||
FAIL(c, dti, node, "Duplicate node name");
|
||||
FAIL(c, dti, child2, "Duplicate node name");
|
||||
}
|
||||
ERROR(duplicate_node_names, check_duplicate_node_names, NULL);
|
||||
|
||||
@ -317,6 +317,11 @@ static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
|
||||
const char *unitname = get_unitname(node);
|
||||
struct property *prop = get_property(node, "reg");
|
||||
|
||||
if (get_subnode(node, "__overlay__")) {
|
||||
/* HACK: Overlay fragments are a special case */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prop) {
|
||||
prop = get_property(node, "ranges");
|
||||
if (prop && !prop->val.len)
|
||||
@ -579,6 +584,8 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti,
|
||||
|
||||
phandle = get_node_phandle(dt, refnode);
|
||||
*((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
|
||||
|
||||
reference_node(refnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -609,11 +616,21 @@ static void fixup_path_references(struct check *c, struct dt_info *dti,
|
||||
path = refnode->fullpath;
|
||||
prop->val = data_insert_at_marker(prop->val, m, path,
|
||||
strlen(path) + 1);
|
||||
|
||||
reference_node(refnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names);
|
||||
|
||||
static void fixup_omit_unused_nodes(struct check *c, struct dt_info *dti,
|
||||
struct node *node)
|
||||
{
|
||||
if (node->omit_if_unused && !node->is_referenced)
|
||||
delete_node(node);
|
||||
}
|
||||
ERROR(omit_unused_nodes, fixup_omit_unused_nodes, NULL, &phandle_references, &path_references);
|
||||
|
||||
/*
|
||||
* Semantic checks
|
||||
*/
|
||||
@ -1017,6 +1034,36 @@ static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *d
|
||||
}
|
||||
WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size);
|
||||
|
||||
static void check_unique_unit_address(struct check *c, struct dt_info *dti,
|
||||
struct node *node)
|
||||
{
|
||||
struct node *childa;
|
||||
|
||||
if (node->addr_cells < 0 || node->size_cells < 0)
|
||||
return;
|
||||
|
||||
if (!node->children)
|
||||
return;
|
||||
|
||||
for_each_child(node, childa) {
|
||||
struct node *childb;
|
||||
const char *addr_a = get_unitname(childa);
|
||||
|
||||
if (!strlen(addr_a))
|
||||
continue;
|
||||
|
||||
for_each_child(node, childb) {
|
||||
const char *addr_b = get_unitname(childb);
|
||||
if (childa == childb)
|
||||
break;
|
||||
|
||||
if (streq(addr_a, addr_b))
|
||||
FAIL(c, dti, childb, "duplicate unit-address (also used in node %s)", childa->fullpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
WARNING(unique_unit_address, check_unique_unit_address, NULL, &avoid_default_addr_size);
|
||||
|
||||
static void check_obsolete_chosen_interrupt_controller(struct check *c,
|
||||
struct dt_info *dti,
|
||||
struct node *node)
|
||||
@ -1357,6 +1404,152 @@ static void check_interrupts_property(struct check *c,
|
||||
}
|
||||
WARNING(interrupts_property, check_interrupts_property, &phandle_references);
|
||||
|
||||
static const struct bus_type graph_port_bus = {
|
||||
.name = "graph-port",
|
||||
};
|
||||
|
||||
static const struct bus_type graph_ports_bus = {
|
||||
.name = "graph-ports",
|
||||
};
|
||||
|
||||
static void check_graph_nodes(struct check *c, struct dt_info *dti,
|
||||
struct node *node)
|
||||
{
|
||||
struct node *child;
|
||||
|
||||
for_each_child(node, child) {
|
||||
if (!(strprefixeq(child->name, child->basenamelen, "endpoint") ||
|
||||
get_property(child, "remote-endpoint")))
|
||||
continue;
|
||||
|
||||
node->bus = &graph_port_bus;
|
||||
|
||||
/* The parent of 'port' nodes can be either 'ports' or a device */
|
||||
if (!node->parent->bus &&
|
||||
(streq(node->parent->name, "ports") || get_property(node, "reg")))
|
||||
node->parent->bus = &graph_ports_bus;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
WARNING(graph_nodes, check_graph_nodes, NULL);
|
||||
|
||||
static void check_graph_child_address(struct check *c, struct dt_info *dti,
|
||||
struct node *node)
|
||||
{
|
||||
int cnt = 0;
|
||||
struct node *child;
|
||||
|
||||
if (node->bus != &graph_ports_bus && node->bus != &graph_port_bus)
|
||||
return;
|
||||
|
||||
for_each_child(node, child) {
|
||||
struct property *prop = get_property(child, "reg");
|
||||
|
||||
/* No error if we have any non-zero unit address */
|
||||
if (prop && propval_cell(prop) != 0)
|
||||
return;
|
||||
|
||||
cnt++;
|
||||
}
|
||||
|
||||
if (cnt == 1 && node->addr_cells != -1)
|
||||
FAIL(c, dti, node, "graph node has single child node '%s', #address-cells/#size-cells are not necessary",
|
||||
node->children->name);
|
||||
}
|
||||
WARNING(graph_child_address, check_graph_child_address, NULL, &graph_nodes);
|
||||
|
||||
static void check_graph_reg(struct check *c, struct dt_info *dti,
|
||||
struct node *node)
|
||||
{
|
||||
char unit_addr[9];
|
||||
const char *unitname = get_unitname(node);
|
||||
struct property *prop;
|
||||
|
||||
prop = get_property(node, "reg");
|
||||
if (!prop || !unitname)
|
||||
return;
|
||||
|
||||
if (!(prop->val.val && prop->val.len == sizeof(cell_t))) {
|
||||
FAIL(c, dti, node, "graph node malformed 'reg' property");
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(unit_addr, sizeof(unit_addr), "%x", propval_cell(prop));
|
||||
if (!streq(unitname, unit_addr))
|
||||
FAIL(c, dti, node, "graph node unit address error, expected \"%s\"",
|
||||
unit_addr);
|
||||
|
||||
if (node->parent->addr_cells != 1)
|
||||
FAIL_PROP(c, dti, node, get_property(node, "#address-cells"),
|
||||
"graph node '#address-cells' is %d, must be 1",
|
||||
node->parent->addr_cells);
|
||||
if (node->parent->size_cells != 0)
|
||||
FAIL_PROP(c, dti, node, get_property(node, "#size-cells"),
|
||||
"graph node '#size-cells' is %d, must be 0",
|
||||
node->parent->size_cells);
|
||||
}
|
||||
|
||||
static void check_graph_port(struct check *c, struct dt_info *dti,
|
||||
struct node *node)
|
||||
{
|
||||
if (node->bus != &graph_port_bus)
|
||||
return;
|
||||
|
||||
if (!strprefixeq(node->name, node->basenamelen, "port"))
|
||||
FAIL(c, dti, node, "graph port node name should be 'port'");
|
||||
|
||||
check_graph_reg(c, dti, node);
|
||||
}
|
||||
WARNING(graph_port, check_graph_port, NULL, &graph_nodes);
|
||||
|
||||
static struct node *get_remote_endpoint(struct check *c, struct dt_info *dti,
|
||||
struct node *endpoint)
|
||||
{
|
||||
int phandle;
|
||||
struct node *node;
|
||||
struct property *prop;
|
||||
|
||||
prop = get_property(endpoint, "remote-endpoint");
|
||||
if (!prop)
|
||||
return NULL;
|
||||
|
||||
phandle = propval_cell(prop);
|
||||
/* Give up if this is an overlay with external references */
|
||||
if (phandle == 0 || phandle == -1)
|
||||
return NULL;
|
||||
|
||||
node = get_node_by_phandle(dti->dt, phandle);
|
||||
if (!node)
|
||||
FAIL_PROP(c, dti, endpoint, prop, "graph phandle is not valid");
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static void check_graph_endpoint(struct check *c, struct dt_info *dti,
|
||||
struct node *node)
|
||||
{
|
||||
struct node *remote_node;
|
||||
|
||||
if (!node->parent || node->parent->bus != &graph_port_bus)
|
||||
return;
|
||||
|
||||
if (!strprefixeq(node->name, node->basenamelen, "endpoint"))
|
||||
FAIL(c, dti, node, "graph endpont node name should be 'endpoint'");
|
||||
|
||||
check_graph_reg(c, dti, node);
|
||||
|
||||
remote_node = get_remote_endpoint(c, dti, node);
|
||||
if (!remote_node)
|
||||
return;
|
||||
|
||||
if (get_remote_endpoint(c, dti, remote_node) != node)
|
||||
FAIL(c, dti, node, "graph connection to node '%s' is not bidirectional",
|
||||
remote_node->fullpath);
|
||||
}
|
||||
WARNING(graph_endpoint, check_graph_endpoint, NULL, &graph_nodes);
|
||||
|
||||
static struct check *check_table[] = {
|
||||
&duplicate_node_names, &duplicate_property_names,
|
||||
&node_name_chars, &node_name_format, &property_name_chars,
|
||||
@ -1366,6 +1559,7 @@ static struct check *check_table[] = {
|
||||
|
||||
&explicit_phandles,
|
||||
&phandle_references, &path_references,
|
||||
&omit_unused_nodes,
|
||||
|
||||
&address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
|
||||
&device_type_is_string, &model_is_string, &status_is_string,
|
||||
@ -1390,6 +1584,7 @@ static struct check *check_table[] = {
|
||||
|
||||
&avoid_default_addr_size,
|
||||
&avoid_unnecessary_addr_size,
|
||||
&unique_unit_address,
|
||||
&obsolete_chosen_interrupt_controller,
|
||||
&chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path,
|
||||
|
||||
@ -1416,6 +1611,8 @@ static struct check *check_table[] = {
|
||||
|
||||
&alias_paths,
|
||||
|
||||
&graph_nodes, &graph_child_address, &graph_port, &graph_endpoint,
|
||||
|
||||
&always_fail,
|
||||
};
|
||||
|
||||
|
@ -153,6 +153,13 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
|
||||
return DT_DEL_NODE;
|
||||
}
|
||||
|
||||
<*>"/omit-if-no-ref/" {
|
||||
DPRINT("Keyword: /omit-if-no-ref/\n");
|
||||
DPRINT("<PROPNODENAME>\n");
|
||||
BEGIN(PROPNODENAME);
|
||||
return DT_OMIT_NO_REF;
|
||||
}
|
||||
|
||||
<*>{LABEL}: {
|
||||
DPRINT("Label: %s\n", yytext);
|
||||
yylval.labelref = xstrdup(yytext);
|
||||
|
@ -63,6 +63,7 @@ extern bool treesource_error;
|
||||
%token DT_BITS
|
||||
%token DT_DEL_PROP
|
||||
%token DT_DEL_NODE
|
||||
%token DT_OMIT_NO_REF
|
||||
%token <propnodename> DT_PROPNODENAME
|
||||
%token <integer> DT_LITERAL
|
||||
%token <integer> DT_CHAR_LITERAL
|
||||
@ -190,18 +191,18 @@ devicetree:
|
||||
}
|
||||
| devicetree DT_REF nodedef
|
||||
{
|
||||
struct node *target = get_node_by_ref($1, $2);
|
||||
|
||||
if (target) {
|
||||
merge_nodes(target, $3);
|
||||
/*
|
||||
* We rely on the rule being always:
|
||||
* versioninfo plugindecl memreserves devicetree
|
||||
* so $-1 is what we want (plugindecl)
|
||||
*/
|
||||
if ($<flags>-1 & DTSF_PLUGIN) {
|
||||
add_orphan_node($1, $3, $2);
|
||||
} else {
|
||||
/*
|
||||
* We rely on the rule being always:
|
||||
* versioninfo plugindecl memreserves devicetree
|
||||
* so $-1 is what we want (plugindecl)
|
||||
*/
|
||||
if ($<flags>-1 & DTSF_PLUGIN)
|
||||
add_orphan_node($1, $3, $2);
|
||||
struct node *target = get_node_by_ref($1, $2);
|
||||
|
||||
if (target)
|
||||
merge_nodes(target, $3);
|
||||
else
|
||||
ERROR(&@2, "Label or path %s not found", $2);
|
||||
}
|
||||
@ -217,6 +218,18 @@ devicetree:
|
||||
ERROR(&@3, "Label or path %s not found", $3);
|
||||
|
||||
|
||||
$$ = $1;
|
||||
}
|
||||
| devicetree DT_OMIT_NO_REF DT_REF ';'
|
||||
{
|
||||
struct node *target = get_node_by_ref($1, $3);
|
||||
|
||||
if (target)
|
||||
omit_node_if_unused(target);
|
||||
else
|
||||
ERROR(&@3, "Label or path %s not found", $3);
|
||||
|
||||
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
@ -523,6 +536,10 @@ subnode:
|
||||
{
|
||||
$$ = name_node(build_node_delete(), $2);
|
||||
}
|
||||
| DT_OMIT_NO_REF subnode
|
||||
{
|
||||
$$ = omit_node_if_unused($2);
|
||||
}
|
||||
| DT_LABEL subnode
|
||||
{
|
||||
add_label(&$2->labels, $1);
|
||||
|
@ -168,6 +168,8 @@ struct node {
|
||||
|
||||
struct label *labels;
|
||||
const struct bus_type *bus;
|
||||
|
||||
bool omit_if_unused, is_referenced;
|
||||
};
|
||||
|
||||
#define for_each_label_withdel(l0, l) \
|
||||
@ -202,6 +204,8 @@ struct property *reverse_properties(struct property *first);
|
||||
struct node *build_node(struct property *proplist, struct node *children);
|
||||
struct node *build_node_delete(void);
|
||||
struct node *name_node(struct node *node, char *name);
|
||||
struct node *omit_node_if_unused(struct node *node);
|
||||
struct node *reference_node(struct node *node);
|
||||
struct node *chain_node(struct node *first, struct node *list);
|
||||
struct node *merge_nodes(struct node *old_node, struct node *new_node);
|
||||
struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
|
||||
|
@ -134,6 +134,20 @@ struct node *name_node(struct node *node, char *name)
|
||||
return node;
|
||||
}
|
||||
|
||||
struct node *omit_node_if_unused(struct node *node)
|
||||
{
|
||||
node->omit_if_unused = 1;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
struct node *reference_node(struct node *node)
|
||||
{
|
||||
node->is_referenced = 1;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
struct node *merge_nodes(struct node *old_node, struct node *new_node)
|
||||
{
|
||||
struct property *new_prop, *old_prop;
|
||||
@ -224,10 +238,16 @@ struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref)
|
||||
struct data d = empty_data;
|
||||
char *name;
|
||||
|
||||
d = data_add_marker(d, REF_PHANDLE, ref);
|
||||
d = data_append_integer(d, 0xffffffff, 32);
|
||||
if (ref[0] == '/') {
|
||||
d = data_append_data(d, ref, strlen(ref) + 1);
|
||||
|
||||
p = build_property("target", d);
|
||||
p = build_property("target-path", d);
|
||||
} else {
|
||||
d = data_add_marker(d, REF_PHANDLE, ref);
|
||||
d = data_append_integer(d, 0xffffffff, 32);
|
||||
|
||||
p = build_property("target", d);
|
||||
}
|
||||
|
||||
xasprintf(&name, "fragment@%u",
|
||||
next_orphan_fragment++);
|
||||
|
@ -1 +1 @@
|
||||
#define DTC_VERSION "DTC 1.4.6-gaadd0b65"
|
||||
#define DTC_VERSION "DTC 1.4.6-g84e414b0"
|
||||
|
Loading…
Reference in New Issue
Block a user