diff options
-rw-r--r-- | Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt | 4 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/mfd/max77693.txt | 12 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt | 99 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/net/wireless/esp,esp8089.txt | 31 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt | 7 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt | 5 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/spi/spi-bus.txt | 2 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/vendor-prefixes.txt | 35 | ||||
-rw-r--r-- | Documentation/devicetree/changesets.txt | 19 | ||||
-rw-r--r-- | drivers/of/base.c | 171 | ||||
-rw-r--r-- | drivers/of/platform.c | 2 | ||||
-rw-r--r-- | include/linux/of.h | 144 |
12 files changed, 423 insertions, 108 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt index ae5054c27c99..e3f052d8c11a 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,irqc.txt @@ -1,10 +1,12 @@ -DT bindings for the R-Mobile/R-Car interrupt controller +DT bindings for the R-Mobile/R-Car/RZ/G interrupt controller Required properties: - compatible: has to be "renesas,irqc-<soctype>", "renesas,irqc" as fallback. Examples with soctypes are: - "renesas,irqc-r8a73a4" (R-Mobile APE6) + - "renesas,irqc-r8a7743" (RZ/G1M) + - "renesas,irqc-r8a7745" (RZ/G1E) - "renesas,irqc-r8a7790" (R-Car H2) - "renesas,irqc-r8a7791" (R-Car M2-W) - "renesas,irqc-r8a7792" (R-Car V2H) diff --git a/Documentation/devicetree/bindings/mfd/max77693.txt b/Documentation/devicetree/bindings/mfd/max77693.txt index d3425846aa5b..6a1ae3a2b77f 100644 --- a/Documentation/devicetree/bindings/mfd/max77693.txt +++ b/Documentation/devicetree/bindings/mfd/max77693.txt @@ -17,28 +17,28 @@ Required properties: - interrupt-parent : The parent interrupt controller. Optional properties: -- regulators : The regulators of max77693 have to be instantiated under subnod +- regulators : The regulators of max77693 have to be instantiated under subnode named "regulators" using the following format. regulators { - regualtor-compatible = ESAFEOUT1/ESAFEOUT2/CHARGER - standard regulator constratints[*]. + regulator-compatible = ESAFEOUT1/ESAFEOUT2/CHARGER + standard regulator constraints[*]. }; [*] refer Documentation/devicetree/bindings/regulator/regulator.txt - haptic : The MAX77693 haptic device utilises a PWM controlled motor to provide users with tactile feedback. PWM period and duty-cycle are varied in - order to provide the approprite level of feedback. + order to provide the appropriate level of feedback. Required properties: - - compatible : Must be "maxim,max77693-hpatic" + - compatible : Must be "maxim,max77693-haptic" - haptic-supply : power supply for the haptic motor [*] refer Documentation/devicetree/bindings/regulator/regulator.txt - pwms : phandle to the physical PWM(Pulse Width Modulation) device. PWM properties should be named "pwms". And number of cell is different for each pwm device. - To get more informations, please refer to documentaion. + To get more information, please refer to documentation. [*] refer Documentation/devicetree/bindings/pwm/pwm.txt - charger : Node configuring the charger driver. diff --git a/Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt b/Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt index 51f8d2eba8d8..d93f71ce8346 100644 --- a/Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt +++ b/Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt @@ -1,21 +1,111 @@ * Synopsys DWC Ethernet QoS IP version 4.10 driver (GMAC) +This binding supports the Synopsys Designware Ethernet QoS (Quality Of Service) +IP block. The IP supports multiple options for bus type, clocking and reset +structure, and feature list. Consequently, a number of properties and list +entries in properties are marked as optional, or only required in specific HW +configurations. Required properties: -- compatible: Should be "snps,dwc-qos-ethernet-4.10" +- compatible: One of: + - "axis,artpec6-eqos", "snps,dwc-qos-ethernet-4.10" + Represents the IP core when integrated into the Axis ARTPEC-6 SoC. + - "nvidia,tegra186-eqos", "snps,dwc-qos-ethernet-4.10" + Represents the IP core when integrated into the NVIDIA Tegra186 SoC. + - "snps,dwc-qos-ethernet-4.10" + This combination is deprecated. It should be treated as equivalent to + "axis,artpec6-eqos", "snps,dwc-qos-ethernet-4.10". It is supported to be + compatible with earlier revisions of this binding. - reg: Address and length of the register set for the device -- clocks: Phandles to the reference clock and the bus clock -- clock-names: Should be "phy_ref_clk" for the reference clock and "apb_pclk" - for the bus clock. +- clocks: Phandle and clock specifiers for each entry in clock-names, in the + same order. See ../clock/clock-bindings.txt. +- clock-names: May contain any/all of the following depending on the IP + configuration, in any order: + - "tx" + The EQOS transmit path clock. The HW signal name is clk_tx_i. + In some configurations (e.g. GMII/RGMII), this clock also drives the PHY TX + path. In other configurations, other clocks (such as tx_125, rmii) may + drive the PHY TX path. + - "rx" + The EQOS receive path clock. The HW signal name is clk_rx_i. + In some configurations (e.g. GMII/RGMII), this clock is derived from the + PHY's RX clock output. In other configurations, other clocks (such as + rx_125, rmii) may drive the EQOS RX path. + In cases where the PHY clock is directly fed into the EQOS receive path + without intervening logic, the DT need not represent this clock, since it + is assumed to be fully under the control of the PHY device/driver. In + cases where SoC integration adds additional logic to this path, such as a + SW-controlled clock gate, this clock should be represented in DT. + - "slave_bus" + The CPU/slave-bus (CSR) interface clock. This applies to any bus type; + APB, AHB, AXI, etc. The HW signal name is hclk_i (AHB) or clk_csr_i (other + buses). + - "master_bus" + The master bus interface clock. Only required in configurations that use a + separate clock for the master and slave bus interfaces. The HW signal name + is hclk_i (AHB) or aclk_i (AXI). + - "ptp_ref" + The PTP reference clock. The HW signal name is clk_ptp_ref_i. + - "phy_ref_clk" + This clock is deprecated and should not be used by new compatible values. + It is equivalent to "tx". + - "apb_pclk" + This clock is deprecated and should not be used by new compatible values. + It is equivalent to "slave_bus". + + Note: Support for additional IP configurations may require adding the + following clocks to this list in the future: clk_rx_125_i, clk_tx_125_i, + clk_pmarx_0_i, clk_pmarx1_i, clk_rmii_i, clk_revmii_rx_i, clk_revmii_tx_i. + Configurations exist where multiple similar clocks are used at once, e.g. all + of clk_rx_125_i, clk_pmarx_0_i, clk_pmarx1_i. For this reason it is best to + extend the binding with a separate clock-names entry for each of those RX + clocks, rather than repurposing the existing "rx" clock-names entry as a + generic/logical clock in a similar fashion to "master_bus" and "slave_bus". + This will allow easy support for configurations that support multiple PHY + interfaces using a mux, and hence need to have explicit control over + specific RX clocks. + + The following compatible values require the following set of clocks: + - "nvidia,tegra186-eqos", "snps,dwc-qos-ethernet-4.10": + - "slave_bus" + - "master_bus" + - "rx" + - "tx" + - "ptp_ref" + - "axis,artpec6-eqos", "snps,dwc-qos-ethernet-4.10": + - "slave_bus" + - "master_bus" + - "tx" + - "ptp_ref" + - "snps,dwc-qos-ethernet-4.10" (deprecated): + - "phy_ref_clk" + - "apb_clk" - interrupt-parent: Should be the phandle for the interrupt controller that services interrupts for this device - interrupts: Should contain the core's combined interrupt signal - phy-mode: See ethernet.txt file in the same directory +- resets: Phandle and reset specifiers for each entry in reset-names, in the + same order. See ../reset/reset.txt. +- reset-names: May contain any/all of the following depending on the IP + configuration, in any order: + - "eqos". The reset to the entire module. The HW signal name is hreset_n + (AHB) or aresetn_i (AXI). + + The following compatible values require the following set of resets: + (the reset properties may be omitted if empty) + - "nvidia,tegra186-eqos", "snps,dwc-qos-ethernet-4.10": + - "eqos". + - "axis,artpec6-eqos", "snps,dwc-qos-ethernet-4.10": + - None. + - "snps,dwc-qos-ethernet-4.10" (deprecated): + - None. Optional properties: - dma-coherent: Present if dma operations are coherent - mac-address: See ethernet.txt in the same directory - local-mac-address: See ethernet.txt in the same directory +- phy-reset-gpios: Phandle and specifier for any GPIO used to reset the PHY. + See ../gpio/gpio.txt. - snps,en-lpi: If present it enables use of the AXI low-power interface - snps,write-requests: Number of write requests that the AXI port can issue. It depends on the SoC configuration. @@ -52,6 +142,7 @@ ethernet2@40010000 { reg = <0x40010000 0x4000>; phy-handle = <&phy2>; phy-mode = "gmii"; + phy-reset-gpios = <&gpioctlr 43 GPIO_ACTIVE_LOW>; snps,en-tx-lpi-clockgating; snps,en-lpi; diff --git a/Documentation/devicetree/bindings/net/wireless/esp,esp8089.txt b/Documentation/devicetree/bindings/net/wireless/esp,esp8089.txt new file mode 100644 index 000000000000..19331bb4ff6e --- /dev/null +++ b/Documentation/devicetree/bindings/net/wireless/esp,esp8089.txt @@ -0,0 +1,31 @@ +Espressif ESP8089 wireless SDIO devices + +This node provides properties for controlling the ESP8089 wireless device. +The node is expected to be specified as a child node to the SDIO controller +that connects the device to the system. + +Required properties: + + - compatible : Should be "esp,esp8089". + +Optional properties: + - esp,crystal-26M-en: Integer value for the crystal_26M_en firmware parameter + +Example: + +&mmc1 { + #address-cells = <1>; + #size-cells = <0>; + + vmmc-supply = <®_dldo1>; + mmc-pwrseq = <&wifi_pwrseq>; + bus-width = <4>; + non-removable; + status = "okay"; + + esp8089: sdio_wifi@1 { + compatible = "esp,esp8089"; + reg = <1>; + esp,crystal-26M-en = <2>; + }; +}; diff --git a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt index 330a45b5f0b5..5ecaea1e6eee 100644 --- a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt +++ b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt @@ -24,16 +24,17 @@ Example: compatible = "axis,artpec6-pcie", "snps,dw-pcie"; reg = <0xf8050000 0x2000 0xf8040000 0x1000 - 0xc0000000 0x1000>; + 0xc0000000 0x2000>; reg-names = "dbi", "phy", "config"; #address-cells = <3>; #size-cells = <2>; device_type = "pci"; /* downstream I/O */ - ranges = <0x81000000 0 0x00010000 0xc0010000 0 0x00010000 + ranges = <0x81000000 0 0 0xc0002000 0 0x00010000 /* non-prefetchable memory */ - 0x82000000 0 0xc0020000 0xc0020000 0 0x1ffe0000>; + 0x82000000 0 0xc0012000 0xc0012000 0 0x1ffee000>; num-lanes = <2>; + bus-range = <0x00 0xff>; interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "msi"; #interrupt-cells = <1>; diff --git a/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt b/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt index 337fc97d18c9..3259798a1192 100644 --- a/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt +++ b/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt @@ -55,9 +55,10 @@ nwl_pcie: pcie@fd0e0000 { msi-parent = <&nwl_pcie>; reg = <0x0 0xfd0e0000 0x0 0x1000>, <0x0 0xfd480000 0x0 0x1000>, - <0x0 0xe0000000 0x0 0x1000000>; + <0x80 0x00000000 0x0 0x1000000>; reg-names = "breg", "pcireg", "cfg"; - ranges = <0x02000000 0x00000000 0xe1000000 0x00000000 0xe1000000 0 0x0f000000>; + ranges = <0x02000000 0x00000000 0xe0000000 0x00000000 0xe0000000 0x00000000 0x10000000 /* non-prefetchable memory */ + 0x43000000 0x00000006 0x00000000 0x00000006 0x00000000 0x00000002 0x00000000>;/* prefetchable memory */ pcie_intc: legacy-interrupt-controller { interrupt-controller; diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt index 17822860cb98..4b1d6e74c744 100644 --- a/Documentation/devicetree/bindings/spi/spi-bus.txt +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt @@ -31,7 +31,7 @@ with max(cs-gpios > hw cs). So if for example the controller has 2 CS lines, and the cs-gpios property looks like this: -cs-gpios = <&gpio1 0 0> <0> <&gpio1 1 0> <&gpio1 2 0>; +cs-gpios = <&gpio1 0 0>, <0>, <&gpio1 1 0>, <&gpio1 2 0>; Then it should be configured so that num_chipselect = 4 with the following mapping: diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 1992aa97d45a..851e2caf9ae0 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -3,8 +3,8 @@ Device tree binding vendor prefix registry. Keep list in alphabetical order. This isn't an exhaustive list, but you should add new prefixes to it before using them to avoid name-space collisions. -abilis Abilis Systems abcn Abracon Corporation +abilis Abilis Systems active-semi Active-Semi International Inc ad Avionic Design GmbH adapteva Adapteva, Inc. @@ -36,6 +36,7 @@ aspeed ASPEED Technology Inc. atlas Atlas Scientific LLC atmel Atmel Corporation auo AU Optronics Corporation +auvidea Auvidea GmbH avago Avago Technologies avic Shanghai AVIC Optoelectronics Co., Ltd. axis Axis Communications AB @@ -85,6 +86,7 @@ elan Elan Microelectronic Corp. embest Shenzhen Embest Technology Co., Ltd. emmicro EM Microelectronic energymicro Silicon Laboratories (formerly Energy Micro AS) +engicam Engicam S.r.l. epcos EPCOS AG epfl Ecole Polytechnique Fédérale de Lausanne epson Seiko Epson Corp. @@ -101,8 +103,8 @@ focaltech FocalTech Systems Co.,Ltd fsl Freescale Semiconductor ge General Electric Company geekbuying GeekBuying -GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc. gef GE Fanuc Intelligent Platforms Embedded Systems, Inc. +GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc. geniatech Geniatech, Inc. giantplus Giantplus Technology Co., Ltd. globalscale Globalscale Technologies, Inc. @@ -126,7 +128,6 @@ i2se I2SE GmbH ibm International Business Machines (IBM) idt Integrated Device Technologies, Inc. ifi Ingenieurburo Fur Ic-Technologie (I/F/I) -iom Iomega Corporation img Imagination Technologies Ltd. infineon Infineon Technologies inforce Inforce Computing @@ -135,11 +136,14 @@ innolux Innolux Corporation intel Intel Corporation intercontrol Inter Control Group invensense InvenSense Inc. +iom Iomega Corporation isee ISEE 2007 S.L. isil Intersil issi Integrated Silicon Solutions Inc. +jdi Japan Display Inc. jedec JEDEC Solid State Technology Association karo Ka-Ro electronics GmbH +keithkoep Keith & Koep GmbH keymile Keymile GmbH kinetic Kinetic Technologies kosagi Sutajio Ko-Usagi PTE Ltd. @@ -149,8 +153,8 @@ lantiq Lantiq Semiconductor lenovo Lenovo Group Ltd. lg LG Corporation linux Linux-specific binding -lsi LSI Corp. (LSI Logic) lltc Linear Technology Corporation +lsi LSI Corp. (LSI Logic) marvell Marvell Technology Group Ltd. maxim Maxim Integrated Products meas Measurement Specialties @@ -190,20 +194,20 @@ onnn ON Semiconductor Corp. ontat On Tat Industrial Company opencores OpenCores.org option Option NV +ORCL Oracle Corporation ortustech Ortus Technology Co., Ltd. ovti OmniVision Technologies -ORCL Oracle Corporation oxsemi Oxford Semiconductor, Ltd. panasonic Panasonic Corporation parade Parade Technologies Inc. pericom Pericom Technology Inc. phytec PHYTEC Messtechnik GmbH picochip Picochip Ltd +pixcir PIXCIR MICROELECTRONICS Co., Ltd plathome Plat'Home Co., Ltd. plda PLDA -pixcir PIXCIR MICROELECTRONICS Co., Ltd -pulsedlight PulsedLight, Inc powervr PowerVR (deprecated, use img) +pulsedlight PulsedLight, Inc qca Qualcomm Atheros, Inc. qcom Qualcomm Technologies, Inc qemu QEMU, a generic and open source machine emulator and virtualizer @@ -231,12 +235,13 @@ sgx SGX Sensortech sharp Sharp Corporation si-en Si-En Technology Ltd. sigma Sigma Designs, Inc. +sii Seiko Instruments, Inc. sil Silicon Image silabs Silicon Laboratories +silead Silead Inc. +silergy Silergy Corp. siliconmitus Silicon Mitus, Inc. simtek -sii Seiko Instruments, Inc. -silergy Silergy Corp. sirf SiRF Technology, Inc. sis Silicon Integrated Systems Corp. sitronix Sitronix Technology Corporation @@ -254,9 +259,12 @@ starry Starry Electronic Technology (ShenZhen) Co., LTD startek Startek ste ST-Ericsson stericsson ST-Ericsson +summit Summit microelectronics +sunchip Shenzhen Sunchip Technology Co., Ltd +SUNW Sun Microsystems, Inc +swir Sierra Wireless syna Synaptics Inc. synology Synology, Inc. -SUNW Sun Microsystems, Inc tbs TBS Technologies tcg Trusted Computing Group tcl Toby Churchill Ltd. @@ -265,17 +273,18 @@ technologic Technologic Systems thine THine Electronics, Inc. ti Texas Instruments tlm Trusted Logic Mobility +topeet Topeet toradex Toradex AG toshiba Toshiba Corporation toumaz Toumaz -tplink TP-LINK Technologies Co., Ltd. tpk TPK U.S.A. LLC +tplink TP-LINK Technologies Co., Ltd. tronfy Tronfy tronsmart Tronsmart truly Truly Semiconductors Limited tyan Tyan Computer Corporation -upisemi uPI Semiconductor Corp. uniwest United Western Technologies Corp (UniWest) +upisemi uPI Semiconductor Corp. urt United Radiant Technology Corporation usi Universal Scientific Industrial Co., Ltd. v3 V3 Semiconductor @@ -293,7 +302,7 @@ x-powers X-Powers xes Extreme Engineering Solutions (X-ES) xillybus Xillybus Ltd. xlnx Xilinx -zyxel ZyXEL Communications Corp. zarlink Zarlink Semiconductor zii Zodiac Inflight Innovations zte ZTE Corp. +zyxel ZyXEL Communications Corp. diff --git a/Documentation/devicetree/changesets.txt b/Documentation/devicetree/changesets.txt index 935ba5acc34e..cb488eeb6353 100644 --- a/Documentation/devicetree/changesets.txt +++ b/Documentation/devicetree/changesets.txt @@ -21,20 +21,11 @@ a set of changes. No changes to the active tree are made at this point. All the change operations are recorded in the of_changeset 'entries' list. -3. mutex_lock(of_mutex) - starts a changeset; The global of_mutex -ensures there can only be one editor at a time. - -4. of_changeset_apply() - Apply the changes to the tree. Either the +3. of_changeset_apply() - Apply the changes to the tree. Either the entire changeset will get applied, or if there is an error the tree will -be restored to the previous state - -5. mutex_unlock(of_mutex) - All operations complete, release the mutex +be restored to the previous state. The core ensures proper serialization +through locking. An unlocked version __of_changeset_apply is available, +if needed. If a successfully applied changeset needs to be removed, it can be done -with the following sequence. - -1. mutex_lock(of_mutex) - -2. of_changeset_revert() - -3. mutex_unlock(of_mutex) +with of_changeset_revert(). diff --git a/drivers/of/base.c b/drivers/of/base.c index 3ce69536a7b3..a0bccb54a9bd 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1146,16 +1146,18 @@ EXPORT_SYMBOL_GPL(of_property_count_elems_of_size); * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. - * @len: requested length of property value + * @min: minimum allowed length of property value + * @max: maximum allowed length of property value (0 means unlimited) + * @len: if !=NULL, actual length is written to here * * Search for a property in a device node and valid the requested size. * Returns the property value on success, -EINVAL if the property does not * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the - * property data isn't large enough. + * property data is too small or too large. * */ static void *of_find_property_value_of_size(const struct device_node *np, - const char *propname, u32 len) + const char *propname, u32 min, u32 max, size_t *len) { struct property *prop = of_find_property(np, propname, NULL); @@ -1163,9 +1165,14 @@ static void *of_find_property_value_of_size(const struct device_node *np, return ERR_PTR(-EINVAL); if (!prop->value) return ERR_PTR(-ENODATA); - if (len > prop->length) + if (prop->length < min) + return ERR_PTR(-EOVERFLOW); + if (max && prop->length > max) return ERR_PTR(-EOVERFLOW); + if (len) + *len = prop->length; + return prop->value; } @@ -1189,7 +1196,9 @@ int of_property_read_u32_index(const struct device_node *np, u32 index, u32 *out_value) { const u32 *val = of_find_property_value_of_size(np, propname, - ((index + 1) * sizeof(*out_value))); + ((index + 1) * sizeof(*out_value)), + 0, + NULL); if (IS_ERR(val)) return PTR_ERR(val); @@ -1200,102 +1209,145 @@ int of_property_read_u32_index(const struct device_node *np, EXPORT_SYMBOL_GPL(of_property_read_u32_index); /** - * of_property_read_u8_array - Find and read an array of u8 from a property. + * of_property_read_variable_u8_array - Find and read an array of u8 from a + * property, with bounds on the minimum and maximum array size. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_values: pointer to return value, modified only if return value is 0. - * @sz: number of array elements to read + * @sz_min: minimum number of array elements to read + * @sz_max: maximum number of array elements to read, if zero there is no + * upper limit on the number of elements in the dts entry but only + * sz_min will be read. * * Search for a property in a device node and read 8-bit value(s) from - * it. Returns 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the - * property data isn't large enough. + * it. Returns number of elements read on success, -EINVAL if the property + * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW + * if the property data is smaller than sz_min or longer than sz_max. * * dts entry of array should be like: * property = /bits/ 8 <0x50 0x60 0x70>; * * The out_values is modified only if a valid u8 value can be decoded. */ -int of_property_read_u8_array(const struct device_node *np, - const char *propname, u8 *out_values, size_t sz) +int of_property_read_variable_u8_array(const struct device_node *np, + const char *propname, u8 *out_values, + size_t sz_min, size_t sz_max) { + size_t sz, count; const u8 *val = of_find_property_value_of_size(np, propname, - (sz * sizeof(*out_values))); + (sz_min * sizeof(*out_values)), + (sz_max * sizeof(*out_values)), + &sz); if (IS_ERR(val)) return PTR_ERR(val); - while (sz--) + if (!sz_max) + sz = sz_min; + else + sz /= sizeof(*out_values); + + count = sz; + while (count--) *out_values++ = *val++; - return 0; + + return sz; } -EXPORT_SYMBOL_GPL(of_property_read_u8_array); +EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array); /** - * of_property_read_u16_array - Find and read an array of u16 from a property. + * of_property_read_variable_u16_array - Find and read an array of u16 from a + * property, with bounds on the minimum and maximum array size. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_values: pointer to return value, modified only if return value is 0. - * @sz: number of array elements to read + * @sz_min: minimum number of array elements to read + * @sz_max: maximum number of array elements to read, if zero there is no + * upper limit on the number of elements in the dts entry but only + * sz_min will be read. * * Search for a property in a device node and read 16-bit value(s) from - * it. Returns 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the - * property data isn't large enough. + * it. Returns number of elements read on success, -EINVAL if the property + * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW + * if the property data is smaller than sz_min or longer than sz_max. * * dts entry of array should be like: * property = /bits/ 16 <0x5000 0x6000 0x7000>; * * The out_values is modified only if a valid u16 value can be decoded. */ -int of_property_read_u16_array(const struct device_node *np, - const char *propname, u16 *out_values, size_t sz) +int of_property_read_variable_u16_array(const struct device_node *np, + const char *propname, u16 *out_values, + size_t sz_min, size_t sz_max) { + size_t sz, count; const __be16 *val = of_find_property_value_of_size(np, propname, - (sz * sizeof(*out_values))); + (sz_min * sizeof(*out_values)), + (sz_max * sizeof(*out_values)), + &sz); if (IS_ERR(val)) return PTR_ERR(val); - while (sz--) + if (!sz_max) + sz = sz_min; + else + sz /= sizeof(*out_values); + + count = sz; + while (count--) *out_values++ = be16_to_cpup(val++); - return 0; + + return sz; } -EXPORT_SYMBOL_GPL(of_property_read_u16_array); +EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array); /** - * of_property_read_u32_array - Find and read an array of 32 bit integers - * from a property. + * of_property_read_variable_u32_array - Find and read an array of 32 bit + * integers from a property, with bounds on the minimum and maximum array size. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_values: pointer to return value, modified only if return value is 0. - * @sz: number of array elements to read + * @sz_min: minimum number of array elements to read + * @sz_max: maximum number of array elements to read, if zero there is no + * upper limit on the number of elements in the dts entry but only + * sz_min will be read. * * Search for a property in a device node and read 32-bit value(s) from - * it. Returns 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the - * property data isn't large enough. + * it. Returns number of elements read on success, -EINVAL if the property + * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW + * if the property data is smaller than sz_min or longer than sz_max. * * The out_values is modified only if a valid u32 value can be decoded. */ -int of_property_read_u32_array(const struct device_node *np, +int of_property_read_variable_u32_array(const struct device_node *np, const char *propname, u32 *out_values, - size_t sz) + size_t sz_min, size_t sz_max) { + size_t sz, count; const __be32 *val = of_find_property_value_of_size(np, propname, - (sz * sizeof(*out_values))); + (sz_min * sizeof(*out_values)), + (sz_max * sizeof(*out_values)), + &sz); if (IS_ERR(val)) return PTR_ERR(val); - while (sz--) + if (!sz_max) + sz = sz_min; + else + sz /= sizeof(*out_values); + + count = sz; + while (count--) *out_values++ = be32_to_cpup(val++); - return 0; + + return sz; } -EXPORT_SYMBOL_GPL(of_property_read_u32_array); +EXPORT_SYMBOL_GPL(of_property_read_variable_u32_array); /** * of_property_read_u64 - Find and read a 64 bit integer from a property @@ -1314,7 +1366,9 @@ int of_property_read_u64(const struct device_node *np, const char *propname, u64 *out_value) { const __be32 *val = of_find_property_value_of_size(np, propname, - sizeof(*out_value)); + sizeof(*out_value), + 0, + NULL); if (IS_ERR(val)) return PTR_ERR(val); @@ -1325,38 +1379,51 @@ int of_property_read_u64(const struct device_node *np, const char *propname, EXPORT_SYMBOL_GPL(of_property_read_u64); /** - * of_property_read_u64_array - Find and read an array of 64 bit integers - * from a property. + * of_property_read_variable_u64_array - Find and read an array of 64 bit + * integers from a property, with bounds on the minimum and maximum array size. * * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_values: pointer to return value, modified only if return value is 0. - * @sz: number of array elements to read + * @sz_min: minimum number of array elements to read + * @sz_max: maximum number of array elements to read, if zero there is no + * upper limit on the number of elements in the dts entry but only + * sz_min will be read. * * Search for a property in a device node and read 64-bit value(s) from - * it. Returns 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the - * property data isn't large enough. + * it. Returns number of elements read on success, -EINVAL if the property + * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW + * if the property data is smaller than sz_min or longer than sz_max. * * The out_values is modified only if a valid u64 value can be decoded. */ -int of_property_read_u64_array(const struct device_node *np, +int of_property_read_variable_u64_array(const struct device_node *np, const char *propname, u64 *out_values, - size_t sz) + size_t sz_min, size_t sz_max) { + size_t sz, count; const __be32 *val = of_find_property_value_of_size(np, propname, - (sz * sizeof(*out_values))); + (sz_min * sizeof(*out_values)), + (sz_max * sizeof(*out_values)), + &sz); if (IS_ERR(val)) return PTR_ERR(val); - while (sz--) { + if (!sz_max) + sz = sz_min; + else + sz /= sizeof(*out_values); + + count = sz; + while (count--) { *out_values++ = of_read_number(val, 2); val += 2; } - return 0; + + return sz; } -EXPORT_SYMBOL_GPL(of_property_read_u64_array); +EXPORT_SYMBOL_GPL(of_property_read_variable_u64_array); /** * of_property_read_string - Find and read a string from a property diff --git a/drivers/of/platform.c b/drivers/of/platform.c index f39ccd5aa701..f811d2796437 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -142,6 +142,7 @@ struct platform_device *of_device_alloc(struct device_node *np, } dev->dev.of_node = of_node_get(np); + dev->dev.fwnode = &np->fwnode; dev->dev.parent = parent ? : &platform_bus; if (bus_id) @@ -241,6 +242,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node, /* setup generic device info */ dev->dev.of_node = of_node_get(node); + dev->dev.fwnode = &node->fwnode; dev->dev.parent = parent ? : &platform_bus; dev->dev.platform_data = platform_data; if (bus_id) diff --git a/include/linux/of.h b/include/linux/of.h index 3d9ff8e9d803..299aeb192727 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -291,20 +291,24 @@ extern int of_property_count_elems_of_size(const struct device_node *np, extern int of_property_read_u32_index(const struct device_node *np, const char *propname, u32 index, u32 *out_value); -extern int of_property_read_u8_array(const struct device_node *np, - const char *propname, u8 *out_values, size_t sz); -extern int of_property_read_u16_array(const struct device_node *np, - const char *propname, u16 *out_values, size_t sz); -extern int of_property_read_u32_array(const struct device_node *np, - const char *propname, - u32 *out_values, - size_t sz); +extern int of_property_read_variable_u8_array(const struct device_node *np, + const char *propname, u8 *out_values, + size_t sz_min, size_t sz_max); +extern int of_property_read_variable_u16_array(const struct device_node *np, + const char *propname, u16 *out_values, + size_t sz_min, size_t sz_max); +extern int of_property_read_variable_u32_array(const struct device_node *np, + const char *propname, + u32 *out_values, + size_t sz_min, + size_t sz_max); extern int of_property_read_u64(const struct device_node *np, const char *propname, u64 *out_value); -extern int of_property_read_u64_array(const struct device_node *np, - const char *propname, - u64 *out_values, - size_t sz); +extern int of_property_read_variable_u64_array(const struct device_node *np, + const char *propname, + u64 *out_values, + size_t sz_min, + size_t sz_max); extern int of_property_read_string(const struct device_node *np, const char *propname, @@ -380,6 +384,122 @@ extern int of_detach_node(struct device_node *); #define of_match_ptr(_ptr) (_ptr) +/** + * of_property_read_u8_array - Find and read an array of u8 from a property. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @out_values: pointer to return value, modified only if return value is 0. + * @sz: number of array elements to read + * + * Search for a property in a device node and read 8-bit value(s) from + * it. Returns 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + * + * dts entry of array should be like: + * property = /bits/ 8 <0x50 0x60 0x70>; + * + * The out_values is modified only if a valid u8 value can be decoded. + */ +static inline int of_property_read_u8_array(const struct device_node *np, + const char *propname, + u8 *out_values, size_t sz) +{ + int ret = of_property_read_variable_u8_array(np, propname, out_values, + sz, 0); + if (ret >= 0) + return 0; + else + return ret; +} + +/** + * of_property_read_u16_array - Find and read an array of u16 from a property. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @out_values: pointer to return value, modified only if return value is 0. + * @sz: number of array elements to read + * + * Search for a property in a device node and read 16-bit value(s) from + * it. Returns 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + * + * dts entry of array should be like: + * property = /bits/ 16 <0x5000 0x6000 0x7000>; + * + * The out_values is modified only if a valid u16 value can be decoded. + */ +static inline int of_property_read_u16_array(const struct device_node *np, + const char *propname, + u16 *out_values, size_t sz) +{ + int ret = of_property_read_variable_u16_array(np, propname, out_values, + sz, 0); + if (ret >= 0) + return 0; + else + return ret; +} + +/** + * of_property_read_u32_array - Find and read an array of 32 bit integers + * from a property. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @out_values: pointer to return value, modified only if return value is 0. + * @sz: number of array elements to read + * + * Search for a property in a device node and read 32-bit value(s) from + * it. Returns 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + * + * The out_values is modified only if a valid u32 value can be decoded. + */ +static inline int of_property_read_u32_array(const struct device_node *np, + const char *propname, + u32 *out_values, size_t sz) +{ + int ret = of_property_read_variable_u32_array(np, propname, out_values, + sz, 0); + if (ret >= 0) + return 0; + else + return ret; +} + +/** + * of_property_read_u64_array - Find and read an array of 64 bit integers + * from a property. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @out_values: pointer to return value, modified only if return value is 0. + * @sz: number of array elements to read + * + * Search for a property in a device node and read 64-bit value(s) from + * it. Returns 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + * + * The out_values is modified only if a valid u64 value can be decoded. + */ +static inline int of_property_read_u64_array(const struct device_node *np, + const char *propname, + u64 *out_values, size_t sz) +{ + int ret = of_property_read_variable_u64_array(np, propname, out_values, + sz, 0); + if (ret >= 0) + return 0; + else + return ret; +} + /* * struct property *prop; * const __be32 *p; |