Pull DeviceTree updates from Rob Herring: - vsprintf format specifier %pOF for device_node's. This will enable us to stop storing the full node names. Conversion of users will happen next cycle. - Update documentation to point to DT specification instead of ePAPR. - Split out graph and property functions to a separate file. - New of-graph functions for ALSA - Add vendor prefixes for RISC-V, Linksys, iWave Systems, Roofull, Itead, and BananaPi. - Improve dtx_diff utility filename printing. * tag 'devicetree-for-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (32 commits) of: document /sys/firmware/fdt dt-bindings: Add RISC-V vendor prefix vsprintf: Add %p extension "%pOF" for device tree of: find_node_by_full_name rewrite to compare each level of: use kbasename instead of open coding dt-bindings: thermal: add file extension to brcm,ns-thermal of: update ePAPR references to point to Devicetree Specification scripts/dtc: dtx_diff - Show real file names in diff header of: detect invalid phandle in overlay of: be consistent in form of file mode of: make __of_attach_node() static of: address.c header comment typo of: fdt.c header comment typo of: make of_fdt_is_compatible() static dt-bindings: display-timing.txt convert non-ascii characters to ascii Documentation: remove overlay-notes reference to non-existent file dt-bindings: usb: exynos-usb: Add missing required VDD properties dt-bindings: Add vendor prefix for Linksys MAINTAINERS: add device tree ABI documentation file of: Add vendor prefix for iWave Systems Technologies Pvt. Ltd ...
Unified · Split
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | What: /sys/firmware/devicetree/* |
| 2 | 2 | Date: November 2013 |
| 3 | −Contact: Grant Likely <grant.likely@linaro.org> | |
| 3 | +Contact: Grant Likely <grant.likely@arm.com>, devicetree@vger.kernel.org | |
| 4 | 4 | Description: |
| 5 | 5 | When using OpenFirmware or a Flattened Device Tree to enumerate |
| 6 | 6 | hardware, the device tree structure will be exposed in this |
| @@ -26,3 +26,27 @@ Description: · 19 unmodified lines | ||
| 26 | 26 | name plus address). Properties are represented as files |
| 27 | 27 | in the directory. The contents of each file is the exact |
| 28 | 28 | binary data from the device tree. |
| 29 | + | |
| 30 | +What: /sys/firmware/fdt | |
| 31 | +Date: February 2015 | |
| 32 | +KernelVersion: 3.19 | |
| 33 | +Contact: Frank Rowand <frowand.list@gmail.com>, devicetree@vger.kernel.org | |
| 34 | +Description: | |
| 35 | + Exports the FDT blob that was passed to the kernel by | |
| 36 | + the bootloader. This allows userland applications such | |
| 37 | + as kexec to access the raw binary. This blob is also | |
| 38 | + useful when debugging since it contains any changes | |
| 39 | + made to the blob by the bootloader. | |
| 40 | + | |
| 41 | + The fact that this node does not reside under | |
| 42 | + /sys/firmware/device-tree is deliberate: FDT is also used | |
| 43 | + on arm64 UEFI/ACPI systems to communicate just the UEFI | |
| 44 | + and ACPI entry points, but the FDT is never unflattened | |
| 45 | + and used to configure the system. | |
| 46 | + | |
| 47 | + A CRC32 checksum is calculated over the entire FDT | |
| 48 | + blob, and verified at late_initcall time. The sysfs | |
| 49 | + entry is instantiated only if the checksum is valid, | |
| 50 | + i.e., if the FDT blob has not been modified in the mean | |
| 51 | + time. Otherwise, a warning is printed. | |
| 52 | +Users: kexec, debugging | |
| @@ -11,13 +11,6 @@ clusters, through memory mapped interface, with a global control register · 10 unmodified lines | ||
| 11 | 11 | space and multiple sets of interface control registers, one per slave |
| 12 | 12 | interface. |
| 13 | 13 | |
| 14 | −Bindings for the CCI node follow the ePAPR standard, available from: | |
| 15 | − | |
| 16 | −www.power.org/documentation/epapr-version-1-1/ | |
| 17 | − | |
| 18 | −with the addition of the bindings described in this document which are | |
| 19 | −specific to ARM. | |
| 20 | − | |
| 21 | 14 | * CCI interconnect node |
| 22 | 15 | |
| 23 | 16 | Description: Describes a CCI cache coherent Interconnect component |
| @@ -50,10 +43,10 @@ specific to ARM. · 26 unmodified lines | ||
| 50 | 43 | as a tuple of cells, containing child address, |
| 51 | 44 | parent address and the size of the region in the |
| 52 | 45 | child address space. |
| 53 | − Definition: A standard property. Follow rules in the ePAPR for | |
| 54 | − hierarchical bus addressing. CCI interfaces | |
| 55 | − addresses refer to the parent node addressing | |
| 56 | − scheme to declare their register bases. | |
| 46 | + Definition: A standard property. Follow rules in the Devicetree | |
| 47 | + Specification for hierarchical bus addressing. CCI | |
| 48 | + interfaces addresses refer to the parent node | |
| 49 | + addressing scheme to declare their register bases. | |
| 57 | 50 | |
| 58 | 51 | CCI interconnect node can define the following child nodes: |
| 59 | 52 | |
| @@ -6,9 +6,9 @@ The device tree allows to describe the layout of CPUs in a system through · 5 unmodified lines | ||
| 6 | 6 | the "cpus" node, which in turn contains a number of subnodes (ie "cpu") |
| 7 | 7 | defining properties for every cpu. |
| 8 | 8 | |
| 9 | −Bindings for CPU nodes follow the ePAPR v1.1 standard, available from: | |
| 9 | +Bindings for CPU nodes follow the Devicetree Specification, available from: | |
| 10 | 10 | |
| 11 | −https://www.power.org/documentation/epapr-version-1-1/ | |
| 11 | +https://www.devicetree.org/specifications/ | |
| 12 | 12 | |
| 13 | 13 | with updates for 32-bit and 64-bit ARM systems provided in this document. |
| 14 | 14 | |
| @@ -16,8 +16,8 @@ with updates for 32-bit and 64-bit ARM systems provided in this document. · 1 unmodified line | ||
| 16 | 16 | Convention used in this document |
| 17 | 17 | ================================ |
| 18 | 18 | |
| 19 | −This document follows the conventions described in the ePAPR v1.1, with | |
| 20 | −the addition: | |
| 19 | +This document follows the conventions described in the Devicetree | |
| 20 | +Specification, with the addition: | |
| 21 | 21 | |
| 22 | 22 | - square brackets define bitfields, eg reg[7:0] value of the bitfield in |
| 23 | 23 | the reg property contained in bits 7 down to 0 |
| @@ -26,8 +26,9 @@ the addition: · 2 unmodified lines | ||
| 26 | 26 | cpus and cpu node bindings definition |
| 27 | 27 | ===================================== |
| 28 | 28 | |
| 29 | −The ARM architecture, in accordance with the ePAPR, requires the cpus and cpu | |
| 30 | −nodes to be present and contain the properties described below. | |
| 29 | +The ARM architecture, in accordance with the Devicetree Specification, | |
| 30 | +requires the cpus and cpu nodes to be present and contain the properties | |
| 31 | +described below. | |
| 31 | 32 | |
| 32 | 33 | - cpus node |
| 33 | 34 | |
| @@ -695,5 +695,5 @@ cpus { · 694 unmodified lines | ||
| 695 | 695 | [4] ARM Architecture Reference Manuals |
| 696 | 696 | http://infocenter.arm.com/help/index.jsp |
| 697 | 697 | |
| 698 | −[5] ePAPR standard | |
| 699 | − https://www.power.org/documentation/epapr-version-1-1/ | |
| 698 | +[5] Devicetree Specification | |
| 699 | + https://www.devicetree.org/specifications/ | |
| @@ -4,8 +4,8 @@ ARM cores often have a separate L2C210/L2C220/L2C310 (also known as PL210/PL220/ · 3 unmodified lines | ||
| 4 | 4 | PL310 and variants) based level 2 cache controller. All these various implementations |
| 5 | 5 | of the L2 cache controller have compatible programming models (Note 1). |
| 6 | 6 | Some of the properties that are just prefixed "cache-*" are taken from section |
| 7 | −3.7.3 of the ePAPR v1.1 specification which can be found at: | |
| 8 | −https://www.power.org/wp-content/uploads/2012/06/Power_ePAPR_APPROVED_v1.1.pdf | |
| 7 | +3.7.3 of the Devicetree Specification which can be found at: | |
| 8 | +https://www.devicetree.org/specifications/ | |
| 9 | 9 | |
| 10 | 10 | The ARM L2 cache representation in the device tree should be done as follows: |
| 11 | 11 | |
| @@ -29,9 +29,9 @@ corresponding to the system hierarchy; syntactically they are defined as device · 28 unmodified lines | ||
| 29 | 29 | tree nodes. |
| 30 | 30 | |
| 31 | 31 | The remainder of this document provides the topology bindings for ARM, based |
| 32 | −on the ePAPR standard, available from: | |
| 32 | +on the Devicetree Specification, available from: | |
| 33 | 33 | |
| 34 | −http://www.power.org/documentation/epapr-version-1-1/ | |
| 34 | +https://www.devicetree.org/specifications/ | |
| 35 | 35 | |
| 36 | 36 | If not stated otherwise, whenever a reference to a cpu node phandle is made its |
| 37 | 37 | value must point to a cpu node compliant with the cpu node bindings as |
| @@ -10,7 +10,7 @@ enabled for child devices connected to the bus (either on-SoC or externally) · 9 unmodified lines | ||
| 10 | 10 | to function. |
| 11 | 11 | |
| 12 | 12 | While "simple-pm-bus" follows the "simple-bus" set of properties, as specified |
| 13 | −in ePAPR, it is not an extension of "simple-bus". | |
| 13 | +in the Devicetree Specification, it is not an extension of "simple-bus". | |
| 14 | 14 | |
| 15 | 15 | |
| 16 | 16 | Required properties: |
| @@ -10,7 +10,8 @@ stdout-path property · 9 unmodified lines | ||
| 10 | 10 | -------------------- |
| 11 | 11 | |
| 12 | 12 | Device trees may specify the device to be used for boot console output |
| 13 | −with a stdout-path property under /chosen, as described in ePAPR, e.g. | |
| 13 | +with a stdout-path property under /chosen, as described in the Devicetree | |
| 14 | +Specification, e.g. | |
| 14 | 15 | |
| 15 | 16 | / { |
| 16 | 17 | chosen { |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | Common properties |
| 2 | 2 | |
| 3 | −The ePAPR specification does not define any properties related to hardware | |
| 3 | +The Devicetree Specification does not define any properties related to hardware | |
| 4 | 4 | byteswapping, but endianness issues show up frequently in porting Linux to |
| 5 | 5 | different machine types. This document attempts to provide a consistent |
| 6 | 6 | way of handling byteswapping across drivers. |
| @@ -118,8 +118,8 @@ PROPERTIES · 117 unmodified lines | ||
| 118 | 118 | Definition: A list of clock name strings in the same order as the |
| 119 | 119 | clocks property. |
| 120 | 120 | |
| 121 | − Note: All other standard properties (see the ePAPR) are allowed | |
| 122 | − but are optional. | |
| 121 | + Note: All other standard properties (see the Devicetree Specification) | |
| 122 | + are allowed but are optional. | |
| 123 | 123 | |
| 124 | 124 | |
| 125 | 125 | EXAMPLE |
| @@ -55,8 +55,8 @@ PROPERTIES · 54 unmodified lines | ||
| 55 | 55 | triplet that includes the child address, parent address, & |
| 56 | 56 | length. |
| 57 | 57 | |
| 58 | − Note: All other standard properties (see the ePAPR) are allowed | |
| 59 | − but are optional. | |
| 58 | + Note: All other standard properties (see the Devicetree Specification) | |
| 59 | + are allowed but are optional. | |
| 60 | 60 | |
| 61 | 61 | EXAMPLE |
| 62 | 62 | crypto@a0000 { |
| @@ -57,11 +57,11 @@ can be specified. · 56 unmodified lines | ||
| 57 | 57 | The parameters are defined as: |
| 58 | 58 | |
| 59 | 59 | +----------+-------------------------------------+----------+-------+ |
| 60 | − | | ↑ | | | | |
| 60 | + | | ^ | | | | |
| 61 | 61 | | | |vback_porch | | | |
| 62 | − | | ↓ | | | | |
| 62 | + | | v | | | | |
| 63 | 63 | +----------#######################################----------+-------+ |
| 64 | − | # ↑ # | | | |
| 64 | + | # ^ # | | | |
| 65 | 65 | | # | # | | |
| 66 | 66 | | hback # | # hfront | hsync | |
| 67 | 67 | | porch # | hactive # porch | len | |
| @@ -69,15 +69,15 @@ The parameters are defined as: · 1 unmodified line | ||
| 69 | 69 | | # | # | | |
| 70 | 70 | | # |vactive # | | |
| 71 | 71 | | # | # | | |
| 72 | − | # ↓ # | | | |
| 72 | + | # v # | | | |
| 73 | 73 | +----------#######################################----------+-------+ |
| 74 | − | | ↑ | | | | |
| 74 | + | | ^ | | | | |
| 75 | 75 | | | |vfront_porch | | | |
| 76 | − | | ↓ | | | | |
| 76 | + | | v | | | | |
| 77 | 77 | +----------+-------------------------------------+----------+-------+ |
| 78 | − | | ↑ | | | | |
| 78 | + | | ^ | | | | |
| 79 | 79 | | | |vsync_len | | | |
| 80 | − | | ↓ | | | | |
| 80 | + | | v | | | | |
| 81 | 81 | +----------+-------------------------------------+----------+-------+ |
| 82 | 82 | |
| 83 | 83 | Example: |
| @@ -34,7 +34,7 @@ remote device, an 'endpoint' child node must be provided for each link. · 33 unmodified lines | ||
| 34 | 34 | If more than one port is present in a device node or there is more than one |
| 35 | 35 | endpoint at a port, or a port node needs to be associated with a selected |
| 36 | 36 | hardware interface, a common scheme using '#address-cells', '#size-cells' |
| 37 | −and 'reg' properties is used number the nodes. | |
| 37 | +and 'reg' properties is used to number the nodes. | |
| 38 | 38 | |
| 39 | 39 | device { |
| 40 | 40 | ... |
| @@ -89,9 +89,9 @@ Links between endpoints · 48 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | Each endpoint should contain a 'remote-endpoint' phandle property that points |
| 91 | 91 | to the corresponding endpoint in the port of the remote device. In turn, the |
| 92 | −remote endpoint should contain a 'remote-endpoint' property. If it has one, | |
| 93 | −it must not point to another than the local endpoint. Two endpoints with their | |
| 94 | −'remote-endpoint' phandles pointing at each other form a link between the | |
| 92 | +remote endpoint should contain a 'remote-endpoint' property. If it has one, it | |
| 93 | +must not point to anything other than the local endpoint. Two endpoints with | |
| 94 | +their 'remote-endpoint' phandles pointing at each other form a link between the | |
| 95 | 95 | containing ports. |
| 96 | 96 | |
| 97 | 97 | device-1 { |
| @@ -110,13 +110,12 @@ device-2 { · 12 unmodified lines | ||
| 110 | 110 | }; |
| 111 | 111 | }; |
| 112 | 112 | |
| 113 | − | |
| 114 | 113 | Required properties |
| 115 | 114 | ------------------- |
| 116 | 115 | |
| 117 | 116 | If there is more than one 'port' or more than one 'endpoint' node or 'reg' |
| 118 | −property is present in port and/or endpoint nodes the following properties | |
| 119 | −are required in a relevant parent node: | |
| 117 | +property present in the port and/or endpoint nodes then the following | |
| 118 | +properties are required in a relevant parent node: | |
| 120 | 119 | |
| 121 | 120 | - #address-cells : number of cells required to define port/endpoint |
| 122 | 121 | identifier, should be 1. |
| @@ -3,6 +3,7 @@ Austrian Microsystems AS3935 Franklin lightning sensor device driver · 2 unmodified lines | ||
| 3 | 3 | Required properties: |
| 4 | 4 | - compatible: must be "ams,as3935" |
| 5 | 5 | - reg: SPI chip select number for the device |
| 6 | + - spi-max-frequency: specifies maximum SPI clock frequency | |
| 6 | 7 | - spi-cpha: SPI Mode 1. Refer to spi/spi-bus.txt for generic SPI |
| 7 | 8 | slave node bindings. |
| 8 | 9 | - interrupt-parent : should be the phandle for the interrupt controller |
| @@ -21,6 +22,7 @@ Example: · 12 unmodified lines | ||
| 21 | 22 | as3935@0 { |
| 22 | 23 | compatible = "ams,as3935"; |
| 23 | 24 | reg = <0>; |
| 25 | + spi-max-frequency = <400000>; | |
| 24 | 26 | spi-cpha; |
| 25 | 27 | interrupt-parent = <&gpio1>; |
| 26 | 28 | interrupts = <16 1>; |
| @@ -92,7 +92,6 @@ Example 2: · 91 unmodified lines | ||
| 92 | 92 | |
| 93 | 93 | * References |
| 94 | 94 | |
| 95 | −[1] Power.org (TM) Standard for Embedded Power Architecture (TM) Platform | |
| 96 | − Requirements (ePAPR), Version 1.0, July 2008. | |
| 97 | − (http://www.power.org/resources/downloads/Power_ePAPR_APPROVED_v1.0.pdf) | |
| 95 | +[1] Devicetree Specification | |
| 96 | + (https://www.devicetree.org/specifications/) | |
| 98 | 97 | |
| @@ -8,7 +8,8 @@ The following properties are common to the Ethernet controllers: · 7 unmodified lines | ||
| 8 | 8 | property; |
| 9 | 9 | - max-speed: number, specifies maximum speed in Mbit/s supported by the device; |
| 10 | 10 | - max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than |
| 11 | − the maximum frame size (there's contradiction in ePAPR). | |
| 11 | + the maximum frame size (there's contradiction in the Devicetree | |
| 12 | + Specification). | |
| 12 | 13 | - phy-mode: string, operation mode of the PHY interface. This is now a de-facto |
| 13 | 14 | standard property; supported values are: |
| 14 | 15 | * "internal" |
| @@ -35,9 +36,11 @@ The following properties are common to the Ethernet controllers: · 20 unmodified lines | ||
| 35 | 36 | * "rxaui" |
| 36 | 37 | * "xaui" |
| 37 | 38 | * "10gbase-kr" (10GBASE-KR, XFI, SFI) |
| 38 | −- phy-connection-type: the same as "phy-mode" property but described in ePAPR; | |
| 39 | +- phy-connection-type: the same as "phy-mode" property but described in the | |
| 40 | + Devicetree Specification; | |
| 39 | 41 | - phy-handle: phandle, specifies a reference to a node representing a PHY |
| 40 | − device; this property is described in ePAPR and so preferred; | |
| 42 | + device; this property is described in the Devicetree Specification and so | |
| 43 | + preferred; | |
| 41 | 44 | - phy: the same as "phy-handle" property, not recommended for new bindings. |
| 42 | 45 | - phy-device: the same as "phy-handle" property, not recommended for new |
| 43 | 46 | bindings. |
File renamed without changes.
| @@ -31,7 +31,7 @@ mmc3: mmc@01c12000 { · 30 unmodified lines | ||
| 31 | 31 | non-removable; |
| 32 | 32 | status = "okay"; |
| 33 | 33 | |
| 34 | − brcmf: bcrmf@1 { | |
| 34 | + brcmf: wifi@1 { | |
| 35 | 35 | reg = <1>; |
| 36 | 36 | compatible = "brcm,bcm4329-fmac"; |
| 37 | 37 | interrupt-parent = <&pio>; |
| @@ -3,10 +3,10 @@ Power Architecture CPU Binding · 2 unmodified lines | ||
| 3 | 3 | Copyright 2013 Freescale Semiconductor Inc. |
| 4 | 4 | |
| 5 | 5 | Power Architecture CPUs in Freescale SOCs are represented in device trees as |
| 6 | −per the definition in ePAPR. | |
| 6 | +per the definition in the Devicetree Specification. | |
| 7 | 7 | |
| 8 | −In addition to the ePAPR definitions, the properties defined below may be | |
| 9 | −present on CPU nodes. | |
| 8 | +In addition to the the Devicetree Specification definitions, the properties | |
| 9 | +defined below may be present on CPU nodes. | |
| 10 | 10 | |
| 11 | 11 | PROPERTIES |
| 12 | 12 | |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | Freescale L2 Cache Controller |
| 2 | 2 | |
| 3 | 3 | L2 cache is present in Freescale's QorIQ and QorIQ Qonverge platforms. |
| 4 | −The cache bindings explained below are ePAPR compliant | |
| 4 | +The cache bindings explained below are Devicetree Specification compliant | |
| 5 | 5 | |
| 6 | 6 | Required Properties: |
| 7 | 7 | |
| @@ -124,8 +124,8 @@ Port-Write Unit: · 123 unmodified lines | ||
| 124 | 124 | A single IRQ that handles port-write conditions is |
| 125 | 125 | specified by this property. (Typically shared with error). |
| 126 | 126 | |
| 127 | − Note: All other standard properties (see the ePAPR) are allowed | |
| 128 | − but are optional. | |
| 127 | + Note: All other standard properties (see the Devicetree Specification) | |
| 128 | + are allowed but are optional. | |
| 129 | 129 | |
| 130 | 130 | Example: |
| 131 | 131 | rmu: rmu@d3000 { |
| @@ -72,7 +72,8 @@ the following properties: · 71 unmodified lines | ||
| 72 | 72 | represents the LIODN associated with maintenance transactions |
| 73 | 73 | for the port. |
| 74 | 74 | |
| 75 | −Note: All other standard properties (see ePAPR) are allowed but are optional. | |
| 75 | +Note: All other standard properties (see the Devicetree Specification) | |
| 76 | +are allowed but are optional. | |
| 76 | 77 | |
| 77 | 78 | Example: |
| 78 | 79 | |
File renamed without changes.
| @@ -92,6 +92,8 @@ Required properties: · 91 unmodified lines | ||
| 92 | 92 | parent's address space |
| 93 | 93 | - clocks: Clock IDs array as required by the controller. |
| 94 | 94 | - clock-names: names of clocks correseponding to IDs in the clock property |
| 95 | + - vdd10-supply: 1.0V powr supply | |
| 96 | + - vdd33-supply: 3.0V/3.3V power supply | |
| 95 | 97 | |
| 96 | 98 | Sub-nodes: |
| 97 | 99 | The dwc3 core should be added as subnode to Exynos dwc3 glue. |
| @@ -107,6 +109,8 @@ Example: · 9 unmodified lines | ||
| 107 | 109 | #address-cells = <1>; |
| 108 | 110 | #size-cells = <1>; |
| 109 | 111 | ranges; |
| 112 | + vdd10-supply = <&ldo11_reg>; | |
| 113 | + vdd33-supply = <&ldo9_reg>; | |
| 110 | 114 | |
| 111 | 115 | dwc3 { |
| 112 | 116 | compatible = "synopsys,dwc3"; |
| @@ -45,6 +45,7 @@ avia avia semiconductor · 44 unmodified lines | ||
| 45 | 45 | avic Shanghai AVIC Optoelectronics Co., Ltd. |
| 46 | 46 | axentia Axentia Technologies AB |
| 47 | 47 | axis Axis Communications AB |
| 48 | +bananapi BIPAI KEJI LIMITED | |
| 48 | 49 | boe BOE Technology Group Co., Ltd. |
| 49 | 50 | bosch Bosch Sensortec GmbH |
| 50 | 51 | boundary Boundary Devices Inc. |
| @@ -159,6 +160,8 @@ iom Iomega Corporation · 108 unmodified lines | ||
| 159 | 160 | isee ISEE 2007 S.L. |
| 160 | 161 | isil Intersil |
| 161 | 162 | issi Integrated Silicon Solutions Inc. |
| 163 | +itead ITEAD Intelligent Systems Co.Ltd | |
| 164 | +iwave iWave Systems Technologies Pvt. Ltd. | |
| 162 | 165 | jdi Japan Display Inc. |
| 163 | 166 | jedec JEDEC Solid State Technology Association |
| 164 | 167 | karo Ka-Ro electronics GmbH |
| @@ -177,6 +180,7 @@ lg LG Corporation · 12 unmodified lines | ||
| 177 | 180 | libretech Shenzhen Libre Technology Co., Ltd |
| 178 | 181 | licheepi Lichee Pi |
| 179 | 182 | linaro Linaro Limited |
| 183 | +linksys Belkin International, Inc. (Linksys) | |
| 180 | 184 | linux Linux-specific binding |
| 181 | 185 | lltc Linear Technology Corporation |
| 182 | 186 | lsi LSI Corp. (LSI Logic) |
| @@ -269,8 +273,10 @@ renesas Renesas Electronics Corporation · 86 unmodified lines | ||
| 269 | 273 | richtek Richtek Technology Corporation |
| 270 | 274 | ricoh Ricoh Co. Ltd. |
| 271 | 275 | rikomagic Rikomagic Tech Corp. Ltd |
| 276 | +riscv RISC-V Foundation | |
| 272 | 277 | rockchip Fuzhou Rockchip Electronics Co., Ltd |
| 273 | 278 | rohm ROHM Semiconductor Co., Ltd |
| 279 | +roofull Shenzhen Roofull Technology Co, Ltd | |
| 274 | 280 | samsung Samsung Semiconductor |
| 275 | 281 | samtec Samtec/Softing company |
| 276 | 282 | sandisk Sandisk Corporation |
| @@ -1413,7 +1413,7 @@ Optional property: · 1412 unmodified lines | ||
| 1413 | 1413 | from DMA operations originating from the bus. It provides a means of |
| 1414 | 1414 | defining a mapping or translation between the physical address space of |
| 1415 | 1415 | the bus and the physical address space of the parent of the bus. |
| 1416 | − (for more information see ePAPR specification) | |
| 1416 | + (for more information see the Devicetree Specification) | |
| 1417 | 1417 | |
| 1418 | 1418 | * DMA Bus child |
| 1419 | 1419 | Optional property: |
| @@ -3,8 +3,7 @@ Device Tree Overlay Notes · 2 unmodified lines | ||
| 3 | 3 | |
| 4 | 4 | This document describes the implementation of the in-kernel |
| 5 | 5 | device tree overlay functionality residing in drivers/of/overlay.c and is a |
| 6 | −companion document to Documentation/devicetree/dt-object-internal.txt[1] & | |
| 7 | −Documentation/devicetree/dynamic-resolution-notes.txt[2] | |
| 6 | +companion document to Documentation/devicetree/dynamic-resolution-notes.txt[1] | |
| 8 | 7 | |
| 9 | 8 | How overlays work |
| 10 | 9 | ----------------- |
| @@ -16,8 +15,7 @@ Since the kernel mainly deals with devices, any new device node that result · 5 unmodified lines | ||
| 16 | 15 | in an active device should have it created while if the device node is either |
| 17 | 16 | disabled or removed all together, the affected device should be deregistered. |
| 18 | 17 | |
| 19 | −Lets take an example where we have a foo board with the following base tree | |
| 20 | −which is taken from [1]. | |
| 18 | +Lets take an example where we have a foo board with the following base tree: | |
| 21 | 19 | |
| 22 | 20 | ---- foo.dts ----------------------------------------------------------------- |
| 23 | 21 | /* FOO platform */ |
| @@ -36,7 +34,7 @@ which is taken from [1]. · 12 unmodified lines | ||
| 36 | 34 | }; |
| 37 | 35 | ---- foo.dts ----------------------------------------------------------------- |
| 38 | 36 | |
| 39 | −The overlay bar.dts, when loaded (and resolved as described in [2]) should | |
| 37 | +The overlay bar.dts, when loaded (and resolved as described in [1]) should | |
| 40 | 38 | |
| 41 | 39 | ---- bar.dts ----------------------------------------------------------------- |
| 42 | 40 | /plugin/; /* allow undefined label references and record them */ |
| @@ -387,7 +387,7 @@ static void __init harmony_init_machine(void) · 386 unmodified lines | ||
| 387 | 387 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
| 388 | 388 | } |
| 389 | 389 | |
| 390 | −"simple-bus" is defined in the ePAPR 1.0 specification as a property | |
| 390 | +"simple-bus" is defined in the Devicetree Specification as a property | |
| 391 | 391 | meaning a simple memory mapped bus, so the of_platform_populate() code |
| 392 | 392 | could be written to just assume simple-bus compatible nodes will |
| 393 | 393 | always be traversed. However, we pass it in as an argument so that |
| @@ -275,6 +275,42 @@ struct va_format: · 274 unmodified lines | ||
| 275 | 275 | |
| 276 | 276 | Passed by reference. |
| 277 | 277 | |
| 278 | +kobjects: | |
| 279 | + %pO | |
| 280 | + | |
| 281 | + Base specifier for kobject based structs. Must be followed with | |
| 282 | + character for specific type of kobject as listed below: | |
| 283 | + | |
| 284 | + Device tree nodes: | |
| 285 | + | |
| 286 | + %pOF[fnpPcCF] | |
| 287 | + | |
| 288 | + For printing device tree nodes. The optional arguments are: | |
| 289 | + f device node full_name | |
| 290 | + n device node name | |
| 291 | + p device node phandle | |
| 292 | + P device node path spec (name + @unit) | |
| 293 | + F device node flags | |
| 294 | + c major compatible string | |
| 295 | + C full compatible string | |
| 296 | + Without any arguments prints full_name (same as %pOFf) | |
| 297 | + The separator when using multiple arguments is ':' | |
| 298 | + | |
| 299 | + Examples: | |
| 300 | + | |
| 301 | + %pOF /foo/bar@0 - Node full name | |
| 302 | + %pOFf /foo/bar@0 - Same as above | |
| 303 | + %pOFfp /foo/bar@0:10 - Node full name + phandle | |
| 304 | + %pOFfcF /foo/bar@0:foo,device:--P- - Node full name + | |
| 305 | + major compatible string + | |
| 306 | + node flags | |
| 307 | + D - dynamic | |
| 308 | + d - detached | |
| 309 | + P - Populated | |
| 310 | + B - Populated bus | |
| 311 | + | |
| 312 | + Passed by reference. | |
| 313 | + | |
| 278 | 314 | struct clk: |
| 279 | 315 | |
| 280 | 316 | %pC pll1 |
| @@ -41,9 +41,9 @@ The scheme below assumes that the kernel is loaded below 0x40000000. · 40 unmodified lines | ||
| 41 | 41 | 00..1F -> 00 -> 00 -> 00 |
| 42 | 42 | |
| 43 | 43 | The default location of IO peripherals is above 0xf0000000. This may be changed |
| 44 | −using a "ranges" property in a device tree simple-bus node. See ePAPR 1.1, §6.5 | |
| 45 | −for details on the syntax and semantic of simple-bus nodes. The following | |
| 46 | −limitations apply: | |
| 44 | +using a "ranges" property in a device tree simple-bus node. See the Devicetree | |
| 45 | +Specification, section 4.5 for details on the syntax and semantics of | |
| 46 | +simple-bus nodes. The following limitations apply: | |
| 47 | 47 | |
| 48 | 48 | 1. Only top level simple-bus nodes are considered |
| 49 | 49 | |
| @@ -9664,6 +9664,7 @@ S: Maintained · 9663 unmodified lines | ||
| 9664 | 9664 | F: drivers/of/ |
| 9665 | 9665 | F: include/linux/of*.h |
| 9666 | 9666 | F: scripts/dtc/ |
| 9667 | +F: Documentation/ABI/testing/sysfs-firmware-ofw | |
| 9667 | 9668 | |
| 9668 | 9669 | OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS |
| 9669 | 9670 | M: Rob Herring <robh+dt@kernel.org> |
| @@ -1,4 +1,4 @@ | ||
| 1 | −obj-y = base.o device.o platform.o | |
| 1 | +obj-y = base.o device.o platform.o property.o | |
| 2 | 2 | obj-$(CONFIG_OF_DYNAMIC) += dynamic.o |
| 3 | 3 | obj-$(CONFIG_OF_FLATTREE) += fdt.o |
| 4 | 4 | obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o |
| @@ -710,7 +710,7 @@ static int __of_address_to_resource(struct device_node *dev, · 709 unmodified lines | ||
| 710 | 710 | * |
| 711 | 711 | * Note that if your address is a PIO address, the conversion will fail if |
| 712 | 712 | * the physical address can't be internally converted to an IO token with |
| 713 | − * pci_address_to_pio(), that is because it's either called to early or it | |
| 713 | + * pci_address_to_pio(), that is because it's either called too early or it | |
| 714 | 714 | * can't be matched to any host bridge IO space |
| 715 | 715 | */ |
| 716 | 716 | int of_address_to_resource(struct device_node *dev, int index, |
| @@ -155,7 +155,7 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp) · 154 unmodified lines | ||
| 155 | 155 | |
| 156 | 156 | sysfs_bin_attr_init(&pp->attr); |
| 157 | 157 | pp->attr.attr.name = safe_name(&np->kobj, pp->name); |
| 158 | − pp->attr.attr.mode = secure ? S_IRUSR : S_IRUGO; | |
| 158 | + pp->attr.attr.mode = secure ? 0400 : 0444; | |
| 159 | 159 | pp->attr.size = secure ? 0 : pp->length; |
| 160 | 160 | pp->attr.read = of_node_property_read; |
| 161 | 161 | |
| @@ -773,16 +773,31 @@ static struct device_node *__of_find_node_by_path(struct device_node *parent, · 611 unmodified lines | ||
| 773 | 773 | return NULL; |
| 774 | 774 | |
| 775 | 775 | __for_each_child_of_node(parent, child) { |
| 776 | − const char *name = strrchr(child->full_name, '/'); | |
| 777 | − if (WARN(!name, "malformed device_node %s\n", child->full_name)) | |
| 778 | − continue; | |
| 779 | − name++; | |
| 776 | + const char *name = kbasename(child->full_name); | |
| 780 | 777 | if (strncmp(path, name, len) == 0 && (strlen(name) == len)) |
| 781 | 778 | return child; |
| 782 | 779 | } |
| 783 | 780 | return NULL; |
| 784 | 781 | } |
| 785 | 782 | |
| 783 | +struct device_node *__of_find_node_by_full_path(struct device_node *node, | |
| 784 | + const char *path) | |
| 785 | +{ | |
| 786 | + const char *separator = strchr(path, ':'); | |
| 787 | + | |
| 788 | + while (node && *path == '/') { | |
| 789 | + struct device_node *tmp = node; | |
| 790 | + | |
| 791 | + path++; /* Increment past '/' delimiter */ | |
| 792 | + node = __of_find_node_by_path(node, path); | |
| 793 | + of_node_put(tmp); | |
| 794 | + path = strchrnul(path, '/'); | |
| 795 | + if (separator && separator < path) | |
| 796 | + break; | |
| 797 | + } | |
| 798 | + return node; | |
| 799 | +} | |
| 800 | + | |
| 786 | 801 | /** |
| 787 | 802 | * of_find_node_opts_by_path - Find a node matching a full OF path |
| 788 | 803 | * @path: Either the full path to match, or if the path does not |
| @@ -842,16 +857,7 @@ struct device_node *of_find_node_opts_by_path(const char *path, const char **opt · 53 unmodified lines | ||
| 842 | 857 | raw_spin_lock_irqsave(&devtree_lock, flags); |
| 843 | 858 | if (!np) |
| 844 | 859 | np = of_node_get(of_root); |
| 845 | − while (np && *path == '/') { | |
| 846 | − struct device_node *tmp = np; | |
| 847 | − | |
| 848 | − path++; /* Increment past '/' delimiter */ | |
| 849 | − np = __of_find_node_by_path(np, path); | |
| 850 | − of_node_put(tmp); | |
| 851 | − path = strchrnul(path, '/'); | |
| 852 | − if (separator && separator < path) | |
| 853 | − break; | |
| 854 | − } | |
| 860 | + np = __of_find_node_by_full_path(np, path); | |
| 855 | 861 | raw_spin_unlock_irqrestore(&devtree_lock, flags); |
| 856 | 862 | return np; |
| 857 | 863 | } |
| @@ -1113,458 +1119,6 @@ struct device_node *of_find_node_by_phandle(phandle handle) · 255 unmodified lines | ||
| 1113 | 1119 | } |
| 1114 | 1120 | EXPORT_SYMBOL(of_find_node_by_phandle); |
| 1115 | 1121 | |
| 1116 | −/** | |
| 1117 | − * of_property_count_elems_of_size - Count the number of elements in a property | |
| 1118 | − * | |
| 1119 | − * @np: device node from which the property value is to be read. | |
| 1120 | − * @propname: name of the property to be searched. | |
| 1121 | − * @elem_size: size of the individual element | |
| 1122 | − * | |
| 1123 | − * Search for a property in a device node and count the number of elements of | |
| 1124 | − * size elem_size in it. Returns number of elements on sucess, -EINVAL if the | |
| 1125 | − * property does not exist or its length does not match a multiple of elem_size | |
| 1126 | − * and -ENODATA if the property does not have a value. | |
| 1127 | − */ | |
| 1128 | −int of_property_count_elems_of_size(const struct device_node *np, | |
| 1129 | − const char *propname, int elem_size) | |
| 1130 | −{ | |
| 1131 | − struct property *prop = of_find_property(np, propname, NULL); | |
| 1132 | − | |
| 1133 | − if (!prop) | |
| 1134 | − return -EINVAL; | |
| 1135 | − if (!prop->value) | |
| 1136 | − return -ENODATA; | |
| 1137 | − | |
| 1138 | − if (prop->length % elem_size != 0) { | |
| 1139 | − pr_err("size of %s in node %s is not a multiple of %d\n", | |
| 1140 | − propname, np->full_name, elem_size); | |
| 1141 | − return -EINVAL; | |
| 1142 | − } | |
| 1143 | − | |
| 1144 | − return prop->length / elem_size; | |
| 1145 | −} | |
| 1146 | −EXPORT_SYMBOL_GPL(of_property_count_elems_of_size); | |
| 1147 | − | |
| 1148 | −/** | |
| 1149 | − * of_find_property_value_of_size | |
| 1150 | − * | |
| 1151 | − * @np: device node from which the property value is to be read. | |
| 1152 | − * @propname: name of the property to be searched. | |
| 1153 | − * @min: minimum allowed length of property value | |
| 1154 | − * @max: maximum allowed length of property value (0 means unlimited) | |
| 1155 | − * @len: if !=NULL, actual length is written to here | |
| 1156 | − * | |
| 1157 | − * Search for a property in a device node and valid the requested size. | |
| 1158 | − * Returns the property value on success, -EINVAL if the property does not | |
| 1159 | − * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the | |
| 1160 | − * property data is too small or too large. | |
| 1161 | − * | |
| 1162 | − */ | |
| 1163 | −static void *of_find_property_value_of_size(const struct device_node *np, | |
| 1164 | − const char *propname, u32 min, u32 max, size_t *len) | |
| 1165 | −{ | |
| 1166 | − struct property *prop = of_find_property(np, propname, NULL); | |
| 1167 | − | |
| 1168 | − if (!prop) | |
| 1169 | − return ERR_PTR(-EINVAL); | |
| 1170 | − if (!prop->value) | |
| 1171 | − return ERR_PTR(-ENODATA); | |
| 1172 | − if (prop->length < min) | |
| 1173 | − return ERR_PTR(-EOVERFLOW); | |
| 1174 | − if (max && prop->length > max) | |
| 1175 | − return ERR_PTR(-EOVERFLOW); | |
| 1176 | − | |
| 1177 | − if (len) | |
| 1178 | − *len = prop->length; | |
| 1179 | − | |
| 1180 | − return prop->value; | |
| 1181 | −} | |
| 1182 | − | |
| 1183 | −/** | |
| 1184 | − * of_property_read_u32_index - Find and read a u32 from a multi-value property. | |
| 1185 | − * | |
| 1186 | − * @np: device node from which the property value is to be read. | |
| 1187 | − * @propname: name of the property to be searched. | |
| 1188 | − * @index: index of the u32 in the list of values | |
| 1189 | − * @out_value: pointer to return value, modified only if no error. | |
| 1190 | − * | |
| 1191 | − * Search for a property in a device node and read nth 32-bit value from | |
| 1192 | − * it. Returns 0 on success, -EINVAL if the property does not exist, | |
| 1193 | − * -ENODATA if property does not have a value, and -EOVERFLOW if the | |
| 1194 | − * property data isn't large enough. | |
| 1195 | − * | |
| 1196 | − * The out_value is modified only if a valid u32 value can be decoded. | |
| 1197 | − */ | |
| 1198 | −int of_property_read_u32_index(const struct device_node *np, | |
| 1199 | − const char *propname, | |
| 1200 | − u32 index, u32 *out_value) | |
| 1201 | −{ | |
| 1202 | − const u32 *val = of_find_property_value_of_size(np, propname, | |
| 1203 | − ((index + 1) * sizeof(*out_value)), | |
| 1204 | − 0, | |
| 1205 | − NULL); | |
| 1206 | − | |
| 1207 | − if (IS_ERR(val)) | |
| 1208 | − return PTR_ERR(val); | |
| 1209 | − | |
| 1210 | − *out_value = be32_to_cpup(((__be32 *)val) + index); | |
| 1211 | − return 0; | |
| 1212 | −} | |
| 1213 | −EXPORT_SYMBOL_GPL(of_property_read_u32_index); | |
| 1214 | − | |
| 1215 | −/** | |
| 1216 | − * of_property_read_u64_index - Find and read a u64 from a multi-value property. | |
| 1217 | − * | |
| 1218 | − * @np: device node from which the property value is to be read. | |
| 1219 | − * @propname: name of the property to be searched. | |
| 1220 | − * @index: index of the u64 in the list of values | |
| 1221 | − * @out_value: pointer to return value, modified only if no error. | |
| 1222 | − * | |
| 1223 | − * Search for a property in a device node and read nth 64-bit value from | |
| 1224 | − * it. Returns 0 on success, -EINVAL if the property does not exist, | |
| 1225 | − * -ENODATA if property does not have a value, and -EOVERFLOW if the | |
| 1226 | − * property data isn't large enough. | |
| 1227 | − * | |
| 1228 | − * The out_value is modified only if a valid u64 value can be decoded. | |
| 1229 | − */ | |
| 1230 | −int of_property_read_u64_index(const struct device_node *np, | |
| 1231 | − const char *propname, | |
| 1232 | − u32 index, u64 *out_value) | |
| 1233 | −{ | |
| 1234 | − const u64 *val = of_find_property_value_of_size(np, propname, | |
| 1235 | − ((index + 1) * sizeof(*out_value)), | |
| 1236 | − 0, NULL); | |
| 1237 | − | |
| 1238 | − if (IS_ERR(val)) | |
| 1239 | − return PTR_ERR(val); | |
| 1240 | − | |
| 1241 | − *out_value = be64_to_cpup(((__be64 *)val) + index); | |
| 1242 | − return 0; | |
| 1243 | −} | |
| 1244 | −EXPORT_SYMBOL_GPL(of_property_read_u64_index); | |
| 1245 | − | |
| 1246 | −/** | |
| 1247 | − * of_property_read_variable_u8_array - Find and read an array of u8 from a | |
| 1248 | − * property, with bounds on the minimum and maximum array size. | |
| 1249 | − * | |
| 1250 | − * @np: device node from which the property value is to be read. | |
| 1251 | − * @propname: name of the property to be searched. | |
| 1252 | − * @out_values: pointer to return value, modified only if return value is 0. | |
| 1253 | − * @sz_min: minimum number of array elements to read | |
| 1254 | − * @sz_max: maximum number of array elements to read, if zero there is no | |
| 1255 | − * upper limit on the number of elements in the dts entry but only | |
| 1256 | − * sz_min will be read. | |
| 1257 | − * | |
| 1258 | − * Search for a property in a device node and read 8-bit value(s) from | |
| 1259 | − * it. Returns number of elements read on success, -EINVAL if the property | |
| 1260 | − * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | |
| 1261 | − * if the property data is smaller than sz_min or longer than sz_max. | |
| 1262 | − * | |
| 1263 | − * dts entry of array should be like: | |
| 1264 | − * property = /bits/ 8 <0x50 0x60 0x70>; | |
| 1265 | − * | |
| 1266 | − * The out_values is modified only if a valid u8 value can be decoded. | |
| 1267 | − */ | |
| 1268 | −int of_property_read_variable_u8_array(const struct device_node *np, | |
| 1269 | − const char *propname, u8 *out_values, | |
| 1270 | − size_t sz_min, size_t sz_max) | |
| 1271 | −{ | |
| 1272 | − size_t sz, count; | |
| 1273 | − const u8 *val = of_find_property_value_of_size(np, propname, | |
| 1274 | − (sz_min * sizeof(*out_values)), | |
| 1275 | − (sz_max * sizeof(*out_values)), | |
| 1276 | − &sz); | |
| 1277 | − | |
| 1278 | − if (IS_ERR(val)) | |
| 1279 | − return PTR_ERR(val); | |
| 1280 | − | |
| 1281 | − if (!sz_max) | |
| 1282 | − sz = sz_min; | |
| 1283 | − else | |
| 1284 | − sz /= sizeof(*out_values); | |
| 1285 | − | |
| 1286 | − count = sz; | |
| 1287 | − while (count--) | |
| 1288 | − *out_values++ = *val++; | |
| 1289 | − | |
| 1290 | − return sz; | |
| 1291 | −} | |
| 1292 | −EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array); | |
| 1293 | − | |
| 1294 | −/** | |
| 1295 | − * of_property_read_variable_u16_array - Find and read an array of u16 from a | |
| 1296 | − * property, with bounds on the minimum and maximum array size. | |
| 1297 | − * | |
| 1298 | − * @np: device node from which the property value is to be read. | |
| 1299 | − * @propname: name of the property to be searched. | |
| 1300 | − * @out_values: pointer to return value, modified only if return value is 0. | |
| 1301 | − * @sz_min: minimum number of array elements to read | |
| 1302 | − * @sz_max: maximum number of array elements to read, if zero there is no | |
| 1303 | − * upper limit on the number of elements in the dts entry but only | |
| 1304 | − * sz_min will be read. | |
| 1305 | − * | |
| 1306 | − * Search for a property in a device node and read 16-bit value(s) from | |
| 1307 | − * it. Returns number of elements read on success, -EINVAL if the property | |
| 1308 | − * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | |
| 1309 | − * if the property data is smaller than sz_min or longer than sz_max. | |
| 1310 | − * | |
| 1311 | − * dts entry of array should be like: | |
| 1312 | − * property = /bits/ 16 <0x5000 0x6000 0x7000>; | |
| 1313 | − * | |
| 1314 | − * The out_values is modified only if a valid u16 value can be decoded. | |
| 1315 | − */ | |
| 1316 | −int of_property_read_variable_u16_array(const struct device_node *np, | |
| 1317 | − const char *propname, u16 *out_values, | |
| 1318 | − size_t sz_min, size_t sz_max) | |
| 1319 | −{ | |
| 1320 | − size_t sz, count; | |
| 1321 | − const __be16 *val = of_find_property_value_of_size(np, propname, | |
| 1322 | − (sz_min * sizeof(*out_values)), | |
| 1323 | − (sz_max * sizeof(*out_values)), | |
| 1324 | − &sz); | |
| 1325 | − | |
| 1326 | − if (IS_ERR(val)) | |
| 1327 | − return PTR_ERR(val); | |
| 1328 | − | |
| 1329 | − if (!sz_max) | |
| 1330 | − sz = sz_min; | |
| 1331 | − else | |
| 1332 | − sz /= sizeof(*out_values); | |
| 1333 | − | |
| 1334 | − count = sz; | |
| 1335 | − while (count--) | |
| 1336 | − *out_values++ = be16_to_cpup(val++); | |
| 1337 | − | |
| 1338 | − return sz; | |
| 1339 | −} | |
| 1340 | −EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array); | |
| 1341 | − | |
| 1342 | −/** | |
| 1343 | − * of_property_read_variable_u32_array - Find and read an array of 32 bit | |
| 1344 | − * integers from a property, with bounds on the minimum and maximum array size. | |
| 1345 | − * | |
| 1346 | − * @np: device node from which the property value is to be read. | |
| 1347 | − * @propname: name of the property to be searched. | |
| 1348 | − * @out_values: pointer to return value, modified only if return value is 0. | |
| 1349 | − * @sz_min: minimum number of array elements to read | |
| 1350 | − * @sz_max: maximum number of array elements to read, if zero there is no | |
| 1351 | − * upper limit on the number of elements in the dts entry but only | |
| 1352 | − * sz_min will be read. | |
| 1353 | − * | |
| 1354 | − * Search for a property in a device node and read 32-bit value(s) from | |
| 1355 | − * it. Returns number of elements read on success, -EINVAL if the property | |
| 1356 | − * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | |
| 1357 | − * if the property data is smaller than sz_min or longer than sz_max. | |
| 1358 | − * | |
| 1359 | − * The out_values is modified only if a valid u32 value can be decoded. | |
| 1360 | − */ | |
| 1361 | −int of_property_read_variable_u32_array(const struct device_node *np, | |
| 1362 | − const char *propname, u32 *out_values, | |
| 1363 | − size_t sz_min, size_t sz_max) | |
| 1364 | −{ | |
| 1365 | − size_t sz, count; | |
| 1366 | − const __be32 *val = of_find_property_value_of_size(np, propname, | |
| 1367 | − (sz_min * sizeof(*out_values)), | |
| 1368 | − (sz_max * sizeof(*out_values)), | |
| 1369 | − &sz); | |
| 1370 | − | |
| 1371 | − if (IS_ERR(val)) | |
| 1372 | − return PTR_ERR(val); | |
| 1373 | − | |
| 1374 | − if (!sz_max) | |
| 1375 | − sz = sz_min; | |
| 1376 | − else | |
| 1377 | − sz /= sizeof(*out_values); | |
| 1378 | − | |
| 1379 | − count = sz; | |
| 1380 | − while (count--) | |
| 1381 | − *out_values++ = be32_to_cpup(val++); | |
| 1382 | − | |
| 1383 | − return sz; | |
| 1384 | −} | |
| 1385 | −EXPORT_SYMBOL_GPL(of_property_read_variable_u32_array); | |
| 1386 | − | |
| 1387 | −/** | |
| 1388 | − * of_property_read_u64 - Find and read a 64 bit integer from a property | |
| 1389 | − * @np: device node from which the property value is to be read. | |
| 1390 | − * @propname: name of the property to be searched. | |
| 1391 | − * @out_value: pointer to return value, modified only if return value is 0. | |
| 1392 | − * | |
| 1393 | − * Search for a property in a device node and read a 64-bit value from | |
| 1394 | − * it. Returns 0 on success, -EINVAL if the property does not exist, | |
| 1395 | − * -ENODATA if property does not have a value, and -EOVERFLOW if the | |
| 1396 | − * property data isn't large enough. | |
| 1397 | − * | |
| 1398 | − * The out_value is modified only if a valid u64 value can be decoded. | |
| 1399 | − */ | |
| 1400 | −int of_property_read_u64(const struct device_node *np, const char *propname, | |
| 1401 | − u64 *out_value) | |
| 1402 | −{ | |
| 1403 | − const __be32 *val = of_find_property_value_of_size(np, propname, | |
| 1404 | − sizeof(*out_value), | |
| 1405 | − 0, | |
| 1406 | − NULL); | |
| 1407 | − | |
| 1408 | − if (IS_ERR(val)) | |
| 1409 | − return PTR_ERR(val); | |
| 1410 | − | |
| 1411 | − *out_value = of_read_number(val, 2); | |
| 1412 | − return 0; | |
| 1413 | −} | |
| 1414 | −EXPORT_SYMBOL_GPL(of_property_read_u64); | |
| 1415 | − | |
| 1416 | −/** | |
| 1417 | − * of_property_read_variable_u64_array - Find and read an array of 64 bit | |
| 1418 | − * integers from a property, with bounds on the minimum and maximum array size. | |
| 1419 | − * | |
| 1420 | − * @np: device node from which the property value is to be read. | |
| 1421 | − * @propname: name of the property to be searched. | |
| 1422 | − * @out_values: pointer to return value, modified only if return value is 0. | |
| 1423 | − * @sz_min: minimum number of array elements to read | |
| 1424 | − * @sz_max: maximum number of array elements to read, if zero there is no | |
| 1425 | − * upper limit on the number of elements in the dts entry but only | |
| 1426 | − * sz_min will be read. | |
| 1427 | − * | |
| 1428 | − * Search for a property in a device node and read 64-bit value(s) from | |
| 1429 | − * it. Returns number of elements read on success, -EINVAL if the property | |
| 1430 | − * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | |
| 1431 | − * if the property data is smaller than sz_min or longer than sz_max. | |
| 1432 | − * | |
| 1433 | − * The out_values is modified only if a valid u64 value can be decoded. | |
| 1434 | − */ | |
| 1435 | −int of_property_read_variable_u64_array(const struct device_node *np, | |
| 1436 | − const char *propname, u64 *out_values, | |
| 1437 | − size_t sz_min, size_t sz_max) | |
| 1438 | −{ | |
| 1439 | − size_t sz, count; | |
| 1440 | − const __be32 *val = of_find_property_value_of_size(np, propname, | |
| 1441 | − (sz_min * sizeof(*out_values)), | |
| 1442 | − (sz_max * sizeof(*out_values)), | |
| 1443 | − &sz); | |
| 1444 | − | |
| 1445 | − if (IS_ERR(val)) | |
| 1446 | − return PTR_ERR(val); | |
| 1447 | − | |
| 1448 | − if (!sz_max) | |
| 1449 | − sz = sz_min; | |
| 1450 | − else | |
| 1451 | − sz /= sizeof(*out_values); | |
| 1452 | − | |
| 1453 | − count = sz; | |
| 1454 | − while (count--) { | |
| 1455 | − *out_values++ = of_read_number(val, 2); | |
| 1456 | − val += 2; | |
| 1457 | − } | |
| 1458 | − | |
| 1459 | − return sz; | |
| 1460 | −} | |
| 1461 | −EXPORT_SYMBOL_GPL(of_property_read_variable_u64_array); | |
| 1462 | − | |
| 1463 | −/** | |
| 1464 | − * of_property_read_string - Find and read a string from a property | |
| 1465 | − * @np: device node from which the property value is to be read. | |
| 1466 | − * @propname: name of the property to be searched. | |
| 1467 | − * @out_string: pointer to null terminated return string, modified only if | |
| 1468 | − * return value is 0. | |
| 1469 | − * | |
| 1470 | − * Search for a property in a device tree node and retrieve a null | |
| 1471 | − * terminated string value (pointer to data, not a copy). Returns 0 on | |
| 1472 | − * success, -EINVAL if the property does not exist, -ENODATA if property | |
| 1473 | − * does not have a value, and -EILSEQ if the string is not null-terminated | |
| 1474 | − * within the length of the property data. | |
| 1475 | − * | |
| 1476 | − * The out_string pointer is modified only if a valid string can be decoded. | |
| 1477 | − */ | |
| 1478 | −int of_property_read_string(const struct device_node *np, const char *propname, | |
| 1479 | − const char **out_string) | |
| 1480 | −{ | |
| 1481 | − const struct property *prop = of_find_property(np, propname, NULL); | |
| 1482 | − if (!prop) | |
| 1483 | − return -EINVAL; | |
| 1484 | − if (!prop->value) | |
| 1485 | − return -ENODATA; | |
| 1486 | − if (strnlen(prop->value, prop->length) >= prop->length) | |
| 1487 | − return -EILSEQ; | |
| 1488 | − *out_string = prop->value; | |
| 1489 | − return 0; | |
| 1490 | −} | |
| 1491 | −EXPORT_SYMBOL_GPL(of_property_read_string); | |
| 1492 | − | |
| 1493 | −/** | |
| 1494 | − * of_property_match_string() - Find string in a list and return index | |
| 1495 | − * @np: pointer to node containing string list property | |
| 1496 | − * @propname: string list property name | |
| 1497 | − * @string: pointer to string to search for in string list | |
| 1498 | − * | |
| 1499 | − * This function searches a string list property and returns the index | |
| 1500 | − * of a specific string value. | |
| 1501 | − */ | |
| 1502 | −int of_property_match_string(const struct device_node *np, const char *propname, | |
| 1503 | − const char *string) | |
| 1504 | −{ | |
| 1505 | − const struct property *prop = of_find_property(np, propname, NULL); | |
| 1506 | − size_t l; | |
| 1507 | − int i; | |
| 1508 | − const char *p, *end; | |
| 1509 | − | |
| 1510 | − if (!prop) | |
| 1511 | − return -EINVAL; | |
| 1512 | − if (!prop->value) | |
| 1513 | − return -ENODATA; | |
| 1514 | − | |
| 1515 | − p = prop->value; | |
| 1516 | − end = p + prop->length; | |
| 1517 | − | |
| 1518 | − for (i = 0; p < end; i++, p += l) { | |
| 1519 | − l = strnlen(p, end - p) + 1; | |
| 1520 | − if (p + l > end) | |
| 1521 | − return -EILSEQ; | |
| 1522 | − pr_debug("comparing %s with %s\n", string, p); | |
| 1523 | − if (strcmp(string, p) == 0) | |
| 1524 | − return i; /* Found it; return index */ | |
| 1525 | − } | |
| 1526 | − return -ENODATA; | |
| 1527 | −} | |
| 1528 | −EXPORT_SYMBOL_GPL(of_property_match_string); | |
| 1529 | − | |
| 1530 | −/** | |
| 1531 | − * of_property_read_string_helper() - Utility helper for parsing string properties | |
| 1532 | − * @np: device node from which the property value is to be read. | |
| 1533 | − * @propname: name of the property to be searched. | |
| 1534 | − * @out_strs: output array of string pointers. | |
| 1535 | − * @sz: number of array elements to read. | |
| 1536 | − * @skip: Number of strings to skip over at beginning of list. | |
| 1537 | − * | |
| 1538 | − * Don't call this function directly. It is a utility helper for the | |
| 1539 | − * of_property_read_string*() family of functions. | |
| 1540 | − */ | |
| 1541 | −int of_property_read_string_helper(const struct device_node *np, | |
| 1542 | − const char *propname, const char **out_strs, | |
| 1543 | − size_t sz, int skip) | |
| 1544 | −{ | |
| 1545 | − const struct property *prop = of_find_property(np, propname, NULL); | |
| 1546 | − int l = 0, i = 0; | |
| 1547 | − const char *p, *end; | |
| 1548 | − | |
| 1549 | − if (!prop) | |
| 1550 | − return -EINVAL; | |
| 1551 | − if (!prop->value) | |
| 1552 | − return -ENODATA; | |
| 1553 | − p = prop->value; | |
| 1554 | − end = p + prop->length; | |
| 1555 | − | |
| 1556 | − for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) { | |
| 1557 | − l = strnlen(p, end - p) + 1; | |
| 1558 | − if (p + l > end) | |
| 1559 | − return -EILSEQ; | |
| 1560 | − if (out_strs && i >= skip) | |
| 1561 | − *out_strs++ = p; | |
| 1562 | − } | |
| 1563 | − i -= skip; | |
| 1564 | − return i <= 0 ? -ENODATA : i; | |
| 1565 | −} | |
| 1566 | −EXPORT_SYMBOL_GPL(of_property_read_string_helper); | |
| 1567 | − | |
| 1568 | 1122 | void of_print_phandle_args(const char *msg, const struct of_phandle_args *args) |
| 1569 | 1123 | { |
| 1570 | 1124 | int i; |
| @@ -2213,47 +1767,6 @@ int of_alias_get_highest_id(const char *stem) · 642 unmodified lines | ||
| 2213 | 1767 | } |
| 2214 | 1768 | EXPORT_SYMBOL_GPL(of_alias_get_highest_id); |
| 2215 | 1769 | |
| 2216 | −const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, | |
| 2217 | − u32 *pu) | |
| 2218 | −{ | |
| 2219 | − const void *curv = cur; | |
| 2220 | − | |
| 2221 | − if (!prop) | |
| 2222 | − return NULL; | |
| 2223 | − | |
| 2224 | − if (!cur) { | |
| 2225 | − curv = prop->value; | |
| 2226 | − goto out_val; | |
| 2227 | − } | |
| 2228 | − | |
| 2229 | − curv += sizeof(*cur); | |
| 2230 | − if (curv >= prop->value + prop->length) | |
| 2231 | − return NULL; | |
| 2232 | − | |
| 2233 | −out_val: | |
| 2234 | − *pu = be32_to_cpup(curv); | |
| 2235 | − return curv; | |
| 2236 | −} | |
| 2237 | −EXPORT_SYMBOL_GPL(of_prop_next_u32); | |
| 2238 | − | |
| 2239 | −const char *of_prop_next_string(struct property *prop, const char *cur) | |
| 2240 | −{ | |
| 2241 | − const void *curv = cur; | |
| 2242 | − | |
| 2243 | − if (!prop) | |
| 2244 | − return NULL; | |
| 2245 | − | |
| 2246 | − if (!cur) | |
| 2247 | − return prop->value; | |
| 2248 | − | |
| 2249 | − curv += strlen(cur) + 1; | |
| 2250 | − if (curv >= prop->value + prop->length) | |
| 2251 | − return NULL; | |
| 2252 | − | |
| 2253 | − return curv; | |
| 2254 | −} | |
| 2255 | −EXPORT_SYMBOL_GPL(of_prop_next_string); | |
| 2256 | − | |
| 2257 | 1770 | /** |
| 2258 | 1771 | * of_console_check() - Test and setup console for DT setup |
| 2259 | 1772 | * @dn - Pointer to device node |
| @@ -2327,283 +1840,3 @@ int of_find_last_cache_level(unsigned int cpu) · 67 unmodified lines | ||
| 2327 | 1840 | |
| 2328 | 1841 | return cache_level; |
| 2329 | 1842 | } |
| 2330 | − | |
| 2331 | −/** | |
| 2332 | − * of_graph_parse_endpoint() - parse common endpoint node properties | |
| 2333 | − * @node: pointer to endpoint device_node | |
| 2334 | − * @endpoint: pointer to the OF endpoint data structure | |
| 2335 | − * | |
| 2336 | − * The caller should hold a reference to @node. | |
| 2337 | − */ | |
| 2338 | −int of_graph_parse_endpoint(const struct device_node *node, | |
| 2339 | − struct of_endpoint *endpoint) | |
| 2340 | −{ | |
| 2341 | − struct device_node *port_node = of_get_parent(node); | |
| 2342 | − | |
| 2343 | − WARN_ONCE(!port_node, "%s(): endpoint %s has no parent node\n", | |
| 2344 | − __func__, node->full_name); | |
| 2345 | − | |
| 2346 | − memset(endpoint, 0, sizeof(*endpoint)); | |
| 2347 | − | |
| 2348 | − endpoint->local_node = node; | |
| 2349 | − /* | |
| 2350 | − * It doesn't matter whether the two calls below succeed. | |
| 2351 | − * If they don't then the default value 0 is used. | |
| 2352 | − */ | |
| 2353 | − of_property_read_u32(port_node, "reg", &endpoint->port); | |
| 2354 | − of_property_read_u32(node, "reg", &endpoint->id); | |
| 2355 | − | |
| 2356 | − of_node_put(port_node); | |
| 2357 | − | |
| 2358 | − return 0; | |
| 2359 | −} | |
| 2360 | −EXPORT_SYMBOL(of_graph_parse_endpoint); | |
| 2361 | − | |
| 2362 | −/** | |
| 2363 | − * of_graph_get_port_by_id() - get the port matching a given id | |
| 2364 | − * @parent: pointer to the parent device node | |
| 2365 | − * @id: id of the port | |
| 2366 | − * | |
| 2367 | − * Return: A 'port' node pointer with refcount incremented. The caller | |
| 2368 | − * has to use of_node_put() on it when done. | |
| 2369 | − */ | |
| 2370 | −struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id) | |
| 2371 | −{ | |
| 2372 | − struct device_node *node, *port; | |
| 2373 | − | |
| 2374 | − node = of_get_child_by_name(parent, "ports"); | |
| 2375 | − if (node) | |
| 2376 | − parent = node; | |
| 2377 | − | |
| 2378 | − for_each_child_of_node(parent, port) { | |
| 2379 | − u32 port_id = 0; | |
| 2380 | − | |
| 2381 | − if (of_node_cmp(port->name, "port") != 0) | |
| 2382 | − continue; | |
| 2383 | − of_property_read_u32(port, "reg", &port_id); | |
| 2384 | − if (id == port_id) | |
| 2385 | − break; | |
| 2386 | − } | |
| 2387 | − | |
| 2388 | − of_node_put(node); | |
| 2389 | − | |
| 2390 | − return port; | |
| 2391 | −} | |
| 2392 | −EXPORT_SYMBOL(of_graph_get_port_by_id); | |
| 2393 | − | |
| 2394 | −/** | |
| 2395 | − * of_graph_get_next_endpoint() - get next endpoint node | |
| 2396 | − * @parent: pointer to the parent device node | |
| 2397 | − * @prev: previous endpoint node, or NULL to get first | |
| 2398 | − * | |
| 2399 | − * Return: An 'endpoint' node pointer with refcount incremented. Refcount | |
| 2400 | − * of the passed @prev node is decremented. | |
| 2401 | − */ | |
| 2402 | −struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, | |
| 2403 | − struct device_node *prev) | |
| 2404 | −{ | |
| 2405 | − struct device_node *endpoint; | |
| 2406 | − struct device_node *port; | |
| 2407 | − | |
| 2408 | − if (!parent) | |
| 2409 | − return NULL; | |
| 2410 | − | |
| 2411 | − /* | |
| 2412 | − * Start by locating the port node. If no previous endpoint is specified | |
| 2413 | − * search for the first port node, otherwise get the previous endpoint | |
| 2414 | − * parent port node. | |
| 2415 | − */ | |
| 2416 | − if (!prev) { | |
| 2417 | − struct device_node *node; | |
| 2418 | − | |
| 2419 | − node = of_get_child_by_name(parent, "ports"); | |
| 2420 | − if (node) | |
| 2421 | − parent = node; | |
| 2422 | − | |
| 2423 | − port = of_get_child_by_name(parent, "port"); | |
| 2424 | − of_node_put(node); | |
| 2425 | − | |
| 2426 | − if (!port) { | |
| 2427 | − pr_err("graph: no port node found in %s\n", | |
| 2428 | − parent->full_name); | |
| 2429 | − return NULL; | |
| 2430 | − } | |
| 2431 | − } else { | |
| 2432 | − port = of_get_parent(prev); | |
| 2433 | − if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n", | |
| 2434 | − __func__, prev->full_name)) | |
| 2435 | − return NULL; | |
| 2436 | − } | |
| 2437 | − | |
| 2438 | − while (1) { | |
| 2439 | − /* | |
| 2440 | − * Now that we have a port node, get the next endpoint by | |
| 2441 | − * getting the next child. If the previous endpoint is NULL this | |
| 2442 | − * will return the first child. | |
| 2443 | − */ | |
| 2444 | − endpoint = of_get_next_child(port, prev); | |
| 2445 | − if (endpoint) { | |
| 2446 | − of_node_put(port); | |
| 2447 | − return endpoint; | |
| 2448 | − } | |
| 2449 | − | |
| 2450 | − /* No more endpoints under this port, try the next one. */ | |
| 2451 | − prev = NULL; | |
| 2452 | − | |
| 2453 | − do { | |
| 2454 | − port = of_get_next_child(parent, port); | |
| 2455 | − if (!port) | |
| 2456 | − return NULL; | |
| 2457 | − } while (of_node_cmp(port->name, "port")); | |
| 2458 | − } | |
| 2459 | −} | |
| 2460 | −EXPORT_SYMBOL(of_graph_get_next_endpoint); | |
| 2461 | − | |
| 2462 | −/** | |
| 2463 | − * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers | |
| 2464 | − * @parent: pointer to the parent device node | |
| 2465 | − * @port_reg: identifier (value of reg property) of the parent port node | |
| 2466 | − * @reg: identifier (value of reg property) of the endpoint node | |
| 2467 | − * | |
| 2468 | − * Return: An 'endpoint' node pointer which is identified by reg and at the same | |
| 2469 | − * is the child of a port node identified by port_reg. reg and port_reg are | |
| 2470 | − * ignored when they are -1. | |
| 2471 | − */ | |
| 2472 | −struct device_node *of_graph_get_endpoint_by_regs( | |
| 2473 | − const struct device_node *parent, int port_reg, int reg) | |
| 2474 | −{ | |
| 2475 | − struct of_endpoint endpoint; | |
| 2476 | − struct device_node *node = NULL; | |
| 2477 | − | |
| 2478 | − for_each_endpoint_of_node(parent, node) { | |
| 2479 | − of_graph_parse_endpoint(node, &endpoint); | |
| 2480 | − if (((port_reg == -1) || (endpoint.port == port_reg)) && | |
| 2481 | − ((reg == -1) || (endpoint.id == reg))) | |
| 2482 | − return node; | |
| 2483 | − } | |
| 2484 | − | |
| 2485 | − return NULL; | |
| 2486 | −} | |
| 2487 | −EXPORT_SYMBOL(of_graph_get_endpoint_by_regs); | |
| 2488 | − | |
| 2489 | −/** | |
| 2490 | − * of_graph_get_remote_endpoint() - get remote endpoint node | |
| 2491 | − * @node: pointer to a local endpoint device_node | |
| 2492 | − * | |
| 2493 | − * Return: Remote endpoint node associated with remote endpoint node linked | |
| 2494 | − * to @node. Use of_node_put() on it when done. | |
| 2495 | − */ | |
| 2496 | −struct device_node *of_graph_get_remote_endpoint(const struct device_node *node) | |
| 2497 | −{ | |
| 2498 | − /* Get remote endpoint node. */ | |
| 2499 | − return of_parse_phandle(node, "remote-endpoint", 0); | |
| 2500 | −} | |
| 2501 | −EXPORT_SYMBOL(of_graph_get_remote_endpoint); | |
| 2502 | − | |
| 2503 | −/** | |
| 2504 | − * of_graph_get_port_parent() - get port's parent node | |
| 2505 | − * @node: pointer to a local endpoint device_node | |
| 2506 | − * | |
| 2507 | − * Return: device node associated with endpoint node linked | |
| 2508 | − * to @node. Use of_node_put() on it when done. | |
| 2509 | − */ | |
| 2510 | −struct device_node *of_graph_get_port_parent(struct device_node *node) | |
| 2511 | −{ | |
| 2512 | − unsigned int depth; | |
| 2513 | − | |
| 2514 | − /* Walk 3 levels up only if there is 'ports' node. */ | |
| 2515 | − for (depth = 3; depth && node; depth--) { | |
| 2516 | − node = of_get_next_parent(node); | |
| 2517 | − if (depth == 2 && of_node_cmp(node->name, "ports")) | |
| 2518 | − break; | |
| 2519 | − } | |
| 2520 | − return node; | |
| 2521 | −} | |
| 2522 | −EXPORT_SYMBOL(of_graph_get_port_parent); | |
| 2523 | − | |
| 2524 | −/** | |
| 2525 | − * of_graph_get_remote_port_parent() - get remote port's parent node | |
| 2526 | − * @node: pointer to a local endpoint device_node | |
| 2527 | − * | |
| 2528 | − * Return: Remote device node associated with remote endpoint node linked | |
| 2529 | − * to @node. Use of_node_put() on it when done. | |
| 2530 | − */ | |
| 2531 | −struct device_node *of_graph_get_remote_port_parent( | |
| 2532 | − const struct device_node *node) | |
| 2533 | −{ | |
| 2534 | − struct device_node *np; | |
| 2535 | − | |
| 2536 | − /* Get remote endpoint node. */ | |
| 2537 | − np = of_graph_get_remote_endpoint(node); | |
| 2538 | − | |
| 2539 | − return of_graph_get_port_parent(np); | |
| 2540 | −} | |
| 2541 | −EXPORT_SYMBOL(of_graph_get_remote_port_parent); | |
| 2542 | − | |
| 2543 | −/** | |
| 2544 | − * of_graph_get_remote_port() - get remote port node | |
| 2545 | − * @node: pointer to a local endpoint device_node | |
| 2546 | − * | |
| 2547 | − * Return: Remote port node associated with remote endpoint node linked | |
| 2548 | − * to @node. Use of_node_put() on it when done. | |
| 2549 | − */ | |
| 2550 | −struct device_node *of_graph_get_remote_port(const struct device_node *node) | |
| 2551 | −{ | |
| 2552 | − struct device_node *np; | |
| 2553 | − | |
| 2554 | − /* Get remote endpoint node. */ | |
| 2555 | − np = of_graph_get_remote_endpoint(node); | |
| 2556 | − if (!np) | |
| 2557 | − return NULL; | |
| 2558 | − return of_get_next_parent(np); | |
| 2559 | −} | |
| 2560 | −EXPORT_SYMBOL(of_graph_get_remote_port); | |
| 2561 | − | |
| 2562 | −int of_graph_get_endpoint_count(const struct device_node *np) | |
| 2563 | −{ | |
| 2564 | − struct device_node *endpoint; | |
| 2565 | − int num = 0; | |
| 2566 | − | |
| 2567 | − for_each_endpoint_of_node(np, endpoint) | |
| 2568 | − num++; | |
| 2569 | − | |
| 2570 | − return num; | |
| 2571 | −} | |
| 2572 | −EXPORT_SYMBOL(of_graph_get_endpoint_count); | |
| 2573 | − | |
| 2574 | −/** | |
| 2575 | − * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint | |
| 2576 | − * @node: pointer to parent device_node containing graph port/endpoint | |
| 2577 | − * @port: identifier (value of reg property) of the parent port node | |
| 2578 | − * @endpoint: identifier (value of reg property) of the endpoint node | |
| 2579 | − * | |
| 2580 | − * Return: Remote device node associated with remote endpoint node linked | |
| 2581 | − * to @node. Use of_node_put() on it when done. | |
| 2582 | − */ | |
| 2583 | −struct device_node *of_graph_get_remote_node(const struct device_node *node, | |
| 2584 | − u32 port, u32 endpoint) | |
| 2585 | −{ | |
| 2586 | − struct device_node *endpoint_node, *remote; | |
| 2587 | − | |
| 2588 | − endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint); | |
| 2589 | − if (!endpoint_node) { | |
| 2590 | − pr_debug("no valid endpoint (%d, %d) for node %s\n", | |
| 2591 | − port, endpoint, node->full_name); | |
| 2592 | − return NULL; | |
| 2593 | − } | |
| 2594 | − | |
| 2595 | − remote = of_graph_get_remote_port_parent(endpoint_node); | |
| 2596 | − of_node_put(endpoint_node); | |
| 2597 | − if (!remote) { | |
| 2598 | − pr_debug("no valid remote node\n"); | |
| 2599 | − return NULL; | |
| 2600 | − } | |
| 2601 | − | |
| 2602 | − if (!of_device_is_available(remote)) { | |
| 2603 | − pr_debug("not available for remote node\n"); | |
| 2604 | − return NULL; | |
| 2605 | − } | |
| 2606 | − | |
| 2607 | − return remote; | |
| 2608 | −} | |
| 2609 | −EXPORT_SYMBOL(of_graph_get_remote_node); | |
| @@ -216,7 +216,7 @@ int of_property_notify(int action, struct device_node *np, · 215 unmodified lines | ||
| 216 | 216 | return of_reconfig_notify(action, &pr); |
| 217 | 217 | } |
| 218 | 218 | |
| 219 | −void __of_attach_node(struct device_node *np) | |
| 219 | +static void __of_attach_node(struct device_node *np) | |
| 220 | 220 | { |
| 221 | 221 | const __be32 *phandle; |
| 222 | 222 | int sz; |
| @@ -91,7 +91,7 @@ void of_fdt_limit_memory(int limit) · 90 unmodified lines | ||
| 91 | 91 | * On match, returns a non-zero value with smaller values returned for more |
| 92 | 92 | * specific compatible values. |
| 93 | 93 | */ |
| 94 | −int of_fdt_is_compatible(const void *blob, | |
| 94 | +static int of_fdt_is_compatible(const void *blob, | |
| 95 | 95 | unsigned long node, const char *compat) |
| 96 | 96 | { |
| 97 | 97 | const char *cp; |
| @@ -1053,7 +1053,7 @@ u64 __init dt_mem_next_cell(int s, const __be32 **cellp) · 955 unmodified lines | ||
| 1053 | 1053 | } |
| 1054 | 1054 | |
| 1055 | 1055 | /** |
| 1056 | − * early_init_dt_scan_memory - Look for an parse memory nodes | |
| 1056 | + * early_init_dt_scan_memory - Look for and parse memory nodes | |
| 1057 | 1057 | */ |
| 1058 | 1058 | int __init early_init_dt_scan_memory(unsigned long node, const char *uname, |
| 1059 | 1059 | int depth, void *data) |
| @@ -369,7 +369,10 @@ EXPORT_SYMBOL_GPL(of_irq_parse_one); · 368 unmodified lines | ||
| 369 | 369 | */ |
| 370 | 370 | int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) |
| 371 | 371 | { |
| 372 | − int irq = irq_of_parse_and_map(dev, index); | |
| 372 | + int irq = of_irq_get(dev, index); | |
| 373 | + | |
| 374 | + if (irq < 0) | |
| 375 | + return irq; | |
| 373 | 376 | |
| 374 | 377 | /* Only dereference the resource if both the |
| 375 | 378 | * resource and the irq are valid. */ |
| @@ -77,6 +77,9 @@ extern void *__unflatten_device_tree(const void *blob, · 76 unmodified lines | ||
| 77 | 77 | struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags); |
| 78 | 78 | __printf(2, 3) struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...); |
| 79 | 79 | |
| 80 | +struct device_node *__of_find_node_by_full_path(struct device_node *node, | |
| 81 | + const char *path); | |
| 82 | + | |
| 80 | 83 | extern const void *__of_get_property(const struct device_node *np, |
| 81 | 84 | const char *name, int *lenp); |
| 82 | 85 | extern int __of_add_property(struct device_node *np, struct property *prop); |
| @@ -90,7 +93,6 @@ extern int __of_update_property(struct device_node *np, · 7 unmodified lines | ||
| 90 | 93 | extern void __of_update_property_sysfs(struct device_node *np, |
| 91 | 94 | struct property *newprop, struct property *oldprop); |
| 92 | 95 | |
| 93 | −extern void __of_attach_node(struct device_node *np); | |
| 94 | 96 | extern int __of_attach_node_sysfs(struct device_node *np); |
| 95 | 97 | extern void __of_detach_node(struct device_node *np); |
| 96 | 98 | extern void __of_detach_node_sysfs(struct device_node *np); |
| @@ -132,6 +132,10 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, · 131 unmodified lines | ||
| 132 | 132 | /* NOTE: Multiple mods of created nodes not supported */ |
| 133 | 133 | tchild = of_get_child_by_name(target, cname); |
| 134 | 134 | if (tchild != NULL) { |
| 135 | + /* new overlay phandle value conflicts with existing value */ | |
| 136 | + if (child->phandle) | |
| 137 | + return -EINVAL; | |
| 138 | + | |
| 135 | 139 | /* apply overlay recursively */ |
| 136 | 140 | ret = of_overlay_apply_one(ov, tchild, child); |
| 137 | 141 | of_node_put(tchild); |
| @@ -99,7 +99,7 @@ static void of_device_make_bus_id(struct device *dev) · 98 unmodified lines | ||
| 99 | 99 | |
| 100 | 100 | /* format arguments only used if dev_name() resolves to NULL */ |
| 101 | 101 | dev_set_name(dev, dev_name(dev) ? "%s:%s" : "%s", |
| 102 | − strrchr(node->full_name, '/') + 1, dev_name(dev)); | |
| 102 | + kbasename(node->full_name), dev_name(dev)); | |
| 103 | 103 | node = node->parent; |
| 104 | 104 | } |
| 105 | 105 | } |
| @@ -0,0 +1,806 @@ | ||
| 1 | +/* | |
| 2 | + * drivers/of/property.c - Procedures for accessing and interpreting | |
| 3 | + * Devicetree properties and graphs. | |
| 4 | + * | |
| 5 | + * Initially created by copying procedures from drivers/of/base.c. This | |
| 6 | + * file contains the OF property as well as the OF graph interface | |
| 7 | + * functions. | |
| 8 | + * | |
| 9 | + * Paul Mackerras August 1996. | |
| 10 | + * Copyright (C) 1996-2005 Paul Mackerras. | |
| 11 | + * | |
| 12 | + * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. | |
| 13 | + * {engebret|bergner}@us.ibm.com | |
| 14 | + * | |
| 15 | + * Adapted for sparc and sparc64 by David S. Miller davem@davemloft.net | |
| 16 | + * | |
| 17 | + * Reconsolidated from arch/x/kernel/prom.c by Stephen Rothwell and | |
| 18 | + * Grant Likely. | |
| 19 | + * | |
| 20 | + * This program is free software; you can redistribute it and/or | |
| 21 | + * modify it under the terms of the GNU General Public License | |
| 22 | + * as published by the Free Software Foundation; either version | |
| 23 | + * 2 of the License, or (at your option) any later version. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +#define pr_fmt(fmt) "OF: " fmt | |
| 27 | + | |
| 28 | +#include <linux/of.h> | |
| 29 | +#include <linux/of_device.h> | |
| 30 | +#include <linux/of_graph.h> | |
| 31 | +#include <linux/string.h> | |
| 32 | + | |
| 33 | +#include "of_private.h" | |
| 34 | + | |
| 35 | +/** | |
| 36 | + * of_property_count_elems_of_size - Count the number of elements in a property | |
| 37 | + * | |
| 38 | + * @np: device node from which the property value is to be read. | |
| 39 | + * @propname: name of the property to be searched. | |
| 40 | + * @elem_size: size of the individual element | |
| 41 | + * | |
| 42 | + * Search for a property in a device node and count the number of elements of | |
| 43 | + * size elem_size in it. Returns number of elements on sucess, -EINVAL if the | |
| 44 | + * property does not exist or its length does not match a multiple of elem_size | |
| 45 | + * and -ENODATA if the property does not have a value. | |
| 46 | + */ | |
| 47 | +int of_property_count_elems_of_size(const struct device_node *np, | |
| 48 | + const char *propname, int elem_size) | |
| 49 | +{ | |
| 50 | + struct property *prop = of_find_property(np, propname, NULL); | |
| 51 | + | |
| 52 | + if (!prop) | |
| 53 | + return -EINVAL; | |
| 54 | + if (!prop->value) | |
| 55 | + return -ENODATA; | |
| 56 | + | |
| 57 | + if (prop->length % elem_size != 0) { | |
| 58 | + pr_err("size of %s in node %s is not a multiple of %d\n", | |
| 59 | + propname, np->full_name, elem_size); | |
| 60 | + return -EINVAL; | |
| 61 | + } | |
| 62 | + | |
| 63 | + return prop->length / elem_size; | |
| 64 | +} | |
| 65 | +EXPORT_SYMBOL_GPL(of_property_count_elems_of_size); | |
| 66 | + | |
| 67 | +/** | |
| 68 | + * of_find_property_value_of_size | |
| 69 | + * | |
| 70 | + * @np: device node from which the property value is to be read. | |
| 71 | + * @propname: name of the property to be searched. | |
| 72 | + * @min: minimum allowed length of property value | |
| 73 | + * @max: maximum allowed length of property value (0 means unlimited) | |
| 74 | + * @len: if !=NULL, actual length is written to here | |
| 75 | + * | |
| 76 | + * Search for a property in a device node and valid the requested size. | |
| 77 | + * Returns the property value on success, -EINVAL if the property does not | |
| 78 | + * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the | |
| 79 | + * property data is too small or too large. | |
| 80 | + * | |
| 81 | + */ | |
| 82 | +static void *of_find_property_value_of_size(const struct device_node *np, | |
| 83 | + const char *propname, u32 min, u32 max, size_t *len) | |
| 84 | +{ | |
| 85 | + struct property *prop = of_find_property(np, propname, NULL); | |
| 86 | + | |
| 87 | + if (!prop) | |
| 88 | + return ERR_PTR(-EINVAL); | |
| 89 | + if (!prop->value) | |
| 90 | + return ERR_PTR(-ENODATA); | |
| 91 | + if (prop->length < min) | |
| 92 | + return ERR_PTR(-EOVERFLOW); | |
| 93 | + if (max && prop->length > max) | |
| 94 | + return ERR_PTR(-EOVERFLOW); | |
| 95 | + | |
| 96 | + if (len) | |
| 97 | + *len = prop->length; | |
| 98 | + | |
| 99 | + return prop->value; | |
| 100 | +} | |
| 101 | + | |
| 102 | +/** | |
| 103 | + * of_property_read_u32_index - Find and read a u32 from a multi-value property. | |
| 104 | + * | |
| 105 | + * @np: device node from which the property value is to be read. | |
| 106 | + * @propname: name of the property to be searched. | |
| 107 | + * @index: index of the u32 in the list of values | |
| 108 | + * @out_value: pointer to return value, modified only if no error. | |
| 109 | + * | |
| 110 | + * Search for a property in a device node and read nth 32-bit value from | |
| 111 | + * it. Returns 0 on success, -EINVAL if the property does not exist, | |
| 112 | + * -ENODATA if property does not have a value, and -EOVERFLOW if the | |
| 113 | + * property data isn't large enough. | |
| 114 | + * | |
| 115 | + * The out_value is modified only if a valid u32 value can be decoded. | |
| 116 | + */ | |
| 117 | +int of_property_read_u32_index(const struct device_node *np, | |
| 118 | + const char *propname, | |
| 119 | + u32 index, u32 *out_value) | |
| 120 | +{ | |
| 121 | + const u32 *val = of_find_property_value_of_size(np, propname, | |
| 122 | + ((index + 1) * sizeof(*out_value)), | |
| 123 | + 0, | |
| 124 | + NULL); | |
| 125 | + | |
| 126 | + if (IS_ERR(val)) | |
| 127 | + return PTR_ERR(val); | |
| 128 | + | |
| 129 | + *out_value = be32_to_cpup(((__be32 *)val) + index); | |
| 130 | + return 0; | |
| 131 | +} | |
| 132 | +EXPORT_SYMBOL_GPL(of_property_read_u32_index); | |
| 133 | + | |
| 134 | +/** | |
| 135 | + * of_property_read_u64_index - Find and read a u64 from a multi-value property. | |
| 136 | + * | |
| 137 | + * @np: device node from which the property value is to be read. | |
| 138 | + * @propname: name of the property to be searched. | |
| 139 | + * @index: index of the u64 in the list of values | |
| 140 | + * @out_value: pointer to return value, modified only if no error. | |
| 141 | + * | |
| 142 | + * Search for a property in a device node and read nth 64-bit value from | |
| 143 | + * it. Returns 0 on success, -EINVAL if the property does not exist, | |
| 144 | + * -ENODATA if property does not have a value, and -EOVERFLOW if the | |
| 145 | + * property data isn't large enough. | |
| 146 | + * | |
| 147 | + * The out_value is modified only if a valid u64 value can be decoded. | |
| 148 | + */ | |
| 149 | +int of_property_read_u64_index(const struct device_node *np, | |
| 150 | + const char *propname, | |
| 151 | + u32 index, u64 *out_value) | |
| 152 | +{ | |
| 153 | + const u64 *val = of_find_property_value_of_size(np, propname, | |
| 154 | + ((index + 1) * sizeof(*out_value)), | |
| 155 | + 0, NULL); | |
| 156 | + | |
| 157 | + if (IS_ERR(val)) | |
| 158 | + return PTR_ERR(val); | |
| 159 | + | |
| 160 | + *out_value = be64_to_cpup(((__be64 *)val) + index); | |
| 161 | + return 0; | |
| 162 | +} | |
| 163 | +EXPORT_SYMBOL_GPL(of_property_read_u64_index); | |
| 164 | + | |
| 165 | +/** | |
| 166 | + * of_property_read_variable_u8_array - Find and read an array of u8 from a | |
| 167 | + * property, with bounds on the minimum and maximum array size. | |
| 168 | + * | |
| 169 | + * @np: device node from which the property value is to be read. | |
| 170 | + * @propname: name of the property to be searched. | |
| 171 | + * @out_values: pointer to return value, modified only if return value is 0. | |
| 172 | + * @sz_min: minimum number of array elements to read | |
| 173 | + * @sz_max: maximum number of array elements to read, if zero there is no | |
| 174 | + * upper limit on the number of elements in the dts entry but only | |
| 175 | + * sz_min will be read. | |
| 176 | + * | |
| 177 | + * Search for a property in a device node and read 8-bit value(s) from | |
| 178 | + * it. Returns number of elements read on success, -EINVAL if the property | |
| 179 | + * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | |
| 180 | + * if the property data is smaller than sz_min or longer than sz_max. | |
| 181 | + * | |
| 182 | + * dts entry of array should be like: | |
| 183 | + * property = /bits/ 8 <0x50 0x60 0x70>; | |
| 184 | + * | |
| 185 | + * The out_values is modified only if a valid u8 value can be decoded. | |
| 186 | + */ | |
| 187 | +int of_property_read_variable_u8_array(const struct device_node *np, | |
| 188 | + const char *propname, u8 *out_values, | |
| 189 | + size_t sz_min, size_t sz_max) | |
| 190 | +{ | |
| 191 | + size_t sz, count; | |
| 192 | + const u8 *val = of_find_property_value_of_size(np, propname, | |
| 193 | + (sz_min * sizeof(*out_values)), | |
| 194 | + (sz_max * sizeof(*out_values)), | |
| 195 | + &sz); | |
| 196 | + | |
| 197 | + if (IS_ERR(val)) | |
| 198 | + return PTR_ERR(val); | |
| 199 | + | |
| 200 | + if (!sz_max) | |
| 201 | + sz = sz_min; | |
| 202 | + else | |
| 203 | + sz /= sizeof(*out_values); | |
| 204 | + | |
| 205 | + count = sz; | |
| 206 | + while (count--) | |
| 207 | + *out_values++ = *val++; | |
| 208 | + | |
| 209 | + return sz; | |
| 210 | +} | |
| 211 | +EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array); | |
| 212 | + | |
| 213 | +/** | |
| 214 | + * of_property_read_variable_u16_array - Find and read an array of u16 from a | |
| 215 | + * property, with bounds on the minimum and maximum array size. | |
| 216 | + * | |
| 217 | + * @np: device node from which the property value is to be read. | |
| 218 | + * @propname: name of the property to be searched. | |
| 219 | + * @out_values: pointer to return value, modified only if return value is 0. | |
| 220 | + * @sz_min: minimum number of array elements to read | |
| 221 | + * @sz_max: maximum number of array elements to read, if zero there is no | |
| 222 | + * upper limit on the number of elements in the dts entry but only | |
| 223 | + * sz_min will be read. | |
| 224 | + * | |
| 225 | + * Search for a property in a device node and read 16-bit value(s) from | |
| 226 | + * it. Returns number of elements read on success, -EINVAL if the property | |
| 227 | + * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | |
| 228 | + * if the property data is smaller than sz_min or longer than sz_max. | |
| 229 | + * | |
| 230 | + * dts entry of array should be like: | |
| 231 | + * property = /bits/ 16 <0x5000 0x6000 0x7000>; | |
| 232 | + * | |
| 233 | + * The out_values is modified only if a valid u16 value can be decoded. | |
| 234 | + */ | |
| 235 | +int of_property_read_variable_u16_array(const struct device_node *np, | |
| 236 | + const char *propname, u16 *out_values, | |
| 237 | + size_t sz_min, size_t sz_max) | |
| 238 | +{ | |
| 239 | + size_t sz, count; | |
| 240 | + const __be16 *val = of_find_property_value_of_size(np, propname, | |
| 241 | + (sz_min * sizeof(*out_values)), | |
| 242 | + (sz_max * sizeof(*out_values)), | |
| 243 | + &sz); | |
| 244 | + | |
| 245 | + if (IS_ERR(val)) | |
| 246 | + return PTR_ERR(val); | |
| 247 | + | |
| 248 | + if (!sz_max) | |
| 249 | + sz = sz_min; | |
| 250 | + else | |
| 251 | + sz /= sizeof(*out_values); | |
| 252 | + | |
| 253 | + count = sz; | |
| 254 | + while (count--) | |
| 255 | + *out_values++ = be16_to_cpup(val++); | |
| 256 | + | |
| 257 | + return sz; | |
| 258 | +} | |
| 259 | +EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array); | |
| 260 | + | |
| 261 | +/** | |
| 262 | + * of_property_read_variable_u32_array - Find and read an array of 32 bit | |
| 263 | + * integers from a property, with bounds on the minimum and maximum array size. | |
| 264 | + * | |
| 265 | + * @np: device node from which the property value is to be read. | |
| 266 | + * @propname: name of the property to be searched. | |
| 267 | + * @out_values: pointer to return value, modified only if return value is 0. | |
| 268 | + * @sz_min: minimum number of array elements to read | |
| 269 | + * @sz_max: maximum number of array elements to read, if zero there is no | |
| 270 | + * upper limit on the number of elements in the dts entry but only | |
| 271 | + * sz_min will be read. | |
| 272 | + * | |
| 273 | + * Search for a property in a device node and read 32-bit value(s) from | |
| 274 | + * it. Returns number of elements read on success, -EINVAL if the property | |
| 275 | + * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | |
| 276 | + * if the property data is smaller than sz_min or longer than sz_max. | |
| 277 | + * | |
| 278 | + * The out_values is modified only if a valid u32 value can be decoded. | |
| 279 | + */ | |
| 280 | +int of_property_read_variable_u32_array(const struct device_node *np, | |
| 281 | + const char *propname, u32 *out_values, | |
| 282 | + size_t sz_min, size_t sz_max) | |
| 283 | +{ | |
| 284 | + size_t sz, count; | |
| 285 | + const __be32 *val = of_find_property_value_of_size(np, propname, | |
| 286 | + (sz_min * sizeof(*out_values)), | |
| 287 | + (sz_max * sizeof(*out_values)), | |
| 288 | + &sz); | |
| 289 | + | |
| 290 | + if (IS_ERR(val)) | |
| 291 | + return PTR_ERR(val); | |
| 292 | + | |
| 293 | + if (!sz_max) | |
| 294 | + sz = sz_min; | |
| 295 | + else | |
| 296 | + sz /= sizeof(*out_values); | |
| 297 | + | |
| 298 | + count = sz; | |
| 299 | + while (count--) | |
| 300 | + *out_values++ = be32_to_cpup(val++); | |
| 301 | + | |
| 302 | + return sz; | |
| 303 | +} | |
| 304 | +EXPORT_SYMBOL_GPL(of_property_read_variable_u32_array); | |
| 305 | + | |
| 306 | +/** | |
| 307 | + * of_property_read_u64 - Find and read a 64 bit integer from a property | |
| 308 | + * @np: device node from which the property value is to be read. | |
| 309 | + * @propname: name of the property to be searched. | |
| 310 | + * @out_value: pointer to return value, modified only if return value is 0. | |
| 311 | + * | |
| 312 | + * Search for a property in a device node and read a 64-bit value from | |
| 313 | + * it. Returns 0 on success, -EINVAL if the property does not exist, | |
| 314 | + * -ENODATA if property does not have a value, and -EOVERFLOW if the | |
| 315 | + * property data isn't large enough. | |
| 316 | + * | |
| 317 | + * The out_value is modified only if a valid u64 value can be decoded. | |
| 318 | + */ | |
| 319 | +int of_property_read_u64(const struct device_node *np, const char *propname, | |
| 320 | + u64 *out_value) | |
| 321 | +{ | |
| 322 | + const __be32 *val = of_find_property_value_of_size(np, propname, | |
| 323 | + sizeof(*out_value), | |
| 324 | + 0, | |
| 325 | + NULL); | |
| 326 | + | |
| 327 | + if (IS_ERR(val)) | |
| 328 | + return PTR_ERR(val); | |
| 329 | + | |
| 330 | + *out_value = of_read_number(val, 2); | |
| 331 | + return 0; | |
| 332 | +} | |
| 333 | +EXPORT_SYMBOL_GPL(of_property_read_u64); | |
| 334 | + | |
| 335 | +/** | |
| 336 | + * of_property_read_variable_u64_array - Find and read an array of 64 bit | |
| 337 | + * integers from a property, with bounds on the minimum and maximum array size. | |
| 338 | + * | |
| 339 | + * @np: device node from which the property value is to be read. | |
| 340 | + * @propname: name of the property to be searched. | |
| 341 | + * @out_values: pointer to return value, modified only if return value is 0. | |
| 342 | + * @sz_min: minimum number of array elements to read | |
| 343 | + * @sz_max: maximum number of array elements to read, if zero there is no | |
| 344 | + * upper limit on the number of elements in the dts entry but only | |
| 345 | + * sz_min will be read. | |
| 346 | + * | |
| 347 | + * Search for a property in a device node and read 64-bit value(s) from | |
| 348 | + * it. Returns number of elements read on success, -EINVAL if the property | |
| 349 | + * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW | |
| 350 | + * if the property data is smaller than sz_min or longer than sz_max. | |
| 351 | + * | |
| 352 | + * The out_values is modified only if a valid u64 value can be decoded. | |
| 353 | + */ | |
| 354 | +int of_property_read_variable_u64_array(const struct device_node *np, | |
| 355 | + const char *propname, u64 *out_values, | |
| 356 | + size_t sz_min, size_t sz_max) | |
| 357 | +{ | |
| 358 | + size_t sz, count; | |
| 359 | + const __be32 *val = of_find_property_value_of_size(np, propname, | |
| 360 | + (sz_min * sizeof(*out_values)), | |
| 361 | + (sz_max * sizeof(*out_values)), | |
| 362 | + &sz); | |
| 363 | + | |
| 364 | + if (IS_ERR(val)) | |
| 365 | + return PTR_ERR(val); | |
| 366 | + | |
| 367 | + if (!sz_max) | |
| 368 | + sz = sz_min; | |
| 369 | + else | |
| 370 | + sz /= sizeof(*out_values); | |
| 371 | + | |
| 372 | + count = sz; | |
| 373 | + while (count--) { | |
| 374 | + *out_values++ = of_read_number(val, 2); | |
| 375 | + val += 2; | |
| 376 | + } | |
| 377 | + | |
| 378 | + return sz; | |
| 379 | +} | |
| 380 | +EXPORT_SYMBOL_GPL(of_property_read_variable_u64_array); | |
| 381 | + | |
| 382 | +/** | |
| 383 | + * of_property_read_string - Find and read a string from a property | |
| 384 | + * @np: device node from which the property value is to be read. | |
| 385 | + * @propname: name of the property to be searched. | |
| 386 | + * @out_string: pointer to null terminated return string, modified only if | |
| 387 | + * return value is 0. | |
| 388 | + * | |
| 389 | + * Search for a property in a device tree node and retrieve a null | |
| 390 | + * terminated string value (pointer to data, not a copy). Returns 0 on | |
| 391 | + * success, -EINVAL if the property does not exist, -ENODATA if property | |
| 392 | + * does not have a value, and -EILSEQ if the string is not null-terminated | |
| 393 | + * within the length of the property data. | |
| 394 | + * | |
| 395 | + * The out_string pointer is modified only if a valid string can be decoded. | |
| 396 | + */ | |
| 397 | +int of_property_read_string(const struct device_node *np, const char *propname, | |
| 398 | + const char **out_string) | |
| 399 | +{ | |
| 400 | + const struct property *prop = of_find_property(np, propname, NULL); | |
| 401 | + if (!prop) | |
| 402 | + return -EINVAL; | |
| 403 | + if (!prop->value) | |
| 404 | + return -ENODATA; | |
| 405 | + if (strnlen(prop->value, prop->length) >= prop->length) | |
| 406 | + return -EILSEQ; | |
| 407 | + *out_string = prop->value; | |
| 408 | + return 0; | |
| 409 | +} | |
| 410 | +EXPORT_SYMBOL_GPL(of_property_read_string); | |
| 411 | + | |
| 412 | +/** | |
| 413 | + * of_property_match_string() - Find string in a list and return index | |
| 414 | + * @np: pointer to node containing string list property | |
| 415 | + * @propname: string list property name | |
| 416 | + * @string: pointer to string to search for in string list | |
| 417 | + * | |
| 418 | + * This function searches a string list property and returns the index | |
| 419 | + * of a specific string value. | |
| 420 | + */ | |
| 421 | +int of_property_match_string(const struct device_node *np, const char *propname, | |
| 422 | + const char *string) | |
| 423 | +{ | |
| 424 | + const struct property *prop = of_find_property(np, propname, NULL); | |
| 425 | + size_t l; | |
| 426 | + int i; | |
| 427 | + const char *p, *end; | |
| 428 | + | |
| 429 | + if (!prop) | |
| 430 | + return -EINVAL; | |
| 431 | + if (!prop->value) | |
| 432 | + return -ENODATA; | |
| 433 | + | |
| 434 | + p = prop->value; | |
| 435 | + end = p + prop->length; | |
| 436 | + | |
| 437 | + for (i = 0; p < end; i++, p += l) { | |
| 438 | + l = strnlen(p, end - p) + 1; | |
| 439 | + if (p + l > end) | |
| 440 | + return -EILSEQ; | |
| 441 | + pr_debug("comparing %s with %s\n", string, p); | |
| 442 | + if (strcmp(string, p) == 0) | |
| 443 | + return i; /* Found it; return index */ | |
| 444 | + } | |
| 445 | + return -ENODATA; | |
| 446 | +} | |
| 447 | +EXPORT_SYMBOL_GPL(of_property_match_string); | |
| 448 | + | |
| 449 | +/** | |
| 450 | + * of_property_read_string_helper() - Utility helper for parsing string properties | |
| 451 | + * @np: device node from which the property value is to be read. | |
| 452 | + * @propname: name of the property to be searched. | |
| 453 | + * @out_strs: output array of string pointers. | |
| 454 | + * @sz: number of array elements to read. | |
| 455 | + * @skip: Number of strings to skip over at beginning of list. | |
| 456 | + * | |
| 457 | + * Don't call this function directly. It is a utility helper for the | |
| 458 | + * of_property_read_string*() family of functions. | |
| 459 | + */ | |
| 460 | +int of_property_read_string_helper(const struct device_node *np, | |
| 461 | + const char *propname, const char **out_strs, | |
| 462 | + size_t sz, int skip) | |
| 463 | +{ | |
| 464 | + const struct property *prop = of_find_property(np, propname, NULL); | |
| 465 | + int l = 0, i = 0; | |
| 466 | + const char *p, *end; | |
| 467 | + | |
| 468 | + if (!prop) | |
| 469 | + return -EINVAL; | |
| 470 | + if (!prop->value) | |
| 471 | + return -ENODATA; | |
| 472 | + p = prop->value; | |
| 473 | + end = p + prop->length; | |
| 474 | + | |
| 475 | + for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) { | |
| 476 | + l = strnlen(p, end - p) + 1; | |
| 477 | + if (p + l > end) | |
| 478 | + return -EILSEQ; | |
| 479 | + if (out_strs && i >= skip) | |
| 480 | + *out_strs++ = p; | |
| 481 | + } | |
| 482 | + i -= skip; | |
| 483 | + return i <= 0 ? -ENODATA : i; | |
| 484 | +} | |
| 485 | +EXPORT_SYMBOL_GPL(of_property_read_string_helper); | |
| 486 | + | |
| 487 | +const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, | |
| 488 | + u32 *pu) | |
| 489 | +{ | |
| 490 | + const void *curv = cur; | |
| 491 | + | |
| 492 | + if (!prop) | |
| 493 | + return NULL; | |
| 494 | + | |
| 495 | + if (!cur) { | |
| 496 | + curv = prop->value; | |
| 497 | + goto out_val; | |
| 498 | + } | |
| 499 | + | |
| 500 | + curv += sizeof(*cur); | |
| 501 | + if (curv >= prop->value + prop->length) | |
| 502 | + return NULL; | |
| 503 | + | |
| 504 | +out_val: | |
| 505 | + *pu = be32_to_cpup(curv); | |
| 506 | + return curv; | |
| 507 | +} | |
| 508 | +EXPORT_SYMBOL_GPL(of_prop_next_u32); | |
| 509 | + | |
| 510 | +const char *of_prop_next_string(struct property *prop, const char *cur) | |
| 511 | +{ | |
| 512 | + const void *curv = cur; | |
| 513 | + | |
| 514 | + if (!prop) | |
| 515 | + return NULL; | |
| 516 | + | |
| 517 | + if (!cur) | |
| 518 | + return prop->value; | |
| 519 | + | |
| 520 | + curv += strlen(cur) + 1; | |
| 521 | + if (curv >= prop->value + prop->length) | |
| 522 | + return NULL; | |
| 523 | + | |
| 524 | + return curv; | |
| 525 | +} | |
| 526 | +EXPORT_SYMBOL_GPL(of_prop_next_string); | |
| 527 | + | |
| 528 | +/** | |
| 529 | + * of_graph_parse_endpoint() - parse common endpoint node properties | |
| 530 | + * @node: pointer to endpoint device_node | |
| 531 | + * @endpoint: pointer to the OF endpoint data structure | |
| 532 | + * | |
| 533 | + * The caller should hold a reference to @node. | |
| 534 | + */ | |
| 535 | +int of_graph_parse_endpoint(const struct device_node *node, | |
| 536 | + struct of_endpoint *endpoint) | |
| 537 | +{ | |
| 538 | + struct device_node *port_node = of_get_parent(node); | |
| 539 | + | |
| 540 | + WARN_ONCE(!port_node, "%s(): endpoint %s has no parent node\n", | |
| 541 | + __func__, node->full_name); | |
| 542 | + | |
| 543 | + memset(endpoint, 0, sizeof(*endpoint)); | |
| 544 | + | |
| 545 | + endpoint->local_node = node; | |
| 546 | + /* | |
| 547 | + * It doesn't matter whether the two calls below succeed. | |
| 548 | + * If they don't then the default value 0 is used. | |
| 549 | + */ | |
| 550 | + of_property_read_u32(port_node, "reg", &endpoint->port); | |
| 551 | + of_property_read_u32(node, "reg", &endpoint->id); | |
| 552 | + | |
| 553 | + of_node_put(port_node); | |
| 554 | + | |
| 555 | + return 0; | |
| 556 | +} | |
| 557 | +EXPORT_SYMBOL(of_graph_parse_endpoint); | |
| 558 | + | |
| 559 | +/** | |
| 560 | + * of_graph_get_port_by_id() - get the port matching a given id | |
| 561 | + * @parent: pointer to the parent device node | |
| 562 | + * @id: id of the port | |
| 563 | + * | |
| 564 | + * Return: A 'port' node pointer with refcount incremented. The caller | |
| 565 | + * has to use of_node_put() on it when done. | |
| 566 | + */ | |
| 567 | +struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id) | |
| 568 | +{ | |
| 569 | + struct device_node *node, *port; | |
| 570 | + | |
| 571 | + node = of_get_child_by_name(parent, "ports"); | |
| 572 | + if (node) | |
| 573 | + parent = node; | |
| 574 | + | |
| 575 | + for_each_child_of_node(parent, port) { | |
| 576 | + u32 port_id = 0; | |
| 577 | + | |
| 578 | + if (of_node_cmp(port->name, "port") != 0) | |
| 579 | + continue; | |
| 580 | + of_property_read_u32(port, "reg", &port_id); | |
| 581 | + if (id == port_id) | |
| 582 | + break; | |
| 583 | + } | |
| 584 | + | |
| 585 | + of_node_put(node); | |
| 586 | + | |
| 587 | + return port; | |
| 588 | +} | |
| 589 | +EXPORT_SYMBOL(of_graph_get_port_by_id); | |
| 590 | + | |
| 591 | +/** | |
| 592 | + * of_graph_get_next_endpoint() - get next endpoint node | |
| 593 | + * @parent: pointer to the parent device node | |
| 594 | + * @prev: previous endpoint node, or NULL to get first | |
| 595 | + * | |
| 596 | + * Return: An 'endpoint' node pointer with refcount incremented. Refcount | |
| 597 | + * of the passed @prev node is decremented. | |
| 598 | + */ | |
| 599 | +struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, | |
| 600 | + struct device_node *prev) | |
| 601 | +{ | |
| 602 | + struct device_node *endpoint; | |
| 603 | + struct device_node *port; | |
| 604 | + | |
| 605 | + if (!parent) | |
| 606 | + return NULL; | |
| 607 | + | |
| 608 | + /* | |
| 609 | + * Start by locating the port node. If no previous endpoint is specified | |
| 610 | + * search for the first port node, otherwise get the previous endpoint | |
| 611 | + * parent port node. | |
| 612 | + */ | |
| 613 | + if (!prev) { | |
| 614 | + struct device_node *node; | |
| 615 | + | |
| 616 | + node = of_get_child_by_name(parent, "ports"); | |
| 617 | + if (node) | |
| 618 | + parent = node; | |
| 619 | + | |
| 620 | + port = of_get_child_by_name(parent, "port"); | |
| 621 | + of_node_put(node); | |
| 622 | + | |
| 623 | + if (!port) { | |
| 624 | + pr_err("graph: no port node found in %s\n", | |
| 625 | + parent->full_name); | |
| 626 | + return NULL; | |
| 627 | + } | |
| 628 | + } else { | |
| 629 | + port = of_get_parent(prev); | |
| 630 | + if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n", | |
| 631 | + __func__, prev->full_name)) | |
| 632 | + return NULL; | |
| 633 | + } | |
| 634 | + | |
| 635 | + while (1) { | |
| 636 | + /* | |
| 637 | + * Now that we have a port node, get the next endpoint by | |
| 638 | + * getting the next child. If the previous endpoint is NULL this | |
| 639 | + * will return the first child. | |
| 640 | + */ | |
| 641 | + endpoint = of_get_next_child(port, prev); | |
| 642 | + if (endpoint) { | |
| 643 | + of_node_put(port); | |
| 644 | + return endpoint; | |
| 645 | + } | |
| 646 | + | |
| 647 | + /* No more endpoints under this port, try the next one. */ | |
| 648 | + prev = NULL; | |
| 649 | + | |
| 650 | + do { | |
| 651 | + port = of_get_next_child(parent, port); | |
| 652 | + if (!port) | |
| 653 | + return NULL; | |
| 654 | + } while (of_node_cmp(port->name, "port")); | |
| 655 | + } | |
| 656 | +} | |
| 657 | +EXPORT_SYMBOL(of_graph_get_next_endpoint); | |
| 658 | + | |
| 659 | +/** | |
| 660 | + * of_graph_get_endpoint_by_regs() - get endpoint node of specific identifiers | |
| 661 | + * @parent: pointer to the parent device node | |
| 662 | + * @port_reg: identifier (value of reg property) of the parent port node | |
| 663 | + * @reg: identifier (value of reg property) of the endpoint node | |
| 664 | + * | |
| 665 | + * Return: An 'endpoint' node pointer which is identified by reg and at the same | |
| 666 | + * is the child of a port node identified by port_reg. reg and port_reg are | |
| 667 | + * ignored when they are -1. | |
| 668 | + */ | |
| 669 | +struct device_node *of_graph_get_endpoint_by_regs( | |
| 670 | + const struct device_node *parent, int port_reg, int reg) | |
| 671 | +{ | |
| 672 | + struct of_endpoint endpoint; | |
| 673 | + struct device_node *node = NULL; | |
| 674 | + | |
| 675 | + for_each_endpoint_of_node(parent, node) { | |
| 676 | + of_graph_parse_endpoint(node, &endpoint); | |
| 677 | + if (((port_reg == -1) || (endpoint.port == port_reg)) && | |
| 678 | + ((reg == -1) || (endpoint.id == reg))) | |
| 679 | + return node; | |
| 680 | + } | |
| 681 | + | |
| 682 | + return NULL; | |
| 683 | +} | |
| 684 | +EXPORT_SYMBOL(of_graph_get_endpoint_by_regs); | |
| 685 | + | |
| 686 | +/** | |
| 687 | + * of_graph_get_remote_endpoint() - get remote endpoint node | |
| 688 | + * @node: pointer to a local endpoint device_node | |
| 689 | + * | |
| 690 | + * Return: Remote endpoint node associated with remote endpoint node linked | |
| 691 | + * to @node. Use of_node_put() on it when done. | |
| 692 | + */ | |
| 693 | +struct device_node *of_graph_get_remote_endpoint(const struct device_node *node) | |
| 694 | +{ | |
| 695 | + /* Get remote endpoint node. */ | |
| 696 | + return of_parse_phandle(node, "remote-endpoint", 0); | |
| 697 | +} | |
| 698 | +EXPORT_SYMBOL(of_graph_get_remote_endpoint); | |
| 699 | + | |
| 700 | +/** | |
| 701 | + * of_graph_get_port_parent() - get port's parent node | |
| 702 | + * @node: pointer to a local endpoint device_node | |
| 703 | + * | |
| 704 | + * Return: device node associated with endpoint node linked | |
| 705 | + * to @node. Use of_node_put() on it when done. | |
| 706 | + */ | |
| 707 | +struct device_node *of_graph_get_port_parent(struct device_node *node) | |
| 708 | +{ | |
| 709 | + unsigned int depth; | |
| 710 | + | |
| 711 | + /* Walk 3 levels up only if there is 'ports' node. */ | |
| 712 | + for (depth = 3; depth && node; depth--) { | |
| 713 | + node = of_get_next_parent(node); | |
| 714 | + if (depth == 2 && of_node_cmp(node->name, "ports")) | |
| 715 | + break; | |
| 716 | + } | |
| 717 | + return node; | |
| 718 | +} | |
| 719 | +EXPORT_SYMBOL(of_graph_get_port_parent); | |
| 720 | + | |
| 721 | +/** | |
| 722 | + * of_graph_get_remote_port_parent() - get remote port's parent node | |
| 723 | + * @node: pointer to a local endpoint device_node | |
| 724 | + * | |
| 725 | + * Return: Remote device node associated with remote endpoint node linked | |
| 726 | + * to @node. Use of_node_put() on it when done. | |
| 727 | + */ | |
| 728 | +struct device_node *of_graph_get_remote_port_parent( | |
| 729 | + const struct device_node *node) | |
| 730 | +{ | |
| 731 | + struct device_node *np; | |
| 732 | + | |
| 733 | + /* Get remote endpoint node. */ | |
| 734 | + np = of_graph_get_remote_endpoint(node); | |
| 735 | + | |
| 736 | + return of_graph_get_port_parent(np); | |
| 737 | +} | |
| 738 | +EXPORT_SYMBOL(of_graph_get_remote_port_parent); | |
| 739 | + | |
| 740 | +/** | |
| 741 | + * of_graph_get_remote_port() - get remote port node | |
| 742 | + * @node: pointer to a local endpoint device_node | |
| 743 | + * | |
| 744 | + * Return: Remote port node associated with remote endpoint node linked | |
| 745 | + * to @node. Use of_node_put() on it when done. | |
| 746 | + */ | |
| 747 | +struct device_node *of_graph_get_remote_port(const struct device_node *node) | |
| 748 | +{ | |
| 749 | + struct device_node *np; | |
| 750 | + | |
| 751 | + /* Get remote endpoint node. */ | |
| 752 | + np = of_graph_get_remote_endpoint(node); | |
| 753 | + if (!np) | |
| 754 | + return NULL; | |
| 755 | + return of_get_next_parent(np); | |
| 756 | +} | |
| 757 | +EXPORT_SYMBOL(of_graph_get_remote_port); | |
| 758 | + | |
| 759 | +int of_graph_get_endpoint_count(const struct device_node *np) | |
| 760 | +{ | |
| 761 | + struct device_node *endpoint; | |
| 762 | + int num = 0; | |
| 763 | + | |
| 764 | + for_each_endpoint_of_node(np, endpoint) | |
| 765 | + num++; | |
| 766 | + | |
| 767 | + return num; | |
| 768 | +} | |
| 769 | +EXPORT_SYMBOL(of_graph_get_endpoint_count); | |
| 770 | + | |
| 771 | +/** | |
| 772 | + * of_graph_get_remote_node() - get remote parent device_node for given port/endpoint | |
| 773 | + * @node: pointer to parent device_node containing graph port/endpoint | |
| 774 | + * @port: identifier (value of reg property) of the parent port node | |
| 775 | + * @endpoint: identifier (value of reg property) of the endpoint node | |
| 776 | + * | |
| 777 | + * Return: Remote device node associated with remote endpoint node linked | |
| 778 | + * to @node. Use of_node_put() on it when done. | |
| 779 | + */ | |
| 780 | +struct device_node *of_graph_get_remote_node(const struct device_node *node, | |
| 781 | + u32 port, u32 endpoint) | |
| 782 | +{ | |
| 783 | + struct device_node *endpoint_node, *remote; | |
| 784 | + | |
| 785 | + endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint); | |
| 786 | + if (!endpoint_node) { | |
| 787 | + pr_debug("no valid endpoint (%d, %d) for node %s\n", | |
| 788 | + port, endpoint, node->full_name); | |
| 789 | + return NULL; | |
| 790 | + } | |
| 791 | + | |
| 792 | + remote = of_graph_get_remote_port_parent(endpoint_node); | |
| 793 | + of_node_put(endpoint_node); | |
| 794 | + if (!remote) { | |
| 795 | + pr_debug("no valid remote node\n"); | |
| 796 | + return NULL; | |
| 797 | + } | |
| 798 | + | |
| 799 | + if (!of_device_is_available(remote)) { | |
| 800 | + pr_debug("not available for remote node\n"); | |
| 801 | + return NULL; | |
| 802 | + } | |
| 803 | + | |
| 804 | + return remote; | |
| 805 | +} | |
| 806 | +EXPORT_SYMBOL(of_graph_get_remote_node); | |
| @@ -20,35 +20,11 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <linux/errno.h> |
| 21 | 21 | #include <linux/slab.h> |
| 22 | 22 | |
| 23 | +#include "of_private.h" | |
| 24 | + | |
| 23 | 25 | /* illegal phandle value (set when unresolved) */ |
| 24 | 26 | #define OF_PHANDLE_ILLEGAL 0xdeadbeef |
| 25 | 27 | |
| 26 | −/** | |
| 27 | − * Find a node with the give full name by recursively following any of | |
| 28 | − * the child node links. | |
| 29 | − */ | |
| 30 | −static struct device_node *find_node_by_full_name(struct device_node *node, | |
| 31 | − const char *full_name) | |
| 32 | −{ | |
| 33 | − struct device_node *child, *found; | |
| 34 | − | |
| 35 | − if (!node) | |
| 36 | − return NULL; | |
| 37 | − | |
| 38 | − if (!of_node_cmp(node->full_name, full_name)) | |
| 39 | − return of_node_get(node); | |
| 40 | − | |
| 41 | − for_each_child_of_node(node, child) { | |
| 42 | − found = find_node_by_full_name(child, full_name); | |
| 43 | − if (found != NULL) { | |
| 44 | − of_node_put(child); | |
| 45 | − return found; | |
| 46 | − } | |
| 47 | − } | |
| 48 | − | |
| 49 | − return NULL; | |
| 50 | −} | |
| 51 | − | |
| 52 | 28 | static phandle live_tree_max_phandle(void) |
| 53 | 29 | { |
| 54 | 30 | struct device_node *node; |
| @@ -138,7 +114,7 @@ static int update_usages_of_a_phandle_reference(struct device_node *overlay, · 83 unmodified lines | ||
| 138 | 114 | if (err) |
| 139 | 115 | goto err_fail; |
| 140 | 116 | |
| 141 | − refnode = find_node_by_full_name(overlay, node_path); | |
| 117 | + refnode = __of_find_node_by_full_path(of_node_get(overlay), node_path); | |
| 142 | 118 | if (!refnode) |
| 143 | 119 | continue; |
| 144 | 120 | |
| @@ -165,8 +141,8 @@ err_fail: · 20 unmodified lines | ||
| 165 | 141 | static int node_name_cmp(const struct device_node *dn1, |
| 166 | 142 | const struct device_node *dn2) |
| 167 | 143 | { |
| 168 | − const char *n1 = strrchr(dn1->full_name, '/') ? : "/"; | |
| 169 | − const char *n2 = strrchr(dn2->full_name, '/') ? : "/"; | |
| 144 | + const char *n1 = kbasename(dn1->full_name); | |
| 145 | + const char *n2 = kbasename(dn2->full_name); | |
| 170 | 146 | |
| 171 | 147 | return of_node_cmp(n1, n2); |
| 172 | 148 | } |
| @@ -26,7 +26,9 @@ · 25 unmodified lines | ||
| 26 | 26 | #size-cells = <0>; |
| 27 | 27 | |
| 28 | 28 | dev@100 { |
| 29 | − compatible = "test-sub-device"; | |
| 29 | + compatible = "test-sub-device", | |
| 30 | + "test-compat2", | |
| 31 | + "test-compat3"; | |
| 30 | 32 | reg = <0x100>; |
| 31 | 33 | }; |
| 32 | 34 | }; |
| @@ -239,6 +239,63 @@ static void __init of_unittest_check_tree_linkage(void) · 238 unmodified lines | ||
| 239 | 239 | pr_debug("allnodes list size (%i); sibling lists size (%i)\n", allnode_count, child_count); |
| 240 | 240 | } |
| 241 | 241 | |
| 242 | +static void __init of_unittest_printf_one(struct device_node *np, const char *fmt, | |
| 243 | + const char *expected) | |
| 244 | +{ | |
| 245 | + unsigned char buf[strlen(expected)+10]; | |
| 246 | + int size, i; | |
| 247 | + | |
| 248 | + /* Baseline; check conversion with a large size limit */ | |
| 249 | + memset(buf, 0xff, sizeof(buf)); | |
| 250 | + size = snprintf(buf, sizeof(buf) - 2, fmt, np); | |
| 251 | + | |
| 252 | + /* use strcmp() instead of strncmp() here to be absolutely sure strings match */ | |
| 253 | + unittest((strcmp(buf, expected) == 0) && (buf[size+1] == 0xff), | |
| 254 | + "sprintf failed; fmt='%s' expected='%s' rslt='%s'\n", | |
| 255 | + fmt, expected, buf); | |
| 256 | + | |
| 257 | + /* Make sure length limits work */ | |
| 258 | + size++; | |
| 259 | + for (i = 0; i < 2; i++, size--) { | |
| 260 | + /* Clear the buffer, and make sure it works correctly still */ | |
| 261 | + memset(buf, 0xff, sizeof(buf)); | |
| 262 | + snprintf(buf, size+1, fmt, np); | |
| 263 | + unittest(strncmp(buf, expected, size) == 0 && (buf[size+1] == 0xff), | |
| 264 | + "snprintf failed; size=%i fmt='%s' expected='%s' rslt='%s'\n", | |
| 265 | + size, fmt, expected, buf); | |
| 266 | + } | |
| 267 | +} | |
| 268 | + | |
| 269 | +static void __init of_unittest_printf(void) | |
| 270 | +{ | |
| 271 | + struct device_node *np; | |
| 272 | + const char *full_name = "/testcase-data/platform-tests/test-device@1/dev@100"; | |
| 273 | + char phandle_str[16] = ""; | |
| 274 | + | |
| 275 | + np = of_find_node_by_path(full_name); | |
| 276 | + if (!np) { | |
| 277 | + unittest(np, "testcase data missing\n"); | |
| 278 | + return; | |
| 279 | + } | |
| 280 | + | |
| 281 | + num_to_str(phandle_str, sizeof(phandle_str), np->phandle); | |
| 282 | + | |
| 283 | + of_unittest_printf_one(np, "%pOF", full_name); | |
| 284 | + of_unittest_printf_one(np, "%pOFf", full_name); | |
| 285 | + of_unittest_printf_one(np, "%pOFp", phandle_str); | |
| 286 | + of_unittest_printf_one(np, "%pOFP", "dev@100"); | |
| 287 | + of_unittest_printf_one(np, "ABC %pOFP ABC", "ABC dev@100 ABC"); | |
| 288 | + of_unittest_printf_one(np, "%10pOFP", " dev@100"); | |
| 289 | + of_unittest_printf_one(np, "%-10pOFP", "dev@100 "); | |
| 290 | + of_unittest_printf_one(of_root, "%pOFP", "/"); | |
| 291 | + of_unittest_printf_one(np, "%pOFF", "----"); | |
| 292 | + of_unittest_printf_one(np, "%pOFPF", "dev@100:----"); | |
| 293 | + of_unittest_printf_one(np, "%pOFPFPc", "dev@100:----:dev@100:test-sub-device"); | |
| 294 | + of_unittest_printf_one(np, "%pOFc", "test-sub-device"); | |
| 295 | + of_unittest_printf_one(np, "%pOFC", | |
| 296 | + "\"test-sub-device\",\"test-compat2\",\"test-compat3\""); | |
| 297 | +} | |
| 298 | + | |
| 242 | 299 | struct node_hash { |
| 243 | 300 | struct hlist_node node; |
| 244 | 301 | struct device_node *np; |
| @@ -2269,6 +2326,7 @@ static int __init of_unittest(void) · 2024 unmodified lines | ||
| 2269 | 2326 | of_unittest_find_node_by_name(); |
| 2270 | 2327 | of_unittest_dynamic(); |
| 2271 | 2328 | of_unittest_parse_phandle_with_args(); |
| 2329 | + of_unittest_printf(); | |
| 2272 | 2330 | of_unittest_property_string(); |
| 2273 | 2331 | of_unittest_property_copy(); |
| 2274 | 2332 | of_unittest_changeset(); |
| @@ -148,18 +148,28 @@ extern raw_spinlock_t devtree_lock; · 147 unmodified lines | ||
| 148 | 148 | #ifdef CONFIG_OF |
| 149 | 149 | void of_core_init(void); |
| 150 | 150 | |
| 151 | −static inline bool is_of_node(struct fwnode_handle *fwnode) | |
| 151 | +static inline bool is_of_node(const struct fwnode_handle *fwnode) | |
| 152 | 152 | { |
| 153 | 153 | return !IS_ERR_OR_NULL(fwnode) && fwnode->type == FWNODE_OF; |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | −static inline struct device_node *to_of_node(struct fwnode_handle *fwnode) | |
| 157 | −{ | |
| 158 | − return is_of_node(fwnode) ? | |
| 159 | − container_of(fwnode, struct device_node, fwnode) : NULL; | |
| 160 | −} | |
| 161 | − | |
| 162 | −#define of_fwnode_handle(node) (&(node)->fwnode) | |
| 156 | +#define to_of_node(__fwnode) \ | |
| 157 | + ({ \ | |
| 158 | + typeof(__fwnode) __to_of_node_fwnode = (__fwnode); \ | |
| 159 | + \ | |
| 160 | + is_of_node(__to_of_node_fwnode) ? \ | |
| 161 | + container_of(__to_of_node_fwnode, \ | |
| 162 | + struct device_node, fwnode) : \ | |
| 163 | + NULL; \ | |
| 164 | + }) | |
| 165 | + | |
| 166 | +#define of_fwnode_handle(node) \ | |
| 167 | + ({ \ | |
| 168 | + typeof(node) __of_fwnode_handle_node = (node); \ | |
| 169 | + \ | |
| 170 | + __of_fwnode_handle_node ? \ | |
| 171 | + &__of_fwnode_handle_node->fwnode : NULL; \ | |
| 172 | + }) | |
| 163 | 173 | |
| 164 | 174 | static inline bool of_have_populated_dt(void) |
| 165 | 175 | { |
| @@ -533,12 +543,12 @@ static inline void of_core_init(void) · 367 unmodified lines | ||
| 533 | 543 | { |
| 534 | 544 | } |
| 535 | 545 | |
| 536 | −static inline bool is_of_node(struct fwnode_handle *fwnode) | |
| 546 | +static inline bool is_of_node(const struct fwnode_handle *fwnode) | |
| 537 | 547 | { |
| 538 | 548 | return false; |
| 539 | 549 | } |
| 540 | 550 | |
| 541 | −static inline struct device_node *to_of_node(struct fwnode_handle *fwnode) | |
| 551 | +static inline struct device_node *to_of_node(const struct fwnode_handle *fwnode) | |
| 542 | 552 | { |
| 543 | 553 | return NULL; |
| 544 | 554 | } |
| @@ -627,6 +637,12 @@ static inline int of_device_is_compatible(const struct device_node *device, · 82 unmodified lines | ||
| 627 | 637 | return 0; |
| 628 | 638 | } |
| 629 | 639 | |
| 640 | +static inline int of_device_compatible_match(struct device_node *device, | |
| 641 | + const char *const *compat) | |
| 642 | +{ | |
| 643 | + return 0; | |
| 644 | +} | |
| 645 | + | |
| 630 | 646 | static inline bool of_device_is_available(const struct device_node *device) |
| 631 | 647 | { |
| 632 | 648 | return false; |
| @@ -31,9 +31,6 @@ extern void *of_fdt_get_property(const void *blob, · 30 unmodified lines | ||
| 31 | 31 | unsigned long node, |
| 32 | 32 | const char *name, |
| 33 | 33 | int *size); |
| 34 | −extern int of_fdt_is_compatible(const void *blob, | |
| 35 | − unsigned long node, | |
| 36 | − const char *compat); | |
| 37 | 34 | extern bool of_fdt_is_big_endian(const void *blob, |
| 38 | 35 | unsigned long node); |
| 39 | 36 | extern int of_fdt_match(const void *blob, unsigned long node, |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | #include <linux/dcache.h> |
| 32 | 32 | #include <linux/cred.h> |
| 33 | 33 | #include <linux/uuid.h> |
| 34 | +#include <linux/of.h> | |
| 34 | 35 | #include <net/addrconf.h> |
| 35 | 36 | #ifdef CONFIG_BLOCK |
| 36 | 37 | #include <linux/blkdev.h> |
| @@ -1470,6 +1471,126 @@ char *flags_string(char *buf, char *end, void *flags_ptr, const char *fmt) · 1433 unmodified lines | ||
| 1470 | 1471 | return format_flags(buf, end, flags, names); |
| 1471 | 1472 | } |
| 1472 | 1473 | |
| 1474 | +static const char *device_node_name_for_depth(const struct device_node *np, int depth) | |
| 1475 | +{ | |
| 1476 | + for ( ; np && depth; depth--) | |
| 1477 | + np = np->parent; | |
| 1478 | + | |
| 1479 | + return kbasename(np->full_name); | |
| 1480 | +} | |
| 1481 | + | |
| 1482 | +static noinline_for_stack | |
| 1483 | +char *device_node_gen_full_name(const struct device_node *np, char *buf, char *end) | |
| 1484 | +{ | |
| 1485 | + int depth; | |
| 1486 | + const struct device_node *parent = np->parent; | |
| 1487 | + static const struct printf_spec strspec = { | |
| 1488 | + .field_width = -1, | |
| 1489 | + .precision = -1, | |
| 1490 | + }; | |
| 1491 | + | |
| 1492 | + /* special case for root node */ | |
| 1493 | + if (!parent) | |
| 1494 | + return string(buf, end, "/", strspec); | |
| 1495 | + | |
| 1496 | + for (depth = 0; parent->parent; depth++) | |
| 1497 | + parent = parent->parent; | |
| 1498 | + | |
| 1499 | + for ( ; depth >= 0; depth--) { | |
| 1500 | + buf = string(buf, end, "/", strspec); | |
| 1501 | + buf = string(buf, end, device_node_name_for_depth(np, depth), | |
| 1502 | + strspec); | |
| 1503 | + } | |
| 1504 | + return buf; | |
| 1505 | +} | |
| 1506 | + | |
| 1507 | +static noinline_for_stack | |
| 1508 | +char *device_node_string(char *buf, char *end, struct device_node *dn, | |
| 1509 | + struct printf_spec spec, const char *fmt) | |
| 1510 | +{ | |
| 1511 | + char tbuf[sizeof("xxxx") + 1]; | |
| 1512 | + const char *p; | |
| 1513 | + int ret; | |
| 1514 | + char *buf_start = buf; | |
| 1515 | + struct property *prop; | |
| 1516 | + bool has_mult, pass; | |
| 1517 | + static const struct printf_spec num_spec = { | |
| 1518 | + .flags = SMALL, | |
| 1519 | + .field_width = -1, | |
| 1520 | + .precision = -1, | |
| 1521 | + .base = 10, | |
| 1522 | + }; | |
| 1523 | + | |
| 1524 | + struct printf_spec str_spec = spec; | |
| 1525 | + str_spec.field_width = -1; | |
| 1526 | + | |
| 1527 | + if (!IS_ENABLED(CONFIG_OF)) | |
| 1528 | + return string(buf, end, "(!OF)", spec); | |
| 1529 | + | |
| 1530 | + if ((unsigned long)dn < PAGE_SIZE) | |
| 1531 | + return string(buf, end, "(null)", spec); | |
| 1532 | + | |
| 1533 | + /* simple case without anything any more format specifiers */ | |
| 1534 | + fmt++; | |
| 1535 | + if (fmt[0] == '\0' || strcspn(fmt,"fnpPFcC") > 0) | |
| 1536 | + fmt = "f"; | |
| 1537 | + | |
| 1538 | + for (pass = false; strspn(fmt,"fnpPFcC"); fmt++, pass = true) { | |
| 1539 | + if (pass) { | |
| 1540 | + if (buf < end) | |
| 1541 | + *buf = ':'; | |
| 1542 | + buf++; | |
| 1543 | + } | |
| 1544 | + | |
| 1545 | + switch (*fmt) { | |
| 1546 | + case 'f': /* full_name */ | |
| 1547 | + buf = device_node_gen_full_name(dn, buf, end); | |
| 1548 | + break; | |
| 1549 | + case 'n': /* name */ | |
| 1550 | + buf = string(buf, end, dn->name, str_spec); | |
| 1551 | + break; | |
| 1552 | + case 'p': /* phandle */ | |
| 1553 | + buf = number(buf, end, (unsigned int)dn->phandle, num_spec); | |
| 1554 | + break; | |
| 1555 | + case 'P': /* path-spec */ | |
| 1556 | + p = kbasename(of_node_full_name(dn)); | |
| 1557 | + if (!p[1]) | |
| 1558 | + p = "/"; | |
| 1559 | + buf = string(buf, end, p, str_spec); | |
| 1560 | + break; | |
| 1561 | + case 'F': /* flags */ | |
| 1562 | + tbuf[0] = of_node_check_flag(dn, OF_DYNAMIC) ? 'D' : '-'; | |
| 1563 | + tbuf[1] = of_node_check_flag(dn, OF_DETACHED) ? 'd' : '-'; | |
| 1564 | + tbuf[2] = of_node_check_flag(dn, OF_POPULATED) ? 'P' : '-'; | |
| 1565 | + tbuf[3] = of_node_check_flag(dn, OF_POPULATED_BUS) ? 'B' : '-'; | |
| 1566 | + tbuf[4] = 0; | |
| 1567 | + buf = string(buf, end, tbuf, str_spec); | |
| 1568 | + break; | |
| 1569 | + case 'c': /* major compatible string */ | |
| 1570 | + ret = of_property_read_string(dn, "compatible", &p); | |
| 1571 | + if (!ret) | |
| 1572 | + buf = string(buf, end, p, str_spec); | |
| 1573 | + break; | |
| 1574 | + case 'C': /* full compatible string */ | |
| 1575 | + has_mult = false; | |
| 1576 | + of_property_for_each_string(dn, "compatible", prop, p) { | |
| 1577 | + if (has_mult) | |
| 1578 | + buf = string(buf, end, ",", str_spec); | |
| 1579 | + buf = string(buf, end, "\"", str_spec); | |
| 1580 | + buf = string(buf, end, p, str_spec); | |
| 1581 | + buf = string(buf, end, "\"", str_spec); | |
| 1582 | + | |
| 1583 | + has_mult = true; | |
| 1584 | + } | |
| 1585 | + break; | |
| 1586 | + default: | |
| 1587 | + break; | |
| 1588 | + } | |
| 1589 | + } | |
| 1590 | + | |
| 1591 | + return widen_string(buf, buf - buf_start, end, spec); | |
| 1592 | +} | |
| 1593 | + | |
| 1473 | 1594 | int kptr_restrict __read_mostly; |
| 1474 | 1595 | |
| 1475 | 1596 | /* |
| @@ -1566,6 +1687,16 @@ int kptr_restrict __read_mostly; · 90 unmodified lines | ||
| 1566 | 1687 | * p page flags (see struct page) given as pointer to unsigned long |
| 1567 | 1688 | * g gfp flags (GFP_* and __GFP_*) given as pointer to gfp_t |
| 1568 | 1689 | * v vma flags (VM_*) given as pointer to unsigned long |
| 1690 | + * - 'O' For a kobject based struct. Must be one of the following: | |
| 1691 | + * - 'OF[fnpPcCF]' For a device tree object | |
| 1692 | + * Without any optional arguments prints the full_name | |
| 1693 | + * f device node full_name | |
| 1694 | + * n device node name | |
| 1695 | + * p device node phandle | |
| 1696 | + * P device node path spec (name + @unit) | |
| 1697 | + * F device node flags | |
| 1698 | + * c major compatible string | |
| 1699 | + * C full compatible string | |
| 1569 | 1700 | * |
| 1570 | 1701 | * ** Please update also Documentation/printk-formats.txt when making changes ** |
| 1571 | 1702 | * |
| @@ -1721,6 +1852,11 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, · 149 unmodified lines | ||
| 1721 | 1852 | |
| 1722 | 1853 | case 'G': |
| 1723 | 1854 | return flags_string(buf, end, ptr, fmt); |
| 1855 | + case 'O': | |
| 1856 | + switch (fmt[1]) { | |
| 1857 | + case 'F': | |
| 1858 | + return device_node_string(buf, end, ptr, spec, fmt + 1); | |
| 1859 | + } | |
| 1724 | 1860 | } |
| 1725 | 1861 | spec.flags |= SMALL; |
| 1726 | 1862 | if (spec.field_width == -1) { |
| @@ -5692,7 +5692,7 @@ sub process { · 5691 unmodified lines | ||
| 5692 | 5692 | for (my $count = $linenr; $count <= $lc; $count++) { |
| 5693 | 5693 | my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); |
| 5694 | 5694 | $fmt =~ s/%%//g; |
| 5695 | − if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGN]).)/) { | |
| 5695 | + if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) { | |
| 5696 | 5696 | $bad_extension = $1; |
| 5697 | 5697 | last; |
| 5698 | 5698 | } |
| @@ -338,7 +338,7 @@ DTC="${DTC} ${dtc_flags} -O dts -qq -f ${dtc_sort} -o -" · 337 unmodified lines | ||
| 338 | 338 | |
| 339 | 339 | if (( ${cmd_diff} )) ; then |
| 340 | 340 | |
| 341 | − diff ${diff_flags} \ | |
| 341 | + diff ${diff_flags} --label "${dtx_file_1}" --label "${dtx_file_2}" \ | |
| 342 | 342 | <(compile_to_dts "${dtx_file_1}") \ |
| 343 | 343 | <(compile_to_dts "${dtx_file_2}") |
| 344 | 344 | |