diff options
author | David P <megver83@openmailbox.org> | 2017-10-31 19:53:09 -0300 |
---|---|---|
committer | David P <megver83@openmailbox.org> | 2017-10-31 19:53:22 -0300 |
commit | 7753a2f31e05b6ae2ed8c2fd47a93173944519ea (patch) | |
tree | aa5f21087dbc3f17d017e074f44d3e741d13d4c1 | |
parent | 861cc5acaf28fbc7228f8f41aa194c03e27d4359 (diff) | |
download | abslibre-7753a2f31e05b6ae2ed8c2fd47a93173944519ea.tar.gz abslibre-7753a2f31e05b6ae2ed8c2fd47a93173944519ea.tar.bz2 abslibre-7753a2f31e05b6ae2ed8c2fd47a93173944519ea.zip |
Update pcr/openrc-security
Remove some patches from kernels/linux-libre-lts-knock
-rw-r--r-- | kernels/linux-libre-lts-knock/rcn-libre-4.9.59-armv7-x5.patch | 35632 | ||||
-rw-r--r-- | kernels/linux-libre-lts-knock/tcp_stealth_4.9_1.diff | 642 | ||||
-rw-r--r-- | pcr/openrc-security/PKGBUILD | 7 |
3 files changed, 3 insertions, 36278 deletions
diff --git a/kernels/linux-libre-lts-knock/rcn-libre-4.9.59-armv7-x5.patch b/kernels/linux-libre-lts-knock/rcn-libre-4.9.59-armv7-x5.patch deleted file mode 100644 index c54a3d888..000000000 --- a/kernels/linux-libre-lts-knock/rcn-libre-4.9.59-armv7-x5.patch +++ /dev/null @@ -1,35632 +0,0 @@ -diff --git a/.gitignore b/.gitignore -index c2ed4ec..0544d50 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -114,3 +114,7 @@ all.config - - # Kdevelop4 - *.kdev4 -+ -+# dtb objects -+*.dtb -+*.dtbo -diff --git b/Documentation/ABI/testing/sysfs-devices-platform-bone_capemgr b/Documentation/ABI/testing/sysfs-devices-platform-bone_capemgr -new file mode 100644 -index 0000000..e2df613 ---- /dev/null -+++ b/Documentation/ABI/testing/sysfs-devices-platform-bone_capemgr -@@ -0,0 +1,63 @@ -+What: /sys/devices/platform/bone_capemgr/slots -+Date: May 2015 -+KernelVersion: 4.0 -+Contact: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -+Description: -+ READ: -+ Describe the state of all the slots of the beaglebone capemgr. -+ Each line of the output describes a slot: -+ The slot format is as following: -+ <slot-id>: [P-][F-][O-][l-][L-][D-] \ -+ <overlay-id> <board-name>,<version>, -+ <manufacturer>,<part-number> -+ -+ Where the flags are: -+ P: Slot has been probed -+ F: Slot has failed probing (i.e. no EEPROM detected) -+ O: Slot has been overridden by the user -+ l: Slot is current loading -+ L: Slot has completed loading and is ready -+ D: Slot has been disabled -+ -+ Example: -+ 0: P---L- -1 BeagleBone RS232 CAPE,00A1,Beagleboardtoys,BB-BONE-SERL-03 -+ 1: PF---- -1 -+ 2: PF---- -1 -+ 3: PF---- -1 -+ -+ WRITE: -+ Writing a string of the form <part-number>[:version] issues a request to -+ load a firmware blob containing an overlay. The name of the firmware blob -+ is <part-number>-[version|00A0].dtbo. This act is defined as a slot override. -+ -+ Writing a negative slot id removes the slot if it was an overridden one, or -+ unloads a slot that was probed. -+ -+What: /sys/devices/platform/bone_capemgr/baseboard/<eeprom-field> -+Date: May 2015 -+KernelVersion: 4.0 -+Contact: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -+Description: Contains the probed base board EEPROM field; one of: -+ board-name - board-name as stored in cape EEPROM -+ dc-supplied - whether the cape draws or supplies DC -+ eeprom-format-revision - EEPROM format rev, only 00A0 supported -+ header - header; should be 'aa 55 33 ee' -+ manufacturer - manufacturer string -+ part-number - part-number of the cape -+ serial-number - serial number of the cape -+ version - version of the cape, i.e. 00A0 -+ number-of-pins - displayed but ignored -+ pin-usage - displayed but ignored -+ sys-5v - displayed but ignored -+ vdd-3v3exp - displayed but ignored -+ vdd-5v - displayed but ignored -+What: /sys/devices/platform/bone_capemgr/slot-<n>/<eeprom-field> -+Date: May 2015 -+KernelVersion: 4.0 -+Contact: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -+Description: Contains the probed cape's EEPROM field; the field is one of: -+ board-name - baseboard name i.e. A335BNLT -+ header - header; should be 'aa 55 33 ee' -+ revision - baseboard revision -+ serial-number - baseboard serial number -+ config-option - displayed but ignored -diff --git b/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays b/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays -new file mode 100644 -index 0000000..88d1549 ---- /dev/null -+++ b/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays -@@ -0,0 +1,52 @@ -+What: /sys/firmware/devicetree/overlays/ -+Date: October 2015 -+Contact: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -+Description: -+ This directory contains the applied device tree overlays of -+ the running system, as directories of the overlay id. -+ -+What: /sys/firmware/devicetree/overlays/enable -+Date: October 2015 -+Contact: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -+Description: -+ The master enable switch, by default is 1, and when -+ set to 0 it cannot be re-enabled for security reasons. -+ -+ The discussion about this switch takes place in: -+ http://comments.gmane.org/gmane.linux.drivers.devicetree/101871 -+ -+ Kees Cook: -+ "Coming from the perspective of drawing a bright line between -+ kernel and the root user (which tends to start with disabling -+ kernel module loading), I would say that there at least needs -+ to be a high-level one-way "off" switch for the interface so -+ that systems that have this interface can choose to turn it off -+ during initial boot, etc." -+ -+What: /sys/firmware/devicetree/overlays/<id> -+Date: October 2015 -+Contact: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -+Description: -+ Each directory represents an applied overlay, containing -+ the following attribute files. -+ -+What: /sys/firmware/devicetree/overlays/<id>/can_remove -+Date: October 2015 -+Contact: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -+Description: -+ The attribute set to 1 means that the overlay can be removed, -+ while 0 means that the overlay is being overlapped therefore -+ removal is prohibited. -+ -+What: /sys/firmware/devicetree/overlays/<id>/<fragment-name>/ -+Date: October 2015 -+Contact: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -+Description: -+ Each of these directories contain information about of the -+ particular overlay fragment. -+ -+What: /sys/firmware/devicetree/overlays/<id>/<fragment-name>/target -+Date: October 2015 -+Contact: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -+Description: -+ The full-path of the target of the fragment -diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt -index f53e2ee..29bc4fe 100644 ---- a/Documentation/devicetree/bindings/arm/omap/omap.txt -+++ b/Documentation/devicetree/bindings/arm/omap/omap.txt -@@ -24,6 +24,8 @@ Optional properties: - - ti,no-reset-on-init: When present, the module should not be reset at init - - ti,no-idle-on-init: When present, the module should not be idled at init - - ti,no-idle: When present, the module is never allowed to idle. -+- ti,deassert-hard-reset: list of hwmod and hardware reset line name pairs -+ (ascii strings) to be deasserted upon device instantiation. - - Example: - -diff --git b/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt b/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt -new file mode 100644 -index 0000000..7a31864 ---- /dev/null -+++ b/Documentation/devicetree/bindings/cpufreq/ti-cpufreq.txt -@@ -0,0 +1,132 @@ -+TI CPUFreq and OPP bindings -+================================ -+ -+Certain TI SoCs, like those in the am335x, am437x, am57xx, and dra7xx -+families support different OPPs depending on the silicon variant in use. -+The ti_cpufreq driver can use revision and an efuse value from the SoC to -+provide the OPP framework with supported hardware information. This is -+used to determine which OPPs from the operating-points-v2 table get enabled -+when it is parsed by the OPP framework. -+ -+Required properties: -+-------------------- -+In 'cpus' nodes: -+- operating-points-v2: Phandle to the operating-points-v2 table to use. -+ -+In 'operating-points-v2' table: -+- compatible: Should be -+ - 'operating-points-v2-ti' for am335x, am43xx, and dra7xx/am57xx SoCs -+- ti,syscon-efuse: Syscon phandle, offset to efuse register, efuse register -+ mask, and efuse register shift to get the relevant bits -+ that describe OPP availability. -+- ti,syscon-rev: Syscon and offset used to look up revision value on SoC. -+ -+Optional properties: -+-------------------- -+For each opp entry in 'operating-points-v2' table: -+- opp-supported-hw: Two bitfields indicating: -+ 1. Which revision of the SoC the OPP is supported by -+ 2. Which eFuse bits indicate this OPP is available -+ -+ A bitwise AND is performed against these values and if any bit -+ matches, the OPP gets enabled. Not providing the property for an -+ entry indicates that an OPP is always supported. -+ -+Example: -+-------- -+ -+/* From arch/arm/boot/dts/am33xx.dtsi */ -+cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cpu@0 { -+ compatible = "arm,cortex-a8"; -+ device_type = "cpu"; -+ reg = <0>; -+ -+ operating-points-v2 = <&cpu0_opp_table>; -+ -+ clocks = <&dpll_mpu_ck>; -+ clock-names = "cpu"; -+ -+ clock-latency = <300000>; /* From omap-cpufreq driver */ -+ }; -+}; -+ -+/* -+ * cpu0 has different OPPs depending on SoC revision and some on revisions -+ * 0x2 and 0x4 have eFuse bits that indicate if they are available or not -+ */ -+cpu0_opp_table: opp_table0 { -+ compatible = "operating-points-v2-ti-am3352-cpu"; -+ ti,syscon-efuse = <&scm_conf 0x7fc 0x1fff 0>; -+ ti,syscon-rev = <&scm_conf 0x600>; -+ -+ /* -+ * The three following nodes are marked with opp-suspend -+ * because they can not be enabled simultaneously on a -+ * single SoC. -+ */ -+ opp50@300000000 { -+ opp-hz = /bits/ 64 <300000000>; -+ opp-microvolt = <950000 931000 969000>; -+ opp-supported-hw = <0x06 0x0010>; -+ opp-suspend; -+ }; -+ -+ opp100@275000000 { -+ opp-hz = /bits/ 64 <275000000>; -+ opp-microvolt = <1100000 1078000 1122000>; -+ opp-supported-hw = <0x01 0x00FF>; -+ opp-suspend; -+ }; -+ -+ opp100@300000000 { -+ opp-hz = /bits/ 64 <300000000>; -+ opp-microvolt = <1100000 1078000 1122000>; -+ opp-supported-hw = <0x06 0x0020>; -+ opp-suspend; -+ }; -+ -+ opp100@500000000 { -+ opp-hz = /bits/ 64 <500000000>; -+ opp-microvolt = <1100000 1078000 1122000>; -+ opp-supported-hw = <0x01 0xFFFF>; -+ }; -+ -+ opp100@600000000 { -+ opp-hz = /bits/ 64 <600000000>; -+ opp-microvolt = <1100000 1078000 1122000>; -+ opp-supported-hw = <0x06 0x0040>; -+ }; -+ -+ opp120@600000000 { -+ opp-hz = /bits/ 64 <600000000>; -+ opp-microvolt = <1200000 1176000 1224000>; -+ opp-supported-hw = <0x01 0xFFFF>; -+ }; -+ -+ opp120@720000000 { -+ opp-hz = /bits/ 64 <720000000>; -+ opp-microvolt = <1200000 1176000 1224000>; -+ opp-supported-hw = <0x06 0x0080>; -+ }; -+ -+ oppturbo@720000000 { -+ opp-hz = /bits/ 64 <720000000>; -+ opp-microvolt = <1260000 1234800 1285200>; -+ opp-supported-hw = <0x01 0xFFFF>; -+ }; -+ -+ oppturbo@800000000 { -+ opp-hz = /bits/ 64 <800000000>; -+ opp-microvolt = <1260000 1234800 1285200>; -+ opp-supported-hw = <0x06 0x0100>; -+ }; -+ -+ oppnitro@1000000000 { -+ opp-hz = /bits/ 64 <1000000000>; -+ opp-microvolt = <1325000 1298500 1351500>; -+ opp-supported-hw = <0x04 0x0200>; -+ }; -+}; -diff --git b/Documentation/devicetree/bindings/misc/bone_capemgr.txt b/Documentation/devicetree/bindings/misc/bone_capemgr.txt -new file mode 100644 -index 0000000..7e4fbc9 ---- /dev/null -+++ b/Documentation/devicetree/bindings/misc/bone_capemgr.txt -@@ -0,0 +1,111 @@ -+* Beaglebone cape manager driver -+ -+Required properties: -+- compatible: "ti,bone-capemgr" -+- eeprom: phandle to the EEPROM baseboard. -+ The EEPROM framework interface is use to obtain the data. -+ -+Required children nodes: -+ -+- baseboardmaps: Contains nodes, which each of the them defines a mapping from -+ the baseboard EEPROM board-name ID to a DT friendly compatible -+ string. -+ -+ - board-name: The baseboard EEPROM board name, i.e. A335BONE for the -+ original beaglebone white. -+ - compatible-name: The DT friendly compatible string to be used for matching -+ compatible capes, i.e. "ti,beaglebone" -+ -+ -+ - nvmem-cells: Defines the phandles of the nvmem cells of the baseboard and the -+ slots. -+ - nvmem-cells: Defines the names of the nvmem cells. Required to have at -+ least a baseboard cell name. -+ -+ - #slots: Defines how many slots are there. -+ -+- Example of a beaglebone cape-manager: -+ -+bone_capemgr { -+ compatible = "ti,bone-capemgr"; -+ status = "okay"; -+ -+ nvmem-cell = <&baseboard_data -+ &cape0_data &cape1_data &cape2_data &cape3_data>; -+ nvmem-cell-names = "baseboard", "slot0", "slot1", "slot2", "slot3"; -+ -+ #slots = <4>; -+ -+ /* map board revisions to compatible definitions */ -+ baseboardmaps { -+ baseboard_beaglebone: board@0 { -+ board-name = "A335BONE"; -+ compatible-name = "ti,beaglebone"; -+ }; -+ -+ baseboard_beaglebone_black: board@1 { -+ board-name = "A335BNLT"; -+ compatible-name = "ti,beaglebone-black"; -+ }; -+ }; -+}; -+ -+The format of the cape to be loaded is in a standard overlay format with -+the following root properties that are interpreted by the cape manager: -+ -+Required properties: -+ - compatible: Should be compatible to the baseboard according to the -+ baseboard map value, i.e. "ti,beaglebone". -+ - part-numer: Should contain the part-number as stored in the EEPROM. -+ - version: Should contain a list of all the version that are supported -+ by the single cape dtbo, i.e. "00A1". -+ -+Optional properties: -+ - exclusive-use: A string list which state the resources this cape requires. -+ No processing or matching to anything regarding the internal -+ kernel state is performed; it's purpose is to guard against -+ conflicts with other capes. -+ - priority: A priority to be assigned when loading a cape. A lower value -+ has higher priority. The purpose of the priority is to control -+ which cape is loaded first in case of a conflict. -+ -+- Example of a serial cape: -+ -+/dts-v1/; -+/plugin/; -+/ { -+ compatible = "ti,beaglebone", "ti,beaglebone-black"; -+ -+ /* identification */ -+ part-number = "BB-BONE-SERL-03"; -+ version = "00A1"; -+ -+ /* state the resources this cape uses */ -+ exclusive-use = -+ /* the pin header uses */ -+ "P9.21", /* uart2_txd */ -+ "P9.22", /* uart2_rxd */ -+ /* the hardware ip uses */ -+ "uart2"; -+ -+ fragment@0 { -+ target = <&am33xx_pinmux>; -+ __overlay__ { -+ bb_uart2_pins: pinmux_bb_uart2_pins { -+ pinctrl-single,pins = < -+ 0x150 0x21 /* spi0_sclk.uart2_rxd | MODE1 */ -+ 0x154 0x01 /* spi0_d0.uart2_txd | MODE1 */ -+ >; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&uart2>; -+ __overlay__ { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&bb_uart2_pins>; -+ }; -+ }; -+}; -diff --git b/Documentation/devicetree/bindings/net/allwinner,sun8i-emac.txt b/Documentation/devicetree/bindings/net/allwinner,sun8i-emac.txt -new file mode 100644 -index 0000000..4bf4e53 ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/allwinner,sun8i-emac.txt -@@ -0,0 +1,65 @@ -+* Allwinner sun8i EMAC ethernet controller -+ -+Required properties: -+- compatible: "allwinner,sun8i-a83t-emac", "allwinner,sun8i-h3-emac", -+ or "allwinner,sun50i-a64-emac" -+- reg: address and length of the register sets for the device. -+- reg-names: should be "emac" and "syscon", matching the register sets -+- interrupts: interrupt for the device -+- clocks: A phandle to the reference clock for this device -+- clock-names: should be "ahb" -+- resets: A phandle to the reset control for this device -+- reset-names: should be "ahb" -+- phy-mode: See ethernet.txt -+- phy or phy-handle: See ethernet.txt -+- #address-cells: shall be 1 -+- #size-cells: shall be 0 -+ -+"allwinner,sun8i-h3-emac" also requires: -+- clocks: an extra phandle to the reference clock for the EPHY -+- clock-names: an extra "ephy" entry matching the clocks property -+- resets: an extra phandle to the reset control for the EPHY -+- resets-names: an extra "ephy" entry matching the resets property -+ -+See ethernet.txt in the same directory for generic bindings for ethernet -+controllers. -+ -+The device node referenced by "phy" or "phy-handle" should be a child node -+of this node. See phy.txt for the generic PHY bindings. -+ -+Optional properties: -+- phy-supply: phandle to a regulator if the PHY needs one -+- phy-io-supply: phandle to a regulator if the PHY needs a another one for I/O. -+ This is sometimes found with RGMII PHYs, which use a second -+ regulator for the lower I/O voltage. -+- allwinner,tx-delay: The setting of the TX clock delay chain -+- allwinner,rx-delay: The setting of the RX clock delay chain -+ -+The TX/RX clock delay chain settings are board specific. -+ -+Optional properties for "allwinner,sun8i-h3-emac": -+- allwinner,use-internal-phy: Use the H3 SoC's internal E(thernet) PHY -+- allwinner,leds-active-low: EPHY LEDs are active low -+ -+When the internal PHY is requested, the implementation shall configure the -+internal PHY to use the address specified in the child PHY node. -+ -+Example: -+ -+emac: ethernet@01c0b000 { -+ compatible = "allwinner,sun8i-h3-emac"; -+ reg = <0x01c0b000 0x104>, <0x01c00030 0x4>; -+ reg-names = "emac", "syscon"; -+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; -+ clocks = <&bus_gates 17>, <&bus_gates 128>; -+ clock-names = "ahb", "ephy"; -+ resets = <&ahb_rst 17>, <&ahb_rst 66>; -+ reset-names = "ahb", "ephy"; -+ phy = <&phy1>; -+ allwinner,use-internal-phy; -+ allwinner,leds-active-low; -+ -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+}; -diff --git a/Documentation/devicetree/bindings/opp/opp.txt b/Documentation/devicetree/bindings/opp/opp.txt -index ee91cbd..9f5ca44 100644 ---- a/Documentation/devicetree/bindings/opp/opp.txt -+++ b/Documentation/devicetree/bindings/opp/opp.txt -@@ -86,8 +86,14 @@ Optional properties: - Single entry is for target voltage and three entries are for <target min max> - voltages. - -- Entries for multiple regulators must be present in the same order as -- regulators are specified in device's DT node. -+ Entries for multiple regulators shall be provided in the same field separated -+ by angular brackets <>. The OPP binding doesn't provide any provisions to -+ relate the values to their power supplies or the order in which the supplies -+ need to be configured and that is left for the implementation specific -+ binding. -+ -+ Entries for all regulators shall be of the same size, i.e. either all use a -+ single value or triplets. - - - opp-microvolt-<name>: Named opp-microvolt property. This is exactly similar to - the above opp-microvolt property, but allows multiple voltage ranges to be -@@ -104,10 +110,13 @@ Optional properties: - - Should only be set if opp-microvolt is set for the OPP. - -- Entries for multiple regulators must be present in the same order as -- regulators are specified in device's DT node. If this property isn't required -- for few regulators, then this should be marked as zero for them. If it isn't -- required for any regulator, then this property need not be present. -+ Entries for multiple regulators shall be provided in the same field separated -+ by angular brackets <>. If current values aren't required for a regulator, -+ then it shall be filled with 0. If current values aren't required for any of -+ the regulators, then this field is not required. The OPP binding doesn't -+ provide any provisions to relate the values to their power supplies or the -+ order in which the supplies need to be configured and that is left for the -+ implementation specific binding. - - - opp-microamp-<name>: Named opp-microamp property. Similar to - opp-microvolt-<name> property, but for microamp instead. -@@ -386,10 +395,12 @@ Example 4: Handling multiple regulators - / { - cpus { - cpu@0 { -- compatible = "arm,cortex-a7"; -+ compatible = "vendor,cpu-type"; - ... - -- cpu-supply = <&cpu_supply0>, <&cpu_supply1>, <&cpu_supply2>; -+ vcc0-supply = <&cpu_supply0>; -+ vcc1-supply = <&cpu_supply1>; -+ vcc2-supply = <&cpu_supply2>; - operating-points-v2 = <&cpu0_opp_table>; - }; - }; -diff --git b/Documentation/devicetree/bindings/pinctrl/ti,iodelay-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/ti,iodelay-pinctrl.txt -new file mode 100644 -index 0000000..e12f4e5 ---- /dev/null -+++ b/Documentation/devicetree/bindings/pinctrl/ti,iodelay-pinctrl.txt -@@ -0,0 +1,86 @@ -+Texas Instruments I/O Delay module configuration pinctrl definition -+ -+Used in conjunction with Documentation/devicetree/bindings/pinctrl/ti,omap-pinctrl.txt -+ -+Required Properties: -+- compatible: Should be: -+ "ti,dra7-iodelay" - I/O delay configuration for DRA7 -+- reg - must be the register address range of IODelay module -+- #address-cells = <1>; -+- #size-cells = <0>; -+ -+Important note: Use of "ti,dra7-iodelay" compatible definition need to be -+carefully evaluated due to the expectation of glitch during configuration. -+ -+Example: -+ -+dra7_iodelay_core: padconf@4844a000 { -+ compatible = "ti,dra7-iodelay"; -+ reg = <0x4844a000 0x0d1c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+}; -+ -+Configuration definition follows similar model as the pinctrl-single: -+The groups of pin configuration are defined under "pinctrl-single,pins" -+ -+&dra7_iodelay_core { -+ mmc2_iodelay_3v3_conf: mmc2_iodelay_3v3_conf { -+ pinctrl-single,pins = < -+ 0x18c (A_DELAY(0) | G_DELAY(120)) /* CFG_GPMC_A19_IN */ -+ 0x1a4 (A_DELAY(265) | G_DELAY(360)) /* CFG_GPMC_A20_IN */ -+ 0x1b0 (A_DELAY(0) | G_DELAY(120)) /* CFG_GPMC_A21_IN */ -+ 0x1bc (A_DELAY(0) | G_DELAY(120)) /* CFG_GPMC_A22_IN */ -+ 0x1c8 (A_DELAY(287) | G_DELAY(420)) /* CFG_GPMC_A23_IN */ -+ 0x1d4 (A_DELAY(144) | G_DELAY(240)) /* CFG_GPMC_A24_IN */ -+ 0x1e0 (A_DELAY(0) | G_DELAY(0)) /* CFG_GPMC_A25_IN */ -+ 0x1ec (A_DELAY(120) | G_DELAY(0)) /* CFG_GPMC_A26_IN */ -+ 0x1f8 (A_DELAY(120) | G_DELAY(180)) /* CFG_GPMC_A27_IN */ -+ 0x360 (A_DELAY(0) | G_DELAY(0)) /* CFG_GPMC_CS1_IN */ -+ >; -+ }; -+}; -+ -+Usage in conjunction with pinctrl single: -+ -+For a complete description of the pins both the regular muxing as well as the -+iodelay configuration is necessary. For example: -+ -+&dra7_pmx_core { -+ mmc2_pins_default: mmc2_pins_default { -+ pinctrl-single,pins = < -+ 0x9c (PIN_INPUT_PULLUP | MANUAL_MODE | MUX_MODE1) /* gpmc_a23.mmc2_clk */ -+ 0xb0 (PIN_INPUT_PULLUP | MANUAL_MODE | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ -+ 0xa0 (PIN_INPUT_PULLUP | MANUAL_MODE | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ -+ 0xa4 (PIN_INPUT_PULLUP | MANUAL_MODE | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ -+ 0xa8 (PIN_INPUT_PULLUP | MANUAL_MODE | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ -+ 0xac (PIN_INPUT_PULLUP | MANUAL_MODE | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ -+ 0x8c (PIN_INPUT_PULLUP | MANUAL_MODE | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ -+ 0x90 (PIN_INPUT_PULLUP | MANUAL_MODE | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ -+ 0x94 (PIN_INPUT_PULLUP | MANUAL_MODE | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ -+ 0x98 (PIN_INPUT_PULLUP | MANUAL_MODE | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ -+ >; -+ }; -+}; -+ -+&dra7_iodelay_core { -+ mmc2_iodelay_3v3_conf: mmc2_iodelay_3v3_conf { -+ pinctrl-single,pins = < -+ 0x18c (A_DELAY(0) | G_DELAY(120)) /* CFG_GPMC_A19_IN */ -+ 0x1a4 (A_DELAY(265) | G_DELAY(360)) /* CFG_GPMC_A20_IN */ -+ 0x1b0 (A_DELAY(0) | G_DELAY(120)) /* CFG_GPMC_A21_IN */ -+ 0x1bc (A_DELAY(0) | G_DELAY(120)) /* CFG_GPMC_A22_IN */ -+ 0x1c8 (A_DELAY(287) | G_DELAY(420)) /* CFG_GPMC_A23_IN */ -+ 0x1d4 (A_DELAY(144) | G_DELAY(240)) /* CFG_GPMC_A24_IN */ -+ 0x1e0 (A_DELAY(0) | G_DELAY(0)) /* CFG_GPMC_A25_IN */ -+ 0x1ec (A_DELAY(120) | G_DELAY(0)) /* CFG_GPMC_A26_IN */ -+ 0x1f8 (A_DELAY(120) | G_DELAY(180)) /* CFG_GPMC_A27_IN */ -+ 0x360 (A_DELAY(0) | G_DELAY(0)) /* CFG_GPMC_CS1_IN */ -+ >; -+ }; -+}; -+ -+&mmc2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc2_pins_default &mmc2_iodelay_3v3_conf>; -+}; -diff --git b/Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt b/Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt -new file mode 100644 -index 0000000..ebf0d47 ---- /dev/null -+++ b/Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt -@@ -0,0 +1,48 @@ -+The generic power sequence library -+ -+Some hard-wired devices (eg USB/MMC) need to do power sequence before -+the device can be enumerated on the bus, the typical power sequence -+like: enable USB PHY clock, toggle reset pin, etc. But current -+Linux device driver lacks of such code to do it, it may cause some -+hard-wired devices works abnormal or can't be recognized by -+controller at all. The power sequence will be done before this device -+can be found at the bus. -+ -+The power sequence properties is under the device node. -+ -+Optional properties: -+- clocks: the input clocks for device. -+- reset-gpios: Should specify the GPIO for reset. -+- reset-duration-us: the duration in microsecond for assert reset signal. -+ -+Below is the example of USB power sequence properties on USB device -+nodes which have two level USB hubs. -+ -+&usbotg1 { -+ vbus-supply = <®_usb_otg1_vbus>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usb_otg1_id>; -+ status = "okay"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ genesys: hub@1 { -+ compatible = "usb5e3,608"; -+ reg = <1>; -+ -+ clocks = <&clks IMX6SX_CLK_CKO>; -+ reset-gpios = <&gpio4 5 GPIO_ACTIVE_LOW>; /* hub reset pin */ -+ reset-duration-us = <10>; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ asix: ethernet@1 { -+ compatible = "usbb95,1708"; -+ reg = <1>; -+ -+ clocks = <&clks IMX6SX_CLK_IPG>; -+ reset-gpios = <&gpio4 6 GPIO_ACTIVE_LOW>; /* ethernet_rst */ -+ reset-duration-us = <15>; -+ }; -+ }; -+}; -diff --git a/Documentation/devicetree/bindings/usb/usb-device.txt b/Documentation/devicetree/bindings/usb/usb-device.txt -index 1c35e7b..3661dd2 100644 ---- a/Documentation/devicetree/bindings/usb/usb-device.txt -+++ b/Documentation/devicetree/bindings/usb/usb-device.txt -@@ -13,6 +13,10 @@ Required properties: - - reg: the port number which this device is connecting to, the range - is 1-31. - -+Optional properties: -+power sequence properties, see -+Documentation/devicetree/bindings/power/pwrseq/pwrseq-generic.txt for detail -+ - Example: - - &usb1 { -@@ -21,8 +25,12 @@ Example: - #address-cells = <1>; - #size-cells = <0>; - -- hub: genesys@1 { -+ genesys: hub@1 { - compatible = "usb5e3,608"; - reg = <1>; -+ -+ clocks = <&clks IMX6SX_CLK_CKO>; -+ reset-gpios = <&gpio4 5 GPIO_ACTIVE_LOW>; /* hub reset pin */ -+ reset-duration-us = <10>; - }; - } -diff --git b/Documentation/devicetree/configfs-overlays.txt b/Documentation/devicetree/configfs-overlays.txt -new file mode 100644 -index 0000000..5fa43e0 ---- /dev/null -+++ b/Documentation/devicetree/configfs-overlays.txt -@@ -0,0 +1,31 @@ -+Howto use the configfs overlay interface. -+ -+A device-tree configfs entry is created in /config/device-tree/overlays -+and and it is manipulated using standard file system I/O. -+Note that this is a debug level interface, for use by developers and -+not necessarily something accessed by normal users due to the -+security implications of having direct access to the kernel's device tree. -+ -+* To create an overlay you mkdir the directory: -+ -+ # mkdir /config/device-tree/overlays/foo -+ -+* Either you echo the overlay firmware file to the path property file. -+ -+ # echo foo.dtbo >/config/device-tree/overlays/foo/path -+ -+* Or you cat the contents of the overlay to the dtbo file -+ -+ # cat foo.dtbo >/config/device-tree/overlays/foo/dtbo -+ -+The overlay file will be applied, and devices will be created/destroyed -+as required. -+ -+To remove it simply rmdir the directory. -+ -+ # rmdir /config/device-tree/overlays/foo -+ -+The rationalle of the dual interface (firmware & direct copy) is that each is -+better suited to different use patterns. The firmware interface is what's -+intended to be used by hardware managers in the kernel, while the copy interface -+make sense for developers (since it avoids problems with namespaces). -diff --git a/Documentation/devicetree/overlay-notes.txt b/Documentation/devicetree/overlay-notes.txt -index d418a6c..3e8df30 100644 ---- a/Documentation/devicetree/overlay-notes.txt -+++ b/Documentation/devicetree/overlay-notes.txt -@@ -100,6 +100,14 @@ Finally, if you need to remove all overlays in one-go, just call - of_overlay_destroy_all() which will remove every single one in the correct - order. - -+If your board has multiple slots/places where a single overlay can work -+and each slot is defined by a node, you can use the -+of_overlay_create_target_index() method to select the target. -+ -+For overlays on probeable busses, use the of_overlay_create_target_root() method -+in which you supply a device node as a target root, and which all target -+references in the overlay are performed relative to that node. -+ - Overlay DTS Format - ------------------ - -@@ -110,9 +118,11 @@ The DTS of an overlay should have the following format: - - fragment@0 { /* first child node */ - -- target=<phandle>; /* phandle target of the overlay */ -+ /* phandle target of the overlay */ -+ target=<phandle> [, <phandle>, ...]; - or -- target-path="/path"; /* target path of the overlay */ -+ /* target path of the overlay */ -+ target-path="/path" [ , "/path", ...]; - - __overlay__ { - property-a; /* add property-a to the target */ -@@ -131,3 +141,11 @@ Using the non-phandle based target method allows one to use a base DT which does - not contain a __symbols__ node, i.e. it was not compiled with the -@ option. - The __symbols__ node is only required for the target=<phandle> method, since it - contains the information required to map from a phandle to a tree location. -+ -+Using a target index requires the use of a selector target on the call to -+of_overlay_create_target_index(). I.e. passing an index of 0 will select the -+target in the foo node, an index of 1 the bar node, etc. -+ -+Note that when using the target root create method all target references must -+lie under the target root node. I.e. the overlay is not allowed to 'break' out -+of the root. -diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt -index 86a6746..b093a38 100644 ---- a/Documentation/kernel-parameters.txt -+++ b/Documentation/kernel-parameters.txt -@@ -121,6 +121,7 @@ parameter is applicable: - NET Appropriate network support is enabled. - NUMA NUMA support is enabled. - NFS Appropriate NFS support is enabled. -+ OF Open Firmware support (device tree) is enabled. - OSS OSS sound support is enabled. - PV_OPS A paravirtualized kernel is enabled. - PARIDE The ParIDE (parallel port IDE) subsystem is enabled. -@@ -2872,6 +2873,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. - This can be set from sysctl after boot. - See Documentation/sysctl/vm.txt for details. - -+ of_overlay_disable [OF] Disable device tree overlays at boot time. -+ - ohci1394_dma=early [HW] enable debugging via the ohci1394 driver. - See Documentation/debugging-via-ohci1394.txt for more - info. -diff --git b/Documentation/misc-devices/bone_capemgr.txt b/Documentation/misc-devices/bone_capemgr.txt -new file mode 100644 -index 0000000..2a8c766 ---- /dev/null -+++ b/Documentation/misc-devices/bone_capemgr.txt -@@ -0,0 +1,63 @@ -+--------------------------- -+ Beaglebone Cape-Manager -+--------------------------- -+ -+The beaglebone cape manager driver allows the automatic use of external -+peripheral capes to be automatically supported by Linux without any manual -+setup required by the user. -+ -+Each beaglebone cape should contain an EEPROM that describes -+it in a fixed I2C address on the i2c2 bus of the baseboard. -+The format of the EEPROM is defined in the beaglebone reference -+manual at: -+http://beagleboard.org/static/beaglebone/latest/Docs/Hardware/BONE_SRM.pdf -+ -+Reading the part number and revision information the manager -+requests a firmware file formatted as a device tree overlay blob. -+ -+Applying the overlay the devices are instantiated and the cape is -+ready to be used. -+ -+For instance if the part-number is BB-BONE-SERL-03 and the version is 00A1 -+the firmware file requested will be BB-BONE-SERL-03-00A1-00A1.dtbo -+It will be located by the in-kernel firmware -+loader in the usual place, i.e. /lib/firmware/`uname -r`, /lib/firmware etc. -+ -+The driver supports the following parameters (either as part of the kernel -+command line or supplied at module insertion time). -+ -+disable_partno: A comma delimited list of PART-NUMBER[:REV] of -+ disabled capes. -+enable_partno: A comma delimited list of PART-NUMBER[:REV[:PRIO]] of -+ enabled capes. -+boot_scan_period: The boot scan period in ms. When the cape manager is built-in -+ the kernel image, the firmware loader cannot find the files -+ before the rootfs is mounted. This parameter controls the -+ period with which the boot state is checked in that case. -+ -+There's a sysfs control interface which is defined at the ABI documentation -+area. -+ -+Theory of operation: -+-------------------- -+ -+On driver probe the I2C EEPROM of the baseboard is read and information about -+the current baseboard is retrieved. This information includes the mapping from -+baseboard board name to DT friendly compatible string. I.e. the "A335BONE" board -+name from EEPROM is mapped to the "ti,beaglebone" compatible string which should -+be present in the dtbo to be loaded. -+ -+Afterwards the EEPROMs declared in each slot are probed, and the EEPROMs found -+are decoded keeping track the cape part-number and version data. -+ -+Using the part-number and version a firmware file is requested (the firmware -+file requested is <part-number>-<version>.dtbo). -+ -+The dtbo is unflattend and the resulting device tree is matched against a -+compatible baseboard, and in case of multiple parallel loading capes the -+priorities defined are honored. That means that when there are multiple capes -+being loaded in parallel the ones with the lowest priority number are loaded -+first. -+ -+Applying the device tree overlay makes the cape operational, as if it was part -+of the kernel's booting device tree. -diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt -index 5962949..d1ba882 100644 ---- a/Documentation/printk-formats.txt -+++ b/Documentation/printk-formats.txt -@@ -324,10 +324,49 @@ Network device features: - - Passed by reference. - -+Command from struct task_struct -+ -+ %pT ls -+ -+ For printing executable name excluding path from struct -+ task_struct. -+ -+ Passed by reference. -+ -+Device tree nodes: -+ -+ %pO[fnpPcCFr] -+ -+ For printing device tree nodes. The optional arguments are: -+ f device node full_name -+ n device node name -+ p device node phandle -+ P device node path spec (name + @unit) -+ F device node flags -+ c major compatible string -+ C full compatible string -+ r node reference count -+ Without any arguments prints full_name (same as %pOf) -+ The separator when using multiple arguments is '|' -+ -+ Examples: -+ -+ %pO /foo/bar@0 - Node full name -+ %pOf /foo/bar@0 - Same as above -+ %pOfp /foo/bar@0|10 - Node full name + phandle -+ %pOfcF /foo/bar@0|foo,device|--P- - Node full name + -+ major compatible string + -+ node flags -+ D - dynamic -+ d - detached -+ P - Populated -+ B - Populated bus -+ -+ Passed by reference -+ - If you add other %p extensions, please extend lib/test_printf.c with - one or more test cases, if at all feasible. - -- - Thank you for your cooperation and attention. - - -diff --git a/MAINTAINERS b/MAINTAINERS -index 63cefa6..d49fd46 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -597,6 +597,12 @@ S: Maintained - F: Documentation/i2c/busses/i2c-ali1563 - F: drivers/i2c/busses/i2c-ali1563.c - -+ALLWINNER SUN8I-EMAC ETHERNET DRIVER -+M: Corentin Labbe <clabbe.montjoie@gmail.com> -+L: netdev@vger.kernel.org -+S: Maintained -+F: drivers/net/ethernet/allwinner/sun8i-emac.c -+ - ALLWINNER SECURITY SYSTEM - M: Corentin Labbe <clabbe.montjoie@gmail.com> - L: linux-crypto@vger.kernel.org -@@ -2401,6 +2407,14 @@ W: https://linuxtv.org - S: Supported - F: drivers/media/platform/sti/bdisp - -+BEAGLEBONE CAPEMANAGER -+M: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -+S: Maintained -+F: drivers/misc/beaglebone-capemgr.c -+F: Documentation/misc-devices/bone_capemgr.txt -+F: Documentation/devicetree/bindings/misc/bone_capemgr.txt -+F: Documentation/ABI/testing/sysfs-devices-platform-bone_capemgr -+ - BEFS FILE SYSTEM - M: Luis de Bethencourt <luisbg@osg.samsung.com> - M: Salah Triki <salah.triki@gmail.com> -@@ -9635,6 +9649,15 @@ F: include/linux/pm_* - F: include/linux/powercap.h - F: drivers/powercap/ - -+POWER SEQUENCE LIBRARY -+M: Peter Chen <Peter.Chen@nxp.com> -+T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git -+L: linux-pm@vger.kernel.org -+S: Maintained -+F: Documentation/devicetree/bindings/power/pwrseq/ -+F: drivers/power/pwrseq/ -+F: include/linux/power/pwrseq.h/ -+ - POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS - M: Sebastian Reichel <sre@kernel.org> - L: linux-pm@vger.kernel.org -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index b5d529f..ced2e08 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -1496,8 +1496,7 @@ source kernel/Kconfig.preempt - - config HZ_FIXED - int -- default 200 if ARCH_EBSA110 || ARCH_S3C24XX || \ -- ARCH_S5PV210 || ARCH_EXYNOS4 -+ default 200 if ARCH_EBSA110 - default 128 if SOC_AT91RM9200 - default 0 - -diff --git a/arch/arm/Makefile b/arch/arm/Makefile -index 6be9ee1..6deeab7 100644 ---- a/arch/arm/Makefile -+++ b/arch/arm/Makefile -@@ -13,7 +13,12 @@ - # Ensure linker flags are correct - LDFLAGS := - --LDFLAGS_vmlinux :=-p --no-undefined -X --pic-veneer -+GCCVERSIONISGTE5 := $(shell expr `$(HOSTCC) -dumpversion | cut -f1 -d.` \>= 5) -+ifeq "$(GCCVERSIONISGTE5)" "1" -+LDFLAGS_vmlinux :=-p --no-undefined -X -+else -+LDFLAGS_vmlinux :=-p --no-undefined -X --pic-veneer -+endif - ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) - LDFLAGS_vmlinux += --be8 - LDFLAGS_MODULE += --be8 -diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile -index 50f8d1b..2c30c44 100644 ---- a/arch/arm/boot/Makefile -+++ b/arch/arm/boot/Makefile -@@ -29,6 +29,10 @@ export ZRELADDR INITRD_PHYS PARAMS_PHYS - - targets := Image zImage xipImage bootpImage uImage - -+ifeq ($(CONFIG_OF_OVERLAY),y) -+DTC_FLAGS += -@ -+endif -+ - ifeq ($(CONFIG_XIP_KERNEL),y) - - $(obj)/xipImage: vmlinux FORCE -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 7037201..aabd736 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -1,11 +1,17 @@ - ifeq ($(CONFIG_OF),y) - -+ifeq ($(CONFIG_OF_OVERLAY),y) -+DTC_FLAGS += -@ -+endif -+ - dtb-$(CONFIG_ARCH_ALPINE) += \ - alpine-db.dtb - dtb-$(CONFIG_MACH_ARTPEC6) += \ - artpec6-devboard.dtb -+ - dtb-$(CONFIG_MACH_ASM9260) += \ - alphascale-asm9260-devkit.dtb -+ - # Keep at91 dtb files sorted alphabetically for each SoC - dtb-$(CONFIG_SOC_AT91RM9200) += \ - at91rm9200ek.dtb \ -@@ -155,6 +161,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \ - exynos5420-arndale-octa.dtb \ - exynos5420-peach-pit.dtb \ - exynos5420-smdk5420.dtb \ -+ exynos5422-artik10-eval.dtb \ - exynos5422-odroidxu3.dtb \ - exynos5422-odroidxu3-lite.dtb \ - exynos5422-odroidxu4.dtb \ -@@ -366,6 +373,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ - imx6q-b650v3.dtb \ - imx6q-b850v3.dtb \ - imx6q-cm-fx6.dtb \ -+ imx6q-ccimx6sbc.dtb \ - imx6q-cubox-i.dtb \ - imx6q-dfi-fs700-m60.dtb \ - imx6q-dmo-edmqmx6.dtb \ -@@ -419,6 +427,7 @@ dtb-$(CONFIG_SOC_IMX6SX) += \ - imx6sx-sdb.dtb - dtb-$(CONFIG_SOC_IMX6UL) += \ - imx6ul-14x14-evk.dtb \ -+ imx6ul-14x14-evk-ism43362-b81-evb.dtb \ - imx6ul-geam-kit.dtb \ - imx6ul-pico-hobbit.dtb \ - imx6ul-tx6ul-0010.dtb \ -@@ -548,6 +557,28 @@ dtb-$(CONFIG_SOC_AM33XX) += \ - am335x-base0033.dtb \ - am335x-bone.dtb \ - am335x-boneblack.dtb \ -+ am335x-boneblack-uboot.dtb \ -+ am335x-sancloud-bbe.dtb \ -+ am335x-boneblack-wireless-roboticscape.dtb \ -+ am335x-boneblack-roboticscape.dtb \ -+ am335x-boneblue.dtb \ -+ am335x-boneblack-wireless-emmc-overlay.dtb \ -+ am335x-boneblack-wireless.dtb \ -+ am335x-bonegreen-wireless.dtb \ -+ am335x-boneblack-audio.dtb \ -+ am335x-boneblack-bbb-exp-r.dtb \ -+ am335x-boneblack-bbb-exp-c.dtb \ -+ am335x-boneblack-bbbmini.dtb \ -+ am335x-boneblack-wl1835mod.dtb \ -+ am335x-boneblack-cape-bone-argus.dtb \ -+ am335x-bone-cape-bone-argus.dtb \ -+ am335x-olimex-som.dtb \ -+ am335x-abbbi.dtb \ -+ am335x-bonegreen-overlay.dtb \ -+ am335x-boneblack-overlay.dtb \ -+ am335x-boneblack-nhdmi-overlay.dtb \ -+ am335x-boneblack-hdmi-overlay.dtb \ -+ am335x-boneblack-emmc-overlay.dtb \ - am335x-bonegreen.dtb \ - am335x-chiliboard.dtb \ - am335x-cm-t335.dtb \ -@@ -567,6 +598,7 @@ dtb-$(CONFIG_ARCH_OMAP4) += \ - omap4-panda.dtb \ - omap4-panda-a4.dtb \ - omap4-panda-es.dtb \ -+ omap4-panda-es-b3.dtb \ - omap4-sdp.dtb \ - omap4-sdp-es23plus.dtb \ - omap4-var-dvk-om44.dtb \ -diff --git b/arch/arm/boot/dts/am335x-abbbi.dts b/arch/arm/boot/dts/am335x-abbbi.dts -new file mode 100644 -index 0000000..43efead ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-abbbi.dts -@@ -0,0 +1,163 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * Copyright 2015 Konsulko Group -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common.dtsi" -+ -+ -+/ { -+ model = "Arrow BeagleBone Black Industrial"; -+ compatible = "arrow,am335x-abbbi", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ status = "okay"; -+}; -+ -+&am33xx_pinmux { -+ adi_hdmi_bbbi_pins: adi_hdmi_bbbi_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */ -+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */ -+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */ -+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */ -+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */ -+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */ -+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */ -+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */ -+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */ -+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */ -+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */ -+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */ -+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */ -+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */ -+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */ -+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */ -+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_vsync.lcd_vsync */ -+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_hsync.lcd_hsync */ -+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_pclk.lcd_pclk */ -+ AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */ -+ >; -+ }; -+ adi_hdmi_bbbi_off_pins: adi_hdmi_bbbi_off_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ >; -+ }; -+ -+ mcasp0_pins: mcasp0_pins { -+ pinctrl-single,pins = < -+ 0x1ac (PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_ahclkx.mcasp0_ahclkx */ -+ 0x19c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2 */ -+ 0x194 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */ -+ 0x190 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */ -+ 0x06c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.GPIO1_27 */ -+ >; -+ }; -+ -+ mcasp0_pins_sleep: mcasp0_pins_sleep { -+ pinctrl-single,pins = < -+ 0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE7) /* mcasp0_ahclkx.mcasp0_ahclkx */ -+ 0x19c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* mcasp0_ahclkr.mcasp0_axr2 */ -+ 0x194 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* mcasp0_fsx.mcasp0_fsx */ -+ 0x190 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* mcasp0_aclkx.mcasp0_aclkx */ -+ 0x06c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.GPIO1_27 */ -+ >; -+ }; -+}; -+ -+&lcdc { -+ status = "okay"; -+ port { -+ lcdc_0: endpoint@0 { -+ remote-endpoint = <&hdmi_0>; -+ }; -+ }; -+}; -+ -+&i2c0 { -+ adv7511w { -+ compatible = "adi,adv7511w"; -+ reg = <0x39>; -+ pinctrl-names = "default", "off"; -+ pinctrl-0 = <&adi_hdmi_bbbi_pins>; -+ pinctrl-1 = <&adi_hdmi_bbbi_off_pins>; -+ -+ port { -+ hdmi_0: endpoint@0 { -+ remote-endpoint = <&lcdc_0>; -+ }; -+ }; -+ }; -+}; -+ -+&mcasp0 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&mcasp0_pins>; -+ pinctrl-1 = <&mcasp0_pins_sleep>; -+ status = "okay"; -+ op-mode = <0>; /* MCASP_IIS_MODE */ -+ tdm-slots = <2>; -+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ -+ 0 0 1 0 -+ >; -+ tx-num-evt = <1>; -+ rx-num-evt = <1>; -+}; -+ -+/ { -+ clk_mcasp0_fixed: clk_mcasp0_fixed { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <24576000>; -+ }; -+ -+ clk_mcasp0: clk_mcasp0 { -+ #clock-cells = <0>; -+ compatible = "gpio-gate-clock"; -+ clocks = <&clk_mcasp0_fixed>; -+ enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */ -+ }; -+ -+ hdmi_audio: hdmi_audio@0 { -+ compatible = "linux,hdmi-audio"; -+ status = "okay"; -+ }; -+ -+ sound { -+ compatible = "ti,beaglebone-black-audio"; -+ ti,model = "TI BeagleBone Black"; -+ ti,audio-codec = <&hdmi_audio>; -+ ti,mcasp-controller = <&mcasp0>; -+ ti,audio-routing = -+ "HDMI Out", "TX"; -+ clocks = <&clk_mcasp0>; -+ clock-names = "mclk"; -+ }; -+}; -+ -+&rtc { -+ system-power-controller; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-argus.dtsi b/arch/arm/boot/dts/am335x-bone-argus.dtsi -new file mode 100644 -index 0000000..21afad3 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-argus.dtsi -@@ -0,0 +1,109 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+ -+/ { -+ ocp { -+ P8_07_pinmux { -+ /* gpio2[2] */ -+ status = "disabled"; -+ }; -+ P8_08_pinmux { -+ /* gpio2[3] */ -+ status = "disabled"; -+ }; -+ P8_09_pinmux { -+ /* gpio2[5] */ -+ status = "disabled"; -+ }; -+ P8_10_pinmux { -+ /* gpio2[4] */ -+ status = "disabled"; -+ }; -+ P9_11_pinmux { -+ /* gpio0[30] */ -+ status = "disabled"; -+ }; -+ P9_17_pinmux { -+ /* gpio0[5] */ -+ status = "disabled"; -+ }; -+ P9_18_pinmux { -+ /* gpio0[4] */ -+ status = "disabled"; -+ }; -+ P9_41_pinmux { -+ /* gpio0[20] */ -+ status = "disabled"; -+ }; -+ P9_42_pinmux { -+ /* gpio0[7] */ -+ status = "disabled"; -+ }; -+ }; -+}; -+ -+/ { -+ argus-ups { -+ compatible = "argus-ups"; -+ status = "okay"; -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&argus_ups_pins>; /* Refer to previous label */ -+ /* This section communicates the gpio numbers to the driver module */ -+ /* Note that gpio controllers appear to be numbered from 1-n here rather than 0-(n-1)????? */ -+ gpios = <&gpio0 30 0>, /* Request */ -+ <&gpio0 5 0>, /* Acknowledge */ -+ <&gpio0 4 0>, /* Watchdog */ -+ <&gpio2 2 0>, /* LED 1 Green */ -+ <&gpio2 3 0>, /* LED 1 Red */ -+ <&gpio2 5 0>, /* LED 2 Green */ -+ <&gpio2 4 0>, /* LED 2 Red */ -+ <&gpio0 20 0>, /* General Output #1 */ -+ <&gpio0 7 0>; /* General Output #2 */ -+ debug = <1>; -+ shutdown = <1>; -+ }; -+}; -+ -+&am33xx_pinmux { -+ argus_ups_pins: pinmux_argus_ups_pins { /* Set up pinmux */ -+ pinctrl-single,pins = < -+ 0x070 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_wait0.gpio0_30 */ -+ 0x15c (PIN_OUTPUT_PULLUP | MUX_MODE7) /* spi0_cs0.gpio0_5 */ -+ 0x158 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* spi0_d1.gpio0_4 */ -+ 0x090 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_advn_ale.gpio_2 */ -+ 0x094 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_oen_ren.gpio2_3 */ -+ 0x09c (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_ben0_cle.gpio2_5 */ -+ 0x098 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_gpmc_wen.gpio2_4 */ -+ 0x1b4 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* xdma_event_intr1.gpio0_20 */ -+ 0x164 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* ecap0_in_pwm0_out.gpio0_7 */ -+ >; -+ }; -+ -+ i2c2_pins: pinmux_i2c2_pins { -+ pinctrl-single,pins = < -+ BONE_P9_20 0x73 /* (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3) uart1_ctsn.i2c2_sda */ -+ BONE_P9_19 0x73 /* (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3) uart1_rtsn.i2c2_scl */ -+ >; -+ }; -+}; -+ -+&i2c2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_pins>; -+ -+ status = "okay"; -+ clock-frequency = <100000>; -+ -+ rtc@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-cape-bone-argus.dts b/arch/arm/boot/dts/am335x-bone-cape-bone-argus.dts -new file mode 100644 -index 0000000..82218f5 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-cape-bone-argus.dts -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common-no-capemgr.dtsi" -+ -+/ { -+ model = "TI AM335x BeagleBone"; -+ compatible = "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&ldo3_reg>; -+}; -+ -+#include "am335x-bone-argus.dtsi" -diff --git b/arch/arm/boot/dts/am335x-bone-common-no-capemgr.dtsi b/arch/arm/boot/dts/am335x-bone-common-no-capemgr.dtsi -new file mode 100644 -index 0000000..56b9ccf ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-common-no-capemgr.dtsi -@@ -0,0 +1,362 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <dt-bindings/mfd/tps65217.h> -+ -+/ { -+ cpus { -+ cpu@0 { -+ cpu0-supply = <&dcdc2_reg>; -+ }; -+ }; -+ -+ memory@80000000 { -+ device_type = "memory"; -+ reg = <0x80000000 0x10000000>; /* 256 MB */ -+ }; -+ -+ chosen { -+ stdout-path = &uart0; -+ }; -+ -+ leds { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&user_leds_s0>; -+ -+ compatible = "gpio-leds"; -+ -+ led2 { -+ label = "beaglebone:green:usr0"; -+ gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ default-state = "off"; -+ }; -+ -+ led3 { -+ label = "beaglebone:green:usr1"; -+ gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "mmc0"; -+ default-state = "off"; -+ }; -+ -+ led4 { -+ label = "beaglebone:green:usr2"; -+ gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "cpu0"; -+ default-state = "off"; -+ }; -+ -+ led5 { -+ label = "beaglebone:green:usr3"; -+ gpios = <&gpio1 24 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "mmc1"; -+ default-state = "off"; -+ }; -+ }; -+ -+ vmmcsd_fixed: fixedregulator0 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vmmcsd_fixed"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; -+}; -+ -+&am33xx_pinmux { -+ user_leds_s0: user_leds_s0 { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */ -+ AM33XX_IOPAD(0x858, PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a6.gpio1_22 */ -+ AM33XX_IOPAD(0x85c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a7.gpio1_23 */ -+ AM33XX_IOPAD(0x860, PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a8.gpio1_24 */ -+ >; -+ }; -+ -+ i2c0_pins: pinmux_i2c0_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */ -+ AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */ -+ >; -+ }; -+ -+ i2c2_pins: pinmux_i2c2_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x978, PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_ctsn.i2c2_sda */ -+ AM33XX_IOPAD(0x97c, PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_rtsn.i2c2_scl */ -+ >; -+ }; -+ -+ uart0_pins: pinmux_uart0_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ -+ AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ -+ >; -+ }; -+ -+ cpsw_default: cpsw_default { -+ pinctrl-single,pins = < -+ /* Slave 1 */ -+ 0x108 (PIN_INPUT | MUX_MODE0) /* mii1_col.mii1_col */ -+ 0x10c (PIN_INPUT | MUX_MODE0) /* mii1_crs.mii1_crs */ -+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxerr.mii1_rxerr */ -+ AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txen.mii1_txen */ -+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxdv.mii1_rxdv */ -+ AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd3.mii1_txd3 */ -+ AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd2.mii1_txd2 */ -+ AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd1.mii1_txd1 */ -+ AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd0.mii1_txd0 */ -+ AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_txclk.mii1_txclk */ -+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxclk.mii1_rxclk */ -+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd3.mii1_rxd3 */ -+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd2.mii1_rxd2 */ -+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd1.mii1_rxd1 */ -+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd0.mii1_rxd0 */ -+ >; -+ }; -+ -+ cpsw_sleep: cpsw_sleep { -+ pinctrl-single,pins = < -+ /* Slave 1 reset value */ -+ 0x108 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+ davinci_mdio_default: davinci_mdio_default { -+ pinctrl-single,pins = < -+ /* MDIO */ -+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ -+ AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ -+ >; -+ }; -+ -+ davinci_mdio_sleep: davinci_mdio_sleep { -+ pinctrl-single,pins = < -+ /* MDIO reset value */ -+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+ mmc1_pins: pinmux_mmc1_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* GPIO0_6 */ -+ >; -+ }; -+ -+ emmc_pins: pinmux_emmc_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */ -+ AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */ -+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */ -+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */ -+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */ -+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */ -+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */ -+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */ -+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */ -+ AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */ -+ >; -+ }; -+}; -+ -+&uart0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins>; -+ -+ status = "okay"; -+}; -+ -+&usb { -+ status = "okay"; -+}; -+ -+&usb_ctrl_mod { -+ status = "okay"; -+}; -+ -+&usb0_phy { -+ status = "okay"; -+}; -+ -+&usb1_phy { -+ status = "okay"; -+}; -+ -+&usb0 { -+ status = "okay"; -+ dr_mode = "peripheral"; -+}; -+ -+&usb1 { -+ status = "okay"; -+ dr_mode = "host"; -+}; -+ -+&cppi41dma { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ -+ status = "okay"; -+ clock-frequency = <400000>; -+ -+ tps: tps@24 { -+ reg = <0x24>; -+ }; -+ -+ baseboard_eeprom: baseboard_eeprom@50 { -+ compatible = "at,24c256"; -+ reg = <0x50>; -+ -+ #address-cells = <1>; -+ #size-cells = <1>; -+ baseboard_data: baseboard_data@0 { -+ reg = <0 0x100>; -+ }; -+ }; -+}; -+ -+/include/ "tps65217.dtsi" -+ -+&tps { -+ /* -+ * Configure pmic to enter OFF-state instead of SLEEP-state ("RTC-only -+ * mode") at poweroff. Most BeagleBone versions do not support RTC-only -+ * mode and risk hardware damage if this mode is entered. -+ * -+ * For details, see linux-omap mailing list May 2015 thread -+ * [PATCH] ARM: dts: am335x-bone* enable pmic-shutdown-controller -+ * In particular, messages: -+ * http://www.spinics.net/lists/linux-omap/msg118585.html -+ * http://www.spinics.net/lists/linux-omap/msg118615.html -+ * -+ * You can override this later with -+ * &tps { /delete-property/ ti,pmic-shutdown-controller; } -+ * if you want to use RTC-only mode and made sure you are not affected -+ * by the hardware problems. (Tip: double-check by performing a current -+ * measurement after shutdown: it should be less than 1 mA.) -+ */ -+ -+ interrupts = <7>; /* NMI */ -+ interrupt-parent = <&intc>; -+ -+ ti,pmic-shutdown-controller; -+ -+ charger { -+ interrupts = <TPS65217_IRQ_AC>, <TPS65217_IRQ_USB>; -+ interrupts-names = "AC", "USB"; -+ status = "okay"; -+ }; -+ -+ pwrbutton { -+ interrupts = <TPS65217_IRQ_PB>; -+ status = "okay"; -+ }; -+ -+ regulators { -+ dcdc1_reg: regulator@0 { -+ regulator-name = "vdds_dpr"; -+ regulator-always-on; -+ }; -+ -+ dcdc2_reg: regulator@1 { -+ /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */ -+ regulator-name = "vdd_mpu"; -+ regulator-min-microvolt = <925000>; -+ regulator-max-microvolt = <1351500>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ dcdc3_reg: regulator@2 { -+ /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */ -+ regulator-name = "vdd_core"; -+ regulator-min-microvolt = <925000>; -+ regulator-max-microvolt = <1150000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ ldo1_reg: regulator@3 { -+ regulator-name = "vio,vrtc,vdds"; -+ regulator-always-on; -+ }; -+ -+ ldo2_reg: regulator@4 { -+ regulator-name = "vdd_3v3aux"; -+ regulator-always-on; -+ }; -+ -+ ldo3_reg: regulator@5 { -+ regulator-name = "vdd_1v8"; -+ regulator-always-on; -+ }; -+ -+ ldo4_reg: regulator@6 { -+ regulator-name = "vdd_3v3a"; -+ regulator-always-on; -+ }; -+ }; -+}; -+ -+&cpsw_emac0 { -+ phy_id = <&davinci_mdio>, <0>; -+ phy-mode = "mii"; -+}; -+ -+&mac { -+ slaves = <1>; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&cpsw_default>; -+ pinctrl-1 = <&cpsw_sleep>; -+ status = "okay"; -+}; -+ -+&davinci_mdio { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&davinci_mdio_default>; -+ pinctrl-1 = <&davinci_mdio_sleep>; -+ status = "okay"; -+}; -+ -+&mmc1 { -+ status = "okay"; -+ bus-width = <0x4>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc1_pins>; -+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; -+}; -+ -+&aes { -+ status = "okay"; -+}; -+ -+&sham { -+ status = "okay"; -+}; -+ -+&rtc { -+ system-power-controller; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-common-universal-pins.dtsi b/arch/arm/boot/dts/am335x-bone-common-universal-pins.dtsi -new file mode 100644 -index 0000000..e4d4971 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-common-universal-pins.dtsi -@@ -0,0 +1,941 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&am33xx_pinmux { -+ /************************/ -+ /* P8 Header */ -+ /************************/ -+ -+ /* P8_01 GND */ -+ /* P8_02 GND */ -+ /* P8_03 (ZCZ ball R9 ) emmc */ -+ /* P8_04 (ZCZ ball T9 ) emmc */ -+ /* P8_05 (ZCZ ball R8 ) emmc */ -+ /* P8_06 (ZCZ ball T8 ) emmc */ -+ -+ /* P8_07 (ZCZ ball R7 ) */ -+ P8_07_default_pin: pinmux_P8_07_default_pin { -+ pinctrl-single,pins = <0x090 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_07_gpio_pin: pinmux_P8_07_gpio_pin { -+ pinctrl-single,pins = <0x090 0x2F>; }; /* Mode 7, RxActive */ -+ P8_07_gpio_pu_pin: pinmux_P8_07_gpio_pu_pin { -+ pinctrl-single,pins = <0x090 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_07_gpio_pd_pin: pinmux_P8_07_gpio_pd_pin { -+ pinctrl-single,pins = <0x090 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_07_timer_pin: pinmux_P8_07_timer_pin { -+ pinctrl-single,pins = <0x090 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ -+ /* P8_08 (ZCZ ball T7 ) */ -+ P8_08_default_pin: pinmux_P8_08_default_pin { -+ pinctrl-single,pins = <0x094 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_08_gpio_pin: pinmux_P8_08_gpio_pin { -+ pinctrl-single,pins = <0x094 0x2F>; }; /* Mode 7, RxActive */ -+ P8_08_gpio_pu_pin: pinmux_P8_08_gpio_pu_pin { -+ pinctrl-single,pins = <0x094 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_08_gpio_pd_pin: pinmux_P8_08_gpio_pd_pin { -+ pinctrl-single,pins = <0x094 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_08_timer_pin: pinmux_P8_08_timer_pin { -+ pinctrl-single,pins = <0x094 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ -+ /* P8_09 (ZCZ ball T6 ) */ -+ P8_09_default_pin: pinmux_P8_09_default_pin { -+ pinctrl-single,pins = <0x09c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_09_gpio_pin: pinmux_P8_09_gpio_pin { -+ pinctrl-single,pins = <0x09c 0x2F>; }; /* Mode 7, RxActive */ -+ P8_09_gpio_pu_pin: pinmux_P8_09_gpio_pu_pin { -+ pinctrl-single,pins = <0x09c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_09_gpio_pd_pin: pinmux_P8_09_gpio_pd_pin { -+ pinctrl-single,pins = <0x09c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_09_timer_pin: pinmux_P8_09_timer_pin { -+ pinctrl-single,pins = <0x09c 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ -+ /* P8_10 (ZCZ ball U6 ) */ -+ P8_10_default_pin: pinmux_P8_10_default_pin { -+ pinctrl-single,pins = <0x098 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_10_gpio_pin: pinmux_P8_10_gpio_pin { -+ pinctrl-single,pins = <0x098 0x2F>; }; /* Mode 7, RxActive */ -+ P8_10_gpio_pu_pin: pinmux_P8_10_gpio_pu_pin { -+ pinctrl-single,pins = <0x098 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_10_gpio_pd_pin: pinmux_P8_10_gpio_pd_pin { -+ pinctrl-single,pins = <0x098 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_10_timer_pin: pinmux_P8_10_timer_pin { -+ pinctrl-single,pins = <0x098 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ -+ /* P8_11 (ZCZ ball R12) */ -+ P8_11_default_pin: pinmux_P8_11_default_pin { -+ pinctrl-single,pins = <0x034 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_11_gpio_pin: pinmux_P8_11_gpio_pin { -+ pinctrl-single,pins = <0x034 0x2F>; }; /* Mode 7, RxActive */ -+ P8_11_gpio_pu_pin: pinmux_P8_11_gpio_pu_pin { -+ pinctrl-single,pins = <0x034 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_11_gpio_pd_pin: pinmux_P8_11_gpio_pd_pin { -+ pinctrl-single,pins = <0x034 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_11_pruout_pin: pinmux_P8_11_pruout_pin { -+ pinctrl-single,pins = <0x034 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_11_qep_pin: pinmux_P8_11_qep_pin { -+ pinctrl-single,pins = <0x034 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_12 (ZCZ ball T12) */ -+ P8_12_default_pin: pinmux_P8_12_default_pin { -+ pinctrl-single,pins = <0x030 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_12_gpio_pin: pinmux_P8_12_gpio_pin { -+ pinctrl-single,pins = <0x030 0x2F>; }; /* Mode 7, RxActive */ -+ P8_12_gpio_pu_pin: pinmux_P8_12_gpio_pu_pin { -+ pinctrl-single,pins = <0x030 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_12_gpio_pd_pin: pinmux_P8_12_gpio_pd_pin { -+ pinctrl-single,pins = <0x030 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_12_pruout_pin: pinmux_P8_12_pruout_pin { -+ pinctrl-single,pins = <0x030 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_12_qep_pin: pinmux_P8_12_qep_pin { -+ pinctrl-single,pins = <0x030 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_13 (ZCZ ball T10) */ -+ P8_13_default_pin: pinmux_P8_13_default_pin { -+ pinctrl-single,pins = <0x024 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_13_gpio_pin: pinmux_P8_13_gpio_pin { -+ pinctrl-single,pins = <0x024 0x2F>; }; /* Mode 7, RxActive */ -+ P8_13_gpio_pu_pin: pinmux_P8_13_gpio_pu_pin { -+ pinctrl-single,pins = <0x024 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_13_gpio_pd_pin: pinmux_P8_13_gpio_pd_pin { -+ pinctrl-single,pins = <0x024 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_13_pwm_pin: pinmux_P8_13_pwm_pin { -+ pinctrl-single,pins = <0x024 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_14 (ZCZ ball T11) */ -+ P8_14_default_pin: pinmux_P8_14_default_pin { -+ pinctrl-single,pins = <0x028 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_14_gpio_pin: pinmux_P8_14_gpio_pin { -+ pinctrl-single,pins = <0x028 0x2F>; }; /* Mode 7, RxActive */ -+ P8_14_gpio_pu_pin: pinmux_P8_14_gpio_pu_pin { -+ pinctrl-single,pins = <0x028 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_14_gpio_pd_pin: pinmux_P8_14_gpio_pd_pin { -+ pinctrl-single,pins = <0x028 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_14_pwm_pin: pinmux_P8_14_pwm_pin { -+ pinctrl-single,pins = <0x028 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_15 (ZCZ ball U13) */ -+ P8_15_default_pin: pinmux_P8_15_default_pin { -+ pinctrl-single,pins = <0x03c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_15_gpio_pin: pinmux_P8_15_gpio_pin { -+ pinctrl-single,pins = <0x03c 0x2F>; }; /* Mode 7, RxActive */ -+ P8_15_gpio_pu_pin: pinmux_P8_15_gpio_pu_pin { -+ pinctrl-single,pins = <0x03c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_15_gpio_pd_pin: pinmux_P8_15_gpio_pd_pin { -+ pinctrl-single,pins = <0x03c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_15_pruin_pin: pinmux_P8_15_pruin_pin { -+ pinctrl-single,pins = <0x03c 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_15_qep_pin: pinmux_P8_15_qep_pin { -+ pinctrl-single,pins = <0x03c 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_16 (ZCZ ball V13) */ -+ P8_16_default_pin: pinmux_P8_16_default_pin { -+ pinctrl-single,pins = <0x038 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_16_gpio_pin: pinmux_P8_16_gpio_pin { -+ pinctrl-single,pins = <0x038 0x2F>; }; /* Mode 7, RxActive */ -+ P8_16_gpio_pu_pin: pinmux_P8_16_gpio_pu_pin { -+ pinctrl-single,pins = <0x038 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_16_gpio_pd_pin: pinmux_P8_16_gpio_pd_pin { -+ pinctrl-single,pins = <0x038 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_16_pruin_pin: pinmux_P8_16_pruin_pin { -+ pinctrl-single,pins = <0x038 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_16_qep_pin: pinmux_P8_16_qep_pin { -+ pinctrl-single,pins = <0x038 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_17 (ZCZ ball U12) */ -+ P8_17_default_pin: pinmux_P8_17_default_pin { -+ pinctrl-single,pins = <0x02c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_17_gpio_pin: pinmux_P8_17_gpio_pin { -+ pinctrl-single,pins = <0x02c 0x2F>; }; /* Mode 7, RxActive */ -+ P8_17_gpio_pu_pin: pinmux_P8_17_gpio_pu_pin { -+ pinctrl-single,pins = <0x02c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_17_gpio_pd_pin: pinmux_P8_17_gpio_pd_pin { -+ pinctrl-single,pins = <0x02c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_17_pwm_pin: pinmux_P8_17_pwm_pin { -+ pinctrl-single,pins = <0x02c 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_18 (ZCZ ball V12) */ -+ P8_18_default_pin: pinmux_P8_18_default_pin { -+ pinctrl-single,pins = <0x08c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_18_gpio_pin: pinmux_P8_18_gpio_pin { -+ pinctrl-single,pins = <0x08c 0x2F>; }; /* Mode 7, RxActive */ -+ P8_18_gpio_pu_pin: pinmux_P8_18_gpio_pu_pin { -+ pinctrl-single,pins = <0x08c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_18_gpio_pd_pin: pinmux_P8_18_gpio_pd_pin { -+ pinctrl-single,pins = <0x08c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ -+ /* P8_19 (ZCZ ball U10) */ -+ P8_19_default_pin: pinmux_P8_19_default_pin { -+ pinctrl-single,pins = <0x020 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_19_gpio_pin: pinmux_P8_19_gpio_pin { -+ pinctrl-single,pins = <0x020 0x2F>; }; /* Mode 7, RxActive */ -+ P8_19_gpio_pu_pin: pinmux_P8_19_gpio_pu_pin { -+ pinctrl-single,pins = <0x020 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_19_gpio_pd_pin: pinmux_P8_19_gpio_pd_pin { -+ pinctrl-single,pins = <0x020 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_19_pwm_pin: pinmux_P8_19_pwm_pin { -+ pinctrl-single,pins = <0x020 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_20 (ZCZ ball V9 ) emmc */ -+ /* P8_21 (ZCZ ball U9 ) emmc */ -+ /* P8_22 (ZCZ ball V8 ) emmc */ -+ /* P8_23 (ZCZ ball U8 ) emmc */ -+ /* P8_24 (ZCZ ball V7 ) emmc */ -+ /* P8_25 (ZCZ ball U7 ) emmc */ -+ -+ /* P8_26 (ZCZ ball V6 ) */ -+ P8_26_default_pin: pinmux_P8_26_default_pin { -+ pinctrl-single,pins = <0x07c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_26_gpio_pin: pinmux_P8_26_gpio_pin { -+ pinctrl-single,pins = <0x07c 0x2F>; }; /* Mode 7, RxActive */ -+ P8_26_gpio_pu_pin: pinmux_P8_26_gpio_pu_pin { -+ pinctrl-single,pins = <0x07c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_26_gpio_pd_pin: pinmux_P8_26_gpio_pd_pin { -+ pinctrl-single,pins = <0x07c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ -+ /* P8_27 (ZCZ ball U5 ) hdmi */ -+ P8_27_default_pin: pinmux_P8_27_default_pin { -+ pinctrl-single,pins = <0x0e0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_27_gpio_pin: pinmux_P8_27_gpio_pin { -+ pinctrl-single,pins = <0x0e0 0x2F>; }; /* Mode 7, RxActive */ -+ P8_27_gpio_pu_pin: pinmux_P8_27_gpio_pu_pin { -+ pinctrl-single,pins = <0x0e0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_27_gpio_pd_pin: pinmux_P8_27_gpio_pd_pin { -+ pinctrl-single,pins = <0x0e0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_27_pruout_pin: pinmux_P8_27_pruout_pin { -+ pinctrl-single,pins = <0x0e0 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_27_pruin_pin: pinmux_P8_27_pruin_pin { -+ pinctrl-single,pins = <0x0e0 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_27_hdmi_pin: pinmux_P8_27_hdmi_pin { -+ pinctrl-single,pins = <0x0e0 0x00>; }; /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ -+ -+ /* P8_28 (ZCZ ball V5 ) hdmi */ -+ P8_28_default_pin: pinmux_P8_28_default_pin { -+ pinctrl-single,pins = <0x0e8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_28_gpio_pin: pinmux_P8_28_gpio_pin { -+ pinctrl-single,pins = <0x0e8 0x2F>; }; /* Mode 7, RxActive */ -+ P8_28_gpio_pu_pin: pinmux_P8_28_gpio_pu_pin { -+ pinctrl-single,pins = <0x0e8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_28_gpio_pd_pin: pinmux_P8_28_gpio_pd_pin { -+ pinctrl-single,pins = <0x0e8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_28_pruout_pin: pinmux_P8_28_pruout_pin { -+ pinctrl-single,pins = <0x0e8 0x05>; }; /* Mode 5, Pull-Down */ -+ P8_28_pruin_pin: pinmux_P8_28_pruin_pin { -+ pinctrl-single,pins = <0x0e8 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_28_hdmi_pin: pinmux_P8_28_hdmi_pin { -+ pinctrl-single,pins = <0x0e8 0x00>; }; /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ -+ -+ /* P8_29 (ZCZ ball R5 ) hdmi */ -+ P8_29_default_pin: pinmux_P8_29_default_pin { -+ pinctrl-single,pins = <0x0e4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_29_gpio_pin: pinmux_P8_29_gpio_pin { -+ pinctrl-single,pins = <0x0e4 0x2F>; }; /* Mode 7, RxActive */ -+ P8_29_gpio_pu_pin: pinmux_P8_29_gpio_pu_pin { -+ pinctrl-single,pins = <0x0e4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_29_gpio_pd_pin: pinmux_P8_29_gpio_pd_pin { -+ pinctrl-single,pins = <0x0e4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_29_pruout_pin: pinmux_P8_29_pruout_pin { -+ pinctrl-single,pins = <0x0e4 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_29_pruin_pin: pinmux_P8_29_pruin_pin { -+ pinctrl-single,pins = <0x0e4 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_29_hdmi_pin: pinmux_P8_29_hdmi_pin { -+ pinctrl-single,pins = <0x0e4 0x00>; }; /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ -+ -+ /* P8_30 (ZCZ ball R6 ) hdmi */ -+ P8_30_default_pin: pinmux_P8_30_default_pin { -+ pinctrl-single,pins = <0x0ec 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_30_gpio_pin: pinmux_P8_30_gpio_pin { -+ pinctrl-single,pins = <0x0ec 0x2F>; }; /* Mode 7, RxActive */ -+ P8_30_gpio_pu_pin: pinmux_P8_30_gpio_pu_pin { -+ pinctrl-single,pins = <0x0ec 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_30_gpio_pd_pin: pinmux_P8_30_gpio_pd_pin { -+ pinctrl-single,pins = <0x0ec 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_30_pruout_pin: pinmux_P8_30_pruout_pin { -+ pinctrl-single,pins = <0x0ec 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_30_pruin_pin: pinmux_P8_30_pruin_pin { -+ pinctrl-single,pins = <0x0ec 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_30_hdmi_pin: pinmux_P8_30_hdmi_pin { -+ pinctrl-single,pins = <0x0ec 0x00>; }; /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ -+ -+ /* P8_31 (ZCZ ball V4 ) hdmi */ -+ P8_31_default_pin: pinmux_P8_31_default_pin { -+ pinctrl-single,pins = <0x0d8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_31_gpio_pin: pinmux_P8_31_gpio_pin { -+ pinctrl-single,pins = <0x0d8 0x2F>; }; /* Mode 7, RxActive */ -+ P8_31_gpio_pu_pin: pinmux_P8_31_gpio_pu_pin { -+ pinctrl-single,pins = <0x0d8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_31_gpio_pd_pin: pinmux_P8_31_gpio_pd_pin { -+ pinctrl-single,pins = <0x0d8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_31_uart_pin: pinmux_P8_31_uart_pin { -+ pinctrl-single,pins = <0x0d8 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ P8_31_hdmi_pin: pinmux_P8_31_hdmi_pin { -+ pinctrl-single,pins = <0x0d8 0x08>; }; /* lcd_data14.lcd_data14, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_32 (ZCZ ball T5 ) hdmi */ -+ P8_32_default_pin: pinmux_P8_32_default_pin { -+ pinctrl-single,pins = <0x0dc 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_32_gpio_pin: pinmux_P8_32_gpio_pin { -+ pinctrl-single,pins = <0x0dc 0x2F>; }; /* Mode 7, RxActive */ -+ P8_32_gpio_pu_pin: pinmux_P8_32_gpio_pu_pin { -+ pinctrl-single,pins = <0x0dc 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_32_gpio_pd_pin: pinmux_P8_32_gpio_pd_pin { -+ pinctrl-single,pins = <0x0dc 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_32_uart_pin: pinmux_P8_32_uart_pin { -+ pinctrl-single,pins = <0x0dc 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_32_hdmi_pin: pinmux_P8_32_hdmi_pin { -+ pinctrl-single,pins = <0x0dc 0x08>; }; /* lcd_data15.lcd_data15, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_33 (ZCZ ball V3 ) hdmi */ -+ P8_33_default_pin: pinmux_P8_33_default_pin { -+ pinctrl-single,pins = <0x0d4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_33_gpio_pin: pinmux_P8_33_gpio_pin { -+ pinctrl-single,pins = <0x0d4 0x2F>; }; /* Mode 7, RxActive */ -+ P8_33_gpio_pu_pin: pinmux_P8_33_gpio_pu_pin { -+ pinctrl-single,pins = <0x0d4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_33_gpio_pd_pin: pinmux_P8_33_gpio_pd_pin { -+ pinctrl-single,pins = <0x0d4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_33_hdmi_pin: pinmux_P8_33_hdmi_pin { -+ pinctrl-single,pins = <0x0d4 0x08>; }; /* lcd_data13.lcd_data13, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ P8_33_qep_pin: pinmux_P8_33_qep_pin { -+ pinctrl-single,pins = <0x0d4 0x22>; }; /* Mode 2, Pull-Down, RxActive */ -+ -+ /* P8_34 (ZCZ ball U4 ) hdmi */ -+ P8_34_default_pin: pinmux_P8_34_default_pin { -+ pinctrl-single,pins = <0x0cc 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_34_gpio_pin: pinmux_P8_34_gpio_pin { -+ pinctrl-single,pins = <0x0cc 0x2F>; }; /* Mode 7, RxActive */ -+ P8_34_gpio_pu_pin: pinmux_P8_34_gpio_pu_pin { -+ pinctrl-single,pins = <0x0cc 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_34_gpio_pd_pin: pinmux_P8_34_gpio_pd_pin { -+ pinctrl-single,pins = <0x0cc 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_34_pwm_pin: pinmux_P8_34_pwm_pin { -+ pinctrl-single,pins = <0x0cc 0x22>; }; /* Mode 2, Pull-Down, RxActive */ -+ P8_34_hdmi_pin: pinmux_P8_34_hdmi_pin { -+ pinctrl-single,pins = <0x0cc 0x08>; }; /* lcd_data11.lcd_data11, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_35 (ZCZ ball V2 ) hdmi */ -+ P8_35_default_pin: pinmux_P8_35_default_pin { -+ pinctrl-single,pins = <0x0d0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_35_gpio_pin: pinmux_P8_35_gpio_pin { -+ pinctrl-single,pins = <0x0d0 0x2F>; }; /* Mode 7, RxActive */ -+ P8_35_gpio_pu_pin: pinmux_P8_35_gpio_pu_pin { -+ pinctrl-single,pins = <0x0d0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_35_gpio_pd_pin: pinmux_P8_35_gpio_pd_pin { -+ pinctrl-single,pins = <0x0d0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_35_hdmi_pin: pinmux_P8_35_hdmi_pin { -+ pinctrl-single,pins = <0x0d0 0x08>; }; /* lcd_data12.lcd_data12, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ P8_35_qep_pin: pinmux_P8_35_qep_pin { -+ pinctrl-single,pins = <0x0d0 0x22>; }; /* Mode 2, Pull-Down, RxActive */ -+ -+ /* P8_36 (ZCZ ball U3 ) hdmi */ -+ P8_36_default_pin: pinmux_P8_36_default_pin { -+ pinctrl-single,pins = <0x0c8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_36_gpio_pin: pinmux_P8_36_gpio_pin { -+ pinctrl-single,pins = <0x0c8 0x2F>; }; /* Mode 7, RxActive */ -+ P8_36_gpio_pu_pin: pinmux_P8_36_gpio_pu_pin { -+ pinctrl-single,pins = <0x0c8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_36_gpio_pd_pin: pinmux_P8_36_gpio_pd_pin { -+ pinctrl-single,pins = <0x0c8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_36_pwm_pin: pinmux_P8_36_pwm_pin { -+ pinctrl-single,pins = <0x0c8 0x22>; }; /* Mode 2, Pull-Down, RxActive */ -+ P8_36_hdmi_pin: pinmux_P8_36_hdmi_pin { -+ pinctrl-single,pins = <0x0c8 0x08>; }; /* lcd_data10.lcd_data10, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_37 (ZCZ ball U1 ) hdmi */ -+ P8_37_default_pin: pinmux_P8_37_default_pin { -+ pinctrl-single,pins = <0x0c0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_37_gpio_pin: pinmux_P8_37_gpio_pin { -+ pinctrl-single,pins = <0x0c0 0x2F>; }; /* Mode 7, RxActive */ -+ P8_37_gpio_pu_pin: pinmux_P8_37_gpio_pu_pin { -+ pinctrl-single,pins = <0x0c0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_37_gpio_pd_pin: pinmux_P8_37_gpio_pd_pin { -+ pinctrl-single,pins = <0x0c0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_37_uart_pin: pinmux_P8_37_uart_pin { -+ pinctrl-single,pins = <0x0c0 0x04>; }; /* Mode 4, Pull-Down*/ -+ P8_37_pwm_pin: pinmux_P8_37_pwm_pin { -+ pinctrl-single,pins = <0x0c0 0x02>; }; /* Mode 2, Pull-Down*/ -+ P8_37_hdmi_pin: pinmux_P8_37_hdmi_pin { -+ pinctrl-single,pins = <0x0c0 0x08>; }; /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ -+ /* P8_38 (ZCZ ball U2 ) hdmi */ -+ P8_38_default_pin: pinmux_P8_38_default_pin { -+ pinctrl-single,pins = <0x0c4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_38_gpio_pin: pinmux_P8_38_gpio_pin { -+ pinctrl-single,pins = <0x0c4 0x2F>; }; /* Mode 7, RxActive */ -+ P8_38_gpio_pu_pin: pinmux_P8_38_gpio_pu_pin { -+ pinctrl-single,pins = <0x0c4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_38_gpio_pd_pin: pinmux_P8_38_gpio_pd_pin { -+ pinctrl-single,pins = <0x0c4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_38_uart_pin: pinmux_P8_38_uart_pin { -+ pinctrl-single,pins = <0x0c4 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ P8_38_pwm_pin: pinmux_P8_38_pwm_pin { -+ pinctrl-single,pins = <0x0c4 0x22>; }; /* Mode 2, Pull-Down, RxActive */ -+ P8_38_hdmi_pin: pinmux_P8_38_hdmi_pin { -+ pinctrl-single,pins = <0x0c4 0x08>; }; /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ -+ /* P8_39 (ZCZ ball T3 ) hdmi */ -+ P8_39_default_pin: pinmux_P8_39_default_pin { -+ pinctrl-single,pins = <0x0b8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_39_gpio_pin: pinmux_P8_39_gpio_pin { -+ pinctrl-single,pins = <0x0b8 0x2F>; }; /* Mode 7, RxActive */ -+ P8_39_gpio_pu_pin: pinmux_P8_39_gpio_pu_pin { -+ pinctrl-single,pins = <0x0b8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_39_gpio_pd_pin: pinmux_P8_39_gpio_pd_pin { -+ pinctrl-single,pins = <0x0b8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_39_pruout_pin: pinmux_P8_39_pruout_pin { -+ pinctrl-single,pins = <0x0b8 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_39_pruin_pin: pinmux_P8_39_pruin_pin { -+ pinctrl-single,pins = <0x0b8 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_39_hdmi_pin: pinmux_P8_39_hdmi_pin { -+ pinctrl-single,pins = <0x0b8 0x08>; }; /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_40 (ZCZ ball T4 ) hdmi */ -+ P8_40_default_pin: pinmux_P8_40_default_pin { -+ pinctrl-single,pins = <0x0bc 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_40_gpio_pin: pinmux_P8_40_gpio_pin { -+ pinctrl-single,pins = <0x0bc 0x2F>; }; /* Mode 7, RxActive */ -+ P8_40_gpio_pu_pin: pinmux_P8_40_gpio_pu_pin { -+ pinctrl-single,pins = <0x0bc 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_40_gpio_pd_pin: pinmux_P8_40_gpio_pd_pin { -+ pinctrl-single,pins = <0x0bc 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_40_pruout_pin: pinmux_P8_40_pruout_pin { -+ pinctrl-single,pins = <0x0bc 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_40_pruin_pin: pinmux_P8_40_pruin_pin { -+ pinctrl-single,pins = <0x0bc 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_40_hdmi_pin: pinmux_P8_40_hdmi_pin { -+ pinctrl-single,pins = <0x0bc 0x08>; }; /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_41 (ZCZ ball T1 ) hdmi */ -+ P8_41_default_pin: pinmux_P8_41_default_pin { -+ pinctrl-single,pins = <0x0b0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_41_gpio_pin: pinmux_P8_41_gpio_pin { -+ pinctrl-single,pins = <0x0b0 0x2F>; }; /* Mode 7, RxActive */ -+ P8_41_gpio_pu_pin: pinmux_P8_41_gpio_pu_pin { -+ pinctrl-single,pins = <0x0b0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_41_gpio_pd_pin: pinmux_P8_41_gpio_pd_pin { -+ pinctrl-single,pins = <0x0b0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_41_pruout_pin: pinmux_P8_41_pruout_pin { -+ pinctrl-single,pins = <0x0b0 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_41_pruin_pin: pinmux_P8_41_pruin_pin { -+ pinctrl-single,pins = <0x0b0 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_41_hdmi_pin: pinmux_P8_41_hdmi_pin { -+ pinctrl-single,pins = <0x0b0 0x08>; }; /* lcd_data4.lcd_data4, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_42 (ZCZ ball T2 ) hdmi */ -+ P8_42_default_pin: pinmux_P8_42_default_pin { -+ pinctrl-single,pins = <0x0b4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_42_gpio_pin: pinmux_P8_42_gpio_pin { -+ pinctrl-single,pins = <0x0b4 0x2F>; }; /* Mode 7, RxActive */ -+ P8_42_gpio_pu_pin: pinmux_P8_42_gpio_pu_pin { -+ pinctrl-single,pins = <0x0b4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_42_gpio_pd_pin: pinmux_P8_42_gpio_pd_pin { -+ pinctrl-single,pins = <0x0b4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_42_pruout_pin: pinmux_P8_42_pruout_pin { -+ pinctrl-single,pins = <0x0b4 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_42_pruin_pin: pinmux_P8_42_pruin_pin { -+ pinctrl-single,pins = <0x0b4 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_42_hdmi_pin: pinmux_P8_42_hdmi_pin { -+ pinctrl-single,pins = <0x0b4 0x08>; }; /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_43 (ZCZ ball R3 ) hdmi */ -+ P8_43_default_pin: pinmux_P8_43_default_pin { -+ pinctrl-single,pins = <0x0a8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_43_gpio_pin: pinmux_P8_43_gpio_pin { -+ pinctrl-single,pins = <0x0a8 0x2F>; }; /* Mode 7, RxActive */ -+ P8_43_gpio_pu_pin: pinmux_P8_43_gpio_pu_pin { -+ pinctrl-single,pins = <0x0a8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_43_gpio_pd_pin: pinmux_P8_43_gpio_pd_pin { -+ pinctrl-single,pins = <0x0a8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_43_pruout_pin: pinmux_P8_43_pruout_pin { -+ pinctrl-single,pins = <0x0a8 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_43_pruin_pin: pinmux_P8_43_pruin_pin { -+ pinctrl-single,pins = <0x0a8 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_43_pwm_pin: pinmux_P8_43_pwm_pin { -+ pinctrl-single,pins = <0x0a8 0x03>; }; /* Mode 3, Pull-Down */ -+ P8_43_hdmi_pin: pinmux_P8_43_hdmi_pin { -+ pinctrl-single,pins = <0x0a8 0x08>; }; /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_44 (ZCZ ball R4 ) hdmi */ -+ P8_44_default_pin: pinmux_P8_44_default_pin { -+ pinctrl-single,pins = <0x0ac 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_44_gpio_pin: pinmux_P8_44_gpio_pin { -+ pinctrl-single,pins = <0x0ac 0x2F>; }; /* Mode 7, RxActive */ -+ P8_44_gpio_pu_pin: pinmux_P8_44_gpio_pu_pin { -+ pinctrl-single,pins = <0x0ac 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_44_gpio_pd_pin: pinmux_P8_44_gpio_pd_pin { -+ pinctrl-single,pins = <0x0ac 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_44_pruout_pin: pinmux_P8_44_pruout_pin { -+ pinctrl-single,pins = <0x0ac 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_44_pruin_pin: pinmux_P8_44_pruin_pin { -+ pinctrl-single,pins = <0x0ac 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_44_pwm_pin: pinmux_P8_44_pwm_pin { -+ pinctrl-single,pins = <0x0ac 0x23>; }; /* Mode 3, Pull-Down, RxActive */ -+ P8_44_hdmi_pin: pinmux_P8_44_hdmi_pin { -+ pinctrl-single,pins = <0x0ac 0x08>; }; /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_45 (ZCZ ball R1 ) hdmi */ -+ P8_45_default_pin: pinmux_P8_45_default_pin { -+ pinctrl-single,pins = <0x0a0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_45_gpio_pin: pinmux_P8_45_gpio_pin { -+ pinctrl-single,pins = <0x0a0 0x2F>; }; /* Mode 7, RxActive */ -+ P8_45_gpio_pu_pin: pinmux_P8_45_gpio_pu_pin { -+ pinctrl-single,pins = <0x0a0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_45_gpio_pd_pin: pinmux_P8_45_gpio_pd_pin { -+ pinctrl-single,pins = <0x0a0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_45_pruout_pin: pinmux_P8_45_pruout_pin { -+ pinctrl-single,pins = <0x0a0 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_45_pruin_pin: pinmux_P8_45_pruin_pin { -+ pinctrl-single,pins = <0x0a0 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_45_pwm_pin: pinmux_P8_45_pwm_pin { -+ pinctrl-single,pins = <0x0a0 0x03>; }; /* Mode 3, Pull-Down*/ -+ P8_45_hdmi_pin: pinmux_P8_45_hdmi_pin { -+ pinctrl-single,pins = <0x0a0 0x08>; }; /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_46 (ZCZ ball R2 ) hdmi */ -+ P8_46_default_pin: pinmux_P8_46_default_pin { -+ pinctrl-single,pins = <0x0a4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_46_gpio_pin: pinmux_P8_46_gpio_pin { -+ pinctrl-single,pins = <0x0a4 0x2F>; }; /* Mode 7, RxActive */ -+ P8_46_gpio_pu_pin: pinmux_P8_46_gpio_pu_pin { -+ pinctrl-single,pins = <0x0a4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_46_gpio_pd_pin: pinmux_P8_46_gpio_pd_pin { -+ pinctrl-single,pins = <0x0a4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_46_pruout_pin: pinmux_P8_46_pruout_pin { -+ pinctrl-single,pins = <0x0a4 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_46_pruin_pin: pinmux_P8_46_pruin_pin { -+ pinctrl-single,pins = <0x0a4 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_46_pwm_pin: pinmux_P8_46_pwm_pin { -+ pinctrl-single,pins = <0x0a4 0x03>; }; /* Mode 3, Pull-Down*/ -+ P8_46_hdmi_pin: pinmux_P8_46_hdmi_pin { -+ pinctrl-single,pins = <0x0a4 0x08>; }; /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /************************/ -+ /* P9 Header */ -+ /************************/ -+ -+ /* P9_01 GND */ -+ /* P9_02 GND */ -+ /* P9_03 3.3V */ -+ /* P9_04 3.3V */ -+ /* P9_05 VDD_5V */ -+ /* P9_06 VDD_5V */ -+ /* P9_07 SYS_5V */ -+ /* P9_08 SYS_5V */ -+ /* P9_09 PWR_BUT */ -+ /* P9_10 (ZCZ ball A10) RESETn */ -+ -+ /* P9_11 (ZCZ ball T17) */ -+ P9_11_default_pin: pinmux_P9_11_default_pin { -+ pinctrl-single,pins = <0x070 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_11_gpio_pin: pinmux_P9_11_gpio_pin { -+ pinctrl-single,pins = <0x070 0x2F>; }; /* Mode 7, RxActive */ -+ P9_11_gpio_pu_pin: pinmux_P9_11_gpio_pu_pin { -+ pinctrl-single,pins = <0x070 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_11_gpio_pd_pin: pinmux_P9_11_gpio_pd_pin { -+ pinctrl-single,pins = <0x070 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_11_uart_pin: pinmux_P9_11_uart_pin { -+ pinctrl-single,pins = <0x070 0x36>; }; /* Mode 6, Pull-Up, RxActive */ -+ -+ /* P9_12 (ZCZ ball U18) */ -+ P9_12_default_pin: pinmux_P9_12_default_pin { -+ pinctrl-single,pins = <0x078 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_12_gpio_pin: pinmux_P9_12_gpio_pin { -+ pinctrl-single,pins = <0x078 0x2F>; }; /* Mode 7, RxActive */ -+ P9_12_gpio_pu_pin: pinmux_P9_12_gpio_pu_pin { -+ pinctrl-single,pins = <0x078 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_12_gpio_pd_pin: pinmux_P9_12_gpio_pd_pin { -+ pinctrl-single,pins = <0x078 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ -+ /* P9_13 (ZCZ ball U17) */ -+ P9_13_default_pin: pinmux_P9_13_default_pin { -+ pinctrl-single,pins = <0x074 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_13_gpio_pin: pinmux_P9_13_gpio_pin { -+ pinctrl-single,pins = <0x074 0x2F>; }; /* Mode 7, RxActive */ -+ P9_13_gpio_pu_pin: pinmux_P9_13_gpio_pu_pin { -+ pinctrl-single,pins = <0x074 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_13_gpio_pd_pin: pinmux_P9_13_gpio_pd_pin { -+ pinctrl-single,pins = <0x074 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_13_uart_pin: pinmux_P9_13_uart_pin { -+ pinctrl-single,pins = <0x074 0x36>; }; /* Mode 6, Pull-Up, RxActive */ -+ -+ /* P9_14 (ZCZ ball U14) */ -+ P9_14_default_pin: pinmux_P9_14_default_pin { -+ pinctrl-single,pins = <0x048 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_14_gpio_pin: pinmux_P9_14_gpio_pin { -+ pinctrl-single,pins = <0x048 0x2F>; }; /* Mode 7, RxActive */ -+ P9_14_gpio_pu_pin: pinmux_P9_14_gpio_pu_pin { -+ pinctrl-single,pins = <0x048 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_14_gpio_pd_pin: pinmux_P9_14_gpio_pd_pin { -+ pinctrl-single,pins = <0x048 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_14_pwm_pin: pinmux_P9_14_pwm_pin { -+ pinctrl-single,pins = <0x048 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_15 (ZCZ ball R13) */ -+ P9_15_default_pin: pinmux_P9_15_default_pin { -+ pinctrl-single,pins = <0x040 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_15_gpio_pin: pinmux_P9_15_gpio_pin { -+ pinctrl-single,pins = <0x040 0x2F>; }; /* Mode 7, RxActive */ -+ P9_15_gpio_pu_pin: pinmux_P9_15_gpio_pu_pin { -+ pinctrl-single,pins = <0x040 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_15_gpio_pd_pin: pinmux_P9_15_gpio_pd_pin { -+ pinctrl-single,pins = <0x040 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_15_pwm_pin: pinmux_P9_15_pwm_pin { -+ pinctrl-single,pins = <0x040 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_16 (ZCZ ball T14) */ -+ P9_16_default_pin: pinmux_P9_16_default_pin { -+ pinctrl-single,pins = <0x04c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_16_gpio_pin: pinmux_P9_16_gpio_pin { -+ pinctrl-single,pins = <0x04c 0x2F>; }; /* Mode 7, RxActive */ -+ P9_16_gpio_pu_pin: pinmux_P9_16_gpio_pu_pin { -+ pinctrl-single,pins = <0x04c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_16_gpio_pd_pin: pinmux_P9_16_gpio_pd_pin { -+ pinctrl-single,pins = <0x04c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_16_pwm_pin: pinmux_P9_16_pwm_pin { -+ pinctrl-single,pins = <0x04c 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_17 (ZCZ ball A16) */ -+ P9_17_default_pin: pinmux_P9_17_default_pin { -+ pinctrl-single,pins = <0x15c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_17_gpio_pin: pinmux_P9_17_gpio_pin { -+ pinctrl-single,pins = <0x15c 0x2F>; }; /* Mode 7, RxActive */ -+ P9_17_gpio_pu_pin: pinmux_P9_17_gpio_pu_pin { -+ pinctrl-single,pins = <0x15c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_17_gpio_pd_pin: pinmux_P9_17_gpio_pd_pin { -+ pinctrl-single,pins = <0x15c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_17_spi_pin: pinmux_P9_17_spi_pin { -+ pinctrl-single,pins = <0x15c 0x30>; }; /* Mode 0, Pull-Up, RxActive */ -+ P9_17_i2c_pin: pinmux_P9_17_i2c_pin { -+ pinctrl-single,pins = <0x15c 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_17_pwm_pin: pinmux_P9_17_pwm_pin { -+ pinctrl-single,pins = <0x15c 0x33>; }; /* Mode 3, Pull-Up, RxActive */ -+ -+ /* P9_18 (ZCZ ball B16) */ -+ P9_18_default_pin: pinmux_P9_18_default_pin { -+ pinctrl-single,pins = <0x158 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_18_gpio_pin: pinmux_P9_18_gpio_pin { -+ pinctrl-single,pins = <0x158 0x2F>; }; /* Mode 7, RxActive */ -+ P9_18_gpio_pu_pin: pinmux_P9_18_gpio_pu_pin { -+ pinctrl-single,pins = <0x158 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_18_gpio_pd_pin: pinmux_P9_18_gpio_pd_pin { -+ pinctrl-single,pins = <0x158 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_18_spi_pin: pinmux_P9_18_spi_pin { -+ pinctrl-single,pins = <0x158 0x30>; }; /* Mode 0, Pull-Up, RxActive */ -+ P9_18_i2c_pin: pinmux_P9_18_i2c_pin { -+ pinctrl-single,pins = <0x158 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_18_pwm_pin: pinmux_P9_18_pwm_pin { -+ pinctrl-single,pins = <0x158 0x33>; }; /* Mode 3, Pull-Up, RxActive */ -+ -+ /* P9_19 (ZCZ ball D17) */ -+ P9_19_default_pin: pinmux_P9_19_default_pin { -+ pinctrl-single,pins = <0x17c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_19_gpio_pin: pinmux_P9_19_gpio_pin { -+ pinctrl-single,pins = <0x17c 0x2F>; }; /* Mode 7, RxActive */ -+ P9_19_gpio_pu_pin: pinmux_P9_19_gpio_pu_pin { -+ pinctrl-single,pins = <0x17c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_19_gpio_pd_pin: pinmux_P9_19_gpio_pd_pin { -+ pinctrl-single,pins = <0x17c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_19_can_pin: pinmux_P9_19_can_pin { -+ pinctrl-single,pins = <0x17c 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_19_i2c_pin: pinmux_P9_19_i2c_pin { -+ pinctrl-single,pins = <0x17c 0x73>; }; /* (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3) */ -+ -+ /* P9_20 (ZCZ ball D18) */ -+ P9_20_default_pin: pinmux_P9_20_default_pin { -+ pinctrl-single,pins = <0x178 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_20_gpio_pin: pinmux_P9_20_gpio_pin { -+ pinctrl-single,pins = <0x178 0x2F>; }; /* Mode 7, RxActive */ -+ P9_20_gpio_pu_pin: pinmux_P9_20_gpio_pu_pin { -+ pinctrl-single,pins = <0x178 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_20_gpio_pd_pin: pinmux_P9_20_gpio_pd_pin { -+ pinctrl-single,pins = <0x178 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_20_can_pin: pinmux_P9_20_can_pin { -+ pinctrl-single,pins = <0x178 0x12>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_20_i2c_pin: pinmux_P9_20_i2c_pin { -+ pinctrl-single,pins = <0x178 0x73>; }; /* (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3) */ -+ -+ /* P9_21 (ZCZ ball B17) */ -+ P9_21_default_pin: pinmux_P9_21_default_pin { -+ pinctrl-single,pins = <0x154 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_21_gpio_pin: pinmux_P9_21_gpio_pin { -+ pinctrl-single,pins = <0x154 0x2F>; }; /* Mode 7, RxActive */ -+ P9_21_gpio_pu_pin: pinmux_P9_21_gpio_pu_pin { -+ pinctrl-single,pins = <0x154 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_21_gpio_pd_pin: pinmux_P9_21_gpio_pd_pin { -+ pinctrl-single,pins = <0x154 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_21_spi_pin: pinmux_P9_21_spi_pin { -+ pinctrl-single,pins = <0x154 0x30>; }; /* Mode 0, Pull-Up, RxActive */ -+ P9_21_uart_pin: pinmux_P9_21_uart_pin { -+ pinctrl-single,pins = <0x154 0x31>; }; /* Mode 1, Pull-Up, RxActive */ -+ P9_21_i2c_pin: pinmux_P9_21_i2c_pin { -+ pinctrl-single,pins = <0x154 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_21_pwm_pin: pinmux_P9_21_pwm_pin { -+ pinctrl-single,pins = <0x154 0x33>; }; /* Mode 3, Pull-Up, RxActive */ -+ -+ /* P9_22 (ZCZ ball A17) */ -+ P9_22_default_pin: pinmux_P9_22_default_pin { -+ pinctrl-single,pins = <0x150 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_22_gpio_pin: pinmux_P9_22_gpio_pin { -+ pinctrl-single,pins = <0x150 0x2F>; }; /* Mode 7, RxActive */ -+ P9_22_gpio_pu_pin: pinmux_P9_22_gpio_pu_pin { -+ pinctrl-single,pins = <0x150 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_22_gpio_pd_pin: pinmux_P9_22_gpio_pd_pin { -+ pinctrl-single,pins = <0x150 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_22_spi_pin: pinmux_P9_22_spi_pin { -+ pinctrl-single,pins = <0x150 0x30>; }; /* Mode 0, Pull-Up, RxActive */ -+ P9_22_uart_pin: pinmux_P9_22_uart_pin { -+ pinctrl-single,pins = <0x150 0x31>; }; /* Mode 1, Pull-Up, RxActive */ -+ P9_22_i2c_pin: pinmux_P9_22_i2c_pin { -+ pinctrl-single,pins = <0x150 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_22_pwm_pin: pinmux_P9_22_pwm_pin { -+ pinctrl-single,pins = <0x150 0x33>; }; /* Mode 3, Pull-Up, RxActive */ -+ -+ /* P9_23 (ZCZ ball V14) */ -+ P9_23_default_pin: pinmux_P9_23_default_pin { -+ pinctrl-single,pins = <0x044 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_23_gpio_pin: pinmux_P9_23_gpio_pin { -+ pinctrl-single,pins = <0x044 0x2F>; }; /* Mode 7, RxActive */ -+ P9_23_gpio_pu_pin: pinmux_P9_23_gpio_pu_pin { -+ pinctrl-single,pins = <0x044 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_23_gpio_pd_pin: pinmux_P9_23_gpio_pd_pin { -+ pinctrl-single,pins = <0x044 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_23_pwm_pin: pinmux_P9_23_pwm_pin { -+ pinctrl-single,pins = <0x044 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_24 (ZCZ ball D15) */ -+ P9_24_default_pin: pinmux_P9_24_default_pin { -+ pinctrl-single,pins = <0x184 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_24_gpio_pin: pinmux_P9_24_gpio_pin { -+ pinctrl-single,pins = <0x184 0x2F>; }; /* Mode 7, RxActive */ -+ P9_24_gpio_pu_pin: pinmux_P9_24_gpio_pu_pin { -+ pinctrl-single,pins = <0x184 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_24_gpio_pd_pin: pinmux_P9_24_gpio_pd_pin { -+ pinctrl-single,pins = <0x184 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_24_uart_pin: pinmux_P9_24_uart_pin { -+ pinctrl-single,pins = <0x184 0x30>; }; /* Mode 0, Pull-Up, RxActive */ -+ P9_24_can_pin: pinmux_P9_24_can_pin { -+ pinctrl-single,pins = <0x184 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_24_i2c_pin: pinmux_P9_24_i2c_pin { -+ pinctrl-single,pins = <0x184 0x33>; }; /* Mode 3, Pull-Up, RxActive */ -+ P9_24_pruin_pin: pinmux_P9_24_pruin_pin { -+ pinctrl-single,pins = <0x184 0x36>; }; /* Mode 6, Pull-Up, RxActive */ -+ -+ /* P9_25 (ZCZ ball A14) Audio */ -+ P9_25_default_pin: pinmux_P9_25_default_pin { -+ pinctrl-single,pins = <0x1ac 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_25_gpio_pin: pinmux_P9_25_gpio_pin { -+ pinctrl-single,pins = <0x1ac 0x2F>; }; /* Mode 7, RxActive */ -+ P9_25_gpio_pu_pin: pinmux_P9_25_gpio_pu_pin { -+ pinctrl-single,pins = <0x1ac 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_25_gpio_pd_pin: pinmux_P9_25_gpio_pd_pin { -+ pinctrl-single,pins = <0x1ac 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_25_qep_pin: pinmux_P9_25_qep_pin { -+ pinctrl-single,pins = <0x1ac 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_25_pruout_pin: pinmux_P9_25_pruout_pin { -+ pinctrl-single,pins = <0x1ac 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_25_pruin_pin: pinmux_P9_25_pruin_pin { -+ pinctrl-single,pins = <0x1ac 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P9_25_audio_pin: pinmux_P9_25_audio_pin { -+ pinctrl-single,pins = <0x1ac (PIN_INPUT_PULLUP | MUX_MODE0)>; }; /* mcasp0_ahclkx.mcasp0_ahclkx */ -+ -+ /* P9_26 (ZCZ ball D16) */ -+ P9_26_default_pin: pinmux_P9_26_default_pin { -+ pinctrl-single,pins = <0x180 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_26_gpio_pin: pinmux_P9_26_gpio_pin { -+ pinctrl-single,pins = <0x180 0x2F>; }; /* Mode 7, RxActive */ -+ P9_26_gpio_pu_pin: pinmux_P9_26_gpio_pu_pin { -+ pinctrl-single,pins = <0x180 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_26_gpio_pd_pin: pinmux_P9_26_gpio_pd_pin { -+ pinctrl-single,pins = <0x180 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_26_uart_pin: pinmux_P9_26_uart_pin { -+ pinctrl-single,pins = <0x180 0x30>; }; /* Mode 0, Pull-Up, RxActive */ -+ P9_26_can_pin: pinmux_P9_26_can_pin { -+ pinctrl-single,pins = <0x180 0x12>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_26_i2c_pin: pinmux_P9_26_i2c_pin { -+ pinctrl-single,pins = <0x180 0x33>; }; /* Mode 3, Pull-Up, RxActive */ -+ P9_26_pruin_pin: pinmux_P9_26_pruin_pin { -+ pinctrl-single,pins = <0x180 0x36>; }; /* Mode 6, Pull-Up, RxActive */ -+ -+ /* P9_27 (ZCZ ball C13) */ -+ P9_27_default_pin: pinmux_P9_27_default_pin { -+ pinctrl-single,pins = <0x1a4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_27_gpio_pin: pinmux_P9_27_gpio_pin { -+ pinctrl-single,pins = <0x1a4 0x2F>; }; /* Mode 7, RxActive */ -+ P9_27_gpio_pu_pin: pinmux_P9_27_gpio_pu_pin { -+ pinctrl-single,pins = <0x1a4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_27_gpio_pd_pin: pinmux_P9_27_gpio_pd_pin { -+ pinctrl-single,pins = <0x1a4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_27_qep_pin: pinmux_P9_27_qep_pin { -+ pinctrl-single,pins = <0x1a4 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_27_pruout_pin: pinmux_P9_27_pruout_pin { -+ pinctrl-single,pins = <0x1a4 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_27_pruin_pin: pinmux_P9_27_pruin_pin { -+ pinctrl-single,pins = <0x1a4 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_28 (ZCZ ball C12) Audio */ -+ P9_28_default_pin: pinmux_P9_28_default_pin { -+ pinctrl-single,pins = <0x19c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_28_gpio_pin: pinmux_P9_28_gpio_pin { -+ pinctrl-single,pins = <0x19c 0x2F>; }; /* Mode 7, RxActive */ -+ P9_28_gpio_pu_pin: pinmux_P9_28_gpio_pu_pin { -+ pinctrl-single,pins = <0x19c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_28_gpio_pd_pin: pinmux_P9_28_gpio_pd_pin { -+ pinctrl-single,pins = <0x19c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_28_pwm_pin: pinmux_P9_28_pwm_pin { -+ pinctrl-single,pins = <0x19c 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_28_spi_pin: pinmux_P9_28_spi_pin { -+ pinctrl-single,pins = <0x19c 0x23>; }; /* Mode 3, Pull-Down, RxActive */ -+ P9_28_pwm2_pin: pinmux_P9_28_pwm2_pin { -+ pinctrl-single,pins = <0x19c 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ P9_28_pruout_pin: pinmux_P9_28_pruout_pin { -+ pinctrl-single,pins = <0x19c 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_28_pruin_pin: pinmux_P9_28_pruin_pin { -+ pinctrl-single,pins = <0x19c 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P9_28_audio_pin: pinmux_P9_28_audio_pin { -+ pinctrl-single,pins = <0x19c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)>; }; /* mcasp0_ahclkr.mcasp0_axr2 */ -+ -+ /* P9_29 (ZCZ ball B13) Audio */ -+ P9_29_default_pin: pinmux_P9_29_default_pin { -+ pinctrl-single,pins = <0x194 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_29_gpio_pin: pinmux_P9_29_gpio_pin { -+ pinctrl-single,pins = <0x194 0x2F>; }; /* Mode 7, RxActive */ -+ P9_29_gpio_pu_pin: pinmux_P9_29_gpio_pu_pin { -+ pinctrl-single,pins = <0x194 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_29_gpio_pd_pin: pinmux_P9_29_gpio_pd_pin { -+ pinctrl-single,pins = <0x194 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_29_pwm_pin: pinmux_P9_29_pwm_pin { -+ pinctrl-single,pins = <0x194 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_29_spi_pin: pinmux_P9_29_spi_pin { -+ pinctrl-single,pins = <0x194 0x23>; }; /* Mode 3, Pull-Down, RxActive */ -+ P9_29_pruout_pin: pinmux_P9_29_pruout_pin { -+ pinctrl-single,pins = <0x194 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_29_pruin_pin: pinmux_P9_29_pruin_pin { -+ pinctrl-single,pins = <0x194 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P9_29_audio_pin: pinmux_P9_29_audio_pin { -+ pinctrl-single,pins = <0x194 (PIN_OUTPUT_PULLUP | MUX_MODE0)>; }; /* mcasp0_fsx.mcasp0_fsx */ -+ -+ /* P9_30 (ZCZ ball D12) */ -+ P9_30_default_pin: pinmux_P9_30_default_pin { -+ pinctrl-single,pins = <0x198 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_30_gpio_pin: pinmux_P9_30_gpio_pin { -+ pinctrl-single,pins = <0x198 0x2F>; }; /* Mode 7, RxActive */ -+ P9_30_gpio_pu_pin: pinmux_P9_30_gpio_pu_pin { -+ pinctrl-single,pins = <0x198 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_30_gpio_pd_pin: pinmux_P9_30_gpio_pd_pin { -+ pinctrl-single,pins = <0x198 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_30_pwm_pin: pinmux_P9_30_pwm_pin { -+ pinctrl-single,pins = <0x198 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_30_spi_pin: pinmux_P9_30_spi_pin { -+ pinctrl-single,pins = <0x198 0x23>; }; /* Mode 3, Pull-Down, RxActive */ -+ P9_30_pruout_pin: pinmux_P9_30_pruout_pin { -+ pinctrl-single,pins = <0x198 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_30_pruin_pin: pinmux_P9_30_pruin_pin { -+ pinctrl-single,pins = <0x198 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_31 (ZCZ ball A13) Audio */ -+ P9_31_default_pin: pinmux_P9_31_default_pin { -+ pinctrl-single,pins = <0x190 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_31_gpio_pin: pinmux_P9_31_gpio_pin { -+ pinctrl-single,pins = <0x190 0x2F>; }; /* Mode 7, RxActive */ -+ P9_31_gpio_pu_pin: pinmux_P9_31_gpio_pu_pin { -+ pinctrl-single,pins = <0x190 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_31_gpio_pd_pin: pinmux_P9_31_gpio_pd_pin { -+ pinctrl-single,pins = <0x190 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_31_pwm_pin: pinmux_P9_31_pwm_pin { -+ pinctrl-single,pins = <0x190 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_31_spi_pin: pinmux_P9_31_spi_pin { -+ pinctrl-single,pins = <0x190 0x23>; }; /* Mode 3, Pull-Down, RxActive */ -+ P9_31_pruout_pin: pinmux_P9_31_pruout_pin { -+ pinctrl-single,pins = <0x190 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_31_pruin_pin: pinmux_P9_31_pruin_pin { -+ pinctrl-single,pins = <0x190 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P9_31_audio_pin: pinmux_P9_31_audio_pin { -+ pinctrl-single,pins = <0x190 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)>; }; /* mcasp0_aclkx.mcasp0_aclkx */ -+ -+ /* P9_32 VADC */ -+ /* P9_33 (ZCZ ball C8 ) AIN4 */ -+ /* P9_34 AGND */ -+ /* P9_35 (ZCZ ball A8 ) AIN6 */ -+ /* P9_36 (ZCZ ball B8 ) AIN5 */ -+ /* P9_37 (ZCZ ball B7 ) AIN2 */ -+ /* P9_38 (ZCZ ball A7 ) AIN3 */ -+ /* P9_39 (ZCZ ball B6 ) AIN0 */ -+ /* P9_40 (ZCZ ball C7 ) AIN1 */ -+ -+ /* P9_41 (ZCZ ball D14) */ -+ P9_41_default_pin: pinmux_P9_41_default_pin { -+ pinctrl-single,pins = <0x1b4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_41_gpio_pin: pinmux_P9_41_gpio_pin { -+ pinctrl-single,pins = <0x1b4 0x2F>; }; /* Mode 7, RxActive */ -+ P9_41_gpio_pu_pin: pinmux_P9_41_gpio_pu_pin { -+ pinctrl-single,pins = <0x1b4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_41_gpio_pd_pin: pinmux_P9_41_gpio_pd_pin { -+ pinctrl-single,pins = <0x1b4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_41_timer_pin: pinmux_P9_41_timer_pin { -+ pinctrl-single,pins = <0x1b4 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ P9_41_pruin_pin: pinmux_P9_41_pruin_pin { -+ pinctrl-single,pins = <0x1b4 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ -+ /* P9_41.1 */ -+ /* P9_91 (ZCZ ball D13) */ -+ P9_91_default_pin: pinmux_P9_91_default_pin { -+ pinctrl-single,pins = <0x1a8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_91_gpio_pin: pinmux_P9_91_gpio_pin { -+ pinctrl-single,pins = <0x1a8 0x2F>; }; /* Mode 7, RxActive */ -+ P9_91_gpio_pu_pin: pinmux_P9_91_gpio_pu_pin { -+ pinctrl-single,pins = <0x1a8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_91_gpio_pd_pin: pinmux_P9_91_gpio_pd_pin { -+ pinctrl-single,pins = <0x1a8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_91_qep_pin: pinmux_P9_91_qep_pin { -+ pinctrl-single,pins = <0x1a8 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_91_pruout_pin: pinmux_P9_91_pruout_pin { -+ pinctrl-single,pins = <0x1a8 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_91_pruin_pin: pinmux_P9_91_pruin_pin { -+ pinctrl-single,pins = <0x1a8 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_42 (ZCZ ball C18) */ -+ P9_42_default_pin: pinmux_P9_42_default_pin { -+ pinctrl-single,pins = <0x164 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_42_gpio_pin: pinmux_P9_42_gpio_pin { -+ pinctrl-single,pins = <0x164 0x2F>; }; /* Mode 7, RxActive */ -+ P9_42_gpio_pu_pin: pinmux_P9_42_gpio_pu_pin { -+ pinctrl-single,pins = <0x164 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_42_gpio_pd_pin: pinmux_P9_42_gpio_pd_pin { -+ pinctrl-single,pins = <0x164 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_42_pwm_pin: pinmux_P9_42_pwm_pin { -+ pinctrl-single,pins = <0x164 0x20>; }; /* Mode 0, Pull-Down, RxActive */ -+ P9_42_uart_pin: pinmux_P9_42_uart_pin { -+ pinctrl-single,pins = <0x164 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_42_spics_pin: pinmux_P9_42_spics_pin { -+ pinctrl-single,pins = <0x164 0x22>; }; /* Mode 2, Pull-Down, RxActive */ -+ P9_42_spiclk_pin: pinmux_P9_42_spiclk_pin { -+ pinctrl-single,pins = <0x164 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P9_42.1 */ -+ /* P9_92 (ZCZ ball B12) */ -+ P9_92_default_pin: pinmux_P9_92_default_pin { -+ pinctrl-single,pins = <0x1a0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_92_gpio_pin: pinmux_P9_92_gpio_pin { -+ pinctrl-single,pins = <0x1a0 0x2F>; }; /* Mode 7, RxActive */ -+ P9_92_gpio_pu_pin: pinmux_P9_92_gpio_pu_pin { -+ pinctrl-single,pins = <0x1a0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_92_gpio_pd_pin: pinmux_P9_92_gpio_pd_pin { -+ pinctrl-single,pins = <0x1a0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_92_qep_pin: pinmux_P9_92_qep_pin { -+ pinctrl-single,pins = <0x1a0 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_92_pruout_pin: pinmux_P9_92_pruout_pin { -+ pinctrl-single,pins = <0x1a0 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_92_pruin_pin: pinmux_P9_92_pruin_pin { -+ pinctrl-single,pins = <0x1a0 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_43 GND */ -+ /* P9_44 GND */ -+ /* P9_45 GND */ -+ /* P9_46 GND */ -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-common-universal.dtsi b/arch/arm/boot/dts/am335x-bone-common-universal.dtsi -new file mode 100644 -index 0000000..781e33f ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-common-universal.dtsi -@@ -0,0 +1,2052 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&am33xx_pinmux { -+ /************************/ -+ /* P8 Header */ -+ /************************/ -+ -+ /* P8_01 GND */ -+ /* P8_02 GND */ -+ /* P8_03 (ZCZ ball R9 ) emmc */ -+ /* P8_04 (ZCZ ball T9 ) emmc */ -+ /* P8_05 (ZCZ ball R8 ) emmc */ -+ /* P8_06 (ZCZ ball T8 ) emmc */ -+ -+ /* P8_07 (ZCZ ball R7 ) */ -+ P8_07_default_pin: pinmux_P8_07_default_pin { -+ pinctrl-single,pins = <0x090 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_07_gpio_pin: pinmux_P8_07_gpio_pin { -+ pinctrl-single,pins = <0x090 0x2F>; }; /* Mode 7, RxActive */ -+ P8_07_gpio_pu_pin: pinmux_P8_07_gpio_pu_pin { -+ pinctrl-single,pins = <0x090 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_07_gpio_pd_pin: pinmux_P8_07_gpio_pd_pin { -+ pinctrl-single,pins = <0x090 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_07_timer_pin: pinmux_P8_07_timer_pin { -+ pinctrl-single,pins = <0x090 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ -+ /* P8_08 (ZCZ ball T7 ) */ -+ P8_08_default_pin: pinmux_P8_08_default_pin { -+ pinctrl-single,pins = <0x094 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_08_gpio_pin: pinmux_P8_08_gpio_pin { -+ pinctrl-single,pins = <0x094 0x2F>; }; /* Mode 7, RxActive */ -+ P8_08_gpio_pu_pin: pinmux_P8_08_gpio_pu_pin { -+ pinctrl-single,pins = <0x094 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_08_gpio_pd_pin: pinmux_P8_08_gpio_pd_pin { -+ pinctrl-single,pins = <0x094 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_08_timer_pin: pinmux_P8_08_timer_pin { -+ pinctrl-single,pins = <0x094 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ -+ /* P8_09 (ZCZ ball T6 ) */ -+ P8_09_default_pin: pinmux_P8_09_default_pin { -+ pinctrl-single,pins = <0x09c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_09_gpio_pin: pinmux_P8_09_gpio_pin { -+ pinctrl-single,pins = <0x09c 0x2F>; }; /* Mode 7, RxActive */ -+ P8_09_gpio_pu_pin: pinmux_P8_09_gpio_pu_pin { -+ pinctrl-single,pins = <0x09c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_09_gpio_pd_pin: pinmux_P8_09_gpio_pd_pin { -+ pinctrl-single,pins = <0x09c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_09_timer_pin: pinmux_P8_09_timer_pin { -+ pinctrl-single,pins = <0x09c 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ -+ /* P8_10 (ZCZ ball U6 ) */ -+ P8_10_default_pin: pinmux_P8_10_default_pin { -+ pinctrl-single,pins = <0x098 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_10_gpio_pin: pinmux_P8_10_gpio_pin { -+ pinctrl-single,pins = <0x098 0x2F>; }; /* Mode 7, RxActive */ -+ P8_10_gpio_pu_pin: pinmux_P8_10_gpio_pu_pin { -+ pinctrl-single,pins = <0x098 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_10_gpio_pd_pin: pinmux_P8_10_gpio_pd_pin { -+ pinctrl-single,pins = <0x098 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_10_timer_pin: pinmux_P8_10_timer_pin { -+ pinctrl-single,pins = <0x098 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ -+ /* P8_11 (ZCZ ball R12) */ -+ P8_11_default_pin: pinmux_P8_11_default_pin { -+ pinctrl-single,pins = <0x034 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_11_gpio_pin: pinmux_P8_11_gpio_pin { -+ pinctrl-single,pins = <0x034 0x2F>; }; /* Mode 7, RxActive */ -+ P8_11_gpio_pu_pin: pinmux_P8_11_gpio_pu_pin { -+ pinctrl-single,pins = <0x034 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_11_gpio_pd_pin: pinmux_P8_11_gpio_pd_pin { -+ pinctrl-single,pins = <0x034 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_11_pruout_pin: pinmux_P8_11_pruout_pin { -+ pinctrl-single,pins = <0x034 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_11_qep_pin: pinmux_P8_11_qep_pin { -+ pinctrl-single,pins = <0x034 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_12 (ZCZ ball T12) */ -+ P8_12_default_pin: pinmux_P8_12_default_pin { -+ pinctrl-single,pins = <0x030 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_12_gpio_pin: pinmux_P8_12_gpio_pin { -+ pinctrl-single,pins = <0x030 0x2F>; }; /* Mode 7, RxActive */ -+ P8_12_gpio_pu_pin: pinmux_P8_12_gpio_pu_pin { -+ pinctrl-single,pins = <0x030 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_12_gpio_pd_pin: pinmux_P8_12_gpio_pd_pin { -+ pinctrl-single,pins = <0x030 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_12_pruout_pin: pinmux_P8_12_pruout_pin { -+ pinctrl-single,pins = <0x030 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_12_qep_pin: pinmux_P8_12_qep_pin { -+ pinctrl-single,pins = <0x030 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_13 (ZCZ ball T10) */ -+ P8_13_default_pin: pinmux_P8_13_default_pin { -+ pinctrl-single,pins = <0x024 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_13_gpio_pin: pinmux_P8_13_gpio_pin { -+ pinctrl-single,pins = <0x024 0x2F>; }; /* Mode 7, RxActive */ -+ P8_13_gpio_pu_pin: pinmux_P8_13_gpio_pu_pin { -+ pinctrl-single,pins = <0x024 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_13_gpio_pd_pin: pinmux_P8_13_gpio_pd_pin { -+ pinctrl-single,pins = <0x024 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_13_pwm_pin: pinmux_P8_13_pwm_pin { -+ pinctrl-single,pins = <0x024 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_14 (ZCZ ball T11) */ -+ P8_14_default_pin: pinmux_P8_14_default_pin { -+ pinctrl-single,pins = <0x028 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_14_gpio_pin: pinmux_P8_14_gpio_pin { -+ pinctrl-single,pins = <0x028 0x2F>; }; /* Mode 7, RxActive */ -+ P8_14_gpio_pu_pin: pinmux_P8_14_gpio_pu_pin { -+ pinctrl-single,pins = <0x028 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_14_gpio_pd_pin: pinmux_P8_14_gpio_pd_pin { -+ pinctrl-single,pins = <0x028 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_14_pwm_pin: pinmux_P8_14_pwm_pin { -+ pinctrl-single,pins = <0x028 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_15 (ZCZ ball U13) */ -+ P8_15_default_pin: pinmux_P8_15_default_pin { -+ pinctrl-single,pins = <0x03c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_15_gpio_pin: pinmux_P8_15_gpio_pin { -+ pinctrl-single,pins = <0x03c 0x2F>; }; /* Mode 7, RxActive */ -+ P8_15_gpio_pu_pin: pinmux_P8_15_gpio_pu_pin { -+ pinctrl-single,pins = <0x03c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_15_gpio_pd_pin: pinmux_P8_15_gpio_pd_pin { -+ pinctrl-single,pins = <0x03c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_15_pruin_pin: pinmux_P8_15_pruin_pin { -+ pinctrl-single,pins = <0x03c 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_15_qep_pin: pinmux_P8_15_qep_pin { -+ pinctrl-single,pins = <0x03c 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_16 (ZCZ ball V13) */ -+ P8_16_default_pin: pinmux_P8_16_default_pin { -+ pinctrl-single,pins = <0x038 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_16_gpio_pin: pinmux_P8_16_gpio_pin { -+ pinctrl-single,pins = <0x038 0x2F>; }; /* Mode 7, RxActive */ -+ P8_16_gpio_pu_pin: pinmux_P8_16_gpio_pu_pin { -+ pinctrl-single,pins = <0x038 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_16_gpio_pd_pin: pinmux_P8_16_gpio_pd_pin { -+ pinctrl-single,pins = <0x038 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_16_pruin_pin: pinmux_P8_16_pruin_pin { -+ pinctrl-single,pins = <0x038 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_16_qep_pin: pinmux_P8_16_qep_pin { -+ pinctrl-single,pins = <0x038 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_17 (ZCZ ball U12) */ -+ P8_17_default_pin: pinmux_P8_17_default_pin { -+ pinctrl-single,pins = <0x02c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_17_gpio_pin: pinmux_P8_17_gpio_pin { -+ pinctrl-single,pins = <0x02c 0x2F>; }; /* Mode 7, RxActive */ -+ P8_17_gpio_pu_pin: pinmux_P8_17_gpio_pu_pin { -+ pinctrl-single,pins = <0x02c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_17_gpio_pd_pin: pinmux_P8_17_gpio_pd_pin { -+ pinctrl-single,pins = <0x02c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_17_pwm_pin: pinmux_P8_17_pwm_pin { -+ pinctrl-single,pins = <0x02c 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_18 (ZCZ ball V12) */ -+ P8_18_default_pin: pinmux_P8_18_default_pin { -+ pinctrl-single,pins = <0x08c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_18_gpio_pin: pinmux_P8_18_gpio_pin { -+ pinctrl-single,pins = <0x08c 0x2F>; }; /* Mode 7, RxActive */ -+ P8_18_gpio_pu_pin: pinmux_P8_18_gpio_pu_pin { -+ pinctrl-single,pins = <0x08c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_18_gpio_pd_pin: pinmux_P8_18_gpio_pd_pin { -+ pinctrl-single,pins = <0x08c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ -+ /* P8_19 (ZCZ ball U10) */ -+ P8_19_default_pin: pinmux_P8_19_default_pin { -+ pinctrl-single,pins = <0x020 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_19_gpio_pin: pinmux_P8_19_gpio_pin { -+ pinctrl-single,pins = <0x020 0x2F>; }; /* Mode 7, RxActive */ -+ P8_19_gpio_pu_pin: pinmux_P8_19_gpio_pu_pin { -+ pinctrl-single,pins = <0x020 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_19_gpio_pd_pin: pinmux_P8_19_gpio_pd_pin { -+ pinctrl-single,pins = <0x020 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_19_pwm_pin: pinmux_P8_19_pwm_pin { -+ pinctrl-single,pins = <0x020 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P8_20 (ZCZ ball V9 ) emmc */ -+ /* P8_21 (ZCZ ball U9 ) emmc */ -+ /* P8_22 (ZCZ ball V8 ) emmc */ -+ /* P8_23 (ZCZ ball U8 ) emmc */ -+ /* P8_24 (ZCZ ball V7 ) emmc */ -+ /* P8_25 (ZCZ ball U7 ) emmc */ -+ -+ /* P8_26 (ZCZ ball V6 ) */ -+ P8_26_default_pin: pinmux_P8_26_default_pin { -+ pinctrl-single,pins = <0x07c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_26_gpio_pin: pinmux_P8_26_gpio_pin { -+ pinctrl-single,pins = <0x07c 0x2F>; }; /* Mode 7, RxActive */ -+ P8_26_gpio_pu_pin: pinmux_P8_26_gpio_pu_pin { -+ pinctrl-single,pins = <0x07c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_26_gpio_pd_pin: pinmux_P8_26_gpio_pd_pin { -+ pinctrl-single,pins = <0x07c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ -+ /* P8_27 (ZCZ ball U5 ) hdmi */ -+ P8_27_default_pin: pinmux_P8_27_default_pin { -+ pinctrl-single,pins = <0x0e0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_27_gpio_pin: pinmux_P8_27_gpio_pin { -+ pinctrl-single,pins = <0x0e0 0x2F>; }; /* Mode 7, RxActive */ -+ P8_27_gpio_pu_pin: pinmux_P8_27_gpio_pu_pin { -+ pinctrl-single,pins = <0x0e0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_27_gpio_pd_pin: pinmux_P8_27_gpio_pd_pin { -+ pinctrl-single,pins = <0x0e0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_27_pruout_pin: pinmux_P8_27_pruout_pin { -+ pinctrl-single,pins = <0x0e0 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_27_pruin_pin: pinmux_P8_27_pruin_pin { -+ pinctrl-single,pins = <0x0e0 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_27_hdmi_pin: pinmux_P8_27_hdmi_pin { -+ pinctrl-single,pins = <0x0e0 0x00>; }; /* lcd_vsync.lcd_vsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ -+ -+ /* P8_28 (ZCZ ball V5 ) hdmi */ -+ P8_28_default_pin: pinmux_P8_28_default_pin { -+ pinctrl-single,pins = <0x0e8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_28_gpio_pin: pinmux_P8_28_gpio_pin { -+ pinctrl-single,pins = <0x0e8 0x2F>; }; /* Mode 7, RxActive */ -+ P8_28_gpio_pu_pin: pinmux_P8_28_gpio_pu_pin { -+ pinctrl-single,pins = <0x0e8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_28_gpio_pd_pin: pinmux_P8_28_gpio_pd_pin { -+ pinctrl-single,pins = <0x0e8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_28_pruout_pin: pinmux_P8_28_pruout_pin { -+ pinctrl-single,pins = <0x0e8 0x05>; }; /* Mode 5, Pull-Down */ -+ P8_28_pruin_pin: pinmux_P8_28_pruin_pin { -+ pinctrl-single,pins = <0x0e8 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_28_hdmi_pin: pinmux_P8_28_hdmi_pin { -+ pinctrl-single,pins = <0x0e8 0x00>; }; /* lcd_pclk.lcd_pclk, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ -+ -+ /* P8_29 (ZCZ ball R5 ) hdmi */ -+ P8_29_default_pin: pinmux_P8_29_default_pin { -+ pinctrl-single,pins = <0x0e4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_29_gpio_pin: pinmux_P8_29_gpio_pin { -+ pinctrl-single,pins = <0x0e4 0x2F>; }; /* Mode 7, RxActive */ -+ P8_29_gpio_pu_pin: pinmux_P8_29_gpio_pu_pin { -+ pinctrl-single,pins = <0x0e4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_29_gpio_pd_pin: pinmux_P8_29_gpio_pd_pin { -+ pinctrl-single,pins = <0x0e4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_29_pruout_pin: pinmux_P8_29_pruout_pin { -+ pinctrl-single,pins = <0x0e4 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_29_pruin_pin: pinmux_P8_29_pruin_pin { -+ pinctrl-single,pins = <0x0e4 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_29_hdmi_pin: pinmux_P8_29_hdmi_pin { -+ pinctrl-single,pins = <0x0e4 0x00>; }; /* lcd_hsync.lcd_hsync, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ -+ -+ /* P8_30 (ZCZ ball R6 ) hdmi */ -+ P8_30_default_pin: pinmux_P8_30_default_pin { -+ pinctrl-single,pins = <0x0ec 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_30_gpio_pin: pinmux_P8_30_gpio_pin { -+ pinctrl-single,pins = <0x0ec 0x2F>; }; /* Mode 7, RxActive */ -+ P8_30_gpio_pu_pin: pinmux_P8_30_gpio_pu_pin { -+ pinctrl-single,pins = <0x0ec 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_30_gpio_pd_pin: pinmux_P8_30_gpio_pd_pin { -+ pinctrl-single,pins = <0x0ec 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_30_pruout_pin: pinmux_P8_30_pruout_pin { -+ pinctrl-single,pins = <0x0ec 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_30_pruin_pin: pinmux_P8_30_pruin_pin { -+ pinctrl-single,pins = <0x0ec 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_30_hdmi_pin: pinmux_P8_30_hdmi_pin { -+ pinctrl-single,pins = <0x0ec 0x00>; }; /* lcd_ac_bias_en.lcd_ac_bias_en, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT */ -+ -+ /* P8_31 (ZCZ ball V4 ) hdmi */ -+ P8_31_default_pin: pinmux_P8_31_default_pin { -+ pinctrl-single,pins = <0x0d8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_31_gpio_pin: pinmux_P8_31_gpio_pin { -+ pinctrl-single,pins = <0x0d8 0x2F>; }; /* Mode 7, RxActive */ -+ P8_31_gpio_pu_pin: pinmux_P8_31_gpio_pu_pin { -+ pinctrl-single,pins = <0x0d8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_31_gpio_pd_pin: pinmux_P8_31_gpio_pd_pin { -+ pinctrl-single,pins = <0x0d8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_31_uart_pin: pinmux_P8_31_uart_pin { -+ pinctrl-single,pins = <0x0d8 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ P8_31_hdmi_pin: pinmux_P8_31_hdmi_pin { -+ pinctrl-single,pins = <0x0d8 0x08>; }; /* lcd_data14.lcd_data14, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_32 (ZCZ ball T5 ) hdmi */ -+ P8_32_default_pin: pinmux_P8_32_default_pin { -+ pinctrl-single,pins = <0x0dc 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_32_gpio_pin: pinmux_P8_32_gpio_pin { -+ pinctrl-single,pins = <0x0dc 0x2F>; }; /* Mode 7, RxActive */ -+ P8_32_gpio_pu_pin: pinmux_P8_32_gpio_pu_pin { -+ pinctrl-single,pins = <0x0dc 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_32_gpio_pd_pin: pinmux_P8_32_gpio_pd_pin { -+ pinctrl-single,pins = <0x0dc 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_32_uart_pin: pinmux_P8_32_uart_pin { -+ pinctrl-single,pins = <0x0dc 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_32_hdmi_pin: pinmux_P8_32_hdmi_pin { -+ pinctrl-single,pins = <0x0dc 0x08>; }; /* lcd_data15.lcd_data15, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_33 (ZCZ ball V3 ) hdmi */ -+ P8_33_default_pin: pinmux_P8_33_default_pin { -+ pinctrl-single,pins = <0x0d4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_33_gpio_pin: pinmux_P8_33_gpio_pin { -+ pinctrl-single,pins = <0x0d4 0x2F>; }; /* Mode 7, RxActive */ -+ P8_33_gpio_pu_pin: pinmux_P8_33_gpio_pu_pin { -+ pinctrl-single,pins = <0x0d4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_33_gpio_pd_pin: pinmux_P8_33_gpio_pd_pin { -+ pinctrl-single,pins = <0x0d4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_33_hdmi_pin: pinmux_P8_33_hdmi_pin { -+ pinctrl-single,pins = <0x0d4 0x08>; }; /* lcd_data13.lcd_data13, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_34 (ZCZ ball U4 ) hdmi */ -+ P8_34_default_pin: pinmux_P8_34_default_pin { -+ pinctrl-single,pins = <0x0cc 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_34_gpio_pin: pinmux_P8_34_gpio_pin { -+ pinctrl-single,pins = <0x0cc 0x2F>; }; /* Mode 7, RxActive */ -+ P8_34_gpio_pu_pin: pinmux_P8_34_gpio_pu_pin { -+ pinctrl-single,pins = <0x0cc 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_34_gpio_pd_pin: pinmux_P8_34_gpio_pd_pin { -+ pinctrl-single,pins = <0x0cc 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_34_pwm_pin: pinmux_P8_34_pwm_pin { -+ pinctrl-single,pins = <0x0cc 0x22>; }; /* Mode 2, Pull-Down, RxActive */ -+ P8_34_hdmi_pin: pinmux_P8_34_hdmi_pin { -+ pinctrl-single,pins = <0x0cc 0x08>; }; /* lcd_data11.lcd_data11, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_35 (ZCZ ball V2 ) hdmi */ -+ P8_35_default_pin: pinmux_P8_35_default_pin { -+ pinctrl-single,pins = <0x0d0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_35_gpio_pin: pinmux_P8_35_gpio_pin { -+ pinctrl-single,pins = <0x0d0 0x2F>; }; /* Mode 7, RxActive */ -+ P8_35_gpio_pu_pin: pinmux_P8_35_gpio_pu_pin { -+ pinctrl-single,pins = <0x0d0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_35_gpio_pd_pin: pinmux_P8_35_gpio_pd_pin { -+ pinctrl-single,pins = <0x0d0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_35_hdmi_pin: pinmux_P8_35_hdmi_pin { -+ pinctrl-single,pins = <0x0d0 0x08>; }; /* lcd_data12.lcd_data12, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_36 (ZCZ ball U3 ) hdmi */ -+ P8_36_default_pin: pinmux_P8_36_default_pin { -+ pinctrl-single,pins = <0x0c8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_36_gpio_pin: pinmux_P8_36_gpio_pin { -+ pinctrl-single,pins = <0x0c8 0x2F>; }; /* Mode 7, RxActive */ -+ P8_36_gpio_pu_pin: pinmux_P8_36_gpio_pu_pin { -+ pinctrl-single,pins = <0x0c8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_36_gpio_pd_pin: pinmux_P8_36_gpio_pd_pin { -+ pinctrl-single,pins = <0x0c8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_36_pwm_pin: pinmux_P8_36_pwm_pin { -+ pinctrl-single,pins = <0x0c8 0x22>; }; /* Mode 2, Pull-Down, RxActive */ -+ P8_36_hdmi_pin: pinmux_P8_36_hdmi_pin { -+ pinctrl-single,pins = <0x0c8 0x08>; }; /* lcd_data10.lcd_data10, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_37 (ZCZ ball U1 ) hdmi */ -+ P8_37_default_pin: pinmux_P8_37_default_pin { -+ pinctrl-single,pins = <0x0c0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_37_gpio_pin: pinmux_P8_37_gpio_pin { -+ pinctrl-single,pins = <0x0c0 0x2F>; }; /* Mode 7, RxActive */ -+ P8_37_gpio_pu_pin: pinmux_P8_37_gpio_pu_pin { -+ pinctrl-single,pins = <0x0c0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_37_gpio_pd_pin: pinmux_P8_37_gpio_pd_pin { -+ pinctrl-single,pins = <0x0c0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_37_uart_pin: pinmux_P8_37_uart_pin { -+ pinctrl-single,pins = <0x0c0 0x04>; }; /* Mode 4, Pull-Down*/ -+ P8_37_pwm_pin: pinmux_P8_37_pwm_pin { -+ pinctrl-single,pins = <0x0c0 0x02>; }; /* Mode 2, Pull-Down*/ -+ P8_37_hdmi_pin: pinmux_P8_37_hdmi_pin { -+ pinctrl-single,pins = <0x0c0 0x08>; }; /* lcd_data8.lcd_data8, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ -+ /* P8_38 (ZCZ ball U2 ) hdmi */ -+ P8_38_default_pin: pinmux_P8_38_default_pin { -+ pinctrl-single,pins = <0x0c4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_38_gpio_pin: pinmux_P8_38_gpio_pin { -+ pinctrl-single,pins = <0x0c4 0x2F>; }; /* Mode 7, RxActive */ -+ P8_38_gpio_pu_pin: pinmux_P8_38_gpio_pu_pin { -+ pinctrl-single,pins = <0x0c4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_38_gpio_pd_pin: pinmux_P8_38_gpio_pd_pin { -+ pinctrl-single,pins = <0x0c4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_38_uart_pin: pinmux_P8_38_uart_pin { -+ pinctrl-single,pins = <0x0c4 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ P8_38_pwm_pin: pinmux_P8_38_pwm_pin { -+ pinctrl-single,pins = <0x0c4 0x22>; }; /* Mode 2, Pull-Down, RxActive */ -+ P8_38_hdmi_pin: pinmux_P8_38_hdmi_pin { -+ pinctrl-single,pins = <0x0c4 0x08>; }; /* lcd_data9.lcd_data9, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ -+ /* P8_39 (ZCZ ball T3 ) hdmi */ -+ P8_39_default_pin: pinmux_P8_39_default_pin { -+ pinctrl-single,pins = <0x0b8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_39_gpio_pin: pinmux_P8_39_gpio_pin { -+ pinctrl-single,pins = <0x0b8 0x2F>; }; /* Mode 7, RxActive */ -+ P8_39_gpio_pu_pin: pinmux_P8_39_gpio_pu_pin { -+ pinctrl-single,pins = <0x0b8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_39_gpio_pd_pin: pinmux_P8_39_gpio_pd_pin { -+ pinctrl-single,pins = <0x0b8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_39_pruout_pin: pinmux_P8_39_pruout_pin { -+ pinctrl-single,pins = <0x0b8 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_39_pruin_pin: pinmux_P8_39_pruin_pin { -+ pinctrl-single,pins = <0x0b8 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_39_hdmi_pin: pinmux_P8_39_hdmi_pin { -+ pinctrl-single,pins = <0x0b8 0x08>; }; /* lcd_data6.lcd_data6, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_40 (ZCZ ball T4 ) hdmi */ -+ P8_40_default_pin: pinmux_P8_40_default_pin { -+ pinctrl-single,pins = <0x0bc 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_40_gpio_pin: pinmux_P8_40_gpio_pin { -+ pinctrl-single,pins = <0x0bc 0x2F>; }; /* Mode 7, RxActive */ -+ P8_40_gpio_pu_pin: pinmux_P8_40_gpio_pu_pin { -+ pinctrl-single,pins = <0x0bc 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_40_gpio_pd_pin: pinmux_P8_40_gpio_pd_pin { -+ pinctrl-single,pins = <0x0bc 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_40_pruout_pin: pinmux_P8_40_pruout_pin { -+ pinctrl-single,pins = <0x0bc 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_40_pruin_pin: pinmux_P8_40_pruin_pin { -+ pinctrl-single,pins = <0x0bc 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_40_hdmi_pin: pinmux_P8_40_hdmi_pin { -+ pinctrl-single,pins = <0x0bc 0x08>; }; /* lcd_data7.lcd_data7, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_41 (ZCZ ball T1 ) hdmi */ -+ P8_41_default_pin: pinmux_P8_41_default_pin { -+ pinctrl-single,pins = <0x0b0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_41_gpio_pin: pinmux_P8_41_gpio_pin { -+ pinctrl-single,pins = <0x0b0 0x2F>; }; /* Mode 7, RxActive */ -+ P8_41_gpio_pu_pin: pinmux_P8_41_gpio_pu_pin { -+ pinctrl-single,pins = <0x0b0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_41_gpio_pd_pin: pinmux_P8_41_gpio_pd_pin { -+ pinctrl-single,pins = <0x0b0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_41_pruout_pin: pinmux_P8_41_pruout_pin { -+ pinctrl-single,pins = <0x0b0 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_41_pruin_pin: pinmux_P8_41_pruin_pin { -+ pinctrl-single,pins = <0x0b0 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_41_hdmi_pin: pinmux_P8_41_hdmi_pin { -+ pinctrl-single,pins = <0x0b0 0x08>; }; /* lcd_data4.lcd_data4, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_42 (ZCZ ball T2 ) hdmi */ -+ P8_42_default_pin: pinmux_P8_42_default_pin { -+ pinctrl-single,pins = <0x0b4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_42_gpio_pin: pinmux_P8_42_gpio_pin { -+ pinctrl-single,pins = <0x0b4 0x2F>; }; /* Mode 7, RxActive */ -+ P8_42_gpio_pu_pin: pinmux_P8_42_gpio_pu_pin { -+ pinctrl-single,pins = <0x0b4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_42_gpio_pd_pin: pinmux_P8_42_gpio_pd_pin { -+ pinctrl-single,pins = <0x0b4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_42_pruout_pin: pinmux_P8_42_pruout_pin { -+ pinctrl-single,pins = <0x0b4 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_42_pruin_pin: pinmux_P8_42_pruin_pin { -+ pinctrl-single,pins = <0x0b4 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_42_hdmi_pin: pinmux_P8_42_hdmi_pin { -+ pinctrl-single,pins = <0x0b4 0x08>; }; /* lcd_data5.lcd_data5, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_43 (ZCZ ball R3 ) hdmi */ -+ P8_43_default_pin: pinmux_P8_43_default_pin { -+ pinctrl-single,pins = <0x0a8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_43_gpio_pin: pinmux_P8_43_gpio_pin { -+ pinctrl-single,pins = <0x0a8 0x2F>; }; /* Mode 7, RxActive */ -+ P8_43_gpio_pu_pin: pinmux_P8_43_gpio_pu_pin { -+ pinctrl-single,pins = <0x0a8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_43_gpio_pd_pin: pinmux_P8_43_gpio_pd_pin { -+ pinctrl-single,pins = <0x0a8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_43_pruout_pin: pinmux_P8_43_pruout_pin { -+ pinctrl-single,pins = <0x0a8 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_43_pruin_pin: pinmux_P8_43_pruin_pin { -+ pinctrl-single,pins = <0x0a8 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_43_pwm_pin: pinmux_P8_43_pwm_pin { -+ pinctrl-single,pins = <0x0a8 0x03>; }; /* Mode 3, Pull-Down */ -+ P8_43_hdmi_pin: pinmux_P8_43_hdmi_pin { -+ pinctrl-single,pins = <0x0a8 0x08>; }; /* lcd_data2.lcd_data2, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_44 (ZCZ ball R4 ) hdmi */ -+ P8_44_default_pin: pinmux_P8_44_default_pin { -+ pinctrl-single,pins = <0x0ac 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_44_gpio_pin: pinmux_P8_44_gpio_pin { -+ pinctrl-single,pins = <0x0ac 0x2F>; }; /* Mode 7, RxActive */ -+ P8_44_gpio_pu_pin: pinmux_P8_44_gpio_pu_pin { -+ pinctrl-single,pins = <0x0ac 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_44_gpio_pd_pin: pinmux_P8_44_gpio_pd_pin { -+ pinctrl-single,pins = <0x0ac 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_44_pruout_pin: pinmux_P8_44_pruout_pin { -+ pinctrl-single,pins = <0x0ac 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_44_pruin_pin: pinmux_P8_44_pruin_pin { -+ pinctrl-single,pins = <0x0ac 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_44_pwm_pin: pinmux_P8_44_pwm_pin { -+ pinctrl-single,pins = <0x0ac 0x23>; }; /* Mode 3, Pull-Down, RxActive */ -+ P8_44_hdmi_pin: pinmux_P8_44_hdmi_pin { -+ pinctrl-single,pins = <0x0ac 0x08>; }; /* lcd_data3.lcd_data3, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_45 (ZCZ ball R1 ) hdmi */ -+ P8_45_default_pin: pinmux_P8_45_default_pin { -+ pinctrl-single,pins = <0x0a0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_45_gpio_pin: pinmux_P8_45_gpio_pin { -+ pinctrl-single,pins = <0x0a0 0x2F>; }; /* Mode 7, RxActive */ -+ P8_45_gpio_pu_pin: pinmux_P8_45_gpio_pu_pin { -+ pinctrl-single,pins = <0x0a0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_45_gpio_pd_pin: pinmux_P8_45_gpio_pd_pin { -+ pinctrl-single,pins = <0x0a0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_45_pruout_pin: pinmux_P8_45_pruout_pin { -+ pinctrl-single,pins = <0x0a0 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_45_pruin_pin: pinmux_P8_45_pruin_pin { -+ pinctrl-single,pins = <0x0a0 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_45_pwm_pin: pinmux_P8_45_pwm_pin { -+ pinctrl-single,pins = <0x0a0 0x03>; }; /* Mode 3, Pull-Down*/ -+ P8_45_hdmi_pin: pinmux_P8_45_hdmi_pin { -+ pinctrl-single,pins = <0x0a0 0x08>; }; /* lcd_data0.lcd_data0, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /* P8_46 (ZCZ ball R2 ) hdmi */ -+ P8_46_default_pin: pinmux_P8_46_default_pin { -+ pinctrl-single,pins = <0x0a4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_46_gpio_pin: pinmux_P8_46_gpio_pin { -+ pinctrl-single,pins = <0x0a4 0x2F>; }; /* Mode 7, RxActive */ -+ P8_46_gpio_pu_pin: pinmux_P8_46_gpio_pu_pin { -+ pinctrl-single,pins = <0x0a4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P8_46_gpio_pd_pin: pinmux_P8_46_gpio_pd_pin { -+ pinctrl-single,pins = <0x0a4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P8_46_pruout_pin: pinmux_P8_46_pruout_pin { -+ pinctrl-single,pins = <0x0a4 0x05>; }; /* Mode 5, Pull-Down*/ -+ P8_46_pruin_pin: pinmux_P8_46_pruin_pin { -+ pinctrl-single,pins = <0x0a4 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P8_46_pwm_pin: pinmux_P8_46_pwm_pin { -+ pinctrl-single,pins = <0x0a4 0x03>; }; /* Mode 3, Pull-Down*/ -+ P8_46_hdmi_pin: pinmux_P8_46_hdmi_pin { -+ pinctrl-single,pins = <0x0a4 0x08>; }; /* lcd_data1.lcd_data1, OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA */ -+ -+ /************************/ -+ /* P9 Header */ -+ /************************/ -+ -+ /* P9_01 GND */ -+ /* P9_02 GND */ -+ /* P9_03 3.3V */ -+ /* P9_04 3.3V */ -+ /* P9_05 VDD_5V */ -+ /* P9_06 VDD_5V */ -+ /* P9_07 SYS_5V */ -+ /* P9_08 SYS_5V */ -+ /* P9_09 PWR_BUT */ -+ /* P9_10 (ZCZ ball A10) RESETn */ -+ -+ /* P9_11 (ZCZ ball T17) */ -+ P9_11_default_pin: pinmux_P9_11_default_pin { -+ pinctrl-single,pins = <0x070 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_11_gpio_pin: pinmux_P9_11_gpio_pin { -+ pinctrl-single,pins = <0x070 0x2F>; }; /* Mode 7, RxActive */ -+ P9_11_gpio_pu_pin: pinmux_P9_11_gpio_pu_pin { -+ pinctrl-single,pins = <0x070 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_11_gpio_pd_pin: pinmux_P9_11_gpio_pd_pin { -+ pinctrl-single,pins = <0x070 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_11_uart_pin: pinmux_P9_11_uart_pin { -+ pinctrl-single,pins = <0x070 0x36>; }; /* Mode 6, Pull-Up, RxActive */ -+ -+ /* P9_12 (ZCZ ball U18) */ -+ P9_12_default_pin: pinmux_P9_12_default_pin { -+ pinctrl-single,pins = <0x078 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_12_gpio_pin: pinmux_P9_12_gpio_pin { -+ pinctrl-single,pins = <0x078 0x2F>; }; /* Mode 7, RxActive */ -+ P9_12_gpio_pu_pin: pinmux_P9_12_gpio_pu_pin { -+ pinctrl-single,pins = <0x078 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_12_gpio_pd_pin: pinmux_P9_12_gpio_pd_pin { -+ pinctrl-single,pins = <0x078 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ -+ /* P9_13 (ZCZ ball U17) */ -+ P9_13_default_pin: pinmux_P9_13_default_pin { -+ pinctrl-single,pins = <0x074 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_13_gpio_pin: pinmux_P9_13_gpio_pin { -+ pinctrl-single,pins = <0x074 0x2F>; }; /* Mode 7, RxActive */ -+ P9_13_gpio_pu_pin: pinmux_P9_13_gpio_pu_pin { -+ pinctrl-single,pins = <0x074 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_13_gpio_pd_pin: pinmux_P9_13_gpio_pd_pin { -+ pinctrl-single,pins = <0x074 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_13_uart_pin: pinmux_P9_13_uart_pin { -+ pinctrl-single,pins = <0x074 0x36>; }; /* Mode 6, Pull-Up, RxActive */ -+ -+ /* P9_14 (ZCZ ball U14) */ -+ P9_14_default_pin: pinmux_P9_14_default_pin { -+ pinctrl-single,pins = <0x048 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_14_gpio_pin: pinmux_P9_14_gpio_pin { -+ pinctrl-single,pins = <0x048 0x2F>; }; /* Mode 7, RxActive */ -+ P9_14_gpio_pu_pin: pinmux_P9_14_gpio_pu_pin { -+ pinctrl-single,pins = <0x048 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_14_gpio_pd_pin: pinmux_P9_14_gpio_pd_pin { -+ pinctrl-single,pins = <0x048 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_14_pwm_pin: pinmux_P9_14_pwm_pin { -+ pinctrl-single,pins = <0x048 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_15 (ZCZ ball R13) */ -+ P9_15_default_pin: pinmux_P9_15_default_pin { -+ pinctrl-single,pins = <0x040 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_15_gpio_pin: pinmux_P9_15_gpio_pin { -+ pinctrl-single,pins = <0x040 0x2F>; }; /* Mode 7, RxActive */ -+ P9_15_gpio_pu_pin: pinmux_P9_15_gpio_pu_pin { -+ pinctrl-single,pins = <0x040 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_15_gpio_pd_pin: pinmux_P9_15_gpio_pd_pin { -+ pinctrl-single,pins = <0x040 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_15_pwm_pin: pinmux_P9_15_pwm_pin { -+ pinctrl-single,pins = <0x040 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_16 (ZCZ ball T14) */ -+ P9_16_default_pin: pinmux_P9_16_default_pin { -+ pinctrl-single,pins = <0x04c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_16_gpio_pin: pinmux_P9_16_gpio_pin { -+ pinctrl-single,pins = <0x04c 0x2F>; }; /* Mode 7, RxActive */ -+ P9_16_gpio_pu_pin: pinmux_P9_16_gpio_pu_pin { -+ pinctrl-single,pins = <0x04c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_16_gpio_pd_pin: pinmux_P9_16_gpio_pd_pin { -+ pinctrl-single,pins = <0x04c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_16_pwm_pin: pinmux_P9_16_pwm_pin { -+ pinctrl-single,pins = <0x04c 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_17 (ZCZ ball A16) */ -+ P9_17_default_pin: pinmux_P9_17_default_pin { -+ pinctrl-single,pins = <0x15c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_17_gpio_pin: pinmux_P9_17_gpio_pin { -+ pinctrl-single,pins = <0x15c 0x2F>; }; /* Mode 7, RxActive */ -+ P9_17_gpio_pu_pin: pinmux_P9_17_gpio_pu_pin { -+ pinctrl-single,pins = <0x15c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_17_gpio_pd_pin: pinmux_P9_17_gpio_pd_pin { -+ pinctrl-single,pins = <0x15c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_17_spi_pin: pinmux_P9_17_spi_pin { -+ pinctrl-single,pins = <0x15c 0x30>; }; /* Mode 0, Pull-Up, RxActive */ -+ P9_17_i2c_pin: pinmux_P9_17_i2c_pin { -+ pinctrl-single,pins = <0x15c 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_17_pwm_pin: pinmux_P9_17_pwm_pin { -+ pinctrl-single,pins = <0x15c 0x33>; }; /* Mode 3, Pull-Up, RxActive */ -+ -+ /* P9_18 (ZCZ ball B16) */ -+ P9_18_default_pin: pinmux_P9_18_default_pin { -+ pinctrl-single,pins = <0x158 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_18_gpio_pin: pinmux_P9_18_gpio_pin { -+ pinctrl-single,pins = <0x158 0x2F>; }; /* Mode 7, RxActive */ -+ P9_18_gpio_pu_pin: pinmux_P9_18_gpio_pu_pin { -+ pinctrl-single,pins = <0x158 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_18_gpio_pd_pin: pinmux_P9_18_gpio_pd_pin { -+ pinctrl-single,pins = <0x158 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_18_spi_pin: pinmux_P9_18_spi_pin { -+ pinctrl-single,pins = <0x158 0x30>; }; /* Mode 0, Pull-Up, RxActive */ -+ P9_18_i2c_pin: pinmux_P9_18_i2c_pin { -+ pinctrl-single,pins = <0x158 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_18_pwm_pin: pinmux_P9_18_pwm_pin { -+ pinctrl-single,pins = <0x158 0x33>; }; /* Mode 3, Pull-Up, RxActive */ -+ -+ /* P9_19 (ZCZ ball D17) */ -+ P9_19_default_pin: pinmux_P9_19_default_pin { -+ pinctrl-single,pins = <0x17c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_19_gpio_pin: pinmux_P9_19_gpio_pin { -+ pinctrl-single,pins = <0x17c 0x2F>; }; /* Mode 7, RxActive */ -+ P9_19_gpio_pu_pin: pinmux_P9_19_gpio_pu_pin { -+ pinctrl-single,pins = <0x17c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_19_gpio_pd_pin: pinmux_P9_19_gpio_pd_pin { -+ pinctrl-single,pins = <0x17c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_19_can_pin: pinmux_P9_19_can_pin { -+ pinctrl-single,pins = <0x17c 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_19_i2c_pin: pinmux_P9_19_i2c_pin { -+ pinctrl-single,pins = <0x17c 0x73>; }; /* (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3) */ -+ -+ /* P9_20 (ZCZ ball D18) */ -+ P9_20_default_pin: pinmux_P9_20_default_pin { -+ pinctrl-single,pins = <0x178 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_20_gpio_pin: pinmux_P9_20_gpio_pin { -+ pinctrl-single,pins = <0x178 0x2F>; }; /* Mode 7, RxActive */ -+ P9_20_gpio_pu_pin: pinmux_P9_20_gpio_pu_pin { -+ pinctrl-single,pins = <0x178 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_20_gpio_pd_pin: pinmux_P9_20_gpio_pd_pin { -+ pinctrl-single,pins = <0x178 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_20_can_pin: pinmux_P9_20_can_pin { -+ pinctrl-single,pins = <0x178 0x12>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_20_i2c_pin: pinmux_P9_20_i2c_pin { -+ pinctrl-single,pins = <0x178 0x73>; }; /* (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3) */ -+ -+ /* P9_21 (ZCZ ball B17) */ -+ P9_21_default_pin: pinmux_P9_21_default_pin { -+ pinctrl-single,pins = <0x154 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_21_gpio_pin: pinmux_P9_21_gpio_pin { -+ pinctrl-single,pins = <0x154 0x2F>; }; /* Mode 7, RxActive */ -+ P9_21_gpio_pu_pin: pinmux_P9_21_gpio_pu_pin { -+ pinctrl-single,pins = <0x154 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_21_gpio_pd_pin: pinmux_P9_21_gpio_pd_pin { -+ pinctrl-single,pins = <0x154 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_21_spi_pin: pinmux_P9_21_spi_pin { -+ pinctrl-single,pins = <0x154 0x30>; }; /* Mode 0, Pull-Up, RxActive */ -+ P9_21_uart_pin: pinmux_P9_21_uart_pin { -+ pinctrl-single,pins = <0x154 0x31>; }; /* Mode 1, Pull-Up, RxActive */ -+ P9_21_i2c_pin: pinmux_P9_21_i2c_pin { -+ pinctrl-single,pins = <0x154 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_21_pwm_pin: pinmux_P9_21_pwm_pin { -+ pinctrl-single,pins = <0x154 0x33>; }; /* Mode 3, Pull-Up, RxActive */ -+ -+ /* P9_22 (ZCZ ball A17) */ -+ P9_22_default_pin: pinmux_P9_22_default_pin { -+ pinctrl-single,pins = <0x150 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_22_gpio_pin: pinmux_P9_22_gpio_pin { -+ pinctrl-single,pins = <0x150 0x2F>; }; /* Mode 7, RxActive */ -+ P9_22_gpio_pu_pin: pinmux_P9_22_gpio_pu_pin { -+ pinctrl-single,pins = <0x150 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_22_gpio_pd_pin: pinmux_P9_22_gpio_pd_pin { -+ pinctrl-single,pins = <0x150 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_22_spi_pin: pinmux_P9_22_spi_pin { -+ pinctrl-single,pins = <0x150 0x30>; }; /* Mode 0, Pull-Up, RxActive */ -+ P9_22_uart_pin: pinmux_P9_22_uart_pin { -+ pinctrl-single,pins = <0x150 0x31>; }; /* Mode 1, Pull-Up, RxActive */ -+ P9_22_i2c_pin: pinmux_P9_22_i2c_pin { -+ pinctrl-single,pins = <0x150 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_22_pwm_pin: pinmux_P9_22_pwm_pin { -+ pinctrl-single,pins = <0x150 0x33>; }; /* Mode 3, Pull-Up, RxActive */ -+ -+ /* P9_23 (ZCZ ball V14) */ -+ P9_23_default_pin: pinmux_P9_23_default_pin { -+ pinctrl-single,pins = <0x044 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_23_gpio_pin: pinmux_P9_23_gpio_pin { -+ pinctrl-single,pins = <0x044 0x2F>; }; /* Mode 7, RxActive */ -+ P9_23_gpio_pu_pin: pinmux_P9_23_gpio_pu_pin { -+ pinctrl-single,pins = <0x044 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_23_gpio_pd_pin: pinmux_P9_23_gpio_pd_pin { -+ pinctrl-single,pins = <0x044 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_23_pwm_pin: pinmux_P9_23_pwm_pin { -+ pinctrl-single,pins = <0x044 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_24 (ZCZ ball D15) */ -+ P9_24_default_pin: pinmux_P9_24_default_pin { -+ pinctrl-single,pins = <0x184 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_24_gpio_pin: pinmux_P9_24_gpio_pin { -+ pinctrl-single,pins = <0x184 0x2F>; }; /* Mode 7, RxActive */ -+ P9_24_gpio_pu_pin: pinmux_P9_24_gpio_pu_pin { -+ pinctrl-single,pins = <0x184 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_24_gpio_pd_pin: pinmux_P9_24_gpio_pd_pin { -+ pinctrl-single,pins = <0x184 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_24_uart_pin: pinmux_P9_24_uart_pin { -+ pinctrl-single,pins = <0x184 0x30>; }; /* Mode 0, Pull-Up, RxActive */ -+ P9_24_can_pin: pinmux_P9_24_can_pin { -+ pinctrl-single,pins = <0x184 0x32>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_24_i2c_pin: pinmux_P9_24_i2c_pin { -+ pinctrl-single,pins = <0x184 0x33>; }; /* Mode 3, Pull-Up, RxActive */ -+ P9_24_pruin_pin: pinmux_P9_24_pruin_pin { -+ pinctrl-single,pins = <0x184 0x36>; }; /* Mode 6, Pull-Up, RxActive */ -+ -+ /* P9_25 (ZCZ ball A14) Audio */ -+ P9_25_default_pin: pinmux_P9_25_default_pin { -+ pinctrl-single,pins = <0x1ac 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_25_gpio_pin: pinmux_P9_25_gpio_pin { -+ pinctrl-single,pins = <0x1ac 0x2F>; }; /* Mode 7, RxActive */ -+ P9_25_gpio_pu_pin: pinmux_P9_25_gpio_pu_pin { -+ pinctrl-single,pins = <0x1ac 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_25_gpio_pd_pin: pinmux_P9_25_gpio_pd_pin { -+ pinctrl-single,pins = <0x1ac 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_25_qep_pin: pinmux_P9_25_qep_pin { -+ pinctrl-single,pins = <0x1ac 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_25_pruout_pin: pinmux_P9_25_pruout_pin { -+ pinctrl-single,pins = <0x1ac 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_25_pruin_pin: pinmux_P9_25_pruin_pin { -+ pinctrl-single,pins = <0x1ac 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P9_25_audio_pin: pinmux_P9_25_audio_pin { -+ pinctrl-single,pins = <0x1ac (PIN_INPUT_PULLUP | MUX_MODE0)>; }; /* mcasp0_ahclkx.mcasp0_ahclkx */ -+ -+ /* P9_26 (ZCZ ball D16) */ -+ P9_26_default_pin: pinmux_P9_26_default_pin { -+ pinctrl-single,pins = <0x180 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_26_gpio_pin: pinmux_P9_26_gpio_pin { -+ pinctrl-single,pins = <0x180 0x2F>; }; /* Mode 7, RxActive */ -+ P9_26_gpio_pu_pin: pinmux_P9_26_gpio_pu_pin { -+ pinctrl-single,pins = <0x180 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_26_gpio_pd_pin: pinmux_P9_26_gpio_pd_pin { -+ pinctrl-single,pins = <0x180 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_26_uart_pin: pinmux_P9_26_uart_pin { -+ pinctrl-single,pins = <0x180 0x30>; }; /* Mode 0, Pull-Up, RxActive */ -+ P9_26_can_pin: pinmux_P9_26_can_pin { -+ pinctrl-single,pins = <0x180 0x12>; }; /* Mode 2, Pull-Up, RxActive */ -+ P9_26_i2c_pin: pinmux_P9_26_i2c_pin { -+ pinctrl-single,pins = <0x180 0x33>; }; /* Mode 3, Pull-Up, RxActive */ -+ P9_26_pruin_pin: pinmux_P9_26_pruin_pin { -+ pinctrl-single,pins = <0x180 0x36>; }; /* Mode 6, Pull-Up, RxActive */ -+ -+ /* P9_27 (ZCZ ball C13) */ -+ P9_27_default_pin: pinmux_P9_27_default_pin { -+ pinctrl-single,pins = <0x1a4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_27_gpio_pin: pinmux_P9_27_gpio_pin { -+ pinctrl-single,pins = <0x1a4 0x2F>; }; /* Mode 7, RxActive */ -+ P9_27_gpio_pu_pin: pinmux_P9_27_gpio_pu_pin { -+ pinctrl-single,pins = <0x1a4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_27_gpio_pd_pin: pinmux_P9_27_gpio_pd_pin { -+ pinctrl-single,pins = <0x1a4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_27_qep_pin: pinmux_P9_27_qep_pin { -+ pinctrl-single,pins = <0x1a4 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_27_pruout_pin: pinmux_P9_27_pruout_pin { -+ pinctrl-single,pins = <0x1a4 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_27_pruin_pin: pinmux_P9_27_pruin_pin { -+ pinctrl-single,pins = <0x1a4 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_28 (ZCZ ball C12) Audio */ -+ P9_28_default_pin: pinmux_P9_28_default_pin { -+ pinctrl-single,pins = <0x19c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_28_gpio_pin: pinmux_P9_28_gpio_pin { -+ pinctrl-single,pins = <0x19c 0x2F>; }; /* Mode 7, RxActive */ -+ P9_28_gpio_pu_pin: pinmux_P9_28_gpio_pu_pin { -+ pinctrl-single,pins = <0x19c 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_28_gpio_pd_pin: pinmux_P9_28_gpio_pd_pin { -+ pinctrl-single,pins = <0x19c 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_28_pwm_pin: pinmux_P9_28_pwm_pin { -+ pinctrl-single,pins = <0x19c 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_28_spi_pin: pinmux_P9_28_spi_pin { -+ pinctrl-single,pins = <0x19c 0x23>; }; /* Mode 3, Pull-Down, RxActive */ -+ P9_28_pwm2_pin: pinmux_P9_28_pwm2_pin { -+ pinctrl-single,pins = <0x19c 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ P9_28_pruout_pin: pinmux_P9_28_pruout_pin { -+ pinctrl-single,pins = <0x19c 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_28_pruin_pin: pinmux_P9_28_pruin_pin { -+ pinctrl-single,pins = <0x19c 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P9_28_audio_pin: pinmux_P9_28_audio_pin { -+ pinctrl-single,pins = <0x19c (PIN_OUTPUT_PULLDOWN | MUX_MODE2)>; }; /* mcasp0_ahclkr.mcasp0_axr2 */ -+ -+ /* P9_29 (ZCZ ball B13) Audio */ -+ P9_29_default_pin: pinmux_P9_29_default_pin { -+ pinctrl-single,pins = <0x194 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_29_gpio_pin: pinmux_P9_29_gpio_pin { -+ pinctrl-single,pins = <0x194 0x2F>; }; /* Mode 7, RxActive */ -+ P9_29_gpio_pu_pin: pinmux_P9_29_gpio_pu_pin { -+ pinctrl-single,pins = <0x194 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_29_gpio_pd_pin: pinmux_P9_29_gpio_pd_pin { -+ pinctrl-single,pins = <0x194 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_29_pwm_pin: pinmux_P9_29_pwm_pin { -+ pinctrl-single,pins = <0x194 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_29_spi_pin: pinmux_P9_29_spi_pin { -+ pinctrl-single,pins = <0x194 0x23>; }; /* Mode 3, Pull-Down, RxActive */ -+ P9_29_pruout_pin: pinmux_P9_29_pruout_pin { -+ pinctrl-single,pins = <0x194 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_29_pruin_pin: pinmux_P9_29_pruin_pin { -+ pinctrl-single,pins = <0x194 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P9_29_audio_pin: pinmux_P9_29_audio_pin { -+ pinctrl-single,pins = <0x194 (PIN_OUTPUT_PULLUP | MUX_MODE0)>; }; /* mcasp0_fsx.mcasp0_fsx */ -+ -+ /* P9_30 (ZCZ ball D12) */ -+ P9_30_default_pin: pinmux_P9_30_default_pin { -+ pinctrl-single,pins = <0x198 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_30_gpio_pin: pinmux_P9_30_gpio_pin { -+ pinctrl-single,pins = <0x198 0x2F>; }; /* Mode 7, RxActive */ -+ P9_30_gpio_pu_pin: pinmux_P9_30_gpio_pu_pin { -+ pinctrl-single,pins = <0x198 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_30_gpio_pd_pin: pinmux_P9_30_gpio_pd_pin { -+ pinctrl-single,pins = <0x198 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_30_pwm_pin: pinmux_P9_30_pwm_pin { -+ pinctrl-single,pins = <0x198 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_30_spi_pin: pinmux_P9_30_spi_pin { -+ pinctrl-single,pins = <0x198 0x23>; }; /* Mode 3, Pull-Down, RxActive */ -+ P9_30_pruout_pin: pinmux_P9_30_pruout_pin { -+ pinctrl-single,pins = <0x198 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_30_pruin_pin: pinmux_P9_30_pruin_pin { -+ pinctrl-single,pins = <0x198 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_31 (ZCZ ball A13) Audio */ -+ P9_31_default_pin: pinmux_P9_31_default_pin { -+ pinctrl-single,pins = <0x190 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_31_gpio_pin: pinmux_P9_31_gpio_pin { -+ pinctrl-single,pins = <0x190 0x2F>; }; /* Mode 7, RxActive */ -+ P9_31_gpio_pu_pin: pinmux_P9_31_gpio_pu_pin { -+ pinctrl-single,pins = <0x190 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_31_gpio_pd_pin: pinmux_P9_31_gpio_pd_pin { -+ pinctrl-single,pins = <0x190 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_31_pwm_pin: pinmux_P9_31_pwm_pin { -+ pinctrl-single,pins = <0x190 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_31_spi_pin: pinmux_P9_31_spi_pin { -+ pinctrl-single,pins = <0x190 0x23>; }; /* Mode 3, Pull-Down, RxActive */ -+ P9_31_pruout_pin: pinmux_P9_31_pruout_pin { -+ pinctrl-single,pins = <0x190 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_31_pruin_pin: pinmux_P9_31_pruin_pin { -+ pinctrl-single,pins = <0x190 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ P9_31_audio_pin: pinmux_P9_31_audio_pin { -+ pinctrl-single,pins = <0x190 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)>; }; /* mcasp0_aclkx.mcasp0_aclkx */ -+ -+ /* P9_32 VADC */ -+ /* P9_33 (ZCZ ball C8 ) AIN4 */ -+ /* P9_34 AGND */ -+ /* P9_35 (ZCZ ball A8 ) AIN6 */ -+ /* P9_36 (ZCZ ball B8 ) AIN5 */ -+ /* P9_37 (ZCZ ball B7 ) AIN2 */ -+ /* P9_38 (ZCZ ball A7 ) AIN3 */ -+ /* P9_39 (ZCZ ball B6 ) AIN0 */ -+ /* P9_40 (ZCZ ball C7 ) AIN1 */ -+ -+ /* P9_41 (ZCZ ball D14) */ -+ P9_41_default_pin: pinmux_P9_41_default_pin { -+ pinctrl-single,pins = <0x1b4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_41_gpio_pin: pinmux_P9_41_gpio_pin { -+ pinctrl-single,pins = <0x1b4 0x2F>; }; /* Mode 7, RxActive */ -+ P9_41_gpio_pu_pin: pinmux_P9_41_gpio_pu_pin { -+ pinctrl-single,pins = <0x1b4 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_41_gpio_pd_pin: pinmux_P9_41_gpio_pd_pin { -+ pinctrl-single,pins = <0x1b4 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_41_timer_pin: pinmux_P9_41_timer_pin { -+ pinctrl-single,pins = <0x1b4 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ P9_41_pruin_pin: pinmux_P9_41_pruin_pin { -+ pinctrl-single,pins = <0x1b4 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ -+ /* P9_41.1 */ -+ /* P9_91 (ZCZ ball D13) */ -+ P9_91_default_pin: pinmux_P9_91_default_pin { -+ pinctrl-single,pins = <0x1a8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_91_gpio_pin: pinmux_P9_91_gpio_pin { -+ pinctrl-single,pins = <0x1a8 0x2F>; }; /* Mode 7, RxActive */ -+ P9_91_gpio_pu_pin: pinmux_P9_91_gpio_pu_pin { -+ pinctrl-single,pins = <0x1a8 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_91_gpio_pd_pin: pinmux_P9_91_gpio_pd_pin { -+ pinctrl-single,pins = <0x1a8 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_91_qep_pin: pinmux_P9_91_qep_pin { -+ pinctrl-single,pins = <0x1a8 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_91_pruout_pin: pinmux_P9_91_pruout_pin { -+ pinctrl-single,pins = <0x1a8 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_91_pruin_pin: pinmux_P9_91_pruin_pin { -+ pinctrl-single,pins = <0x1a8 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_42 (ZCZ ball C18) */ -+ P9_42_default_pin: pinmux_P9_42_default_pin { -+ pinctrl-single,pins = <0x164 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_42_gpio_pin: pinmux_P9_42_gpio_pin { -+ pinctrl-single,pins = <0x164 0x2F>; }; /* Mode 7, RxActive */ -+ P9_42_gpio_pu_pin: pinmux_P9_42_gpio_pu_pin { -+ pinctrl-single,pins = <0x164 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_42_gpio_pd_pin: pinmux_P9_42_gpio_pd_pin { -+ pinctrl-single,pins = <0x164 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_42_pwm_pin: pinmux_P9_42_pwm_pin { -+ pinctrl-single,pins = <0x164 0x20>; }; /* Mode 0, Pull-Down, RxActive */ -+ P9_42_uart_pin: pinmux_P9_42_uart_pin { -+ pinctrl-single,pins = <0x164 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_42_spics_pin: pinmux_P9_42_spics_pin { -+ pinctrl-single,pins = <0x164 0x22>; }; /* Mode 2, Pull-Down, RxActive */ -+ P9_42_spiclk_pin: pinmux_P9_42_spiclk_pin { -+ pinctrl-single,pins = <0x164 0x24>; }; /* Mode 4, Pull-Down, RxActive */ -+ -+ /* P9_42.1 */ -+ /* P9_92 (ZCZ ball B12) */ -+ P9_92_default_pin: pinmux_P9_92_default_pin { -+ pinctrl-single,pins = <0x1a0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_92_gpio_pin: pinmux_P9_92_gpio_pin { -+ pinctrl-single,pins = <0x1a0 0x2F>; }; /* Mode 7, RxActive */ -+ P9_92_gpio_pu_pin: pinmux_P9_92_gpio_pu_pin { -+ pinctrl-single,pins = <0x1a0 0x37>; }; /* Mode 7, Pull-Up, RxActive */ -+ P9_92_gpio_pd_pin: pinmux_P9_92_gpio_pd_pin { -+ pinctrl-single,pins = <0x1a0 0x27>; }; /* Mode 7, Pull-Down, RxActive */ -+ P9_92_qep_pin: pinmux_P9_92_qep_pin { -+ pinctrl-single,pins = <0x1a0 0x21>; }; /* Mode 1, Pull-Down, RxActive */ -+ P9_92_pruout_pin: pinmux_P9_92_pruout_pin { -+ pinctrl-single,pins = <0x1a0 0x25>; }; /* Mode 5, Pull-Down, RxActive */ -+ P9_92_pruin_pin: pinmux_P9_92_pruin_pin { -+ pinctrl-single,pins = <0x1a0 0x26>; }; /* Mode 6, Pull-Down, RxActive */ -+ -+ /* P9_43 GND */ -+ /* P9_44 GND */ -+ /* P9_45 GND */ -+ /* P9_46 GND */ -+}; -+ -+/**********************************************************************/ -+/* Pin Multiplex Helpers */ -+/* */ -+/* These provide userspace runtime pin configuration for the */ -+/* BeagleBone cape expansion headers */ -+/**********************************************************************/ -+ -+&ocp { -+ /************************/ -+ /* P8 Header */ -+ /************************/ -+ -+ P8_07_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer"; -+ pinctrl-0 = <&P8_07_default_pin>; -+ pinctrl-1 = <&P8_07_gpio_pin>; -+ pinctrl-2 = <&P8_07_gpio_pu_pin>; -+ pinctrl-3 = <&P8_07_gpio_pd_pin>; -+ pinctrl-4 = <&P8_07_timer_pin>; -+ }; -+ -+ P8_08_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer"; -+ pinctrl-0 = <&P8_08_default_pin>; -+ pinctrl-1 = <&P8_08_gpio_pin>; -+ pinctrl-2 = <&P8_08_gpio_pu_pin>; -+ pinctrl-3 = <&P8_08_gpio_pd_pin>; -+ pinctrl-4 = <&P8_08_timer_pin>; -+ }; -+ -+ P8_09_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer"; -+ pinctrl-0 = <&P8_09_default_pin>; -+ pinctrl-1 = <&P8_09_gpio_pin>; -+ pinctrl-2 = <&P8_09_gpio_pu_pin>; -+ pinctrl-3 = <&P8_09_gpio_pd_pin>; -+ pinctrl-4 = <&P8_09_timer_pin>; -+ }; -+ -+ P8_10_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer"; -+ pinctrl-0 = <&P8_10_default_pin>; -+ pinctrl-1 = <&P8_10_gpio_pin>; -+ pinctrl-2 = <&P8_10_gpio_pu_pin>; -+ pinctrl-3 = <&P8_10_gpio_pd_pin>; -+ pinctrl-4 = <&P8_10_timer_pin>; -+ }; -+ -+ P8_11_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "qep"; -+ pinctrl-0 = <&P8_11_default_pin>; -+ pinctrl-1 = <&P8_11_gpio_pin>; -+ pinctrl-2 = <&P8_11_gpio_pu_pin>; -+ pinctrl-3 = <&P8_11_gpio_pd_pin>; -+ pinctrl-4 = <&P8_11_pruout_pin>; -+ pinctrl-5 = <&P8_11_qep_pin>; -+ }; -+ -+ P8_12_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "qep"; -+ pinctrl-0 = <&P8_12_default_pin>; -+ pinctrl-1 = <&P8_12_gpio_pin>; -+ pinctrl-2 = <&P8_12_gpio_pu_pin>; -+ pinctrl-3 = <&P8_12_gpio_pd_pin>; -+ pinctrl-4 = <&P8_12_pruout_pin>; -+ pinctrl-5 = <&P8_12_qep_pin>; -+ }; -+ -+ P8_13_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; -+ pinctrl-0 = <&P8_13_default_pin>; -+ pinctrl-1 = <&P8_13_gpio_pin>; -+ pinctrl-2 = <&P8_13_gpio_pu_pin>; -+ pinctrl-3 = <&P8_13_gpio_pd_pin>; -+ pinctrl-4 = <&P8_13_pwm_pin>; -+ }; -+ -+ P8_14_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; -+ pinctrl-0 = <&P8_14_default_pin>; -+ pinctrl-1 = <&P8_14_gpio_pin>; -+ pinctrl-2 = <&P8_14_gpio_pu_pin>; -+ pinctrl-3 = <&P8_14_gpio_pd_pin>; -+ pinctrl-4 = <&P8_14_pwm_pin>; -+ }; -+ -+ P8_15_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruin", "qep"; -+ pinctrl-0 = <&P8_15_default_pin>; -+ pinctrl-1 = <&P8_15_gpio_pin>; -+ pinctrl-2 = <&P8_15_gpio_pu_pin>; -+ pinctrl-3 = <&P8_15_gpio_pd_pin>; -+ pinctrl-4 = <&P8_15_pruin_pin>; -+ pinctrl-5 = <&P8_15_qep_pin>; -+ }; -+ -+ P8_16_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruin", "qep"; -+ pinctrl-0 = <&P8_16_default_pin>; -+ pinctrl-1 = <&P8_16_gpio_pin>; -+ pinctrl-2 = <&P8_16_gpio_pu_pin>; -+ pinctrl-3 = <&P8_16_gpio_pd_pin>; -+ pinctrl-4 = <&P8_16_pruin_pin>; -+ pinctrl-5 = <&P8_16_qep_pin>; -+ }; -+ -+ P8_17_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; -+ pinctrl-0 = <&P8_17_default_pin>; -+ pinctrl-1 = <&P8_17_gpio_pin>; -+ pinctrl-2 = <&P8_17_gpio_pu_pin>; -+ pinctrl-3 = <&P8_17_gpio_pd_pin>; -+ pinctrl-4 = <&P8_17_pwm_pin>; -+ }; -+ -+ P8_18_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio"; -+ pinctrl-0 = <&P8_18_default_pin>; -+ pinctrl-1 = <&P8_18_gpio_pin>; -+ pinctrl-2 = <&P8_18_gpio_pu_pin>; -+ pinctrl-3 = <&P8_18_gpio_pd_pin>; -+ }; -+ -+ P8_19_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; -+ pinctrl-0 = <&P8_19_default_pin>; -+ pinctrl-1 = <&P8_19_gpio_pin>; -+ pinctrl-2 = <&P8_19_gpio_pu_pin>; -+ pinctrl-3 = <&P8_19_gpio_pd_pin>; -+ pinctrl-4 = <&P8_19_pwm_pin>; -+ }; -+ -+ P8_26_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio"; -+ pinctrl-0 = <&P8_26_default_pin>; -+ pinctrl-1 = <&P8_26_gpio_pin>; -+ pinctrl-2 = <&P8_26_gpio_pu_pin>; -+ pinctrl-3 = <&P8_26_gpio_pd_pin>; -+ }; -+ -+ P8_27_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin", "hdmi"; -+ pinctrl-0 = <&P8_27_default_pin>; -+ pinctrl-1 = <&P8_27_gpio_pin>; -+ pinctrl-2 = <&P8_27_gpio_pu_pin>; -+ pinctrl-3 = <&P8_27_gpio_pd_pin>; -+ pinctrl-4 = <&P8_27_pruout_pin>; -+ pinctrl-5 = <&P8_27_pruin_pin>; -+ pinctrl-6 = <&P8_27_hdmi_pin>; -+ }; -+ -+ P8_28_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin", "hdmi"; -+ pinctrl-0 = <&P8_28_default_pin>; -+ pinctrl-1 = <&P8_28_gpio_pin>; -+ pinctrl-2 = <&P8_28_gpio_pu_pin>; -+ pinctrl-3 = <&P8_28_gpio_pd_pin>; -+ pinctrl-4 = <&P8_28_pruout_pin>; -+ pinctrl-5 = <&P8_28_pruin_pin>; -+ pinctrl-6 = <&P8_28_hdmi_pin>; -+ }; -+ -+ P8_29_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin", "hdmi"; -+ pinctrl-0 = <&P8_29_default_pin>; -+ pinctrl-1 = <&P8_29_gpio_pin>; -+ pinctrl-2 = <&P8_29_gpio_pu_pin>; -+ pinctrl-3 = <&P8_29_gpio_pd_pin>; -+ pinctrl-4 = <&P8_29_pruout_pin>; -+ pinctrl-5 = <&P8_29_pruin_pin>; -+ pinctrl-6 = <&P8_29_hdmi_pin>; -+ }; -+ -+ P8_30_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin", "hdmi"; -+ pinctrl-0 = <&P8_30_default_pin>; -+ pinctrl-1 = <&P8_30_gpio_pin>; -+ pinctrl-2 = <&P8_30_gpio_pu_pin>; -+ pinctrl-3 = <&P8_30_gpio_pd_pin>; -+ pinctrl-4 = <&P8_30_pruout_pin>; -+ pinctrl-5 = <&P8_30_pruin_pin>; -+ pinctrl-6 = <&P8_30_hdmi_pin>; -+ }; -+ -+ P8_31_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd","uart", "hdmi"; -+ pinctrl-0 = <&P8_31_default_pin>; -+ pinctrl-1 = <&P8_31_gpio_pin>; -+ pinctrl-2 = <&P8_31_gpio_pu_pin>; -+ pinctrl-3 = <&P8_31_gpio_pd_pin>; -+ pinctrl-4 = <&P8_31_uart_pin>; -+ pinctrl-5 = <&P8_31_hdmi_pin>; -+ }; -+ -+ P8_32_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "hdmi"; -+ pinctrl-0 = <&P8_32_default_pin>; -+ pinctrl-1 = <&P8_32_gpio_pin>; -+ pinctrl-2 = <&P8_32_gpio_pu_pin>; -+ pinctrl-3 = <&P8_32_gpio_pd_pin>; -+ pinctrl-4 = <&P8_32_hdmi_pin>; -+ }; -+ -+ P8_33_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "hdmi"; -+ pinctrl-0 = <&P8_33_default_pin>; -+ pinctrl-1 = <&P8_33_gpio_pin>; -+ pinctrl-2 = <&P8_33_gpio_pu_pin>; -+ pinctrl-3 = <&P8_33_gpio_pd_pin>; -+ pinctrl-4 = <&P8_33_hdmi_pin>; -+ }; -+ -+ P8_34_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd","pwm", "hdmi"; -+ pinctrl-0 = <&P8_34_default_pin>; -+ pinctrl-1 = <&P8_34_gpio_pin>; -+ pinctrl-2 = <&P8_34_gpio_pu_pin>; -+ pinctrl-3 = <&P8_34_gpio_pd_pin>; -+ pinctrl-4 = <&P8_34_pwm_pin>; -+ pinctrl-5 = <&P8_34_hdmi_pin>; -+ }; -+ -+ P8_35_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "hdmi"; -+ pinctrl-0 = <&P8_35_default_pin>; -+ pinctrl-1 = <&P8_35_gpio_pin>; -+ pinctrl-2 = <&P8_35_gpio_pu_pin>; -+ pinctrl-3 = <&P8_35_gpio_pd_pin>; -+ pinctrl-4 = <&P8_35_hdmi_pin>; -+ }; -+ -+ P8_36_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd","pwm", "hdmi"; -+ pinctrl-0 = <&P8_36_default_pin>; -+ pinctrl-1 = <&P8_36_gpio_pin>; -+ pinctrl-2 = <&P8_36_gpio_pu_pin>; -+ pinctrl-3 = <&P8_36_gpio_pd_pin>; -+ pinctrl-4 = <&P8_36_pwm_pin>; -+ pinctrl-5 = <&P8_36_hdmi_pin>; -+ }; -+ -+ P8_37_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd","uart","pwm", "hdmi"; -+ pinctrl-0 = <&P8_37_default_pin>; -+ pinctrl-1 = <&P8_37_gpio_pin>; -+ pinctrl-2 = <&P8_37_gpio_pu_pin>; -+ pinctrl-3 = <&P8_37_gpio_pd_pin>; -+ pinctrl-4 = <&P8_37_uart_pin>; -+ pinctrl-5 = <&P8_37_pwm_pin>; -+ pinctrl-6 = <&P8_37_hdmi_pin>; -+ }; -+ -+ P8_38_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd","uart","pwm", "hdmi"; -+ pinctrl-0 = <&P8_38_default_pin>; -+ pinctrl-1 = <&P8_38_gpio_pin>; -+ pinctrl-2 = <&P8_38_gpio_pu_pin>; -+ pinctrl-3 = <&P8_38_gpio_pd_pin>; -+ pinctrl-4 = <&P8_38_uart_pin>; -+ pinctrl-5 = <&P8_38_pwm_pin>; -+ pinctrl-6 = <&P8_38_hdmi_pin>; -+ }; -+ -+ P8_39_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin", "hdmi"; -+ pinctrl-0 = <&P8_39_default_pin>; -+ pinctrl-1 = <&P8_39_gpio_pin>; -+ pinctrl-2 = <&P8_39_gpio_pu_pin>; -+ pinctrl-3 = <&P8_39_gpio_pd_pin>; -+ pinctrl-4 = <&P8_39_pruout_pin>; -+ pinctrl-5 = <&P8_39_pruin_pin>; -+ pinctrl-6 = <&P8_39_hdmi_pin>; -+ }; -+ -+ P8_40_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin", "hdmi"; -+ pinctrl-0 = <&P8_40_default_pin>; -+ pinctrl-1 = <&P8_40_gpio_pin>; -+ pinctrl-2 = <&P8_40_gpio_pu_pin>; -+ pinctrl-3 = <&P8_40_gpio_pd_pin>; -+ pinctrl-4 = <&P8_40_pruout_pin>; -+ pinctrl-5 = <&P8_40_pruin_pin>; -+ pinctrl-6 = <&P8_40_hdmi_pin>; -+ }; -+ -+ P8_41_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin", "hdmi"; -+ pinctrl-0 = <&P8_41_default_pin>; -+ pinctrl-1 = <&P8_41_gpio_pin>; -+ pinctrl-2 = <&P8_41_gpio_pu_pin>; -+ pinctrl-3 = <&P8_41_gpio_pd_pin>; -+ pinctrl-4 = <&P8_41_pruout_pin>; -+ pinctrl-5 = <&P8_41_pruin_pin>; -+ pinctrl-6 = <&P8_41_hdmi_pin>; -+ }; -+ -+ P8_42_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin", "hdmi"; -+ pinctrl-0 = <&P8_42_default_pin>; -+ pinctrl-1 = <&P8_42_gpio_pin>; -+ pinctrl-2 = <&P8_42_gpio_pu_pin>; -+ pinctrl-3 = <&P8_42_gpio_pd_pin>; -+ pinctrl-4 = <&P8_42_pruout_pin>; -+ pinctrl-5 = <&P8_42_pruin_pin>; -+ pinctrl-6 = <&P8_42_hdmi_pin>; -+ }; -+ -+ P8_43_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin","pwm", "hdmi"; -+ pinctrl-0 = <&P8_43_default_pin>; -+ pinctrl-1 = <&P8_43_gpio_pin>; -+ pinctrl-2 = <&P8_43_gpio_pu_pin>; -+ pinctrl-3 = <&P8_43_gpio_pd_pin>; -+ pinctrl-4 = <&P8_43_pruout_pin>; -+ pinctrl-5 = <&P8_43_pruin_pin>; -+ pinctrl-6 = <&P8_43_pwm_pin>; -+ pinctrl-7 = <&P8_43_hdmi_pin>; -+ }; -+ -+ P8_44_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin","pwm", "hdmi"; -+ pinctrl-0 = <&P8_44_default_pin>; -+ pinctrl-1 = <&P8_44_gpio_pin>; -+ pinctrl-2 = <&P8_44_gpio_pu_pin>; -+ pinctrl-3 = <&P8_44_gpio_pd_pin>; -+ pinctrl-4 = <&P8_44_pruout_pin>; -+ pinctrl-5 = <&P8_44_pruin_pin>; -+ pinctrl-6 = <&P8_44_pwm_pin>; -+ pinctrl-7 = <&P8_44_hdmi_pin>; -+ }; -+ -+ P8_45_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin","pwm", "hdmi"; -+ pinctrl-0 = <&P8_45_default_pin>; -+ pinctrl-1 = <&P8_45_gpio_pin>; -+ pinctrl-2 = <&P8_45_gpio_pu_pin>; -+ pinctrl-3 = <&P8_45_gpio_pd_pin>; -+ pinctrl-4 = <&P8_45_pruout_pin>; -+ pinctrl-5 = <&P8_45_pruin_pin>; -+ pinctrl-6 = <&P8_45_pwm_pin>; -+ pinctrl-7 = <&P8_45_hdmi_pin>; -+ }; -+ -+ P8_46_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pruout", "pruin","pwm", "hdmi"; -+ pinctrl-0 = <&P8_46_default_pin>; -+ pinctrl-1 = <&P8_46_gpio_pin>; -+ pinctrl-2 = <&P8_46_gpio_pu_pin>; -+ pinctrl-3 = <&P8_46_gpio_pd_pin>; -+ pinctrl-4 = <&P8_46_pruout_pin>; -+ pinctrl-5 = <&P8_46_pruin_pin>; -+ pinctrl-6 = <&P8_46_pwm_pin>; -+ pinctrl-7 = <&P8_46_hdmi_pin>; -+ }; -+ -+ /************************/ -+ /* P9 Header */ -+ /************************/ -+ -+ P9_11_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart"; -+ pinctrl-0 = <&P9_11_default_pin>; -+ pinctrl-1 = <&P9_11_gpio_pin>; -+ pinctrl-2 = <&P9_11_gpio_pu_pin>; -+ pinctrl-3 = <&P9_11_gpio_pd_pin>; -+ pinctrl-4 = <&P9_11_uart_pin>; -+ }; -+ -+ P9_12_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio"; -+ pinctrl-0 = <&P9_12_default_pin>; -+ pinctrl-1 = <&P9_12_gpio_pin>; -+ pinctrl-2 = <&P9_12_gpio_pu_pin>; -+ pinctrl-3 = <&P9_12_gpio_pd_pin>; -+ }; -+ -+ P9_13_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart"; -+ pinctrl-0 = <&P9_13_default_pin>; -+ pinctrl-1 = <&P9_13_gpio_pin>; -+ pinctrl-2 = <&P9_13_gpio_pu_pin>; -+ pinctrl-3 = <&P9_13_gpio_pd_pin>; -+ pinctrl-4 = <&P9_13_uart_pin>; -+ }; -+ -+ P9_14_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; -+ pinctrl-0 = <&P9_14_default_pin>; -+ pinctrl-1 = <&P9_14_gpio_pin>; -+ pinctrl-2 = <&P9_14_gpio_pu_pin>; -+ pinctrl-3 = <&P9_14_gpio_pd_pin>; -+ pinctrl-4 = <&P9_14_pwm_pin>; -+ }; -+ -+ P9_15_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; -+ pinctrl-0 = <&P9_15_default_pin>; -+ pinctrl-1 = <&P9_15_gpio_pin>; -+ pinctrl-2 = <&P9_15_gpio_pu_pin>; -+ pinctrl-3 = <&P9_15_gpio_pd_pin>; -+ pinctrl-4 = <&P9_15_pwm_pin>; -+ }; -+ -+ P9_16_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; -+ pinctrl-0 = <&P9_16_default_pin>; -+ pinctrl-1 = <&P9_16_gpio_pin>; -+ pinctrl-2 = <&P9_16_gpio_pu_pin>; -+ pinctrl-3 = <&P9_16_gpio_pd_pin>; -+ pinctrl-4 = <&P9_16_pwm_pin>; -+ }; -+ -+ P9_17_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "i2c", "pwm"; -+ pinctrl-0 = <&P9_17_default_pin>; -+ pinctrl-1 = <&P9_17_gpio_pin>; -+ pinctrl-2 = <&P9_17_gpio_pu_pin>; -+ pinctrl-3 = <&P9_17_gpio_pd_pin>; -+ pinctrl-4 = <&P9_17_spi_pin>; -+ pinctrl-5 = <&P9_17_i2c_pin>; -+ pinctrl-6 = <&P9_17_pwm_pin>; -+ }; -+ -+ P9_18_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "i2c", "pwm"; -+ pinctrl-0 = <&P9_18_default_pin>; -+ pinctrl-1 = <&P9_18_gpio_pin>; -+ pinctrl-2 = <&P9_18_gpio_pu_pin>; -+ pinctrl-3 = <&P9_18_gpio_pd_pin>; -+ pinctrl-4 = <&P9_18_spi_pin>; -+ pinctrl-5 = <&P9_18_i2c_pin>; -+ pinctrl-6 = <&P9_18_pwm_pin>; -+ }; -+ -+ P9_19_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "can", "i2c"; -+ pinctrl-0 = <&P9_19_default_pin>; -+ pinctrl-1 = <&P9_19_gpio_pin>; -+ pinctrl-2 = <&P9_19_gpio_pu_pin>; -+ pinctrl-3 = <&P9_19_gpio_pd_pin>; -+ pinctrl-4 = <&P9_19_can_pin>; -+ pinctrl-5 = <&P9_19_i2c_pin>; -+ }; -+ -+ P9_20_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "can", "i2c"; -+ pinctrl-0 = <&P9_20_default_pin>; -+ pinctrl-1 = <&P9_20_gpio_pin>; -+ pinctrl-2 = <&P9_20_gpio_pu_pin>; -+ pinctrl-3 = <&P9_20_gpio_pd_pin>; -+ pinctrl-4 = <&P9_20_can_pin>; -+ pinctrl-5 = <&P9_20_i2c_pin>; -+ }; -+ -+ P9_21_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm"; -+ pinctrl-0 = <&P9_21_default_pin>; -+ pinctrl-1 = <&P9_21_gpio_pin>; -+ pinctrl-2 = <&P9_21_gpio_pu_pin>; -+ pinctrl-3 = <&P9_21_gpio_pd_pin>; -+ pinctrl-4 = <&P9_21_spi_pin>; -+ pinctrl-5 = <&P9_21_uart_pin>; -+ pinctrl-6 = <&P9_21_i2c_pin>; -+ pinctrl-7 = <&P9_21_pwm_pin>; -+ }; -+ -+ P9_22_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm"; -+ pinctrl-0 = <&P9_22_default_pin>; -+ pinctrl-1 = <&P9_22_gpio_pin>; -+ pinctrl-2 = <&P9_22_gpio_pu_pin>; -+ pinctrl-3 = <&P9_22_gpio_pd_pin>; -+ pinctrl-4 = <&P9_22_spi_pin>; -+ pinctrl-5 = <&P9_22_uart_pin>; -+ pinctrl-6 = <&P9_22_i2c_pin>; -+ pinctrl-7 = <&P9_22_pwm_pin>; -+ }; -+ -+ P9_23_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; -+ pinctrl-0 = <&P9_23_default_pin>; -+ pinctrl-1 = <&P9_23_gpio_pin>; -+ pinctrl-2 = <&P9_23_gpio_pu_pin>; -+ pinctrl-3 = <&P9_23_gpio_pd_pin>; -+ pinctrl-4 = <&P9_23_pwm_pin>; -+ }; -+ -+ P9_24_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pruin"; -+ pinctrl-0 = <&P9_24_default_pin>; -+ pinctrl-1 = <&P9_24_gpio_pin>; -+ pinctrl-2 = <&P9_24_gpio_pu_pin>; -+ pinctrl-3 = <&P9_24_gpio_pd_pin>; -+ pinctrl-4 = <&P9_24_uart_pin>; -+ pinctrl-5 = <&P9_24_can_pin>; -+ pinctrl-6 = <&P9_24_i2c_pin>; -+ pinctrl-7 = <&P9_24_pruin_pin>; -+ }; -+ -+ P9_25_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "qep", "pruout", "pruin", "audio"; -+ pinctrl-0 = <&P9_25_default_pin>; -+ pinctrl-1 = <&P9_25_gpio_pin>; -+ pinctrl-2 = <&P9_25_gpio_pu_pin>; -+ pinctrl-3 = <&P9_25_gpio_pd_pin>; -+ pinctrl-4 = <&P9_25_qep_pin>; -+ pinctrl-5 = <&P9_25_pruout_pin>; -+ pinctrl-6 = <&P9_25_pruin_pin>; -+ pinctrl-7 = <&P9_25_audio_pin>; -+ }; -+ -+ P9_26_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pruin"; -+ pinctrl-0 = <&P9_26_default_pin>; -+ pinctrl-1 = <&P9_26_gpio_pin>; -+ pinctrl-2 = <&P9_26_gpio_pu_pin>; -+ pinctrl-3 = <&P9_26_gpio_pd_pin>; -+ pinctrl-4 = <&P9_26_uart_pin>; -+ pinctrl-5 = <&P9_26_can_pin>; -+ pinctrl-6 = <&P9_26_i2c_pin>; -+ pinctrl-7 = <&P9_26_pruin_pin>; -+ }; -+ -+ P9_27_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "qep", "pruout", "pruin"; -+ pinctrl-0 = <&P9_27_default_pin>; -+ pinctrl-1 = <&P9_27_gpio_pin>; -+ pinctrl-2 = <&P9_27_gpio_pu_pin>; -+ pinctrl-3 = <&P9_27_gpio_pd_pin>; -+ pinctrl-4 = <&P9_27_qep_pin>; -+ pinctrl-5 = <&P9_27_pruout_pin>; -+ pinctrl-6 = <&P9_27_pruin_pin>; -+ }; -+ -+ P9_28_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pwm2", "pruout", "pruin", "audio"; -+ pinctrl-0 = <&P9_28_default_pin>; -+ pinctrl-1 = <&P9_28_gpio_pin>; -+ pinctrl-2 = <&P9_28_gpio_pu_pin>; -+ pinctrl-3 = <&P9_28_gpio_pd_pin>; -+ pinctrl-4 = <&P9_28_pwm_pin>; -+ pinctrl-5 = <&P9_28_spi_pin>; -+ pinctrl-6 = <&P9_28_pwm2_pin>; -+ pinctrl-7 = <&P9_28_pruout_pin>; -+ pinctrl-8 = <&P9_28_pruin_pin>; -+ pinctrl-9 = <&P9_28_audio_pin>; -+ }; -+ -+ P9_29_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin", "audio"; -+ pinctrl-0 = <&P9_29_default_pin>; -+ pinctrl-1 = <&P9_29_gpio_pin>; -+ pinctrl-2 = <&P9_29_gpio_pu_pin>; -+ pinctrl-3 = <&P9_29_gpio_pd_pin>; -+ pinctrl-4 = <&P9_29_pwm_pin>; -+ pinctrl-5 = <&P9_29_spi_pin>; -+ pinctrl-6 = <&P9_29_pruout_pin>; -+ pinctrl-7 = <&P9_29_pruin_pin>; -+ pinctrl-8 = <&P9_29_audio_pin>; -+ }; -+ -+ P9_30_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin"; -+ pinctrl-0 = <&P9_30_default_pin>; -+ pinctrl-1 = <&P9_30_gpio_pin>; -+ pinctrl-2 = <&P9_30_gpio_pu_pin>; -+ pinctrl-3 = <&P9_30_gpio_pd_pin>; -+ pinctrl-4 = <&P9_30_pwm_pin>; -+ pinctrl-5 = <&P9_30_spi_pin>; -+ pinctrl-6 = <&P9_30_pruout_pin>; -+ pinctrl-7 = <&P9_30_pruin_pin>; -+ }; -+ -+ P9_31_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin", "audio"; -+ pinctrl-0 = <&P9_31_default_pin>; -+ pinctrl-1 = <&P9_31_gpio_pin>; -+ pinctrl-2 = <&P9_31_gpio_pu_pin>; -+ pinctrl-3 = <&P9_31_gpio_pd_pin>; -+ pinctrl-4 = <&P9_31_pwm_pin>; -+ pinctrl-5 = <&P9_31_spi_pin>; -+ pinctrl-6 = <&P9_31_pruout_pin>; -+ pinctrl-7 = <&P9_31_pruin_pin>; -+ pinctrl-8 = <&P9_31_audio_pin>; -+ }; -+ -+ P9_41_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "timer", "pruin"; -+ pinctrl-0 = <&P9_41_default_pin>; -+ pinctrl-1 = <&P9_41_gpio_pin>; -+ pinctrl-2 = <&P9_41_gpio_pu_pin>; -+ pinctrl-3 = <&P9_41_gpio_pd_pin>; -+ pinctrl-4 = <&P9_41_timer_pin>; -+ pinctrl-5 = <&P9_41_pruin_pin>; -+ }; -+ -+ P9_91_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "qep", "pruout", "pruin"; -+ pinctrl-0 = <&P9_91_default_pin>; -+ pinctrl-1 = <&P9_91_gpio_pin>; -+ pinctrl-2 = <&P9_91_gpio_pu_pin>; -+ pinctrl-3 = <&P9_91_gpio_pd_pin>; -+ pinctrl-4 = <&P9_91_qep_pin>; -+ pinctrl-5 = <&P9_91_pruout_pin>; -+ pinctrl-6 = <&P9_91_pruin_pin>; -+ }; -+ -+ P9_42_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "uart", "spics", "spiclk"; -+ pinctrl-0 = <&P9_42_default_pin>; -+ pinctrl-1 = <&P9_42_gpio_pin>; -+ pinctrl-2 = <&P9_42_gpio_pu_pin>; -+ pinctrl-3 = <&P9_42_gpio_pd_pin>; -+ pinctrl-4 = <&P9_42_pwm_pin>; -+ pinctrl-5 = <&P9_42_uart_pin>; -+ pinctrl-6 = <&P9_42_spics_pin>; -+ pinctrl-7 = <&P9_42_spiclk_pin>; -+ }; -+ -+ P9_92_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "qep", "pruout", "pruin"; -+ pinctrl-0 = <&P9_92_default_pin>; -+ pinctrl-1 = <&P9_92_gpio_pin>; -+ pinctrl-2 = <&P9_92_gpio_pu_pin>; -+ pinctrl-3 = <&P9_92_gpio_pd_pin>; -+ pinctrl-4 = <&P9_92_qep_pin>; -+ pinctrl-5 = <&P9_92_pruout_pin>; -+ pinctrl-6 = <&P9_92_pruin_pin>; -+ }; -+ -+ cape-universal { -+ compatible = "gpio-of-helper"; -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <>; -+ -+ P8_07 { -+ gpio-name = "P8_07"; -+ gpio = <&gpio2 2 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_08 { -+ gpio-name = "P8_08"; -+ gpio = <&gpio2 3 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_09 { -+ gpio-name = "P8_09"; -+ gpio = <&gpio2 5 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_10 { -+ gpio-name = "P8_10"; -+ gpio = <&gpio2 4 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_11 { -+ gpio-name = "P8_11"; -+ gpio = <&gpio1 13 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_12 { -+ gpio-name = "P8_12"; -+ gpio = <&gpio1 12 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_13 { -+ gpio-name = "P8_13"; -+ gpio = <&gpio0 23 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_14 { -+ gpio-name = "P8_14"; -+ gpio = <&gpio0 26 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_15 { -+ gpio-name = "P8_15"; -+ gpio = <&gpio1 15 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_16 { -+ gpio-name = "P8_16"; -+ gpio = <&gpio1 14 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_17 { -+ gpio-name = "P8_17"; -+ gpio = <&gpio0 27 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_18 { -+ gpio-name = "P8_18"; -+ gpio = <&gpio2 1 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_19 { -+ gpio-name = "P8_19"; -+ gpio = <&gpio0 22 0>; -+ input; -+ dir-changeable; -+ }; -+ -+ P8_26 { -+ gpio-name = "P8_26"; -+ gpio = <&gpio1 29 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_27 { -+ gpio-name = "P8_27"; -+ gpio = <&gpio2 22 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_28 { -+ gpio-name = "P8_28"; -+ gpio = <&gpio2 24 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_29 { -+ gpio-name = "P8_29"; -+ gpio = <&gpio2 23 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_30 { -+ gpio-name = "P8_30"; -+ gpio = <&gpio2 25 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_31 { -+ gpio-name = "P8_31"; -+ gpio = <&gpio0 10 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_32 { -+ gpio-name = "P8_32"; -+ gpio = <&gpio0 11 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_33 { -+ gpio-name = "P8_33"; -+ gpio = <&gpio0 9 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_34 { -+ gpio-name = "P8_34"; -+ gpio = <&gpio2 17 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_35 { -+ gpio-name = "P8_35"; -+ gpio = <&gpio0 8 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_36 { -+ gpio-name = "P8_36"; -+ gpio = <&gpio2 16 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_37 { -+ gpio-name = "P8_37"; -+ gpio = <&gpio2 14 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_38 { -+ gpio-name = "P8_38"; -+ gpio = <&gpio2 15 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_39 { -+ gpio-name = "P8_39"; -+ gpio = <&gpio2 12 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_40 { -+ gpio-name = "P8_40"; -+ gpio = <&gpio2 13 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_41 { -+ gpio-name = "P8_41"; -+ gpio = <&gpio2 10 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_42 { -+ gpio-name = "P8_42"; -+ gpio = <&gpio2 11 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_43 { -+ gpio-name = "P8_43"; -+ gpio = <&gpio2 8 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_44 { -+ gpio-name = "P8_44"; -+ gpio = <&gpio2 9 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_45 { -+ gpio-name = "P8_45"; -+ gpio = <&gpio2 6 0>; -+ input; -+ dir-changeable; -+ }; -+ P8_46 { -+ gpio-name = "P8_46"; -+ gpio = <&gpio2 7 0>; -+ input; -+ dir-changeable; -+ }; -+ -+ -+ P9_11 { -+ gpio-name = "P9_11"; -+ gpio = <&gpio0 30 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_12 { -+ gpio-name = "P9_12"; -+ gpio = <&gpio1 28 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_13 { -+ gpio-name = "P9_13"; -+ gpio = <&gpio0 31 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_14 { -+ gpio-name = "P9_14"; -+ gpio = <&gpio1 18 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_15 { -+ gpio-name = "P9_15"; -+ gpio = <&gpio1 16 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_16 { -+ gpio-name = "P9_16"; -+ gpio = <&gpio1 19 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_17 { -+ gpio-name = "P9_17"; -+ gpio = <&gpio0 5 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_18 { -+ gpio-name = "P9_18"; -+ gpio = <&gpio0 4 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_19 { -+ gpio-name = "P9_19"; -+ gpio = <&gpio0 13 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_20 { -+ gpio-name = "P9_20"; -+ gpio = <&gpio0 12 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_21 { -+ gpio-name = "P9_21"; -+ gpio = <&gpio0 3 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_22 { -+ gpio-name = "P9_22"; -+ gpio = <&gpio0 2 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_23 { -+ gpio-name = "P9_23"; -+ gpio = <&gpio1 17 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_24 { -+ gpio-name = "P9_24"; -+ gpio = <&gpio0 15 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_25 { -+ gpio-name = "P9_25"; -+ gpio = <&gpio3 21 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_26 { -+ gpio-name = "P9_26"; -+ gpio = <&gpio0 14 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_27 { -+ gpio-name = "P9_27"; -+ gpio = <&gpio3 19 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_28 { -+ gpio-name = "P9_28"; -+ gpio = <&gpio3 17 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_29 { -+ gpio-name = "P9_29"; -+ gpio = <&gpio3 15 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_30 { -+ gpio-name = "P9_30"; -+ gpio = <&gpio3 16 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_31 { -+ gpio-name = "P9_31"; -+ gpio = <&gpio3 14 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_41 { -+ gpio-name = "P9_41"; -+ gpio = <&gpio0 20 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_91 { -+ gpio-name = "P9_91"; -+ gpio = <&gpio3 20 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_42 { -+ gpio-name = "P9_42"; -+ gpio = <&gpio0 7 0>; -+ input; -+ dir-changeable; -+ }; -+ P9_92 { -+ gpio-name = "P9_92"; -+ gpio = <&gpio3 18 0>; -+ input; -+ dir-changeable; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi -index 007b5e5..54a3b8d 100644 ---- a/arch/arm/boot/dts/am335x-bone-common.dtsi -+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi -@@ -6,6 +6,8 @@ - * published by the Free Software Foundation. - */ - -+#include <dt-bindings/mfd/tps65217.h> -+ - / { - cpus { - cpu@0 { -@@ -29,14 +31,14 @@ - compatible = "gpio-leds"; - - led2 { -- label = "beaglebone:green:heartbeat"; -+ label = "beaglebone:green:usr0"; - gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; - default-state = "off"; - }; - - led3 { -- label = "beaglebone:green:mmc0"; -+ label = "beaglebone:green:usr1"; - gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "mmc0"; - default-state = "off"; -@@ -66,9 +68,6 @@ - }; - - &am33xx_pinmux { -- pinctrl-names = "default"; -- pinctrl-0 = <&clkout2_pin>; -- - user_leds_s0: user_leds_s0 { - pinctrl-single,pins = < - AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */ -@@ -99,15 +98,11 @@ - >; - }; - -- clkout2_pin: pinmux_clkout2_pin { -- pinctrl-single,pins = < -- AM33XX_IOPAD(0x9b4, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */ -- >; -- }; -- - cpsw_default: cpsw_default { - pinctrl-single,pins = < - /* Slave 1 */ -+ 0x108 (PIN_INPUT | MUX_MODE0) /* mii1_col.mii1_col */ -+ 0x10c (PIN_INPUT | MUX_MODE0) /* mii1_crs.mii1_crs */ - AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxerr.mii1_rxerr */ - AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txen.mii1_txen */ - AM33XX_IOPAD(0x918, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxdv.mii1_rxdv */ -@@ -127,6 +122,8 @@ - cpsw_sleep: cpsw_sleep { - pinctrl-single,pins = < - /* Slave 1 reset value */ -+ 0x108 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE7) - AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7) - AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7) - AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7) -@@ -310,8 +307,23 @@ - * by the hardware problems. (Tip: double-check by performing a current - * measurement after shutdown: it should be less than 1 mA.) - */ -+ -+ interrupts = <7>; /* NMI */ -+ interrupt-parent = <&intc>; -+ - ti,pmic-shutdown-controller; - -+ charger { -+ interrupts = <TPS65217_IRQ_AC>, <TPS65217_IRQ_USB>; -+ interrupts-names = "AC", "USB"; -+ status = "okay"; -+ }; -+ -+ pwrbutton { -+ interrupts = <TPS65217_IRQ_PB>; -+ status = "okay"; -+ }; -+ - regulators { - dcdc1_reg: regulator@0 { - regulator-name = "vdds_dpr"; -@@ -393,3 +405,32 @@ - &sham { - status = "okay"; - }; -+ -+&rtc { -+ system-power-controller; -+}; -+ -+/* the cape manager */ -+/ { -+ bone_capemgr { -+ compatible = "ti,bone-capemgr"; -+ status = "okay"; -+ -+ nvmem-cells = <&baseboard_data &cape0_data &cape1_data &cape2_data &cape3_data>; -+ nvmem-cell-names = "baseboard", "slot0", "slot1", "slot2", "slot3"; -+ #slots = <4>; -+ -+ /* map board revisions to compatible definitions */ -+ baseboardmaps { -+ baseboard_beaglebone: board@0 { -+ board-name = "A335BONE"; -+ compatible-name = "ti,beaglebone"; -+ }; -+ -+ baseboard_beaglebone_black: board@1 { -+ board-name = "A335BNLT"; -+ compatible-name = "ti,beaglebone-black"; -+ }; -+ }; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-emmc-in-reset.dtsi b/arch/arm/boot/dts/am335x-bone-emmc-in-reset.dtsi -new file mode 100644 -index 0000000..7d8f673 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-emmc-in-reset.dtsi -@@ -0,0 +1,18 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+/* standard */ -+ -+&gpio1 { -+ emmc_rst { -+ gpio-hog; -+ gpios = <20 0>; -+ output-high; -+ line-name = "EMMC ResetN"; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-jtag.dtsi b/arch/arm/boot/dts/am335x-bone-jtag.dtsi -new file mode 100644 -index 0000000..603ef0a ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-jtag.dtsi -@@ -0,0 +1,20 @@ -+/* -+ * Device Tree Source for bone jtag -+ * -+ * Copyright (C) 2015 Robert Nelson <robertcnelson@gmail.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&am33xx_pinmux { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&clkout2_pin>; -+ -+ clkout2_pin: pinmux_clkout2_pin { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b4, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */ -+ >; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-pinmux-can0.dtsi b/arch/arm/boot/dts/am335x-bone-pinmux-can0.dtsi -new file mode 100644 -index 0000000..0961216 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-pinmux-can0.dtsi -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+#include "am335x-peripheral-can0.dtsi" -+ -+/* cape universal */ -+ -+/* -+ *&ocp { -+ * P9_19_pinmux { -+ * mode = "can"; -+ * }; -+ * P9_20_pinmux { -+ * mode = "can"; -+ * }; -+ *}; -+ * -+ *&dcan0 { -+ * pinctrl-0 = <>; -+ *}; -+ * -+ */ -+ -+/* standard */ -+ -+&am33xx_pinmux { -+ dcan0_pins: pinmux_dcan0_pins { -+ pinctrl-single,pins = < -+ /* P9_20: uart1_ctsn.d_can0_tx */ -+ BONE_P9_20 (PIN_OUTPUT_PULLUP | MUX_MODE2) -+ /* P9_19: uart1_rtsn.d_can0_rx */ -+ BONE_P9_19 (PIN_INPUT_PULLUP | MUX_MODE2) -+ >; -+ }; -+}; -+ -+&dcan0 { -+ pinctrl-0 = <&dcan0_pins>; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-pinmux-can1.dtsi b/arch/arm/boot/dts/am335x-bone-pinmux-can1.dtsi -new file mode 100644 -index 0000000..9e26413 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-pinmux-can1.dtsi -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+#include "am335x-peripheral-can1.dtsi" -+ -+/* cape universal */ -+ -+/* -+ *&ocp { -+ * P9_24_pinmux { -+ * mode = "can"; -+ * }; -+ * P9_26_pinmux { -+ * mode = "can"; -+ * }; -+ *}; -+ * -+ *&dcan1 { -+ * pinctrl-0 = <>; -+ *}; -+ * -+ */ -+ -+/* standard */ -+ -+&am33xx_pinmux { -+ dcan1_pins: pinmux_dcan1_pins { -+ pinctrl-single,pins = < -+ /* P9_26: uart1_rxd.d_can1_tx */ -+ BONE_P9_26 (PIN_OUTPUT_PULLUP | MUX_MODE2) -+ /* P9_24: uart1_txd.d_can1_rx */ -+ BONE_P9_24 (PIN_INPUT_PULLUP | MUX_MODE2) -+ >; -+ }; -+}; -+ -+&dcan1 { -+ pinctrl-0 = <&dcan1_pins>; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-pinmux-emmc.dtsi b/arch/arm/boot/dts/am335x-bone-pinmux-emmc.dtsi -new file mode 100644 -index 0000000..22cf462 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-pinmux-emmc.dtsi -@@ -0,0 +1,88 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+/* Testing */ -+/* lsblk */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+#include "am335x-peripheral-emmc.dtsi" -+ -+/* cape universal */ -+ -+/* -+ *&ocp { -+ * P8_21_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_20_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_25_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_24_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_05_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_06_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_23_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_22_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_03_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_04_pinmux { -+ * state = "disabled"; -+ * }; -+ *}; -+ * -+ *&mmc2 { -+ * pinctrl-0 = <>; -+ *}; -+ * -+ */ -+ -+/* standard */ -+ -+&am33xx_pinmux { -+ emmc_pins: pinmux_emmc_pins { -+ pinctrl-single,pins = < -+ /* P8_21: gpmc_csn1.mmc1_clk */ -+ BONE_P8_21 (PIN_INPUT_PULLUP | MUX_MODE2) -+ /* P8_20: gpmc_csn2.mmc1_cmd */ -+ BONE_P8_20 (PIN_INPUT_PULLUP | MUX_MODE2) -+ /* P8_25: gpmc_ad0.mmc1_dat0 */ -+ BONE_P8_25 (PIN_INPUT_PULLUP | MUX_MODE1) -+ /* P8_24: gpmc_ad1.mmc1_dat1 */ -+ BONE_P8_24 (PIN_INPUT_PULLUP | MUX_MODE1) -+ /* P8_05: gpmc_ad2.mmc1_dat2 */ -+ BONE_P8_05 (PIN_INPUT_PULLUP | MUX_MODE1) -+ /* P8_06: gpmc_ad3.mmc1_dat3 */ -+ BONE_P8_06 (PIN_INPUT_PULLUP | MUX_MODE1) -+ /* P8_23: gpmc_ad4.mmc1_dat4 */ -+ BONE_P8_23 (PIN_INPUT_PULLUP | MUX_MODE1) -+ /* P8_22: gpmc_ad5.mmc1_dat5 */ -+ BONE_P8_22 (PIN_INPUT_PULLUP | MUX_MODE1) -+ /* P8_03: gpmc_ad6.mmc1_dat6 */ -+ BONE_P8_03 (PIN_INPUT_PULLUP | MUX_MODE1) -+ /* P8_04: gpmc_ad7.mmc1_dat7 */ -+ BONE_P8_04 (PIN_INPUT_PULLUP | MUX_MODE1) -+ >; -+ }; -+}; -+ -+&mmc2 { -+ pinctrl-0 = <&emmc_pins>; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-pinmux-i2c2.dtsi b/arch/arm/boot/dts/am335x-bone-pinmux-i2c2.dtsi -new file mode 100644 -index 0000000..abf3b57 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-pinmux-i2c2.dtsi -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+#include "am335x-peripheral-i2c2.dtsi" -+ -+/* cape universal */ -+ -+/* -+ *&ocp { -+ * P9_19_pinmux { -+ * mode = "i2c"; -+ * }; -+ * P9_20_pinmux { -+ * mode = "i2c"; -+ * }; -+ *}; -+ * -+ *&dcan0 { -+ * pinctrl-0 = <>; -+ *}; -+ * -+ */ -+ -+/* standard */ -+ -+&am33xx_pinmux { -+ i2c2_pins: pinmux_i2c2_pins { -+ pinctrl-single,pins = < -+ /* P9_20: uart1_ctsn.i2c2_sda */ -+ BONE_P9_20 (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3) -+ /* P9_19: uart1_rtsn.i2c2_scl */ -+ BONE_P9_19 (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3) -+ >; -+ }; -+}; -+ -+&i2c2 { -+ pinctrl-0 = <&i2c2_pins>; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-pinmux-nxp-hdmi.dtsi b/arch/arm/boot/dts/am335x-bone-pinmux-nxp-hdmi.dtsi -new file mode 100644 -index 0000000..5205fa0 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-pinmux-nxp-hdmi.dtsi -@@ -0,0 +1,120 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include "am335x-peripheral-nxp-hdmi.dtsi" -+ -+/* cape universal */ -+ -+/* -+ *&ocp { -+ * P8_27_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_28_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_29_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_30_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_31_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_32_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_33_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_34_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_35_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_36_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_37_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_38_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_39_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_40_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_41_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_42_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_43_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_44_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_45_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_46_pinmux { -+ * state = "disabled"; -+ * }; -+ *}; -+ */ -+ -+/* standard */ -+ -+&am33xx_pinmux { -+ nxp_hdmi_pins: pinmux_nxp_hdmi_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */ -+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */ -+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */ -+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */ -+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */ -+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */ -+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */ -+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */ -+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */ -+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */ -+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */ -+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */ -+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */ -+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */ -+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */ -+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */ -+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_vsync.lcd_vsync */ -+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_hsync.lcd_hsync */ -+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_pclk.lcd_pclk */ -+ AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */ -+ >; -+ }; -+ -+ nxp_hdmi_off_pins: nxp_hdmi_off_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ >; -+ }; -+}; -+ -+&i2c0 { -+ tda19988 { -+ pinctrl-names = "default", "off"; -+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>; -+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-pinmux-panel-1024x600-24bit.dtsi b/arch/arm/boot/dts/am335x-bone-pinmux-panel-1024x600-24bit.dtsi -new file mode 100644 -index 0000000..65e5fbb ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-pinmux-panel-1024x600-24bit.dtsi -@@ -0,0 +1,151 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+#include "am335x-peripheral-panel-1024x600-24bit.dtsi" -+ -+/* cape universal */ -+ -+/* -+ *&ocp { -+ * P8_27_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_28_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_29_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_30_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_31_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_32_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_33_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_34_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_35_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_36_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_37_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_38_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_39_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_40_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_41_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_42_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_43_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_44_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_45_pinmux { -+ * state = "disabled"; -+ * }; -+ * P8_46_pinmux { -+ * state = "disabled"; -+ * }; -+ *}; -+ */ -+ -+/* standard */ -+ -+&am33xx_pinmux { -+ lcd_24bit_pins: pinmux_lcd_24bit_pins { -+ pinctrl-single,pins = < -+ -+ /* P8_45: lcd_data0.lcd_data0 */ -+ BONE_P8_45 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_46: lcd_data1.lcd_data1 */ -+ BONE_P8_46 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_43: lcd_data2.lcd_data2 */ -+ BONE_P8_43 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_44: lcd_data3.lcd_data3 */ -+ BONE_P8_44 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_41: lcd_data4.lcd_data4 */ -+ BONE_P8_41 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_42: lcd_data5.lcd_data5 */ -+ BONE_P8_42 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_39: lcd_data6.lcd_data6 */ -+ BONE_P8_39 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_40: lcd_data7.lcd_data7 */ -+ BONE_P8_40 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_37: lcd_data8.lcd_data8 */ -+ BONE_P8_37 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_38: lcd_data9.lcd_data9 */ -+ BONE_P8_38 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_36: lcd_data10.lcd_data10 */ -+ BONE_P8_36 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_34: lcd_data11.lcd_data11 */ -+ BONE_P8_34 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_35: lcd_data12.lcd_data12 */ -+ BONE_P8_35 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_33: lcd_data13.lcd_data13 */ -+ BONE_P8_33 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_31: lcd_data14.lcd_data14 */ -+ BONE_P8_31 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_32: lcd_data15.lcd_data15 */ -+ BONE_P8_32 (PIN_OUTPUT | MUX_MODE0) -+ -+ /* gpmc_ad15.lcd_data16 */ -+ BONE_P8_15 (PIN_OUTPUT | MUX_MODE1) -+ /* gpmc_ad14.lcd_data17 */ -+ BONE_P8_16 (PIN_OUTPUT | MUX_MODE1) -+ /* gpmc_ad13.lcd_data18 */ -+ BONE_P8_11 (PIN_OUTPUT | MUX_MODE1) -+ /* gpmc_ad12.lcd_data19 */ -+ BONE_P8_12 (PIN_OUTPUT | MUX_MODE1) -+ /* gpmc_ad11.lcd_data20 */ -+ BONE_P8_17 (PIN_OUTPUT | MUX_MODE1) -+ /* gpmc_ad10.lcd_data21 */ -+ BONE_P8_14 (PIN_OUTPUT | MUX_MODE1) -+ /* gpmc_ad9.lcd_data22 */ -+ BONE_P8_13 (PIN_OUTPUT | MUX_MODE1) -+ /* gpmc_ad8.lcd_data23 */ -+ BONE_P8_19 (PIN_OUTPUT | MUX_MODE1) -+ -+ /* P8_27: lcd_vsync.lcd_vsync */ -+ BONE_P8_27 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_29: lcd_hsync.lcd_hsync */ -+ BONE_P8_29 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_28: lcd_pclk.lcd_pclk*/ -+ BONE_P8_28 (PIN_OUTPUT | MUX_MODE0) -+ /* P8_30: lcd_ac_bias_en.lcd_ac_bias_en */ -+ BONE_P8_30 (PIN_OUTPUT | MUX_MODE0) -+ >; -+ }; -+}; -+ -+/ { -+ panel { -+ pinctrl-0 = <&lcd_24bit_pins>; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-pinmux-spi0.dtsi b/arch/arm/boot/dts/am335x-bone-pinmux-spi0.dtsi -new file mode 100644 -index 0000000..354e66a ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-pinmux-spi0.dtsi -@@ -0,0 +1,51 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+#include "am335x-peripheral-spi0.dtsi" -+ -+/* cape universal */ -+ -+/* -+ *&ocp { -+ * P9_17_pinmux { -+ * status = "disabled"; -+ * }; -+ * P9_18_pinmux { -+ * status = "disabled"; -+ * }; -+ * P9_21_pinmux { -+ * status = "disabled"; -+ * }; -+ * P9_22_pinmux { -+ * status = "disabled"; -+ * }; -+ *}; -+ * -+ *&spi0 { -+ * pinctrl-0 = <>; -+ *}; -+ * -+ */ -+ -+/* standard */ -+ -+&am33xx_pinmux { -+ spi0_pins: pinmux_spi0_pins { -+ pinctrl-single,pins = < -+ 0x150 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_sclk.spi0_sclk */ -+ 0x154 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d0.spi0_d0 */ -+ 0x158 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */ -+ 0x15c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */ -+ >; -+ }; -+}; -+ -+&spi0 { -+ pinctrl-0 = <&spi0_pins>; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-pinmux-spi1.dtsi b/arch/arm/boot/dts/am335x-bone-pinmux-spi1.dtsi -new file mode 100644 -index 0000000..bff7f8d ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-pinmux-spi1.dtsi -@@ -0,0 +1,27 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+#include "am335x-peripheral-spi1.dtsi" -+ -+/* standard */ -+ -+&am33xx_pinmux { -+ spi1_pins: pinmux_spi1_pins { -+ pinctrl-single,pins = < -+ 0x190 0x33 /* mcasp0_aclkx.spi1_sclk, INPUT_PULLUP | MODE3 */ -+ 0x194 0x33 /* mcasp0_fsx.spi1_d0, INPUT_PULLUP | MODE3 */ -+ 0x198 0x13 /* mcasp0_axr0.spi1_d1, OUTPUT_PULLUP | MODE3 */ -+ 0x19c 0x13 /* mcasp0_ahclkr.spi1_cs0, OUTPUT_PULLUP | MODE3 */ -+ // 0x164 0x12 /* eCAP0_in_PWM0_out.spi1_cs1 OUTPUT_PULLUP | MODE2 */ >; -+ }; -+}; -+ -+&spi1 { -+ pinctrl-0 = <&spi1_pins>; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-pinmux-spi1a.dtsi b/arch/arm/boot/dts/am335x-bone-pinmux-spi1a.dtsi -new file mode 100644 -index 0000000..62874c8 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-pinmux-spi1a.dtsi -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+#include "am335x-peripheral-spi1.dtsi" -+ -+/* standard */ -+ -+&am33xx_pinmux { -+ spi1a_pins: pinmux_spi1a_pins { -+ pinctrl-single,pins = < -+ 0x164 0x34 /* eCAP0_in_PWM0_out.spi1_sclk, INPUT_PULLUP | MODE4 */ -+ /* NOTE: P9.42 is connected to two pads */ -+ // 0x1A0 0x27 /* set the other pad to gpio input */ -+ 0x194 0x33 /* mcasp0_fsx.spi1_d0, INPUT_PULLUP | MODE3 */ -+ 0x198 0x13 /* mcasp0_axr0.spi1_d1, OUTPUT_PULLUP | MODE3 */ -+ 0x178 0x14 /* uart1_ctsn.spi1_cs0, OUTPUT_PULLUP | MODE4 */ >; -+ }; -+}; -+ -+&spi1 { -+ pinctrl-0 = <&spi1a_pins>; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-pinmux-ttyS1.dtsi b/arch/arm/boot/dts/am335x-bone-pinmux-ttyS1.dtsi -new file mode 100644 -index 0000000..ae5b813 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-pinmux-ttyS1.dtsi -@@ -0,0 +1,48 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+/* Testing */ -+/* sudo /sbin/getty -L ttyS1 115200 vt102 */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+#include "am335x-peripheral-ttyS1.dtsi" -+ -+/* cape universal */ -+ -+/* -+ *&ocp { -+ * P9_24_pinmux { -+ * mode = "uart"; -+ * }; -+ * P9_26_pinmux { -+ * mode = "uart"; -+ * }; -+ *}; -+ * -+ *&uart1 { -+ * pinctrl-0 = <>; -+ *}; -+ * -+ */ -+ -+/* standard */ -+ -+&am33xx_pinmux { -+ uart1_pins: pinmux_uart1_pins { -+ pinctrl-single,pins = < -+ /* P9_24: uart1_txd.uart1_txd */ -+ BONE_P9_24 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) -+ /* P9_26: uart1_rxd.uart1_rxd */ -+ BONE_P9_26 (PIN_INPUT_PULLUP | MUX_MODE0) -+ >; -+ }; -+}; -+ -+&uart1 { -+ pinctrl-0 = <&uart1_pins>; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-pinmux-ttyS2.dtsi b/arch/arm/boot/dts/am335x-bone-pinmux-ttyS2.dtsi -new file mode 100644 -index 0000000..5fa593a ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-pinmux-ttyS2.dtsi -@@ -0,0 +1,48 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+/* Testing */ -+/* sudo /sbin/getty -L ttyS2 115200 vt102 */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+#include "am335x-peripheral-ttyS2.dtsi" -+ -+/* cape universal */ -+ -+/* -+ *&ocp { -+ * P9_21_pinmux { -+ * mode = "uart"; -+ * }; -+ * P9_22_pinmux { -+ * mode = "uart"; -+ * }; -+ *}; -+ * -+ *&uart2 { -+ * pinctrl-0 = <>; -+ *}; -+ * -+ */ -+ -+/* standard */ -+ -+&am33xx_pinmux { -+ uart2_pins: pinmux_uart2_pins { -+ pinctrl-single,pins = < -+ /* P9_21: spi0_d0.uart2_txd */ -+ BONE_P9_21 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) -+ /* P9_22: spi0_sclk.uart2_rxd */ -+ BONE_P9_22 (PIN_INPUT_PULLUP | MUX_MODE1) -+ >; -+ }; -+}; -+ -+&uart2 { -+ pinctrl-0 = <&uart2_pins>; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-pinmux-ttyS4.dtsi b/arch/arm/boot/dts/am335x-bone-pinmux-ttyS4.dtsi -new file mode 100644 -index 0000000..1d22a95 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-pinmux-ttyS4.dtsi -@@ -0,0 +1,48 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+/* Testing */ -+/* sudo /sbin/getty -L ttyS4 115200 vt102 */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+#include "am335x-peripheral-ttyS4.dtsi" -+ -+/* cape universal */ -+ -+/* -+ *&ocp { -+ * P9_11_pinmux { -+ * mode = "uart"; -+ * }; -+ * P9_13_pinmux { -+ * mode = "uart"; -+ * }; -+ *}; -+ * -+ *&uart4 { -+ * pinctrl-0 = <>; -+ *}; -+ * -+ */ -+ -+/* standard */ -+ -+&am33xx_pinmux { -+ uart4_pins: pinmux_uart4_pins { -+ pinctrl-single,pins = < -+ /* P9_11: gpmc_wait0.uart4_rxd_mux2 */ -+ BONE_P9_11 (PIN_INPUT_PULLUP | MUX_MODE6) -+ /* P9_13: gpmc_wpn.uart4_txd_mux2 */ -+ BONE_P9_13 (PIN_OUTPUT_PULLDOWN | MUX_MODE6) -+ >; -+ }; -+}; -+ -+&uart4 { -+ pinctrl-0 = <&uart4_pins>; -+}; -diff --git b/arch/arm/boot/dts/am335x-bone-pinmux-ttyS5.dtsi b/arch/arm/boot/dts/am335x-bone-pinmux-ttyS5.dtsi -new file mode 100644 -index 0000000..01d0aec ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bone-pinmux-ttyS5.dtsi -@@ -0,0 +1,48 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+/* Testing */ -+/* sudo /sbin/getty -L ttyS5 115200 vt102 */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+#include "am335x-peripheral-ttyS5.dtsi" -+ -+/* cape universal */ -+ -+/* -+ *&ocp { -+ * P8_37_pinmux { -+ * mode = "uart"; -+ * }; -+ * P8_38_pinmux { -+ * mode = "uart"; -+ * }; -+ *}; -+ * -+ *&uart5 { -+ * pinctrl-0 = <>; -+ *}; -+ * -+ */ -+ -+/* standard */ -+ -+&am33xx_pinmux { -+ uart5_pins: pinmux_uart5_pins { -+ pinctrl-single,pins = < -+ /* P8_38: lcd_data9.uart5_rxd */ -+ BONE_P8_38 (PIN_INPUT_PULLUP | MUX_MODE4) -+ /* P8_37: lcd_data8.uart5_txd */ -+ BONE_P8_37 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) -+ >; -+ }; -+}; -+ -+&uart5 { -+ pinctrl-0 = <&uart5_pins>; -+}; -diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts -index 6b84937..3688fff 100644 ---- a/arch/arm/boot/dts/am335x-bone.dts -+++ b/arch/arm/boot/dts/am335x-bone.dts -@@ -9,6 +9,7 @@ - - #include "am33xx.dtsi" - #include "am335x-bone-common.dtsi" -+/* #include "am335x-bone-jtag.dtsi" */ - - / { - model = "TI AM335x BeagleBone"; -diff --git b/arch/arm/boot/dts/am335x-boneblack-audio.dts b/arch/arm/boot/dts/am335x-boneblack-audio.dts -new file mode 100644 -index 0000000..cac3626 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-audio.dts -@@ -0,0 +1,39 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common.dtsi" -+ -+/ { -+ model = "TI AM335x BeagleBone Black"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+ -+ clk_mcasp0_fixed: clk_mcasp0_fixed { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <24576000>; -+ }; -+ -+ clk_mcasp0: clk_mcasp0 { -+ #clock-cells = <0>; -+ compatible = "gpio-gate-clock"; -+ clocks = <&clk_mcasp0_fixed>; -+ enable-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>; /* BeagleBone Black Clk enable on GPIO1_27 */ -+ }; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblack-bbb-exp-c.dts b/arch/arm/boot/dts/am335x-boneblack-bbb-exp-c.dts -new file mode 100644 -index 0000000..8d795c0 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-bbb-exp-c.dts -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common-no-capemgr.dtsi" -+ -+/ { -+ model = "TI AM335x BeagleBone Black"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ status = "okay"; -+}; -+ -+&cpu0_opp_table { -+ /* -+ * All PG 2.0 silicon may not support 1GHz but some of the early -+ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed -+ * to support 1GHz OPP so enable it for PG 2.0 on this board. -+ */ -+ oppnitro@1000000000 { -+ opp-supported-hw = <0x06 0x0100>; -+ }; -+}; -+ -+#include "am335x-cape-bbb-exp-c.dtsi" -diff --git b/arch/arm/boot/dts/am335x-boneblack-bbb-exp-r.dts b/arch/arm/boot/dts/am335x-boneblack-bbb-exp-r.dts -new file mode 100644 -index 0000000..5df881e ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-bbb-exp-r.dts -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common-no-capemgr.dtsi" -+ -+/ { -+ model = "TI AM335x BeagleBone Black"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ status = "okay"; -+}; -+ -+&cpu0_opp_table { -+ /* -+ * All PG 2.0 silicon may not support 1GHz but some of the early -+ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed -+ * to support 1GHz OPP so enable it for PG 2.0 on this board. -+ */ -+ oppnitro@1000000000 { -+ opp-supported-hw = <0x06 0x0100>; -+ }; -+}; -+ -+#include "am335x-cape-bbb-exp-r.dtsi" -diff --git b/arch/arm/boot/dts/am335x-boneblack-bbbmini.dts b/arch/arm/boot/dts/am335x-boneblack-bbbmini.dts -new file mode 100644 -index 0000000..5ed89a2 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-bbbmini.dts -@@ -0,0 +1,207 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * Modified by Mirko Denecke <mirkix@gmail.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common.dtsi" -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+#include <dt-bindings/pinctrl/am33xx.h> -+ -+/ { -+ model = "TI AM335x BeagleBone Black"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ status = "okay"; -+}; -+ -+&cpu0_opp_table { -+ /* -+ * All PG 2.0 silicon may not support 1GHz but some of the early -+ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed -+ * to support 1GHz OPP so enable it for PG 2.0 on this board. -+ */ -+ oppnitro@1000000000 { -+ opp-supported-hw = <0x06 0x0100>; -+ }; -+}; -+ -+&am33xx_pinmux { -+ dcan1_pins: pinmux_dcan1_pins { -+ pinctrl-single,pins = < -+ /* P9_26: uart1_rxd.d_can1_tx */ -+ BONE_P9_26 (PIN_OUTPUT_PULLUP | MUX_MODE2) -+ /* P9_24: uart1_txd.d_can1_rx */ -+ BONE_P9_24 (PIN_INPUT_PULLUP | MUX_MODE2) -+ >; -+ }; -+ -+ pru_pins: pinmux_pru_pins { -+ pinctrl-single,pins = < -+ 0x03c 0x35 /* ecap0_in_pwm0_out.pr1_ecap0_ecap_capin, MODE5 | INPUT_PULLUP | PRU, PPM-sum, SBUS, DSM */ -+ -+ 0x0e8 0x25 /* lcd_pclk.pr1_pru1_pru_r30_10, MODE5 | OUTPUT | PRU, CH_1 */ -+ 0x0e0 0x25 /* lcd_vsync.pr1_pru1_pru_r30_8, MODE5 | OUTPUT | PRU, CH_2 */ -+ 0x0ec 0x25 /* lcd_ac_bias_en.pr1_pru1_pru_r30_11, MODE5 | OUTPUT | PRU, CH_3 */ -+ 0x0e4 0x25 /* lcd_hsync.pr1_pru1_pru_r30_9, MODE5 | OUTPUT | PRU, CH_4 */ -+ 0x0bc 0x25 /* lcd_data7.pr1_pru1_pru_r30_7, MODE5 | OUTPUT | PRU, CH_5 */ -+ 0x0b8 0x25 /* lcd_data6.pr1_pru1_pru_r30_6, MODE5 | OUTPUT | PRU, CH_6 */ -+ 0x0b4 0x25 /* lcd_data5.pr1_pru1_pru_r30_5, MODE5 | OUTPUT | PRU, CH_7 */ -+ 0x0b0 0x25 /* lcd_data4.pr1_pru1_pru_r30_4, MODE5 | OUTPUT | PRU, CH_8 */ -+ 0x0ac 0x25 /* lcd_data3.pr1_pru1_pru_r30_3, MODE5 | OUTPUT | PRU, CH_9 */ -+ 0x0a8 0x25 /* lcd_data2.pr1_pru1_pru_r30_2, MODE5 | OUTPUT | PRU, CH_10 */ -+ 0x0a4 0x25 /* lcd_data1.pr1_pru1_pru_r30_1, MODE5 | OUTPUT | PRU, CH_11 */ -+ 0x0a0 0x25 /* lcd_data0.pr1_pru1_pru_r30_0, MODE5 | OUTPUT | PRU, CH_12 */ -+ -+ BONE_P8_12 (PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* HC-SR04 TRIG */ -+ BONE_P8_16 (PIN_INPUT_PULLDOWN | MUX_MODE6) /* HC-SR04 ECHO */ -+ -+ BONE_P9_25 (PIN_INPUT_PULLDOWN | MUX_MODE6) /* MPU9250 INT */ -+ >; -+ }; -+ -+ spi0_pins: pinmux_spi0_pins { -+ pinctrl-single,pins = < -+ /* P9_22: spi0_sclk.spi0_sclk */ -+ BONE_P9_22 (PIN_INPUT_PULLUP | MUX_MODE0) -+ /* P9_21: spi0_d0.spi0_d0 */ -+ BONE_P9_21 (PIN_INPUT_PULLUP | MUX_MODE0) -+ /* P9_18: spi0_d1.spi0_d1 */ -+ BONE_P9_18 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ /* P9_17: spi0_cs0.spi0_cs0 */ -+ BONE_P9_17 (PIN_OUTPUT_PULLUP | MUX_MODE0) -+ >; -+ }; -+ -+ spi1_pins: pinmux_spi1_pins { -+ pinctrl-single,pins = < -+ /* P9_31: mcasp0_aclkx.spi1_sclk */ -+ BONE_P9_31 (PIN_INPUT_PULLUP | MUX_MODE3) -+ -+ /* P9_29: mcasp0_fsx.spi1_d0 */ -+ BONE_P9_29 (PIN_INPUT_PULLUP | MUX_MODE3) -+ -+ /* P9_30: mcasp0_axr0.spi1_d1 */ -+ BONE_P9_30 (PIN_OUTPUT_PULLUP | MUX_MODE3) -+ -+ /* P9_28: mcasp0_ahclkr.spi1_cs0 */ -+ BONE_P9_28 (PIN_OUTPUT_PULLUP | MUX_MODE3) -+ -+ /* P9_19: uart1_rtsn.spi1_cs1 */ -+/* BONE_P9_19 (PIN_OUTPUT_PULLUP | MUX_MODE4)*/ -+ -+ /* P9_42: ecap0_in_pwm0_out.spi1_cs1 */ -+ BONE_P9_42A (PIN_OUTPUT_PULLUP | MUX_MODE2) -+ >; -+ }; -+ -+ uart4_pins: pinmux_uart4_pins { -+ pinctrl-single,pins = < -+ /* P9_11: gpmc_wait0.uart4_rxd_mux2 */ -+ BONE_P9_11 (PIN_INPUT_PULLUP | MUX_MODE6) -+ /* P9_13: gpmc_wpn.uart4_txd_mux2 */ -+ BONE_P9_13 (PIN_OUTPUT_PULLDOWN | MUX_MODE6) -+ >; -+ }; -+ -+ uart5_pins: pinmux_uart5_pins { -+ pinctrl-single,pins = < -+ /* P8_38: lcd_data9.uart5_rxd */ -+ BONE_P8_38 (PIN_INPUT_PULLUP | MUX_MODE4) -+ /* P8_37: lcd_data8.uart5_txd */ -+ BONE_P8_37 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) -+ >; -+ }; -+}; -+ -+&dcan1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&dcan1_pins>; -+ status = "okay"; -+}; -+ -+&i2c2 { -+ clock-frequency = <400000>; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ status = "okay"; -+ -+ spi0_0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <24000000>; -+ reg = <0>; -+ compatible = "spidev"; -+ }; -+}; -+ -+&spi1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi1_pins>; -+ status = "okay"; -+ -+ spi1_0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0>; -+ spi-max-frequency = <24000000>; -+ compatible = "spidev"; -+ }; -+ -+ spi1_1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1>; -+ spi-max-frequency = <24000000>; -+ compatible = "spidev"; -+ }; -+}; -+ -+&tscadc { -+ adc { -+ ti,adc-channels = <0 1>; -+ }; -+}; -+ -+&pruss { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pru_pins>; -+ status = "okay"; -+}; -+ -+&uart4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart4_pins>; -+ status = "okay"; -+}; -+ -+&uart5 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart5_pins>; -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblack-cape-bone-argus.dts b/arch/arm/boot/dts/am335x-boneblack-cape-bone-argus.dts -new file mode 100644 -index 0000000..c97c912 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-cape-bone-argus.dts -@@ -0,0 +1,105 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common-no-capemgr.dtsi" -+ -+/ { -+ model = "TI AM335x BeagleBone Black"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ status = "okay"; -+}; -+ -+&cpu0_opp_table { -+ /* -+ * All PG 2.0 silicon may not support 1GHz but some of the early -+ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed -+ * to support 1GHz OPP so enable it for PG 2.0 on this board. -+ */ -+ oppnitro@1000000000 { -+ opp-supported-hw = <0x06 0x0100>; -+ }; -+}; -+ -+&am33xx_pinmux { -+ nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */ -+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */ -+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */ -+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */ -+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */ -+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */ -+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */ -+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */ -+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */ -+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */ -+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */ -+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */ -+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */ -+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */ -+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */ -+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */ -+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_vsync.lcd_vsync */ -+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_hsync.lcd_hsync */ -+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_pclk.lcd_pclk */ -+ AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */ -+ >; -+ }; -+ nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ >; -+ }; -+}; -+ -+&lcdc { -+ status = "okay"; -+ port { -+ lcdc_0: endpoint@0 { -+ remote-endpoint = <&hdmi_0>; -+ }; -+ }; -+}; -+ -+&i2c0 { -+ tda19988 { -+ compatible = "nxp,tda998x"; -+ reg = <0x70>; -+ pinctrl-names = "default", "off"; -+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>; -+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; -+ -+ port { -+ hdmi_0: endpoint@0 { -+ remote-endpoint = <&lcdc_0>; -+ }; -+ }; -+ }; -+}; -+ -+#include "am335x-bone-argus.dtsi" -diff --git b/arch/arm/boot/dts/am335x-boneblack-emmc-overlay.dts b/arch/arm/boot/dts/am335x-boneblack-emmc-overlay.dts -new file mode 100644 -index 0000000..ccd358e ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-emmc-overlay.dts -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common.dtsi" -+/* #include <dt-bindings/display/tda998x.h> */ -+/* #include "am335x-bone-jtag.dtsi" */ -+ -+/ { -+ model = "TI AM335x BeagleBone Black"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ status = "okay"; -+}; -+ -+&cpu0_opp_table { -+ /* -+ * All PG 2.0 silicon may not support 1GHz but some of the early -+ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed -+ * to support 1GHz OPP so enable it for PG 2.0 on this board. -+ */ -+ oppnitro@1000000000 { -+ opp-supported-hw = <0x06 0x0100>; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblack-hdmi-overlay.dts b/arch/arm/boot/dts/am335x-boneblack-hdmi-overlay.dts -new file mode 100644 -index 0000000..0582e57 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-hdmi-overlay.dts -@@ -0,0 +1,169 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common.dtsi" -+#include <dt-bindings/display/tda998x.h> -+/* #include "am335x-bone-jtag.dtsi" */ -+ -+/ { -+ model = "TI AM335x BeagleBone Black"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+/* EMMC in reset */ -+&gpio1 { -+ emmc_rst { -+ gpio-hog; -+ gpios = <20 0>; -+ output-high; -+ line-name = "EMMC ResetN"; -+ }; -+}; -+ -+&cpu0_opp_table { -+ /* -+ * All PG 2.0 silicon may not support 1GHz but some of the early -+ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed -+ * to support 1GHz OPP so enable it for PG 2.0 on this board. -+ */ -+ oppnitro@1000000000 { -+ opp-supported-hw = <0x06 0x0100>; -+ }; -+}; -+ -+&am33xx_pinmux { -+ nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */ -+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */ -+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */ -+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */ -+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */ -+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */ -+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */ -+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */ -+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */ -+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */ -+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */ -+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */ -+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */ -+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */ -+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */ -+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */ -+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_vsync.lcd_vsync */ -+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_hsync.lcd_hsync */ -+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_pclk.lcd_pclk */ -+ AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */ -+ >; -+ }; -+ nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ >; -+ }; -+ -+ mcasp0_pins: mcasp0_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */ -+ AM33XX_IOPAD(0x99c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2*/ -+ AM33XX_IOPAD(0x994, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */ -+ AM33XX_IOPAD(0x990, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */ -+ AM33XX_IOPAD(0x86c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.GPIO1_27 */ -+ >; -+ }; -+}; -+ -+&lcdc { -+ status = "okay"; -+ port { -+ lcdc_0: endpoint@0 { -+ remote-endpoint = <&hdmi_0>; -+ }; -+ }; -+}; -+ -+&i2c0 { -+ tda19988: tda19988 { -+ compatible = "nxp,tda998x"; -+ reg = <0x70>; -+ -+ pinctrl-names = "default", "off"; -+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>; -+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; -+ -+ #sound-dai-cells = <0>; -+ audio-ports = < TDA998x_I2S 0x03>; -+ -+ ports { -+ port@0 { -+ hdmi_0: endpoint@0 { -+ remote-endpoint = <&lcdc_0>; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&mcasp0 { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcasp0_pins>; -+ status = "okay"; -+ op-mode = <0>; /* MCASP_IIS_MODE */ -+ tdm-slots = <2>; -+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ -+ 0 0 1 0 -+ >; -+ tx-num-evt = <32>; -+ rx-num-evt = <32>; -+}; -+ -+/ { -+ clk_mcasp0_fixed: clk_mcasp0_fixed { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <24576000>; -+ }; -+ -+ clk_mcasp0: clk_mcasp0 { -+ #clock-cells = <0>; -+ compatible = "gpio-gate-clock"; -+ clocks = <&clk_mcasp0_fixed>; -+ enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */ -+ }; -+ -+ sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,name = "TI BeagleBone Black"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,bitclock-master = <&dailink0_master>; -+ simple-audio-card,frame-master = <&dailink0_master>; -+ -+ dailink0_master: simple-audio-card,cpu { -+ sound-dai = <&mcasp0>; -+ clocks = <&clk_mcasp0>; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&tda19988>; -+ }; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblack-nhdmi-overlay.dts b/arch/arm/boot/dts/am335x-boneblack-nhdmi-overlay.dts -new file mode 100644 -index 0000000..c166c90 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-nhdmi-overlay.dts -@@ -0,0 +1,110 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common.dtsi" -+#include <dt-bindings/display/tda998x.h> -+/* #include "am335x-bone-jtag.dtsi" */ -+ -+/ { -+ model = "TI AM335x BeagleBone Black"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+/* EMMC in reset */ -+&gpio1 { -+ emmc_rst { -+ gpio-hog; -+ gpios = <20 0>; -+ output-high; -+ line-name = "EMMC ResetN"; -+ }; -+}; -+ -+&cpu0_opp_table { -+ /* -+ * All PG 2.0 silicon may not support 1GHz but some of the early -+ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed -+ * to support 1GHz OPP so enable it for PG 2.0 on this board. -+ */ -+ oppnitro@1000000000 { -+ opp-supported-hw = <0x06 0x0100>; -+ }; -+}; -+ -+&am33xx_pinmux { -+ nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */ -+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */ -+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */ -+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */ -+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */ -+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */ -+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */ -+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */ -+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */ -+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */ -+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */ -+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */ -+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */ -+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */ -+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */ -+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */ -+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_vsync.lcd_vsync */ -+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_hsync.lcd_hsync */ -+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_pclk.lcd_pclk */ -+ AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */ -+ >; -+ }; -+ nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ >; -+ }; -+}; -+ -+&lcdc { -+ status = "okay"; -+ port { -+ lcdc_0: endpoint@0 { -+ remote-endpoint = <&hdmi_0>; -+ }; -+ }; -+}; -+ -+&i2c0 { -+ tda19988: tda19988 { -+ compatible = "nxp,tda998x"; -+ reg = <0x70>; -+ -+ pinctrl-names = "default", "off"; -+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>; -+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; -+ -+ ports { -+ port@0 { -+ hdmi_0: endpoint@0 { -+ remote-endpoint = <&lcdc_0>; -+ }; -+ }; -+ }; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblack-overlay.dts b/arch/arm/boot/dts/am335x-boneblack-overlay.dts -new file mode 100644 -index 0000000..e9bbd93 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-overlay.dts -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common.dtsi" -+/* #include <dt-bindings/display/tda998x.h> */ -+/* #include "am335x-bone-jtag.dtsi" */ -+ -+/ { -+ model = "TI AM335x BeagleBone Black"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+/* EMMC in reset */ -+&gpio1 { -+ emmc_rst { -+ gpio-hog; -+ gpios = <20 0>; -+ output-high; -+ line-name = "EMMC ResetN"; -+ }; -+}; -+ -+&cpu0_opp_table { -+ /* -+ * All PG 2.0 silicon may not support 1GHz but some of the early -+ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed -+ * to support 1GHz OPP so enable it for PG 2.0 on this board. -+ */ -+ oppnitro@1000000000 { -+ opp-supported-hw = <0x06 0x0100>; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblack-roboticscape.dts b/arch/arm/boot/dts/am335x-boneblack-roboticscape.dts -new file mode 100644 -index 0000000..16e9376 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-roboticscape.dts -@@ -0,0 +1,56 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+ /****************************************************************************** -+ * This device tree serves to replace the need for an overlay when using -+ * the RoboticsCape. It is similar to the boneblue tree but preserves -+ * pin config for the black. -+ ******************************************************************************/ -+ -+ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common-no-capemgr.dtsi" -+#include "am335x-bone-common-universal-pins.dtsi" -+/* #include "am33xx-pruss-rproc.dtsi" */ -+#include "am335x-roboticscape.dtsi" -+ -+/ { -+ model = "TI AM335x BeagleBone Black"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ status = "okay"; -+}; -+ -+&cpu0_opp_table { -+ /* -+ * All PG 2.0 silicon may not support 1GHz but some of the early -+ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed -+ * to support 1GHz OPP so enable it for PG 2.0 on this board. -+ */ -+ oppnitro@1000000000 { -+ opp-supported-hw = <0x06 0x0100>; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblack-uboot.dts b/arch/arm/boot/dts/am335x-boneblack-uboot.dts -new file mode 100644 -index 0000000..b2f6e36 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-uboot.dts -@@ -0,0 +1,26 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common.dtsi" -+ -+/ { -+ model = "TI AM335x BeagleBone Black"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblack-wireless-emmc-overlay.dts b/arch/arm/boot/dts/am335x-boneblack-wireless-emmc-overlay.dts -new file mode 100644 -index 0000000..78f63bf ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-wireless-emmc-overlay.dts -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common.dtsi" -+/* #include <dt-bindings/display/tda998x.h> */ -+#include "am335x-boneblack-wl1835.dtsi" -+/* #include "am335x-bone-jtag.dtsi" */ -+ -+/ { -+ model = "TI AM335x BeagleBone Black Wireless"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ status = "okay"; -+}; -+ -+&mac { -+ status = "disabled"; -+}; -+ -+&mmc3 { -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblack-wireless-roboticscape.dts b/arch/arm/boot/dts/am335x-boneblack-wireless-roboticscape.dts -new file mode 100644 -index 0000000..4a72d56 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-wireless-roboticscape.dts -@@ -0,0 +1,46 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+ /****************************************************************************** -+ * This device tree serves to replace the need for an overlay when using -+ * the RoboticsCape. It is similar to the boneblue tree but preserves -+ * pin config for the black. -+ ******************************************************************************/ -+ -+ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common-no-capemgr.dtsi" -+#include "am335x-bone-common-universal-pins.dtsi" -+/* #include "am33xx-pruss-rproc.dtsi" */ -+#include "am335x-boneblack-wl1835.dtsi" -+#include "am335x-roboticscape.dtsi" -+ -+/ { -+ model = "TI AM335x BeagleBone Black Wireless"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblack-wireless.dts b/arch/arm/boot/dts/am335x-boneblack-wireless.dts -new file mode 100644 -index 0000000..9b39648 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-wireless.dts -@@ -0,0 +1,165 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common.dtsi" -+#include <dt-bindings/display/tda998x.h> -+#include "am335x-boneblack-wl1835.dtsi" -+/* #include "am335x-bone-jtag.dtsi" */ -+ -+/ { -+ model = "TI AM335x BeagleBone Black Wireless"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ status = "okay"; -+}; -+ -+&mac { -+ status = "disabled"; -+}; -+ -+&mmc3 { -+ status = "okay"; -+}; -+ -+&am33xx_pinmux { -+ nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */ -+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */ -+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */ -+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */ -+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */ -+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */ -+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */ -+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */ -+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */ -+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */ -+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */ -+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */ -+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */ -+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */ -+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */ -+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */ -+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_vsync.lcd_vsync */ -+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_hsync.lcd_hsync */ -+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_pclk.lcd_pclk */ -+ AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */ -+ >; -+ }; -+ nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ >; -+ }; -+ -+ mcasp0_pins: mcasp0_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */ -+ AM33XX_IOPAD(0x99c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2*/ -+ AM33XX_IOPAD(0x994, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */ -+ AM33XX_IOPAD(0x990, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */ -+ AM33XX_IOPAD(0x86c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.GPIO1_27 */ -+ >; -+ }; -+}; -+ -+&lcdc { -+ status = "okay"; -+ port { -+ lcdc_0: endpoint@0 { -+ remote-endpoint = <&hdmi_0>; -+ }; -+ }; -+}; -+ -+&i2c0 { -+ tda19988: tda19988 { -+ compatible = "nxp,tda998x"; -+ reg = <0x70>; -+ -+ pinctrl-names = "default", "off"; -+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>; -+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; -+ -+ #sound-dai-cells = <0>; -+ audio-ports = < TDA998x_I2S 0x03>; -+ -+ ports { -+ port@0 { -+ hdmi_0: endpoint@0 { -+ remote-endpoint = <&lcdc_0>; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&mcasp0 { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcasp0_pins>; -+ status = "okay"; -+ op-mode = <0>; /* MCASP_IIS_MODE */ -+ tdm-slots = <2>; -+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ -+ 0 0 1 0 -+ >; -+ tx-num-evt = <32>; -+ rx-num-evt = <32>; -+}; -+ -+/ { -+ clk_mcasp0_fixed: clk_mcasp0_fixed { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <24576000>; -+ }; -+ -+ clk_mcasp0: clk_mcasp0 { -+ #clock-cells = <0>; -+ compatible = "gpio-gate-clock"; -+ clocks = <&clk_mcasp0_fixed>; -+ enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */ -+ }; -+ -+ sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,name = "TI BeagleBone Black"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,bitclock-master = <&dailink0_master>; -+ simple-audio-card,frame-master = <&dailink0_master>; -+ -+ dailink0_master: simple-audio-card,cpu { -+ sound-dai = <&mcasp0>; -+ clocks = <&clk_mcasp0>; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&tda19988>; -+ }; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblack-wl1835.dtsi b/arch/arm/boot/dts/am335x-boneblack-wl1835.dtsi -new file mode 100644 -index 0000000..ec6c0e4 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-wl1835.dtsi -@@ -0,0 +1,143 @@ -+ -+#include <dt-bindings/interrupt-controller/irq.h> -+ -+/ { -+ wlan_en_reg: fixedregulator@2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "wlan-en-regulator"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ startup-delay-us= <70000>; -+ -+ /* WL_EN */ -+ gpio = <&gpio3 9 0>; -+ enable-active-high; -+ }; -+ -+ leds { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wl18xx_pins>; -+ compatible = "gpio-leds"; -+ -+ wl18xx_bt_en { -+ label = "wl18xx_bt_en"; -+ gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>; -+ default-state = "off"; -+ }; -+ }; -+ -+ btwilink { -+ compatible = "btwilink"; -+ }; -+}; -+ -+&am33xx_pinmux { -+ wl18xx_pins: pinmux_wl18xx_pins { -+ pinctrl-single,pins = < -+ 0x128 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* (K17) gmii1_txd0.gpio0[28] - BT_EN */ -+ >; -+ }; -+ -+ wlbtbuf_pin: pinmux_wlbtbuf_pin { -+ pinctrl-single,pins = < -+ 0x130 ( PIN_OUTPUT_PULLUP | MUX_MODE7 ) /* (L18) gmii1_rxclk.gpio3[10] - LS_BUF_EN */ -+ >; -+ }; -+ -+ mmc3_pins: pinmux_mmc3_pins { -+ pinctrl-single,pins = < -+ 0x13c ( PIN_INPUT_PULLUP | MUX_MODE6 ) /* (L15) gmii1_rxd1.mmc2_clk */ -+ 0x114 ( PIN_INPUT_PULLUP | MUX_MODE6 ) /* (J16) gmii1_txen.mmc2_cmd */ -+ 0x118 ( PIN_INPUT_PULLUP | MUX_MODE5 ) /* (J17) gmii1_rxdv.mmc2_dat0 */ -+ 0x11c ( PIN_INPUT_PULLUP | MUX_MODE5 ) /* (J18) gmii1_txd3.mmc2_dat1 */ -+ 0x120 ( PIN_INPUT_PULLUP | MUX_MODE5 ) /* (K15) gmii1_txd2.mmc2_dat2 */ -+ 0x108 ( PIN_INPUT_PULLUP | MUX_MODE5 ) /* (H16) gmii1_col.mmc2_dat3 */ -+ >; -+ }; -+ -+ mmc3_pins_sleep: pinmux_mmc3_pins_sleep { -+ pinctrl-single,pins = < -+ 0x13c ( PIN_INPUT_PULLDOWN | MUX_MODE6 ) /* (L15) gmii1_rxd1.mmc2_clk */ -+ 0x114 ( PIN_INPUT_PULLDOWN | MUX_MODE6 ) /* (J16) gmii1_txen.mmc2_cmd */ -+ 0x118 ( PIN_INPUT_PULLDOWN | MUX_MODE5 ) /* (J17) gmii1_rxdv.mmc2_dat0 */ -+ 0x11c ( PIN_INPUT_PULLDOWN | MUX_MODE5 ) /* (J18) gmii1_txd3.mmc2_dat1 */ -+ 0x120 ( PIN_INPUT_PULLDOWN | MUX_MODE5 ) /* (K15) gmii1_txd2.mmc2_dat2 */ -+ 0x108 ( PIN_INPUT_PULLDOWN | MUX_MODE5 ) /* (H16) gmii1_col.mmc2_dat3 */ -+ >; -+ }; -+ -+ /* wl18xx card enable/irq GPIOs. */ -+ wlan_pins: pinmux_wlan_pins { -+ pinctrl-single,pins = < -+ 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE7 ) /* (K18) gmii1_txclk.gpio3[9] - WL_EN */ -+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7 ) /* (H18) rmii1_refclk.gpio0[29] - WL_IRQ */ -+ >; -+ }; -+ -+ /* wl18xx card enable/irq GPIOs. */ -+ wlan_pins_sleep: pinmux_wlan_pins_sleep { -+ pinctrl-single,pins = < -+ 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE7 ) /* (K18) gmii1_txclk.gpio3[9] - WL_EN */ -+ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE7 ) /* (H18) rmii1_refclk.gpio0[29] - WL_IRQ */ -+ >; -+ }; -+ -+ uart3_pins_default: pinmux_uart3_pins_default { -+ pinctrl-single,pins = < -+ 0x134 ( PIN_INPUT_PULLUP | MUX_MODE1 ) /* (L17) gmii1_rxd3.uart3_rxd */ -+ 0x138 ( PIN_OUTPUT_PULLDOWN | MUX_MODE1 ) /* (L16) gmii1_rxd2.uart3_txd */ -+ 0x148 ( PIN_INPUT | MUX_MODE3 ) /* (M17) mdio_data.uart3_ctsn */ -+ 0x14c ( PIN_OUTPUT_PULLDOWN | MUX_MODE3 ) /* (M18) mdio_clk.uart3_rtsn */ -+ >; -+ }; -+ -+ uart3_pins_sleep: pinmux_uart3_pins_sleep { -+ pinctrl-single,pins = < -+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* (L17) gmii1_rxd3.uart3_rxd */ -+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* (L16) gmii1_rxd2.uart3_txd */ -+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* (M17) mdio_data.uart3_ctsn */ -+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* (M18) mdio_clk.uart3_rtsn */ -+ >; -+ }; -+}; -+ -+&mmc3 { -+ dmas = <&edma_xbar 12 0 1 -+ &edma_xbar 13 0 2>; -+ dma-names = "tx", "rx"; -+ status = "okay"; -+ vmmc-supply = <&wlan_en_reg>; -+ bus-width = <4>; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&mmc3_pins &wlan_pins &wlbtbuf_pin>; -+ pinctrl-1 = <&mmc3_pins_sleep &wlan_pins_sleep &wlbtbuf_pin>; -+ ti,non-removable; -+ ti,needs-special-hs-handling; -+ cap-power-off-card; -+ keep-power-in-suspend; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ wlcore: wlcore@0 { -+ compatible = "ti,wl1835"; -+ reg = <2>; -+ interrupt-parent = <&gpio0>; -+ interrupts = <29 IRQ_TYPE_EDGE_RISING>; -+ }; -+}; -+ -+&uart3 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&uart3_pins_default>; -+ pinctrl-1 = <&uart3_pins_sleep>; -+ status = "okay"; -+}; -+ -+&gpio3 { -+ ls_buf_en { -+ gpio-hog; -+ gpios = <10 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "LS_BUF_EN"; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblack-wl1835mod-cape.dtsi b/arch/arm/boot/dts/am335x-boneblack-wl1835mod-cape.dtsi -new file mode 100644 -index 0000000..94caa22 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-wl1835mod-cape.dtsi -@@ -0,0 +1,128 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include <dt-bindings/interrupt-controller/irq.h> -+ -+/ { -+ wlan_en_reg: fixedregulator@2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "wlan-en-regulator"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ -+ /* WL_EN */ -+ gpio = <&gpio0 26 0>; -+ enable-active-high; -+ }; -+ -+ kim { -+ compatible = "kim"; -+ nshutdown_gpio = <44>; /* Bank1, pin12 */ -+ dev_name = "/dev/ttyO4"; -+ flow_cntrl = <1>; -+ baud_rate = <3000000>; -+ }; -+ -+ btwilink { -+ compatible = "btwilink"; -+ }; -+}; -+ -+&am33xx_pinmux { -+ bt_pins: pinmux_bt_pins { -+ pinctrl-single,pins = < -+ 0x30 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_ad12.gpio1_12 */ -+ >; -+ }; -+ -+ mmc2_pins: pinmux_mmc2_pins { -+ pinctrl-single,pins = < -+ 0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */ -+ 0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */ -+ 0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */ -+ 0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */ -+ 0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */ -+ 0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */ -+ >; -+ }; -+ -+ mmc2_pins_sleep: pinmux_mmc2_pins_sleep { -+ pinctrl-single,pins = < -+ 0x80 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn1.mmc1_clk */ -+ 0x84 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn2.mmc1_cmd */ -+ 0x00 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad0.mmc1_dat0 */ -+ 0x04 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad1.mmc1_dat1 */ -+ 0x08 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad2.mmc1_dat2 */ -+ 0x0c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad3.mmc1_dat3 */ -+ >; -+ }; -+ -+ /* wl18xx card enable/irq GPIOs. */ -+ wlan_pins: pinmux_wlan_pins { -+ pinctrl-single,pins = < -+ 0x28 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad10.gpio0_26 WL_EN*/ -+ 0x2C (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_ad11.gpio0_27 WL_IRQ*/ -+ 0x7C (PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_csn0.gpio1_29 BF_EN*/ -+ >; -+ }; -+ -+ /* wl18xx card enable/irq GPIOs. */ -+ wlan_pins_sleep: pinmux_wlan_pins_sleep { -+ pinctrl-single,pins = < -+ 0x28 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_ad10.gpio0_26 WL_EN*/ -+ 0x2C (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_ad11.gpio0_27 WL_IRQ*/ -+ 0x7C (PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_csn0.gpio1_29 BF_EN*/ -+ >; -+ }; -+ -+ uart4_pins_default: pinmux_uart4_pins_default { -+ pinctrl-single,pins = < -+ 0xD0 (PIN_INPUT | MUX_MODE6) /* lcd_data12.uart4_cts */ -+ 0xD4 (PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* lcd_data13.uart4_rts */ -+ 0x70 (PIN_INPUT_PULLUP | MUX_MODE6) /* gpmc_wait0.uart4_rxd */ -+ 0x74 (PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* gpmc_wpn.uart4_txd */ -+ >; -+ }; -+ -+ uart4_pins_sleep: pinmux_uart4_pins_sleep { -+ pinctrl-single,pins = < -+ 0xD0 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_data12.uart4_cts */ -+ 0xD4 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_data13.uart4_rts */ -+ 0x70 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_wait0.uart4_rxd */ -+ 0x74 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_wpn.uart4_txd */ -+ >; -+ }; -+}; -+ -+&mmc2 { -+ status = "okay"; -+ vmmc-supply = <&wlan_en_reg>; -+ bus-width = <4>; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&mmc2_pins &wlan_pins>; -+ pinctrl-1 = <&mmc2_pins_sleep &wlan_pins_sleep>; -+ ti,non-removable; -+ ti,needs-special-hs-handling; -+ cap-power-off-card; -+ keep-power-in-suspend; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ wlcore: wlcore@0 { -+ compatible = "ti,wl1835"; -+ reg = <2>; -+ interrupt-parent = <&gpio0>; -+ interrupts = <27 IRQ_TYPE_LEVEL_HIGH>; -+ }; -+}; -+ -+&uart4 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&uart4_pins_default>; -+ pinctrl-1 = <&uart4_pins_sleep>; -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblack-wl1835mod.dts b/arch/arm/boot/dts/am335x-boneblack-wl1835mod.dts -new file mode 100644 -index 0000000..f35b64a ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblack-wl1835mod.dts -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common-no-capemgr.dtsi" -+ -+/ { -+ model = "TI AM335x BeagleBone Black"; -+ compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+/* EMMC in reset */ -+&gpio1 { -+ emmc_rst { -+ gpio-hog; -+ gpios = <20 0>; -+ output-high; -+ line-name = "EMMC ResetN"; -+ }; -+}; -+ -+&cpu0_opp_table { -+ /* -+ * All PG 2.0 silicon may not support 1GHz but some of the early -+ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed -+ * to support 1GHz OPP so enable it for PG 2.0 on this board. -+ */ -+ oppnitro@1000000000 { -+ opp-supported-hw = <0x06 0x0100>; -+ }; -+}; -+ -+#include "am335x-boneblack-wl1835mod-cape.dtsi" -diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts -index 6bbb1fe..8f5d559 100644 ---- a/arch/arm/boot/dts/am335x-boneblack.dts -+++ b/arch/arm/boot/dts/am335x-boneblack.dts -@@ -10,6 +10,7 @@ - #include "am33xx.dtsi" - #include "am335x-bone-common.dtsi" - #include <dt-bindings/display/tda998x.h> -+/* #include "am335x-bone-jtag.dtsi" */ - - / { - model = "TI AM335x BeagleBone Black"; -@@ -34,6 +35,17 @@ - status = "okay"; - }; - -+&cpu0_opp_table { -+ /* -+ * All PG 2.0 silicon may not support 1GHz but some of the early -+ * BeagleBone Blacks have PG 2.0 silicon which is guaranteed -+ * to support 1GHz OPP so enable it for PG 2.0 on this board. -+ */ -+ oppnitro@1000000000 { -+ opp-supported-hw = <0x06 0x0100>; -+ }; -+}; -+ - &am33xx_pinmux { - nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { - pinctrl-single,pins = < -@@ -108,10 +120,6 @@ - }; - }; - --&rtc { -- system-power-controller; --}; -- - &mcasp0 { - #sound-dai-cells = <0>; - pinctrl-names = "default"; -diff --git b/arch/arm/boot/dts/am335x-boneblue-wl1835.dtsi b/arch/arm/boot/dts/am335x-boneblue-wl1835.dtsi -new file mode 100644 -index 0000000..64731b0 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblue-wl1835.dtsi -@@ -0,0 +1,143 @@ -+ -+#include <dt-bindings/interrupt-controller/irq.h> -+ -+/ { -+ wlan_en_reg: fixedregulator@2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "wlan-en-regulator"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ startup-delay-us= <70000>; -+ -+ /* WL_EN */ -+ gpio = <&gpio3 9 0>; -+ enable-active-high; -+ }; -+ -+ leds { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&wl18xx_pins>; -+ compatible = "gpio-leds"; -+ -+ wl18xx_bt_en { -+ label = "wl18xx_bt_en"; -+ gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>; -+ default-state = "off"; -+ }; -+ }; -+ -+ btwilink { -+ compatible = "btwilink"; -+ }; -+}; -+ -+&am33xx_pinmux { -+ wl18xx_pins: pinmux_wl18xx_pins { -+ pinctrl-single,pins = < -+ 0x128 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* (K17) gmii1_txd0.gpio0[28] - BT_EN */ -+ >; -+ }; -+ -+ wlbtbuf_pin: pinmux_wlbtbuf_pin { -+ pinctrl-single,pins = < -+ 0x130 ( PIN_OUTPUT_PULLUP | MUX_MODE7 ) /* (L18) gmii1_rxclk.gpio3[10] - LS_BUF_EN */ -+ >; -+ }; -+ -+ mmc3_pins: pinmux_mmc3_pins { -+ pinctrl-single,pins = < -+ 0x13c ( PIN_INPUT_PULLUP | MUX_MODE6 ) /* (L15) gmii1_rxd1.mmc2_clk */ -+ 0x114 ( PIN_INPUT_PULLUP | MUX_MODE6 ) /* (J16) gmii1_txen.mmc2_cmd */ -+ 0x118 ( PIN_INPUT_PULLUP | MUX_MODE5 ) /* (J17) gmii1_rxdv.mmc2_dat0 */ -+ 0x11c ( PIN_INPUT_PULLUP | MUX_MODE5 ) /* (J18) gmii1_txd3.mmc2_dat1 */ -+ 0x120 ( PIN_INPUT_PULLUP | MUX_MODE5 ) /* (K15) gmii1_txd2.mmc2_dat2 */ -+ 0x108 ( PIN_INPUT_PULLUP | MUX_MODE5 ) /* (H16) gmii1_col.mmc2_dat3 */ -+ >; -+ }; -+ -+ mmc3_pins_sleep: pinmux_mmc3_pins_sleep { -+ pinctrl-single,pins = < -+ 0x13c ( PIN_INPUT_PULLDOWN | MUX_MODE6 ) /* (L15) gmii1_rxd1.mmc2_clk */ -+ 0x114 ( PIN_INPUT_PULLDOWN | MUX_MODE6 ) /* (J16) gmii1_txen.mmc2_cmd */ -+ 0x118 ( PIN_INPUT_PULLDOWN | MUX_MODE5 ) /* (J17) gmii1_rxdv.mmc2_dat0 */ -+ 0x11c ( PIN_INPUT_PULLDOWN | MUX_MODE5 ) /* (J18) gmii1_txd3.mmc2_dat1 */ -+ 0x120 ( PIN_INPUT_PULLDOWN | MUX_MODE5 ) /* (K15) gmii1_txd2.mmc2_dat2 */ -+ 0x108 ( PIN_INPUT_PULLDOWN | MUX_MODE5 ) /* (H16) gmii1_col.mmc2_dat3 */ -+ >; -+ }; -+ -+ /* wl18xx card enable/irq GPIOs. */ -+ wlan_pins: pinmux_wlan_pins { -+ pinctrl-single,pins = < -+ 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE7 ) /* (K18) gmii1_txclk.gpio3[9] - WL_EN */ -+ 0x124 (PIN_INPUT_PULLUP | MUX_MODE7 ) /* (K16) gmii1_txd1.gpio0[21] - WL_IRQ */ -+ >; -+ }; -+ -+ /* wl18xx card enable/irq GPIOs. */ -+ wlan_pins_sleep: pinmux_wlan_pins_sleep { -+ pinctrl-single,pins = < -+ 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE7 ) /* (K18) gmii1_txclk.gpio3[9] - WL_EN */ -+ 0x124 (PIN_INPUT_PULLUP | MUX_MODE7 ) /* (K16) gmii1_txd1.gpio0[21] - WL_IRQ */ -+ >; -+ }; -+ -+ uart3_pins_default: pinmux_uart3_pins_default { -+ pinctrl-single,pins = < -+ 0x134 ( PIN_INPUT_PULLUP | MUX_MODE1 ) /* (L17) gmii1_rxd3.uart3_rxd */ -+ 0x138 ( PIN_OUTPUT_PULLDOWN | MUX_MODE1 ) /* (L16) gmii1_rxd2.uart3_txd */ -+ 0x148 ( PIN_INPUT | MUX_MODE3 ) /* (M17) mdio_data.uart3_ctsn */ -+ 0x14c ( PIN_OUTPUT_PULLDOWN | MUX_MODE3 ) /* (M18) mdio_clk.uart3_rtsn */ -+ >; -+ }; -+ -+ uart3_pins_sleep: pinmux_uart3_pins_sleep { -+ pinctrl-single,pins = < -+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* (L17) gmii1_rxd3.uart3_rxd */ -+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* (L16) gmii1_rxd2.uart3_txd */ -+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* (M17) mdio_data.uart3_ctsn */ -+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* (M18) mdio_clk.uart3_rtsn */ -+ >; -+ }; -+}; -+ -+&mmc3 { -+ dmas = <&edma_xbar 12 0 1 -+ &edma_xbar 13 0 2>; -+ dma-names = "tx", "rx"; -+ status = "okay"; -+ vmmc-supply = <&wlan_en_reg>; -+ bus-width = <4>; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&mmc3_pins &wlan_pins &wlbtbuf_pin>; -+ pinctrl-1 = <&mmc3_pins_sleep &wlan_pins_sleep &wlbtbuf_pin>; -+ ti,non-removable; -+ ti,needs-special-hs-handling; -+ cap-power-off-card; -+ keep-power-in-suspend; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ wlcore: wlcore@0 { -+ compatible = "ti,wl1835"; -+ reg = <2>; -+ interrupt-parent = <&gpio0>; -+ interrupts = <21 IRQ_TYPE_EDGE_RISING>; -+ }; -+}; -+ -+&uart3 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&uart3_pins_default>; -+ pinctrl-1 = <&uart3_pins_sleep>; -+ status = "okay"; -+}; -+ -+&gpio3 { -+ ls_buf_en { -+ gpio-hog; -+ gpios = <10 GPIO_ACTIVE_HIGH>; -+ output-high; -+ line-name = "LS_BUF_EN"; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-boneblue.dts b/arch/arm/boot/dts/am335x-boneblue.dts -new file mode 100644 -index 0000000..e2a2fb5 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-boneblue.dts -@@ -0,0 +1,569 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common-no-capemgr.dtsi" -+#include "am335x-bone-common-universal-pins.dtsi" -+#include "am335x-boneblue-wl1835.dtsi" -+/* #include "am33xx-pruss-rproc.dtsi" */ -+ -+#define BLUE_IO(x, y) AM33XX_IOPAD((x)*4+0x800, (y)) /* not used anymore */ -+ -+ -+/ { -+ model = "TI AM335x BeagleBone Blue"; -+ compatible = "ti,am335x-bone-blue", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ status = "okay"; -+}; -+ -+&mac { -+ status = "disabled"; -+}; -+ -+/******************************************************************************* -+* Pin Muxing -+*******************************************************************************/ -+&am33xx_pinmux { -+ -+ /*************************************************************************** -+ * Static Pinmux -+ ***************************************************************************/ -+ mux_helper_pins: pins { -+ pinctrl-single,pins = < -+ -+ /* GPIO Inputs */ -+ 0x09c 0x37 /*P8.9 Pause BUTTON, input pullup*/ -+ 0x098 0x37 /*P8.10 MODE BUTTON input pullup*/ -+ 0x1AC 0x37 /*P9.25 MPU-9150 INTERRUPT IN*/ -+ -+ /* LEDs GPIO Out*/ -+ 0x090 0x0F /* P8.7 R7 LED_RED */ -+ 0x094 0x0F /* P8.8 T7 LED_GREEN */ -+ 0x02C 0x0F /* P8.17 U12 BATT_LED_1 */ -+ 0x0DC 0x0F /* P8.32 T5 BATT_LED_2 diff from cape! */ -+ 0x07c 0x0F /* P8.26 V6 BATT_LED_3 */ -+ 0x028 0x0F /* P8.14 T11 BATT_LED_4 */ -+ -+ /* Motor Control GPIO Out*/ -+ 0x0a8 0x0F /*P8.43 MDIR_3B*/ -+ 0x0ac 0x0F /*P8.44 MDIR_3A*/ -+ 0x0a0 0x0F /*P8.45 MDIR_4A*/ -+ 0x0a4 0x0F /*P8.46 MDIR_4B*/ -+ 0x074 0x0F /*P9.13 MDIR_1B*/ -+ 0x040 0x0F /*P9.15 MDIR_2A*/ -+ 0x1b4 0x0F /*P9.41 MOT_STBY*/ -+ 0x088 0x0F /*T13 MDIR_1A different from cape! */ -+ 0x0D8 0x0F /*P8.31 MDIR_2B different from cape! */ -+ -+ /* HRPWM 1 */ -+ 0x048 0x6 /* P9_14 | MODE 6 */ -+ 0x04c 0x6 /* P9_16 | MODE 6 */ -+ -+ /* HRPWM 2 */ -+ 0x020 0x4 /* P8_19 | MODE 4 */ -+ 0x024 0x4 /* P8_13 | MODE 4 */ -+ -+ /* EQEP */ -+ 0x1A0 0x31 /* P9_42,EQEP0A, MODE1 */ -+ 0x1A4 0x31 /* P9_27,EQEP0B, MODE1 */ -+ 0x0D4 0x32 /* P8_33,EQEP1B, MODE2 */ -+ 0x0D0 0x32 /* P8_35,EQEP1A, MODE2 */ -+ 0x030 0x34 /* P8_12,EQEP2A, MODE4 */ -+ 0x034 0x34 /* P8_11,EQEP2B, MODE4 */ -+ -+ /* PRU encoder input */ -+ 0x03c 0x36 /* P8_15,PRU0_r31_15,MODE6 */ -+ 0x038 0x36 /* P8_16,PRU0_r31_16,MODE6 */ -+ -+ /* PRU Servo output */ -+ 0x0e0 0x05 /*pru1_pru_r30_8, MODE5*/ -+ 0x0e8 0x05 /*pru1_pru_r30_10, MODE5 */ -+ 0x0e4 0x05 /*pr1_pru1_pru_r30_9, MODE5 */ -+ 0x0ec 0x05 /*pru1_pru_r30_11, MODE5 */ -+ 0x0b8 0x05 /*pru1_pru_r30_6, MODE5 */ -+ 0x0bc 0x05 /*pru1_pru_r30_7, MODE5 */ -+ 0x0b0 0x05 /*pru1_pru_r30_4, MODE5 */ -+ 0x0b4 0x05 /*pru1_pru_r30_5, MODE5 */ -+ 0x0C8 0x0F /*P8.36, SERVO_PWR GPIO OUT*/ -+ -+ /* I2C1 */ -+ 0x15C 0x32 /* P9.17,i2c1_scl,INPUT_PULLUP,MODE2 */ -+ 0x158 0x32 /* P9.18,i2c1_sda,INPUT_PULLUP,MODE2 */ -+ -+ /* I2C2 */ -+ 0x17c 0x73 /* P9.19, i2c2_sda, mode 3 */ -+ 0x178 0x73 /* P9.20, i2c2_sda, mode 3 */ -+ -+ /* UART5 */ -+ 0x0C4 0x34 /* P8.38,uart5_rxd,MODE4 */ -+ 0x0C0 0x14 /* P8.37,uart5_txd,MODE4 */ -+ -+ /* WILINK 8 */ -+ 0x08c 0x0F /*P8.18 V12 A2DP FSYNC */ -+ 0x078 0x0F /*P9.12 A2DP_CLOCK*/ -+ -+ /* DCAN */ -+ 0x16c ( PIN_INPUT | MUX_MODE2 ) /* (E17) uart0_rtsn.dcan1_rx */ -+ 0x168 ( PIN_OUTPUT | MUX_MODE2 ) /* (E18) uart0_ctsn.dcan1_tx */ -+ >; -+ -+ /*********************************************************************** -+ * New configurable pinmux modes for pins not on Black headers -+ ***********************************************************************/ -+ /* H18 SPI1_SS1 */ -+ H18_default_pin: pinmux_H18_default_pin { -+ pinctrl-single,pins = < 0x144 ( PIN_OUTPUT | MUX_MODE4 ) >; }; -+ H18_gpio_pin: pinmux_H18_gpio_pin { -+ pinctrl-single,pins = < 0x144 ( PIN_OUTPUT | MUX_MODE7 ) >; }; -+ H18_gpio_pu_pin: pinmux_H18_gpio_pu_pin { -+ pinctrl-single,pins = < 0x144 ( PIN_INPUT_PULLUP | MUX_MODE7 ) >; }; -+ H18_gpio_pd_pin: pinmux_H18_gpio_pd_pin { -+ pinctrl-single,pins = < 0x144 ( PIN_INPUT_PULLDOWN | MUX_MODE7 ) >; }; -+ H18_spi_pin: pinmux_H18_spi_pin { -+ pinctrl-single,pins = < 0x144 ( PIN_OUTPUT | MUX_MODE2 ) >; }; -+ -+ /* C18 SPI1_SS2 */ -+ C18_default_pin: pinmux_C18_default_pin { -+ pinctrl-single,pins = < 0x164 ( PIN_OUTPUT | MUX_MODE4 ) >; }; -+ C18_gpio_pin: pinmux_C18_gpio_pin { -+ pinctrl-single,pins = < 0x164 ( PIN_OUTPUT | MUX_MODE7 ) >; }; -+ C18_gpio_pu_pin: pinmux_C18_gpio_pu_pin { -+ pinctrl-single,pins = < 0x164 ( PIN_INPUT_PULLUP | MUX_MODE7 ) >; }; -+ C18_gpio_pd_pin: pinmux_C18_gpio_pd_pin { -+ pinctrl-single,pins = < 0x164 ( PIN_INPUT_PULLDOWN | MUX_MODE7 ) >; }; -+ C18_spi_pin: pinmux_C18_spi_pin { -+ pinctrl-single,pins = < 0x164 ( PIN_OUTPUT | MUX_MODE2 ) >; }; -+ -+ /* U16 BLUE_GP0_PIN_3 gpio 1_25 */ -+ U16_default_pin: pinmux_U16_default_pin { -+ pinctrl-single,pins = < 0x064 ( PIN_INPUT_PULLUP | MUX_MODE7 ) >; }; -+ U16_gpio_pin: pinmux_U16_gpio_pin { -+ pinctrl-single,pins = < 0x064 ( PIN_OUTPUT | MUX_MODE7 ) >; }; -+ U16_gpio_pu_pin: pinmux_U16_gpio_pu_pin { -+ pinctrl-single,pins = < 0x064 ( PIN_INPUT_PULLUP | MUX_MODE7 ) >; }; -+ U16_gpio_pd_pin: pinmux_U16_gpio_pd_pin { -+ pinctrl-single,pins = < 0x064 ( PIN_INPUT_PULLDOWN | MUX_MODE7 ) >; }; -+ -+ /* D13 BLUE_GP0_PIN_5 gpio 3_20 */ -+ D13_default_pin: pinmux_D13_default_pin { -+ pinctrl-single,pins = < 0x1A8 ( PIN_INPUT_PULLUP | MUX_MODE7 ) >; }; -+ D13_gpio_pin: pinmux_D13_gpio_pin { -+ pinctrl-single,pins = < 0x1A8 ( PIN_OUTPUT | MUX_MODE7 ) >; }; -+ D13_gpio_pu_pin: pinmux_D13_gpio_pu_pin { -+ pinctrl-single,pins = < 0x1A8 ( PIN_INPUT_PULLUP | MUX_MODE7 ) >; }; -+ D13_gpio_pd_pin: pinmux_D13_gpio_pd_pin { -+ pinctrl-single,pins = < 0x1A8 ( PIN_INPUT_PULLDOWN | MUX_MODE7 ) >; }; -+ -+ /* J15 BLUE_GP1_PIN_3 gpio 3_2 */ -+ J15_default_pin: pinmux_J15_default_pin { -+ pinctrl-single,pins = < 0x110 ( PIN_INPUT_PULLUP | MUX_MODE7 ) >; }; -+ J15_gpio_pin: pinmux_J15_gpio_pin { -+ pinctrl-single,pins = < 0x110 ( PIN_OUTPUT | MUX_MODE7 ) >; }; -+ J15_gpio_pu_pin: pinmux_J15_gpio_pu_pin { -+ pinctrl-single,pins = < 0x110 ( PIN_INPUT_PULLUP | MUX_MODE7 ) >; }; -+ J15_gpio_pd_pin: pinmux_J15_gpio_pd_pin { -+ pinctrl-single,pins = < 0x110 ( PIN_INPUT_PULLDOWN | MUX_MODE7 ) >; }; -+ -+ /* H17 BLUE_GP1_PIN_4 gpio 3_1 */ -+ H17_default_pin: pinmux_H17_default_pin { -+ pinctrl-single,pins = < 0x10C ( PIN_INPUT_PULLUP | MUX_MODE7 ) >; }; -+ H17_gpio_pin: pinmux_H17_gpio_pin { -+ pinctrl-single,pins = < 0x10C ( PIN_OUTPUT | MUX_MODE7 ) >; }; -+ H17_gpio_pu_pin: pinmux_H17_gpio_pu_pin { -+ pinctrl-single,pins = < 0x10C ( PIN_INPUT_PULLUP | MUX_MODE7 ) >; }; -+ H17_gpio_pd_pin: pinmux_H17_gpio_pd_pin { -+ pinctrl-single,pins = < 0x10C ( PIN_INPUT_PULLDOWN | MUX_MODE7 ) >; }; -+ }; -+ -+}; -+ -+ -+/******************************************************************************* -+* apply static and dynamic pinmux modes listed above. Pins shared with the black -+* header pins get the modes from am335x-boneblack-common-universal-pins.dtsi -+*******************************************************************************/ -+&ocp { -+ /* activate the static pinmux helper list of pin modes above */ -+ test_helper: helper { -+ compatible = "bone-pinmux-helper"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mux_helper_pins>; -+ -+ status = "okay"; -+ }; -+ -+ /* UART4 RX DSM */ -+ P9_11_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart"; -+ pinctrl-0 = <&P9_11_default_pin>; -+ pinctrl-1 = <&P9_11_gpio_pin>; -+ pinctrl-2 = <&P9_11_gpio_pu_pin>; -+ pinctrl-3 = <&P9_11_gpio_pd_pin>; -+ pinctrl-4 = <&P9_11_uart_pin>; -+ }; -+ -+ /* UART 2 TX GPS*/ -+ P9_21_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm"; -+ pinctrl-0 = <&P9_21_default_pin>; -+ pinctrl-1 = <&P9_21_gpio_pin>; -+ pinctrl-2 = <&P9_21_gpio_pu_pin>; -+ pinctrl-3 = <&P9_21_gpio_pd_pin>; -+ pinctrl-4 = <&P9_21_spi_pin>; -+ pinctrl-5 = <&P9_21_uart_pin>; -+ pinctrl-6 = <&P9_21_i2c_pin>; -+ pinctrl-7 = <&P9_21_pwm_pin>; -+ }; -+ -+ /* UART 2 RX GPS */ -+ P9_22_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm"; -+ pinctrl-0 = <&P9_22_default_pin>; -+ pinctrl-1 = <&P9_22_gpio_pin>; -+ pinctrl-2 = <&P9_22_gpio_pu_pin>; -+ pinctrl-3 = <&P9_22_gpio_pd_pin>; -+ pinctrl-4 = <&P9_22_spi_pin>; -+ pinctrl-5 = <&P9_22_uart_pin>; -+ pinctrl-6 = <&P9_22_i2c_pin>; -+ pinctrl-7 = <&P9_22_pwm_pin>; -+ }; -+ -+ /* SPI MISO */ -+ P9_29_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin"; -+ pinctrl-0 = <&P9_29_default_pin>; -+ pinctrl-1 = <&P9_29_gpio_pin>; -+ pinctrl-2 = <&P9_29_gpio_pu_pin>; -+ pinctrl-3 = <&P9_29_gpio_pd_pin>; -+ pinctrl-4 = <&P9_29_pwm_pin>; -+ pinctrl-5 = <&P9_29_spi_pin>; -+ pinctrl-6 = <&P9_29_pruout_pin>; -+ pinctrl-7 = <&P9_29_pruin_pin>; -+ }; -+ -+ /* SPI MOSI */ -+ P9_30_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin"; -+ pinctrl-0 = <&P9_30_default_pin>; -+ pinctrl-1 = <&P9_30_gpio_pin>; -+ pinctrl-2 = <&P9_30_gpio_pu_pin>; -+ pinctrl-3 = <&P9_30_gpio_pd_pin>; -+ pinctrl-4 = <&P9_30_pwm_pin>; -+ pinctrl-5 = <&P9_30_spi_pin>; -+ pinctrl-6 = <&P9_30_pruout_pin>; -+ pinctrl-7 = <&P9_30_pruin_pin>; -+ }; -+ -+ /* SPI SCK */ -+ P9_31_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin"; -+ pinctrl-0 = <&P9_31_default_pin>; -+ pinctrl-1 = <&P9_31_gpio_pin>; -+ pinctrl-2 = <&P9_31_gpio_pu_pin>; -+ pinctrl-3 = <&P9_31_gpio_pd_pin>; -+ pinctrl-4 = <&P9_31_pwm_pin>; -+ pinctrl-5 = <&P9_31_spi_pin>; -+ pinctrl-6 = <&P9_31_pruout_pin>; -+ pinctrl-7 = <&P9_31_pruin_pin>; -+ }; -+ -+ /* SPI SS1 */ -+ H18_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi"; -+ pinctrl-0 = <&H18_default_pin>; -+ pinctrl-1 = <&H18_gpio_pin>; -+ pinctrl-2 = <&H18_gpio_pu_pin>; -+ pinctrl-3 = <&H18_gpio_pd_pin>; -+ pinctrl-4 = <&H18_spi_pin>; -+ }; -+ -+ /* SPI SS2 */ -+ C18_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi"; -+ pinctrl-0 = <&C18_default_pin>; -+ pinctrl-1 = <&C18_gpio_pin>; -+ pinctrl-2 = <&C18_gpio_pu_pin>; -+ pinctrl-3 = <&C18_gpio_pd_pin>; -+ pinctrl-4 = <&C18_spi_pin>; -+ }; -+ -+ /* UART 1 TX */ -+ P9_24_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pruin"; -+ pinctrl-0 = <&P9_24_default_pin>; -+ pinctrl-1 = <&P9_24_gpio_pin>; -+ pinctrl-2 = <&P9_24_gpio_pu_pin>; -+ pinctrl-3 = <&P9_24_gpio_pd_pin>; -+ pinctrl-4 = <&P9_24_uart_pin>; -+ pinctrl-5 = <&P9_24_can_pin>; -+ pinctrl-6 = <&P9_24_i2c_pin>; -+ pinctrl-7 = <&P9_24_pruin_pin>; -+ }; -+ -+ /* UART 1 RX */ -+ P9_26_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pruin"; -+ pinctrl-0 = <&P9_26_default_pin>; -+ pinctrl-1 = <&P9_26_gpio_pin>; -+ pinctrl-2 = <&P9_26_gpio_pu_pin>; -+ pinctrl-3 = <&P9_26_gpio_pd_pin>; -+ pinctrl-4 = <&P9_26_uart_pin>; -+ pinctrl-5 = <&P9_26_can_pin>; -+ pinctrl-6 = <&P9_26_i2c_pin>; -+ pinctrl-7 = <&P9_26_pruin_pin>; -+ }; -+ -+ /* U16 BLUE_GP0_PIN_3 gpio 1_25*/ -+ U16_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd"; -+ pinctrl-0 = <&U16_default_pin>; -+ pinctrl-1 = <&U16_gpio_pin>; -+ pinctrl-2 = <&U16_gpio_pu_pin>; -+ pinctrl-3 = <&U16_gpio_pd_pin>; -+ }; -+ -+ -+ /* BLUE_GP0_PIN_3 gpio1_17*/ -+ P9_23_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; -+ pinctrl-0 = <&P9_23_default_pin>; -+ pinctrl-1 = <&P9_23_gpio_pin>; -+ pinctrl-2 = <&P9_23_gpio_pu_pin>; -+ pinctrl-3 = <&P9_23_gpio_pd_pin>; -+ pinctrl-4 = <&P9_23_pwm_pin>; -+ }; -+ -+ /* BLUE_GP0_PIN_5 gpio3_20 */ -+ D13_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd"; -+ pinctrl-0 = <&D13_default_pin>; -+ pinctrl-1 = <&D13_gpio_pin>; -+ pinctrl-2 = <&D13_gpio_pu_pin>; -+ pinctrl-3 = <&D13_gpio_pd_pin>; -+ }; -+ -+ /* BLUE_GP0_PIN_6 gpio3_17 */ -+ P9_28_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pwm2", "pruout", "pruin"; -+ pinctrl-0 = <&P9_28_default_pin>; -+ pinctrl-1 = <&P9_28_gpio_pin>; -+ pinctrl-2 = <&P9_28_gpio_pu_pin>; -+ pinctrl-3 = <&P9_28_gpio_pd_pin>; -+ pinctrl-4 = <&P9_28_pwm_pin>; -+ pinctrl-5 = <&P9_28_spi_pin>; -+ pinctrl-6 = <&P9_28_pwm2_pin>; -+ pinctrl-7 = <&P9_28_pruout_pin>; -+ pinctrl-8 = <&P9_28_pruin_pin>; -+ }; -+ -+ /* BLUE_GP1_PIN_3 gpio3_2 */ -+ J15_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd"; -+ pinctrl-0 = <&J15_default_pin>; -+ pinctrl-1 = <&J15_gpio_pin>; -+ pinctrl-2 = <&J15_gpio_pu_pin>; -+ pinctrl-3 = <&J15_gpio_pd_pin>; -+ }; -+ -+ /* BLUE_GP1_PIN_4 gpio3_1 */ -+ H17_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd"; -+ pinctrl-0 = <&H17_default_pin>; -+ pinctrl-1 = <&H17_gpio_pin>; -+ pinctrl-2 = <&H17_gpio_pu_pin>; -+ pinctrl-3 = <&H17_gpio_pd_pin>; -+ }; -+ -+ -+ -+}; -+ -+ -+/******************************************************************************* -+* PWMSS -+*******************************************************************************/ -+&epwmss0 { -+ status = "okay"; -+}; -+ -+&epwmss1 { -+ status = "okay"; -+}; -+ -+&epwmss2 { -+ status = "okay"; -+}; -+ -+&ehrpwm0 { -+ status = "okay"; -+}; -+ -+&ehrpwm1 { -+ status = "okay"; -+}; -+ -+&ehrpwm2 { -+ status = "okay"; -+}; -+ -+ -+/******************************************************************************* -+* EQEP -+*******************************************************************************/ -+&eqep0 { -+ count_mode = <0>; /* 0 - Quadrature mode, normal 90 phase offset cha & chb. 1 - Direction mode. cha input = clock, chb input = direction */ -+ swap_inputs = <0>; /* Are channel A and channel B swapped? (0 - no, 1 - yes) */ -+ invert_qa = <1>; /* Should we invert the channel A input? */ -+ invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */ -+ invert_qi = <0>; /* Should we invert the index input? */ -+ invert_qs = <0>; /* Should we invert the strobe input? */ -+ status = "okay"; -+}; -+ -+&eqep1 { -+ count_mode = <0>; /* 0 - Quadrature mode, normal 90 phase offset cha & chb. 1 - Direction mode. cha input = clock, chb input = direction */ -+ swap_inputs = <0>; /* Are channel A and channel B swapped? (0 - no, 1 - yes) */ -+ invert_qa = <1>; /* Should we invert the channel A input? */ -+ invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */ -+ invert_qi = <0>; /* Should we invert the index input? */ -+ invert_qs = <0>; /* Should we invert the strobe input? */ -+ status = "okay"; -+}; -+ -+&eqep2 { -+ count_mode = <0>; /* 0 - Quadrature mode, normal 90 phase offset cha & chb. 1 - Direction mode. cha input = clock, chb input = direction */ -+ swap_inputs = <0>; /* Are channel A and channel B swapped? (0 - no, 1 - yes) */ -+ invert_qa = <1>; /* Should we invert the channel A input? */ -+ invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */ -+ invert_qi = <0>; /* Should we invert the index input? */ -+ invert_qs = <0>; /* Should we invert the strobe input? */ -+ status = "okay"; -+}; -+ -+ -+/******************************************************************************* -+ UART -+*******************************************************************************/ -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&uart4 { -+ status = "okay"; -+}; -+ -+&uart5 { -+ status = "okay"; -+}; -+ -+ -+/******************************************************************************* -+ PRU -+*******************************************************************************/ -+&pruss { -+ status = "okay"; -+}; -+ -+ -+/******************************************************************************* -+ I2C -+*******************************************************************************/ -+&i2c1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ clock-frequency = <400000>; -+}; -+ -+&i2c2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ clock-frequency = <400000>; -+}; -+ -+/******************************************************************************* -+ SPI -+*******************************************************************************/ -+&spi1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ channel@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "spidev"; -+ reg = <0>; -+ spi-max-frequency = <24000000>; -+ }; -+ -+ channel@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "spidev"; -+ reg = <1>; -+ spi-max-frequency = <24000000>; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-bonegreen-overlay.dts b/arch/arm/boot/dts/am335x-bonegreen-overlay.dts -new file mode 100644 -index 0000000..a703fcd ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bonegreen-overlay.dts -@@ -0,0 +1,36 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common.dtsi" -+ -+/ { -+ model = "TI AM335x BeagleBone Green"; -+ compatible = "ti,am335x-bone-green", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+/* EMMC in reset */ -+&gpio1 { -+ emmc_rst { -+ gpio-hog; -+ gpios = <20 0>; -+ output-high; -+ line-name = "EMMC ResetN"; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-bonegreen-wireless.dts b/arch/arm/boot/dts/am335x-bonegreen-wireless.dts -new file mode 100644 -index 0000000..f37f39e ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bonegreen-wireless.dts -@@ -0,0 +1,48 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common.dtsi" -+#include "am335x-bonegreen-wl1835.dtsi" -+/* #include "am335x-bone-jtag.dtsi" */ -+ -+/ { -+ model = "TI AM335x BeagleBone Green Wireless"; -+ compatible = "ti,am335x-bone-green", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ status = "okay"; -+}; -+ -+&uart3 { -+ status = "okay"; -+}; -+ -+&mmc3 { -+ status = "okay"; -+}; -+ -+&mac { -+ status = "disabled"; -+}; -diff --git b/arch/arm/boot/dts/am335x-bonegreen-wl1835.dtsi b/arch/arm/boot/dts/am335x-bonegreen-wl1835.dtsi -new file mode 100644 -index 0000000..0d4798d ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-bonegreen-wl1835.dtsi -@@ -0,0 +1,147 @@ -+#include <dt-bindings/interrupt-controller/irq.h> -+ -+/ { -+ wlan_en_reg: fixedregulator@2 { -+ compatible = "regulator-fixed"; -+ regulator-name = "wlan-en-regulator"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ startup-delay-us= <70000>; -+ -+ /* WL_EN */ -+ gpio = <&gpio0 26 0>; -+ enable-active-high; -+ }; -+ -+ btwilink { -+ compatible = "btwilink"; -+ }; -+ -+ wilink8_pcm: wilink8_pcm { -+ compatible = "ti,wilink8_bt"; -+ status = "okay"; -+ }; -+ -+ sound{ -+ compatible = "ti,wilink8-bt-audio"; -+ ti,model = "WILINK8_BT"; -+ ti,audio-codec = <&wilink8_pcm>; -+ ti,mcasp-controller = <&mcasp0>; -+ ti,codec-clock-rate = <24000000>; -+ }; -+}; -+ -+&am33xx_pinmux { -+ bt_pins: pinmux_bt_pins { -+ pinctrl-single,pins = < -+ 0x78 (PIN_OUTPUT | MUX_MODE7) /* gpmc_ad12.gpio1_28 BT_EN*/ -+ >; -+ }; -+ -+ mmc3_pins: pinmux_mmc3_pins { -+ pinctrl-single,pins = < -+ 0x8c ( PIN_INPUT_PULLUP | MUX_MODE3 ) /* gpio2_1 gpmc_clk.mmc2_clk */ -+ 0x88 ( PIN_INPUT_PULLUP | MUX_MODE3) /* gpio2_0 gpmc_csn3.mmc2_cmd */ -+ 0x30 ( PIN_INPUT_PULLUP | MUX_MODE3 ) /* gpio1_12 gpmc_ad12.mmc2_dat0 */ -+ 0x34 ( PIN_INPUT_PULLUP | MUX_MODE3 ) /* gpio1_13 gpmc_ad13.mmc2_dat1 */ -+ 0x38 ( PIN_INPUT_PULLUP | MUX_MODE3 ) /* gpio1_14 gpmc_ad14.mmc2_dat2 */ -+ 0x3c ( PIN_INPUT_PULLUP | MUX_MODE3 ) /* gpio1_15 gpmc_ad15.mmc2_dat3 */ -+ >; -+ }; -+ -+ mmc3_pins_sleep: pinmux_mmc3_pins_sleep { -+ pinctrl-single,pins = < -+ 0x8c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpio2_1 gpmc_clk.mmc2_clk */ -+ 0x88 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpio2_0 gpmc_csn3.mmc2_cmd */ -+ 0x30 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpio1_12 gpmc_ad12.mmc2_dat0 */ -+ 0x34 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpio1_13 gpmc_ad13.mmc2_dat1 */ -+ 0x38 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpio1_14 gpmc_ad14.mmc2_dat2 */ -+ 0x3c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpio1_15 gpmc_ad15.mmc2_dat3 */ -+ >; -+ }; -+ -+ /* wl18xx card enable/irq GPIOs. */ -+ wlan_pins: pinmux_wlan_pins { -+ pinctrl-single,pins = < -+ 0x28 (PIN_OUTPUT_PULLDOWN| MUX_MODE7) /* gpmc_ad10.gpio0_26 WL_EN*/ -+ 0x2C (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad11.gpio0_27 WL_IRQ*/ -+ 0x7C (PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_csn0.gpio1_29 Cape_Buffer_EN*/ -+ >; -+ }; -+ -+ /* wl18xx card enable/irq GPIOs. */ -+ wlan_pins_sleep: pinmux_wlan_pins_sleep { -+ pinctrl-single,pins = < -+ 0x28 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad10.gpio0_26 WL_EN*/ -+ 0x2C (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad11.gpio0_27 WL_IRQ*/ -+ 0x7C (PIN_OUTPUT_PULLUP | MUX_MODE0) /* gpmc_csn0.gpio1_29 Cape_Buffer_EN*/ -+ >; -+ }; -+ -+ uart3_pins_default: pinmux_uart3_pins_default { -+ pinctrl-single,pins = < -+ 0x134 ( PIN_INPUT_PULLUP | MUX_MODE1 ) /* (L17) gmii1_rxd3.uart3_rxd */ -+ 0x138 ( PIN_OUTPUT_PULLDOWN | MUX_MODE1 ) /* (L16) gmii1_rxd2.uart3_txd */ -+ 0x148 ( PIN_INPUT | MUX_MODE3 ) /* (M17) mdio_data.uart3_ctsn */ -+ 0x14c ( PIN_OUTPUT_PULLDOWN | MUX_MODE3 ) /* (M18) mdio_clk.uart3_rtsn */ -+ >; -+ }; -+ -+ uart3_pins_sleep: pinmux_uart3_pins_sleep { -+ pinctrl-single,pins = < -+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* (L17) gmii1_rxd3.uart3_rxd */ -+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* (L16) gmii1_rxd2.uart3_txd */ -+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* (M17) mdio_data.uart3_ctsn */ -+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* (M18) mdio_clk.uart3_rtsn */ -+ >; -+ }; -+}; -+ -+&mmc3 { -+ dmas = <&edma_xbar 12 0 1 -+ &edma_xbar 13 0 2>; -+ dma-names = "tx", "rx"; -+ status = "okay"; -+ vmmc-supply = <&wlan_en_reg>; -+ bus-width = <4>; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&mmc3_pins &wlan_pins>; -+ pinctrl-1 = <&mmc3_pins_sleep &wlan_pins_sleep>; -+ ti,non-removable; -+ ti,needs-special-hs-handling; -+ cap-power-off-card; -+ keep-power-in-suspend; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ wlcore: wlcore@0 { -+ compatible = "ti,wl1835"; -+ reg = <2>; -+ interrupt-parent = <&gpio0>; -+ interrupts = <27 IRQ_TYPE_EDGE_RISING>; -+ }; -+}; -+ -+&uart3 { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&uart3_pins_default &bt_pins>; -+ pinctrl-1 = <&uart3_pins_sleep &bt_pins>; -+ status = "okay"; -+}; -+ -+/* BT_AUD_OUT from wl1835 has to be pulled low when WL_EN is activated. */ -+/* in case it isn't, wilink8 ends up in one of the test modes that */ -+/* intruces various issues (elp wkaeup timeouts etc.) */ -+/* On the BBGW this pin is routed through the level shifter (U21) that */ -+/* introduces a pullup on the line and wilink8 ends up in a bad state. */ -+/* use a gpio hog to force this pin low. An alternative may be adding */ -+/* an external pulldown on U21 pin 4. */ -+ -+&gpio3 { -+ bt_aud_in { -+ gpio-hog; -+ gpios = <16 GPIO_ACTIVE_HIGH>; -+ output-low; -+ line-name = "MCASP0_AXR0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/am335x-bonegreen.dts b/arch/arm/boot/dts/am335x-bonegreen.dts -index dce3c86..647d4bf 100644 ---- a/arch/arm/boot/dts/am335x-bonegreen.dts -+++ b/arch/arm/boot/dts/am335x-bonegreen.dts -@@ -9,6 +9,7 @@ - - #include "am33xx.dtsi" - #include "am335x-bone-common.dtsi" -+/* #include "am335x-bone-jtag.dtsi" */ - - / { - model = "TI AM335x BeagleBone Green"; -@@ -32,22 +33,3 @@ - bus-width = <8>; - status = "okay"; - }; -- --&am33xx_pinmux { -- uart2_pins: uart2_pins { -- pinctrl-single,pins = < -- AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE1) /* spi0_sclk.uart2_rxd */ -- AM33XX_IOPAD(0x954, PIN_OUTPUT | MUX_MODE1) /* spi0_d0.uart2_txd */ -- >; -- }; --}; -- --&uart2 { -- pinctrl-names = "default"; -- pinctrl-0 = <&uart2_pins>; -- status = "okay"; --}; -- --&rtc { -- system-power-controller; --}; -diff --git b/arch/arm/boot/dts/am335x-cape-bbb-exp-c.dtsi b/arch/arm/boot/dts/am335x-cape-bbb-exp-c.dtsi -new file mode 100644 -index 0000000..01f9cde ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-cape-bbb-exp-c.dtsi -@@ -0,0 +1,224 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+ -+#include "am335x-peripheral-can0.dtsi" -+#include "am335x-bone-pinmux-can0.dtsi" -+ -+#include "am335x-peripheral-ttyS1.dtsi" -+#include "am335x-bone-pinmux-ttyS1.dtsi" -+ -+#include "am335x-peripheral-ttyS2.dtsi" -+#include "am335x-bone-pinmux-ttyS2.dtsi" -+ -+#include "am335x-peripheral-ttyS4.dtsi" -+#include "am335x-bone-pinmux-ttyS4.dtsi" -+ -+&am33xx_pinmux { -+ user_leds_s1: user_leds_s1 { -+ pinctrl-single,pins = < -+ 0x98 0x7 /* gpmc_wen.gpio2_4, OUTPUT | MODE7 */ -+ 0x9c 0x7 /* gpmc_ben0_cle.gpio2_5, OUTPUT | MODE7 */ -+ >; -+ }; -+ -+ bb_lcd_pwm_backlight_pins: pinmux_bb_lcd_pwm_backlight_pins { -+ pinctrl-single,pins = < -+ BONE_P9_14 (PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* gpmc_a2.ehrpwm1a */ -+ >; -+ }; -+ -+ keymap3_pins: pinmux_keymap3_pins { -+ pinctrl-single,pins = < -+ 0x040 0x2f /* KEY_UP gpmc_a0.gpio1_16, INPUT | PULLDIS | MODE7 */ -+ 0x04c 0x2f /* KEY_DOWN gpmc_a3.gpio1_19, INPUT | PULLDIS | MODE7 */ -+ 0x078 0x2f /* KEY_RIGHT gpmc_ben1.gpio1_28, INPUT | PULLDIS | MODE7 */ -+ 0x164 0x2f /* KEY_LEFT ecap0_in_pwm0_out.gpio0_7, INPUT | PULLDIS | MODE7 */ -+ 0x1a4 0x2f /* KEY_ENTER mcasp0_fxr.gpio3_19, INPUT | PULLDIS | MODE7 */ -+ >; -+ }; -+ -+ edt_ft5306_ts_pins: pinmux_edt_ft5306_ts_pins { -+ pinctrl-single,pins = < -+ /* CAP_TSC gpmc_a1.gpio1_17, INPUT | MODE7 */ -+ BONE_P9_23 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+ i2c1_pins: pinmux_i2c1_pins { -+ pinctrl-single,pins = < -+ /* spi0_d1.i2c1_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE2 */ -+ BONE_P9_18 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2) -+ /* spi0_cs0.i2c1_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE2 */ -+ BONE_P9_17 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2) -+ >; -+ }; -+ -+ mcasp0_pins: pinmux_mcasp0_pins { -+ pinctrl-single,pins = < -+ 0x190 0x20 /* mcasp0_aclkx.mcasp0_aclkx, INPUT | MODE0 */ -+ 0x194 0x20 /* mcasp0_fsx.mcasp0_fsx, INPUT | MODE0 */ -+ 0x198 0x20 /* mcasp0_axr0.mcasp0_axr0, INPUT | MODE0 */ -+ 0x19c 0x22 /* mcasp0_ahclkr.mcasp0_axr2, INPUT | MODE2 */ -+ >; -+ }; -+}; -+ -+&epwmss1 { -+ status = "okay"; -+}; -+ -+ -+&ehrpwm1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&bb_lcd_pwm_backlight_pins>; -+ status = "okay"; -+}; -+ -+&i2c1 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <400000>; -+ -+ edt-ft5306@38 { -+ status = "okay"; -+ compatible = "edt,edt-ft5306", "edt,edt-ft5x06"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&edt_ft5306_ts_pins>; -+ -+ reg = <0x38>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <17 0>; -+ -+ touchscreen-size-x = <1024>; -+ touchscreen-size-y = <600>; -+ }; -+ -+ tlv320aic3x: tlv320aic3x@1b { -+ compatible = "ti,tlv320aic3x"; -+ reg = <0x1b>; -+ status = "okay"; -+ }; -+}; -+ -+&mcasp0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcasp0_pins>; -+ -+ status = "okay"; -+ -+ op-mode = <0>; /* MCASP_IIS_MODE */ -+ tdm-slots = <2>; -+ num-serializer = <16>; -+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ -+ 1 0 2 0 -+ 0 0 0 0 -+ 0 0 0 0 -+ 0 0 0 0 -+ >; -+ tx-num-evt = <1>; -+ rx-num-evt = <1>; -+}; -+ -+/ { -+ backlight { -+ status = "okay"; -+ compatible = "pwm-backlight"; -+ pwms = <&ehrpwm1 0 50000 0>; -+ brightness-levels = <0 51 53 56 62 75 101 152 255>; -+ default-brightness-level = <8>; -+ }; -+ -+ gpio_keys { -+ compatible = "gpio-keys"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&keymap3_pins>; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ button@1 { -+ debounce_interval = <50>; -+ linux,code = <105>; -+ label = "left"; -+ gpios = <&gpio0 7 0x1>; -+ gpio-key,wakeup; -+ autorepeat; -+ }; -+ button@2 { -+ debounce_interval = <50>; -+ linux,code = <106>; -+ label = "right"; -+ gpios = <&gpio1 28 0x1>; -+ gpio-key,wakeup; -+ autorepeat; -+ }; -+ button@3 { -+ debounce_interval = <50>; -+ linux,code = <103>; -+ label = "up"; -+ gpios = <&gpio1 16 0x1>; -+ gpio-key,wakeup; -+ autorepeat; -+ }; -+ button@4 { -+ debounce_interval = <50>; -+ linux,code = <108>; -+ label = "down"; -+ gpios = <&gpio1 19 0x1>; -+ gpio-key,wakeup; -+ autorepeat; -+ }; -+ button@5 { -+ debounce_interval = <50>; -+ linux,code = <28>; -+ label = "enter"; -+ gpios = <&gpio3 19 0x1>; -+ gpio-key,wakeup; -+ }; -+ }; -+ -+ gpio-leds-cape-lcd { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ -+ pinctrl-0 = <&user_leds_s1>; -+ -+ lcd-led0 { -+ label = "lcd:green:usr0"; -+ gpios = <&gpio2 4 0>; -+ linux,default-trigger = "heartbeat"; -+ default-state = "off"; -+ }; -+ -+ lcd-led1 { -+ label = "lcd:green:usr1"; -+ gpios = <&gpio2 5 0>; -+ linux,default-trigger = "mmc0"; -+ default-state = "off"; -+ }; -+ }; -+ -+ sound { -+ compatible = "ti,da830-evm-audio"; -+ ti,model = "DA830 EVM"; -+ ti,audio-codec = <&tlv320aic3x>; -+ ti,mcasp-controller = <&mcasp0>; -+ ti,codec-clock-rate = <12000000>; -+ ti,audio-routing = -+ "Headphone Jack", "HPLOUT", -+ "Headphone Jack", "HPROUT", -+ "MIC3L", "Mic Jack", -+ "MIC3R", "Mic Jack"; -+ }; -+}; -+ -+#include "am335x-peripheral-panel-1024x600-24bit.dtsi" -+#include "am335x-bone-pinmux-panel-1024x600-24bit.dtsi" -diff --git b/arch/arm/boot/dts/am335x-cape-bbb-exp-r.dtsi b/arch/arm/boot/dts/am335x-cape-bbb-exp-r.dtsi -new file mode 100644 -index 0000000..539409c ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-cape-bbb-exp-r.dtsi -@@ -0,0 +1,217 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+ -+#include "am335x-peripheral-can0.dtsi" -+#include "am335x-bone-pinmux-can0.dtsi" -+ -+#include "am335x-peripheral-ttyS1.dtsi" -+#include "am335x-bone-pinmux-ttyS1.dtsi" -+ -+#include "am335x-peripheral-ttyS2.dtsi" -+#include "am335x-bone-pinmux-ttyS2.dtsi" -+ -+#include "am335x-peripheral-ttyS4.dtsi" -+#include "am335x-bone-pinmux-ttyS4.dtsi" -+ -+&am33xx_pinmux { -+ user_leds_s1: user_leds_s1 { -+ pinctrl-single,pins = < -+ 0x98 0x7 /* gpmc_wen.gpio2_4, OUTPUT | MODE7 */ -+ 0x9c 0x7 /* gpmc_ben0_cle.gpio2_5, OUTPUT | MODE7 */ -+ >; -+ }; -+ -+ bb_lcd_pwm_backlight_pins: pinmux_bb_lcd_pwm_backlight_pins { -+ pinctrl-single,pins = < -+ BONE_P9_14 (PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* gpmc_a2.ehrpwm1a */ -+ >; -+ }; -+ -+ keymap3_pins: pinmux_keymap3_pins { -+ pinctrl-single,pins = < -+ 0x040 0x2f /* KEY_UP gpmc_a0.gpio1_16, INPUT | PULLDIS | MODE7 */ -+ 0x04c 0x2f /* KEY_DOWN gpmc_a3.gpio1_19, INPUT | PULLDIS | MODE7 */ -+ 0x078 0x2f /* KEY_RIGHT gpmc_ben1.gpio1_28, INPUT | PULLDIS | MODE7 */ -+ 0x164 0x2f /* KEY_LEFT ecap0_in_pwm0_out.gpio0_7, INPUT | PULLDIS | MODE7 */ -+ 0x1a4 0x2f /* KEY_ENTER mcasp0_fxr.gpio3_19, INPUT | PULLDIS | MODE7 */ -+ >; -+ }; -+ -+ i2c1_pins: pinmux_i2c1_pins { -+ pinctrl-single,pins = < -+ /* spi0_d1.i2c1_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE2 */ -+ BONE_P9_18 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2) -+ /* spi0_cs0.i2c1_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE2 */ -+ BONE_P9_17 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE2) -+ >; -+ }; -+ -+ mcasp0_pins: pinmux_mcasp0_pins { -+ pinctrl-single,pins = < -+ 0x190 0x20 /* mcasp0_aclkx.mcasp0_aclkx, INPUT | MODE0 */ -+ 0x194 0x20 /* mcasp0_fsx.mcasp0_fsx, INPUT | MODE0 */ -+ 0x198 0x20 /* mcasp0_axr0.mcasp0_axr0, INPUT | MODE0 */ -+ 0x19c 0x22 /* mcasp0_ahclkr.mcasp0_axr2, INPUT | MODE2 */ -+ >; -+ }; -+}; -+ -+&epwmss1 { -+ status = "okay"; -+}; -+ -+ -+&ehrpwm1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&bb_lcd_pwm_backlight_pins>; -+ status = "okay"; -+}; -+ -+&i2c1 { -+ status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <400000>; -+ -+ tlv320aic3x: tlv320aic3x@1b { -+ compatible = "ti,tlv320aic3x"; -+ reg = <0x1b>; -+ status = "okay"; -+ }; -+}; -+ -+&mcasp0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcasp0_pins>; -+ -+ status = "okay"; -+ -+ op-mode = <0>; /* MCASP_IIS_MODE */ -+ tdm-slots = <2>; -+ num-serializer = <16>; -+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ -+ 1 0 2 0 -+ 0 0 0 0 -+ 0 0 0 0 -+ 0 0 0 0 -+ >; -+ tx-num-evt = <1>; -+ rx-num-evt = <1>; -+}; -+ -+&tscadc { -+ status = "okay"; -+ tsc { -+ ti,wires = <4>; -+ ti,x-plate-resistance = <200>; -+ ti,coordinate-readouts = <5>; -+ ti,wire-config = <0x00 0x11 0x22 0x33>; -+ }; -+ -+ adc { -+ ti,adc-channels = <4 5 6 7>; -+ }; -+}; -+ -+/ { -+ backlight { -+ status = "okay"; -+ compatible = "pwm-backlight"; -+ pwms = <&ehrpwm1 0 50000 0>; -+ brightness-levels = <0 51 53 56 62 75 101 152 255>; -+ default-brightness-level = <8>; -+ }; -+ -+ gpio_keys { -+ compatible = "gpio-keys"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&keymap3_pins>; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ button@1 { -+ debounce_interval = <50>; -+ linux,code = <105>; -+ label = "left"; -+ gpios = <&gpio0 7 0x1>; -+ gpio-key,wakeup; -+ autorepeat; -+ }; -+ button@2 { -+ debounce_interval = <50>; -+ linux,code = <106>; -+ label = "right"; -+ gpios = <&gpio1 28 0x1>; -+ gpio-key,wakeup; -+ autorepeat; -+ }; -+ button@3 { -+ debounce_interval = <50>; -+ linux,code = <103>; -+ label = "up"; -+ gpios = <&gpio1 16 0x1>; -+ gpio-key,wakeup; -+ autorepeat; -+ }; -+ button@4 { -+ debounce_interval = <50>; -+ linux,code = <108>; -+ label = "down"; -+ gpios = <&gpio1 19 0x1>; -+ gpio-key,wakeup; -+ autorepeat; -+ }; -+ button@5 { -+ debounce_interval = <50>; -+ linux,code = <28>; -+ label = "enter"; -+ gpios = <&gpio3 19 0x1>; -+ gpio-key,wakeup; -+ }; -+ }; -+ -+ gpio-leds-cape-lcd { -+ compatible = "gpio-leds"; -+ pinctrl-names = "default"; -+ -+ pinctrl-0 = <&user_leds_s1>; -+ -+ lcd-led0 { -+ label = "lcd:green:usr0"; -+ gpios = <&gpio2 4 0>; -+ linux,default-trigger = "heartbeat"; -+ default-state = "off"; -+ }; -+ -+ lcd-led1 { -+ label = "lcd:green:usr1"; -+ gpios = <&gpio2 5 0>; -+ linux,default-trigger = "mmc0"; -+ default-state = "off"; -+ }; -+ }; -+ -+ sound { -+ compatible = "ti,da830-evm-audio"; -+ ti,model = "DA830 EVM"; -+ ti,audio-codec = <&tlv320aic3x>; -+ ti,mcasp-controller = <&mcasp0>; -+ ti,codec-clock-rate = <12000000>; -+ ti,audio-routing = -+ "Headphone Jack", "HPLOUT", -+ "Headphone Jack", "HPROUT", -+ "MIC3L", "Mic Jack", -+ "MIC3R", "Mic Jack"; -+ }; -+}; -+ -+#include "am335x-peripheral-panel-1024x600-24bit.dtsi" -+#include "am335x-bone-pinmux-panel-1024x600-24bit.dtsi" -diff --git b/arch/arm/boot/dts/am335x-cape-rtc-ds1307.dtsi b/arch/arm/boot/dts/am335x-cape-rtc-ds1307.dtsi -new file mode 100644 -index 0000000..bce6ac5 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-cape-rtc-ds1307.dtsi -@@ -0,0 +1,31 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <dt-bindings/board/am335x-bbw-bbb-base.h> -+ -+&am33xx_pinmux { -+ i2c2_pins: pinmux_i2c2_pins { -+ pinctrl-single,pins = < -+ BONE_P9_20 0x73 /* (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3) uart1_ctsn.i2c2_sda */ -+ BONE_P9_19 0x73 /* (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3) uart1_rtsn.i2c2_scl */ -+ >; -+ }; -+}; -+ -+&i2c2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c2_pins>; -+ -+ status = "okay"; -+ clock-frequency = <100000>; -+ -+ rtc@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-olimex-som.dts b/arch/arm/boot/dts/am335x-olimex-som.dts -new file mode 100644 -index 0000000..2b00ad2 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-olimex-som.dts -@@ -0,0 +1,189 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-som-common.dtsi" -+ -+/ { -+ model = "Olimex AM335x SOM"; -+ compatible = "olimex,am335x-olimex-som", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&am33xx_pinmux { -+ lcd_pins_default: lcd_pins_default { -+ pinctrl-single,pins = < -+ 0x20 0x01 /* gpmc_ad8.lcd_data16, OUTPUT | MODE1 */ -+ 0x24 0x01 /* gpmc_ad9.lcd_data17, OUTPUT | MODE1 */ -+ 0x28 0x01 /* gpmc_ad10.lcd_data18, OUTPUT | MODE1 */ -+ 0x2c 0x01 /* gpmc_ad11.lcd_data19, OUTPUT | MODE1 */ -+ 0x30 0x01 /* gpmc_ad12.lcd_data20, OUTPUT | MODE1 */ -+ 0x34 0x01 /* gpmc_ad13.lcd_data21, OUTPUT | MODE1 */ -+ 0x38 0x01 /* gpmc_ad14.lcd_data22, OUTPUT | MODE1 */ -+ 0x3c 0x01 /* gpmc_ad15.lcd_data23, OUTPUT | MODE1 */ -+ 0xa0 0x00 /* lcd_data0.lcd_data0, OUTPUT | MODE0 */ -+ 0xa4 0x00 /* lcd_data1.lcd_data1, OUTPUT | MODE0 */ -+ 0xa8 0x00 /* lcd_data2.lcd_data2, OUTPUT | MODE0 */ -+ 0xac 0x00 /* lcd_data3.lcd_data3, OUTPUT | MODE0 */ -+ 0xb0 0x00 /* lcd_data4.lcd_data4, OUTPUT | MODE0 */ -+ 0xb4 0x00 /* lcd_data5.lcd_data5, OUTPUT | MODE0 */ -+ 0xb8 0x00 /* lcd_data6.lcd_data6, OUTPUT | MODE0 */ -+ 0xbc 0x00 /* lcd_data7.lcd_data7, OUTPUT | MODE0 */ -+ 0xc0 0x00 /* lcd_data8.lcd_data8, OUTPUT | MODE0 */ -+ 0xc4 0x00 /* lcd_data9.lcd_data9, OUTPUT | MODE0 */ -+ 0xc8 0x00 /* lcd_data10.lcd_data10, OUTPUT | MODE0 */ -+ 0xcc 0x00 /* lcd_data11.lcd_data11, OUTPUT | MODE0 */ -+ 0xd0 0x00 /* lcd_data12.lcd_data12, OUTPUT | MODE0 */ -+ 0xd4 0x00 /* lcd_data13.lcd_data13, OUTPUT | MODE0 */ -+ 0xd8 0x00 /* lcd_data14.lcd_data14, OUTPUT | MODE0 */ -+ 0xdc 0x00 /* lcd_data15.lcd_data15, OUTPUT | MODE0 */ -+ 0xe0 0x00 /* lcd_vsync.lcd_vsync, OUTPUT | MODE0 */ -+ 0xe4 0x00 /* lcd_hsync.lcd_hsync, OUTPUT | MODE0 */ -+ 0xe8 0x00 /* lcd_pclk.lcd_pclk, OUTPUT | MODE0 */ -+ 0xec 0x00 /* lcd_ac_bias_en.lcd_ac_bias_en, OUTPUT | MODE0 */ -+ >; -+ }; -+ -+ lcd_pins_sleep: lcd_pins_sleep { -+ pinctrl-single,pins = < -+ 0x20 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad8.lcd_data16 */ -+ 0x24 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad9.lcd_data17 */ -+ 0x28 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad10.lcd_data18 */ -+ 0x2c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad11.lcd_data19 */ -+ 0x30 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad12.lcd_data20 */ -+ 0x34 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad13.lcd_data21 */ -+ 0x38 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad14.lcd_data22 */ -+ 0x3c (PIN_INPUT_PULLDOWN | MUX_MODE7) /* gpmc_ad15.lcd_data23 */ -+ 0xa0 (PULL_DISABLE | MUX_MODE7) /* lcd_data0.lcd_data0 */ -+ 0xa4 (PULL_DISABLE | MUX_MODE7) /* lcd_data1.lcd_data1 */ -+ 0xa8 (PULL_DISABLE | MUX_MODE7) /* lcd_data2.lcd_data2 */ -+ 0xac (PULL_DISABLE | MUX_MODE7) /* lcd_data3.lcd_data3 */ -+ 0xb0 (PULL_DISABLE | MUX_MODE7) /* lcd_data4.lcd_data4 */ -+ 0xb4 (PULL_DISABLE | MUX_MODE7) /* lcd_data5.lcd_data5 */ -+ 0xb8 (PULL_DISABLE | MUX_MODE7) /* lcd_data6.lcd_data6 */ -+ 0xbc (PULL_DISABLE | MUX_MODE7) /* lcd_data7.lcd_data7 */ -+ 0xc0 (PULL_DISABLE | MUX_MODE7) /* lcd_data8.lcd_data8 */ -+ 0xc4 (PULL_DISABLE | MUX_MODE7) /* lcd_data9.lcd_data9 */ -+ 0xc8 (PULL_DISABLE | MUX_MODE7) /* lcd_data10.lcd_data10 */ -+ 0xcc (PULL_DISABLE | MUX_MODE7) /* lcd_data11.lcd_data11 */ -+ 0xd0 (PULL_DISABLE | MUX_MODE7) /* lcd_data12.lcd_data12 */ -+ 0xd4 (PULL_DISABLE | MUX_MODE7) /* lcd_data13.lcd_data13 */ -+ 0xd8 (PULL_DISABLE | MUX_MODE7) /* lcd_data14.lcd_data14 */ -+ 0xdc (PULL_DISABLE | MUX_MODE7) /* lcd_data15.lcd_data15 */ -+ /* lcd_vsync.lcd_vsync,OUTPUT | MODE0 */ -+ 0xe0 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0xe4 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_hsync.lcd_hsync */ -+ 0xe8 (PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_pclk.lcd_pclk */ -+ /* lcd_ac_bias_en.lcd_ac_bias_en */ -+ 0xec (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+}; -+ -+&lcdc { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&lcd_pins_default>; -+ pinctrl-1 = <&lcd_pins_sleep>; -+ status = "okay"; -+ /* display-timings { -+ 480x272 { -+ hactive = <480>; -+ vactive = <272>; -+ hback-porch = <43>; -+ hfront-porch = <8>; -+ hsync-len = <4>; -+ vback-porch = <12>; -+ vfront-porch = <4>; -+ vsync-len = <10>; -+ clock-frequency = <9000000>; -+ hsync-active = <0>; -+ vsync-active = <0>; -+ }; -+ };*/ -+ -+ display-timings { -+ native-mode = <&vga1024x768>; -+ lcd4: 480x272 { -+ clock-frequency = <9000000>; -+ hactive = <480>; -+ vactive = <272>; -+ hfront-porch = <3>; -+ hback-porch = <40>; -+ vback-porch = <8>; -+ vfront-porch = <7>; -+ hsync-len = <2>; -+ vsync-len = <1>; -+ hsync-active = <0>; -+ vsync-active = <0>; -+ }; -+ lcd7: 800x480 { -+ clock-frequency = <33300000>; -+ hactive = <800>; -+ vactive = <480>; -+ hfront-porch = <210>; -+ hback-porch = <40>; -+ vback-porch = <23>; -+ vfront-porch = <20>; -+ hsync-len = <6>; -+ vsync-len = <2>; -+ hsync-active = <0>; -+ vsync-active = <0>; -+ }; -+ lcd10: 1024x600 { -+ clock-frequency = <51200000>; -+ hactive = <1024>; -+ vactive = <600>; -+ hfront-porch = <160>; -+ hback-porch = <140>; -+ vback-porch = <20>; -+ vfront-porch = <12>; -+ hsync-len = <20>; -+ vsync-len = <3>; -+ hsync-active = <0>; -+ vsync-active = <0>; -+ }; -+ -+ vga800x600: 800x600 { -+ clock-frequency = <40000000>; -+ hactive = <800>; -+ vactive = <600>; -+ hfront-porch = <40>; -+ hback-porch = <88>; -+ vfront-porch = <1>; -+ vback-porch = <23>; -+ hsync-len = <128>; -+ vsync-len = <4>; -+ hsync-active = <0>; -+ vsync-active = <0>; -+ }; -+ vga1024x768: 1024x768 { -+ clock-frequency = <65000000>; -+ hactive = <1024>; -+ hfront-porch = <24>; -+ hback-porch = <160>; -+ hsync-len = <136>; -+ vactive = <768>; -+ vfront-porch = <3>; -+ vback-porch = <29>; -+ vsync-len = <6>; -+ hsync-active = <0>; -+ vsync-active = <0>; -+ }; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-peripheral-can0.dtsi b/arch/arm/boot/dts/am335x-peripheral-can0.dtsi -new file mode 100644 -index 0000000..4335e39 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-peripheral-can0.dtsi -@@ -0,0 +1,13 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&dcan0 { -+ pinctrl-names = "default"; -+ -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-peripheral-can1.dtsi b/arch/arm/boot/dts/am335x-peripheral-can1.dtsi -new file mode 100644 -index 0000000..02b5bd1 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-peripheral-can1.dtsi -@@ -0,0 +1,13 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&dcan1 { -+ pinctrl-names = "default"; -+ -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-peripheral-emmc.dtsi b/arch/arm/boot/dts/am335x-peripheral-emmc.dtsi -new file mode 100644 -index 0000000..603f34e ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-peripheral-emmc.dtsi -@@ -0,0 +1,15 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ -+ bus-width = <8>; -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-peripheral-i2c2.dtsi b/arch/arm/boot/dts/am335x-peripheral-i2c2.dtsi -new file mode 100644 -index 0000000..ed9a0b5 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-peripheral-i2c2.dtsi -@@ -0,0 +1,13 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&i2c2 { -+ pinctrl-names = "default"; -+ -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-peripheral-nxp-hdmi.dtsi b/arch/arm/boot/dts/am335x-peripheral-nxp-hdmi.dtsi -new file mode 100644 -index 0000000..1dfd26a ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-peripheral-nxp-hdmi.dtsi -@@ -0,0 +1,29 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&lcdc { -+ status = "okay"; -+ port { -+ lcdc_0: endpoint@0 { -+ remote-endpoint = <&hdmi_0>; -+ }; -+ }; -+}; -+ -+&i2c0 { -+ tda19988 { -+ compatible = "nxp,tda998x"; -+ reg = <0x70>; -+ -+ port { -+ hdmi_0: endpoint@0 { -+ remote-endpoint = <&lcdc_0>; -+ }; -+ }; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-peripheral-panel-1024x600-24bit.dtsi b/arch/arm/boot/dts/am335x-peripheral-panel-1024x600-24bit.dtsi -new file mode 100644 -index 0000000..74ddc12 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-peripheral-panel-1024x600-24bit.dtsi -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&lcdc { -+ status = "okay"; -+}; -+ -+/ { -+ panel { -+ status = "okay"; -+ compatible = "ti,tilcdc,panel"; -+ pinctrl-names = "default"; -+ -+ panel-info { -+ ac-bias = <255>; -+ ac-bias-intrpt = <0>; -+ dma-burst-sz = <16>; -+ bpp = <32>; -+ fdd = <0x80>; -+ sync-edge = <0>; -+ sync-ctrl = <0>; -+ raster-order = <1>; -+ fifo-th = <0>; -+ }; -+ display-timings { -+ native-mode = <&timing0>; -+ timing0: 1024x600 { -+ clock-frequency = <36000000>; -+ hactive = <1024>; -+ vactive = <600>; -+ hfront-porch = <1>; -+ hback-porch = <45>; -+ hsync-len = <30>; -+ vback-porch = <22>; -+ vfront-porch = <12>; -+ vsync-len = <2>; -+ hsync-active = <1>; -+ vsync-active = <1>; -+ de-active = <1>; -+ pixelclk-active = <0>; -+ }; -+ }; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-peripheral-spi0.dtsi b/arch/arm/boot/dts/am335x-peripheral-spi0.dtsi -new file mode 100644 -index 0000000..969e352 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-peripheral-spi0.dtsi -@@ -0,0 +1,13 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&spi0 { -+ pinctrl-names = "default"; -+ -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-peripheral-spi1.dtsi b/arch/arm/boot/dts/am335x-peripheral-spi1.dtsi -new file mode 100644 -index 0000000..ac5fe97 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-peripheral-spi1.dtsi -@@ -0,0 +1,13 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&spi1 { -+ pinctrl-names = "default"; -+ -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-peripheral-spi1a.dtsi b/arch/arm/boot/dts/am335x-peripheral-spi1a.dtsi -new file mode 100644 -index 0000000..ac5fe97 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-peripheral-spi1a.dtsi -@@ -0,0 +1,13 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&spi1 { -+ pinctrl-names = "default"; -+ -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-peripheral-ttyS1.dtsi b/arch/arm/boot/dts/am335x-peripheral-ttyS1.dtsi -new file mode 100644 -index 0000000..f59fa4c ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-peripheral-ttyS1.dtsi -@@ -0,0 +1,13 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&uart1 { -+ pinctrl-names = "default"; -+ -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-peripheral-ttyS2.dtsi b/arch/arm/boot/dts/am335x-peripheral-ttyS2.dtsi -new file mode 100644 -index 0000000..a25d6cf ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-peripheral-ttyS2.dtsi -@@ -0,0 +1,13 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&uart2 { -+ pinctrl-names = "default"; -+ -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-peripheral-ttyS4.dtsi b/arch/arm/boot/dts/am335x-peripheral-ttyS4.dtsi -new file mode 100644 -index 0000000..adc89f0 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-peripheral-ttyS4.dtsi -@@ -0,0 +1,13 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&uart4 { -+ pinctrl-names = "default"; -+ -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-peripheral-ttyS5.dtsi b/arch/arm/boot/dts/am335x-peripheral-ttyS5.dtsi -new file mode 100644 -index 0000000..8b42fb0 ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-peripheral-ttyS5.dtsi -@@ -0,0 +1,13 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+&uart5 { -+ pinctrl-names = "default"; -+ -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/am335x-roboticscape.dtsi b/arch/arm/boot/dts/am335x-roboticscape.dtsi -new file mode 100644 -index 0000000..77d815a ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-roboticscape.dtsi -@@ -0,0 +1,395 @@ -+/******************************************************************************* -+* pinmux and modules used by roboticscape -+* included in: -+* am335x-boneblack-roboticscape.dts -+* am335x-boneblack-wireless-roboticscape.dts -+*******************************************************************************/ -+ -+ -+ -+/******************************************************************************* -+* Pin Muxing -+*******************************************************************************/ -+&am33xx_pinmux { -+ -+ /*************************************************************************** -+ * Static Pinmux -+ ***************************************************************************/ -+ mux_helper_pins: pins { -+ pinctrl-single,pins = < -+ -+ /* GPIO Input Pullup */ -+ 0x09c 0x37 /*P8.9 T6 PAUSE_BTN */ -+ 0x098 0x37 /*P8.10 U6 MODE_BTN */ -+ 0x1AC 0x37 /*P9.25 A14 IMU_INT */ -+ -+ /* LEDs GPIO Out*/ -+ 0x090 0x0F /* P8.7 R7 LED_RED */ -+ 0x094 0x0F /* P8.8 T7 LED_GREEN */ -+ 0x028 0x0F /*P8.14 T11 BATT_LED_4 */ -+ 0x02C 0x0F /*P8.17 U12 BATT_LED_1 */ -+ 0x08c 0x0F /*P8.18 V12 BATT_LED_2 */ -+ 0x07c 0x0F /*P8.26 V6 BATT_LED_3 */ -+ -+ /* Motor Control GPIO Out*/ -+ 0x0cc 0x0F /*P8.34 MDIR_2B different from blue!!*/ -+ 0x0a8 0x0F /*P8.43 MDIR_3B*/ -+ 0x0ac 0x0F /*P8.44 MDIR_3A*/ -+ 0x0a0 0x0F /*P8.45 MDIR_4A*/ -+ 0x0a4 0x0F /*P8.46 MDIR_4B*/ -+ 0x078 0x0F /*P9.12 MDIR_1A different from blue!!*/ -+ 0x074 0x0F /*P9.13 MDIR_1B*/ -+ 0x040 0x0F /*P9.15 MDIR_2A*/ -+ 0x1b4 0x0F /*P9.41 MOT_STBY*/ -+ -+ /* HRPWM 1 */ -+ 0x048 0x6 /* P9_14 | MODE 6 */ -+ 0x04c 0x6 /* P9_16 | MODE 6 */ -+ -+ /* HRPWM 2 */ -+ 0x020 0x4 /* P8_19 | MODE 4 */ -+ 0x024 0x4 /* P8_13 | MODE 4 */ -+ -+ /* EQEP */ -+ 0x1A0 0x31 /* P9_42,EQEP0A, MODE1 */ -+ 0x1A4 0x31 /* P9_27,EQEP0B, MODE1 */ -+ 0x0D4 0x32 /* P8_33,EQEP1B, MODE2 */ -+ 0x0D0 0x32 /* P8_35,EQEP1A, MODE2 */ -+ 0x030 0x34 /* P8_12,EQEP2A, MODE4 */ -+ 0x034 0x34 /* P8_11,EQEP2B, MODE4 */ -+ -+ /* PRU encoder input */ -+ 0x03c 0x36 /* P8_15,PRU0_r31_15,MODE6 */ -+ 0x038 0x36 /* P8_16,PRU0_r31_16,MODE6 */ -+ -+ /* PRU Servo output */ -+ 0x0e0 0x05 /*pru1_pru_r30_8, MODE5*/ -+ 0x0e8 0x05 /*pru1_pru_r30_10, MODE5 */ -+ 0x0e4 0x05 /*pr1_pru1_pru_r30_9, MODE5 */ -+ 0x0ec 0x05 /*pru1_pru_r30_11, MODE5 */ -+ 0x0b8 0x05 /*pru1_pru_r30_6, MODE5 */ -+ 0x0bc 0x05 /*pru1_pru_r30_7, MODE5 */ -+ 0x0b0 0x05 /*pru1_pru_r30_4, MODE5 */ -+ 0x0b4 0x05 /*pru1_pru_r30_5, MODE5 */ -+ 0x0C8 0x0F /*P8.36, SERVO_PWR GPIO OUT*/ -+ -+ /* I2C1 */ -+ 0x15C 0x32 /* P9.17,i2c1_scl,INPUT_PULLUP,MODE2 */ -+ 0x158 0x32 /* P9.18,i2c1_sda,INPUT_PULLUP,MODE2 */ -+ -+ /* I2C2 */ -+ 0x17c 0x73 /* P9.19, i2c2_sda, mode 3 */ -+ 0x178 0x73 /* P9.20, i2c2_sda, mode 3 */ -+ -+ /* UART5 */ -+ 0x0C4 0x34 /* P8.38,uart5_rxd,MODE4 */ -+ 0x0C0 0x14 /* P8.37,uart5_txd,MODE4 */ -+ -+ >; -+ }; -+ -+}; -+ -+ -+/******************************************************************************* -+* apply static and dynamic pinmux modes listed above. Configurable pins get the -+* modes from am335x-boneblack-common-universal-pins.dtsi -+*******************************************************************************/ -+&ocp { -+ /* activate the static pinmux helper list of pin modes above */ -+ test_helper: helper { -+ compatible = "bone-pinmux-helper"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mux_helper_pins>; -+ -+ status = "okay"; -+ }; -+ -+ /* UART4 RX DSM */ -+ P9_11_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart"; -+ pinctrl-0 = <&P9_11_default_pin>; -+ pinctrl-1 = <&P9_11_gpio_pin>; -+ pinctrl-2 = <&P9_11_gpio_pu_pin>; -+ pinctrl-3 = <&P9_11_gpio_pd_pin>; -+ pinctrl-4 = <&P9_11_uart_pin>; -+ }; -+ -+ /* UART 2 TX GPS*/ -+ P9_21_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm"; -+ pinctrl-0 = <&P9_21_default_pin>; -+ pinctrl-1 = <&P9_21_gpio_pin>; -+ pinctrl-2 = <&P9_21_gpio_pu_pin>; -+ pinctrl-3 = <&P9_21_gpio_pd_pin>; -+ pinctrl-4 = <&P9_21_spi_pin>; -+ pinctrl-5 = <&P9_21_uart_pin>; -+ pinctrl-6 = <&P9_21_i2c_pin>; -+ pinctrl-7 = <&P9_21_pwm_pin>; -+ }; -+ -+ /* UART 2 RX GPS */ -+ P9_22_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "spi", "uart", "i2c", "pwm"; -+ pinctrl-0 = <&P9_22_default_pin>; -+ pinctrl-1 = <&P9_22_gpio_pin>; -+ pinctrl-2 = <&P9_22_gpio_pu_pin>; -+ pinctrl-3 = <&P9_22_gpio_pd_pin>; -+ pinctrl-4 = <&P9_22_spi_pin>; -+ pinctrl-5 = <&P9_22_uart_pin>; -+ pinctrl-6 = <&P9_22_i2c_pin>; -+ pinctrl-7 = <&P9_22_pwm_pin>; -+ }; -+ -+ /* SPI MISO */ -+ P9_29_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin"; -+ pinctrl-0 = <&P9_29_default_pin>; -+ pinctrl-1 = <&P9_29_gpio_pin>; -+ pinctrl-2 = <&P9_29_gpio_pu_pin>; -+ pinctrl-3 = <&P9_29_gpio_pd_pin>; -+ pinctrl-4 = <&P9_29_pwm_pin>; -+ pinctrl-5 = <&P9_29_spi_pin>; -+ pinctrl-6 = <&P9_29_pruout_pin>; -+ pinctrl-7 = <&P9_29_pruin_pin>; -+ }; -+ -+ /* SPI MOSI */ -+ P9_30_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin"; -+ pinctrl-0 = <&P9_30_default_pin>; -+ pinctrl-1 = <&P9_30_gpio_pin>; -+ pinctrl-2 = <&P9_30_gpio_pu_pin>; -+ pinctrl-3 = <&P9_30_gpio_pd_pin>; -+ pinctrl-4 = <&P9_30_pwm_pin>; -+ pinctrl-5 = <&P9_30_spi_pin>; -+ pinctrl-6 = <&P9_30_pruout_pin>; -+ pinctrl-7 = <&P9_30_pruin_pin>; -+ }; -+ -+ /* SPI SCK */ -+ P9_31_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pruout", "pruin"; -+ pinctrl-0 = <&P9_31_default_pin>; -+ pinctrl-1 = <&P9_31_gpio_pin>; -+ pinctrl-2 = <&P9_31_gpio_pu_pin>; -+ pinctrl-3 = <&P9_31_gpio_pd_pin>; -+ pinctrl-4 = <&P9_31_pwm_pin>; -+ pinctrl-5 = <&P9_31_spi_pin>; -+ pinctrl-6 = <&P9_31_pruout_pin>; -+ pinctrl-7 = <&P9_31_pruin_pin>; -+ }; -+ -+ /* SPI SS1 GPIO3_17*/ -+ P9_28_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm", "spi", "pwm2", "pruout", "pruin"; -+ pinctrl-0 = <&P9_28_default_pin>; -+ pinctrl-1 = <&P9_28_gpio_pin>; -+ pinctrl-2 = <&P9_28_gpio_pu_pin>; -+ pinctrl-3 = <&P9_28_gpio_pd_pin>; -+ pinctrl-4 = <&P9_28_pwm_pin>; -+ pinctrl-5 = <&P9_28_spi_pin>; -+ pinctrl-6 = <&P9_28_pwm2_pin>; -+ pinctrl-7 = <&P9_28_pruout_pin>; -+ pinctrl-8 = <&P9_28_pruin_pin>; -+ }; -+ -+ /* SPI SS1 GPIO1_17*/ -+ P9_23_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "pwm"; -+ pinctrl-0 = <&P9_23_default_pin>; -+ pinctrl-1 = <&P9_23_gpio_pin>; -+ pinctrl-2 = <&P9_23_gpio_pu_pin>; -+ pinctrl-3 = <&P9_23_gpio_pd_pin>; -+ pinctrl-4 = <&P9_23_pwm_pin>; -+ }; -+ -+ /* UART 1 TX */ -+ P9_24_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pruin"; -+ pinctrl-0 = <&P9_24_default_pin>; -+ pinctrl-1 = <&P9_24_gpio_pin>; -+ pinctrl-2 = <&P9_24_gpio_pu_pin>; -+ pinctrl-3 = <&P9_24_gpio_pd_pin>; -+ pinctrl-4 = <&P9_24_uart_pin>; -+ pinctrl-5 = <&P9_24_can_pin>; -+ pinctrl-6 = <&P9_24_i2c_pin>; -+ pinctrl-7 = <&P9_24_pruin_pin>; -+ }; -+ -+ /* UART 1 RX */ -+ P9_26_pinmux { -+ compatible = "bone-pinmux-helper"; -+ status = "okay"; -+ pinctrl-names = "default", "gpio", "gpio_pu", "gpio_pd", "uart", "can", "i2c", "pruin"; -+ pinctrl-0 = <&P9_26_default_pin>; -+ pinctrl-1 = <&P9_26_gpio_pin>; -+ pinctrl-2 = <&P9_26_gpio_pu_pin>; -+ pinctrl-3 = <&P9_26_gpio_pd_pin>; -+ pinctrl-4 = <&P9_26_uart_pin>; -+ pinctrl-5 = <&P9_26_can_pin>; -+ pinctrl-6 = <&P9_26_i2c_pin>; -+ pinctrl-7 = <&P9_26_pruin_pin>; -+ }; -+ -+ -+}; -+ -+ -+/******************************************************************************* -+* PWMSS -+*******************************************************************************/ -+&epwmss0 { -+ status = "okay"; -+}; -+ -+&epwmss1 { -+ status = "okay"; -+}; -+ -+&epwmss2 { -+ status = "okay"; -+}; -+ -+&ehrpwm0 { -+ status = "okay"; -+}; -+ -+&ehrpwm1 { -+ status = "okay"; -+}; -+ -+&ehrpwm2 { -+ status = "okay"; -+}; -+ -+/******************************************************************************* -+* EQEP -+*******************************************************************************/ -+&eqep0 { -+ count_mode = <0>; /* 0 - Quadrature mode, normal 90 phase offset cha & chb. 1 - Direction mode. cha input = clock, chb input = direction */ -+ swap_inputs = <0>; /* Are channel A and channel B swapped? (0 - no, 1 - yes) */ -+ invert_qa = <1>; /* Should we invert the channel A input? */ -+ invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */ -+ invert_qi = <0>; /* Should we invert the index input? */ -+ invert_qs = <0>; /* Should we invert the strobe input? */ -+ -+ status = "okay"; -+}; -+ -+&eqep1 { -+ count_mode = <0>; /* 0 - Quadrature mode, normal 90 phase offset cha & chb. 1 - Direction mode. cha input = clock, chb input = direction */ -+ swap_inputs = <0>; /* Are channel A and channel B swapped? (0 - no, 1 - yes) */ -+ invert_qa = <1>; /* Should we invert the channel A input? */ -+ invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */ -+ invert_qi = <0>; /* Should we invert the index input? */ -+ invert_qs = <0>; /* Should we invert the strobe input? */ -+ -+ status = "okay"; -+}; -+ -+&eqep2 { -+ count_mode = <0>; /* 0 - Quadrature mode, normal 90 phase offset cha & chb. 1 - Direction mode. cha input = clock, chb input = direction */ -+ swap_inputs = <0>; /* Are channel A and channel B swapped? (0 - no, 1 - yes) */ -+ invert_qa = <1>; /* Should we invert the channel A input? */ -+ invert_qb = <1>; /* Should we invert the channel B input? I invert these because my encoder outputs drive transistors that pull down the pins */ -+ invert_qi = <0>; /* Should we invert the index input? */ -+ invert_qs = <0>; /* Should we invert the strobe input? */ -+ -+ status = "okay"; -+}; -+ -+ -+/******************************************************************************* -+* UART -+*******************************************************************************/ -+&uart1 { -+ status = "okay"; -+}; -+ -+&uart2 { -+ status = "okay"; -+}; -+ -+&uart4 { -+ status = "okay"; -+}; -+ -+&uart5 { -+ status = "okay"; -+}; -+ -+ -+/******************************************************************************* -+* PRU Encoder and Servos -+*******************************************************************************/ -+&pruss { -+ status = "okay"; -+}; -+ -+ -+/******************************************************************************* -+* I2C -+*******************************************************************************/ -+&i2c1 { -+ status = "okay"; -+ clock-frequency = <400000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+}; -+ -+&i2c2 { -+ status = "okay"; -+ clock-frequency = <400000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+}; -+ -+ -+/******************************************************************************* -+* SPI -+*******************************************************************************/ -+&spi1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ channel@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ compatible = "spidev"; -+ -+ reg = <0>; -+ spi-max-frequency = <16000000>; -+ spi-cpha; -+ }; -+ -+ channel@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ compatible = "spidev"; -+ -+ reg = <1>; -+ spi-max-frequency = <16000000>; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-sancloud-bbe.dts b/arch/arm/boot/dts/am335x-sancloud-bbe.dts -new file mode 100644 -index 0000000..a36b04b ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-sancloud-bbe.dts -@@ -0,0 +1,264 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "am33xx.dtsi" -+#include "am335x-bone-common.dtsi" -+#include <dt-bindings/interrupt-controller/irq.h> -+#include <dt-bindings/display/tda998x.h> -+/* #include "am335x-bone-jtag.dtsi" */ -+ -+/ { -+ model = "SanCloud BeagleBone Enhanced"; -+ compatible = "sancloud,am335x-boneenhanced", "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; -+}; -+ -+&ldo3_reg { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+}; -+ -+&mmc1 { -+ vmmc-supply = <&vmmcsd_fixed>; -+}; -+ -+&mmc2 { -+ vmmc-supply = <&vmmcsd_fixed>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&emmc_pins>; -+ bus-width = <8>; -+ status = "okay"; -+ ti,vcc-aux-disable-is-sleep; -+}; -+ -+&am33xx_pinmux { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&usb_hub_ctrl>; -+ -+ nxp_hdmi_bonelt_pins: nxp_hdmi_bonelt_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0.lcd_data0 */ -+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1.lcd_data1 */ -+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2.lcd_data2 */ -+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3.lcd_data3 */ -+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4.lcd_data4 */ -+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5.lcd_data5 */ -+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6.lcd_data6 */ -+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7.lcd_data7 */ -+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8.lcd_data8 */ -+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9.lcd_data9 */ -+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10.lcd_data10 */ -+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11.lcd_data11 */ -+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12.lcd_data12 */ -+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13.lcd_data13 */ -+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14.lcd_data14 */ -+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15.lcd_data15 */ -+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_vsync.lcd_vsync */ -+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_hsync.lcd_hsync */ -+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_pclk.lcd_pclk */ -+ AM33XX_IOPAD(0x8ec, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* lcd_ac_bias_en.lcd_ac_bias_en */ -+ >; -+ }; -+ nxp_hdmi_bonelt_off_pins: nxp_hdmi_bonelt_off_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr0 */ -+ >; -+ }; -+ -+ cpsw_default: cpsw_default { -+ pinctrl-single,pins = < -+ /* Slave 1 */ -+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txen.rgmii1_tctl */ -+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxdv.rgmii1_rctl */ -+ 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd3.rgmii1_td3 */ -+ 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd2.rgmii1_td2 */ -+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd1.rgmii1_td1 */ -+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txd0.rgmii1_td0 */ -+ 0x12c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mii1_txclk.rgmii1_tclk */ -+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxclk.rgmii1_rclk */ -+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd3.rgmii1_rd3 */ -+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd2.rgmii1_rd2 */ -+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd1.rgmii1_rd1 */ -+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE2) /* mii1_rxd0.rgmii1_rd0 */ -+ >; -+ }; -+ -+ cpsw_sleep: cpsw_sleep { -+ pinctrl-single,pins = < -+ /* Slave 1 reset value */ -+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+ davinci_mdio_default: davinci_mdio_default { -+ pinctrl-single,pins = < -+ /* MDIO */ -+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ -+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ -+ >; -+ }; -+ -+ davinci_mdio_sleep: davinci_mdio_sleep { -+ pinctrl-single,pins = < -+ /* MDIO reset value */ -+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+ usb_hub_ctrl: usb_hub_ctrl { -+ pinctrl-single,pins = < -+ 0x144 (PIN_OUTPUT_PULLUP | MUX_MODE7) /* mcasp0_ahclkr.gpio3_17 */ -+ >; -+ }; -+ -+ mpu6050_pins: pinmux_mpu6050_pins { -+ pinctrl-single,pins = < -+ 0x168 (PIN_INPUT | MUX_MODE7) /* spi0_sclk.gpio0_2 */ -+ >; -+ }; -+ -+ lps3331ap_pins: pinmux_lps3331ap_pins { -+ pinctrl-single,pins = < -+ 0x6C (PIN_INPUT | MUX_MODE7) /* conf_gpmc_a11.gpio1_27 */ -+ >; -+ }; -+ -+ mcasp0_pins: mcasp0_pins { -+ pinctrl-single,pins = < -+ AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLUP | MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */ -+ AM33XX_IOPAD(0x99c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2*/ -+ AM33XX_IOPAD(0x994, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */ -+ AM33XX_IOPAD(0x990, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */ -+ AM33XX_IOPAD(0x86c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.GPIO1_27 */ -+ >; -+ }; -+}; -+ -+&lcdc { -+ status = "okay"; -+ port { -+ lcdc_0: endpoint@0 { -+ remote-endpoint = <&hdmi_0>; -+ }; -+ }; -+}; -+ -+&mac { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&cpsw_default>; -+ pinctrl-1 = <&cpsw_sleep>; -+}; -+ -+&davinci_mdio { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&davinci_mdio_default>; -+ pinctrl-1 = <&davinci_mdio_sleep>; -+}; -+ -+&cpsw_emac0 { -+ phy_id = <&davinci_mdio>, <0>; -+ phy-mode = "rgmii-txid"; -+}; -+ -+&i2c0 { -+ tda19988: tda19988 { -+ compatible = "nxp,tda998x"; -+ reg = <0x70>; -+ -+ pinctrl-names = "default", "off"; -+ pinctrl-0 = <&nxp_hdmi_bonelt_pins>; -+ pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; -+ -+ #sound-dai-cells = <0>; -+ audio-ports = < TDA998x_I2S 0x03>; -+ -+ ports { -+ port@0 { -+ hdmi_0: endpoint@0 { -+ remote-endpoint = <&lcdc_0>; -+ }; -+ }; -+ }; -+ }; -+ -+ lps331ap: lps331ap@5C { -+ compatible = "st,lps331ap"; -+ st,drdy-int-pin = <1>; -+ reg = <0x5C>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <27 IRQ_TYPE_EDGE_RISING>; -+ }; -+ -+ mpu6050: mpu6050@68 { -+ compatible = "invensense,mpu6050"; -+ reg = <0x68>; -+ interrupt-parent = <&gpio0>; -+ interrupts = <2 IRQ_TYPE_EDGE_RISING>; -+ //orientation = <0xff 0 0 0 1 0 0 0 0xff>; -+ }; -+}; -+ -+&mcasp0 { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mcasp0_pins>; -+ status = "okay"; -+ op-mode = <0>; /* MCASP_IIS_MODE */ -+ tdm-slots = <2>; -+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ -+ 0 0 1 0 -+ >; -+ tx-num-evt = <32>; -+ rx-num-evt = <32>; -+}; -+ -+/ { -+ clk_mcasp0_fixed: clk_mcasp0_fixed { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <24576000>; -+ }; -+ -+ clk_mcasp0: clk_mcasp0 { -+ #clock-cells = <0>; -+ compatible = "gpio-gate-clock"; -+ clocks = <&clk_mcasp0_fixed>; -+ enable-gpios = <&gpio1 27 0>; /* BeagleBone Black Clk enable on GPIO1_27 */ -+ }; -+ -+ sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,name = "TI BeagleBone Black"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,bitclock-master = <&dailink0_master>; -+ simple-audio-card,frame-master = <&dailink0_master>; -+ -+ dailink0_master: simple-audio-card,cpu { -+ sound-dai = <&mcasp0>; -+ clocks = <&clk_mcasp0>; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&tda19988>; -+ }; -+ }; -+}; -diff --git b/arch/arm/boot/dts/am335x-som-common.dtsi b/arch/arm/boot/dts/am335x-som-common.dtsi -new file mode 100644 -index 0000000..fb4399b ---- /dev/null -+++ b/arch/arm/boot/dts/am335x-som-common.dtsi -@@ -0,0 +1,465 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+/ { -+ -+ cpus { -+ cpu@0 { -+ cpu0-supply = <&dcdc2_fixed>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x80000000 0x20000000>; /* 512 MB */ -+ }; -+ -+ ocp { -+ uart0: serial@44e09000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins>; -+ -+ status = "okay"; -+ }; -+ uart1: serial@48022000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart1_pins>; -+ status = "okay"; -+ -+ }; -+ uart4: serial@481a8000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart4_pins>; -+ status = "okay"; -+ }; -+ -+ epwmss0: epwmss@48300000 { -+ status = "okay"; -+ -+ ecap0: ecap@48300100 { -+ status = "okay"; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&ecap0_pins_default>; -+ pinctrl-1 = <&ecap0_pins_sleep>; -+ }; -+ }; -+ -+ musb: usb@47400000 { -+ status = "okay"; -+ -+ control@44e10000 { -+ status = "okay"; -+ }; -+ -+ usb-phy@47401300 { -+ status = "okay"; -+ }; -+ -+ usb-phy@47401b00 { -+ status = "okay"; -+ }; -+ -+ usb@47401000 { -+ status = "okay"; -+ dr_mode = "otg"; -+ }; -+ -+ usb@47401800 { -+ status = "okay"; -+ dr_mode = "host"; -+ }; -+ -+ dma-controller@07402000 { -+ status = "okay"; -+ }; -+ }; -+ -+ i2c0: i2c@44e0b000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ status = "okay"; -+ clock-frequency = <100000>; -+ -+ tps: tps@24 { -+ reg = <0x24>; -+ }; -+ }; -+ }; -+ -+ vmmcsd_fixed: fixedregulator@0 { -+ compatible = "regulator-fixed"; -+ regulator-name = "vmmcsd_fixed"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ }; -+ -+ dcdc2_fixed: fixedregulator@1 { -+ /* VDD_MPU voltage limits 0.95V - 1.325V with +/-4% tolerance */ -+ compatible = "regulator-fixed"; -+ regulator-name = "dcdc2_fixed"; -+ -+ regulator-min-microvolt = <1378000>; -+ regulator-max-microvolt = <1378000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ leds { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&user_leds_s0>; -+ -+ compatible = "gpio-leds"; -+ -+ led@1 { -+ label = "led1:green:heartbeat"; -+ gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ }; -+ -+ led@2 { -+ label = "led2:red:heartbeat"; -+ gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ }; -+ -+ led@3 { -+ label = "led3:yello:heartbeat"; -+ gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "heartbeat"; -+ }; -+ -+ led@4 { -+ label = "bkl"; -+ gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; -+ linux,default-trigger = "default-on"; -+ }; -+ }; -+ -+ backlight { -+ compatible = "pwm-backlight"; -+ pwms = <&ecap0 0 500000 1>; -+ brightness-levels = < -+ 0 1 2 3 4 5 6 7 8 9 -+ 10 11 12 13 14 15 16 17 18 19 -+ 20 21 22 23 24 25 26 27 28 29 -+ 30 31 32 33 34 35 36 37 38 39 -+ 40 41 42 43 44 45 46 47 48 49 -+ 50 51 52 53 54 55 56 57 58 59 -+ 60 61 62 63 64 65 66 67 68 69 -+ 70 71 72 73 74 75 76 77 78 79 -+ 80 81 82 83 84 85 86 87 88 89 -+ 90 91 92 93 94 95 96 97 98 99 -+ 100 -+ >; -+ default-brightness-level = <50>; -+ }; -+}; -+ -+&am33xx_pinmux { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&clkout2_pin>; -+ -+ user_leds_s0: user_leds_s0 { -+ pinctrl-single,pins = < -+ 0x1b0 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* xdma_event_intr0.gpio0_19 */ -+ 0x198 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* mcasp0_axr0.gpio3_20 */ -+ 0x1a8 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* mcasp0_axr1.gpio3_21 */ -+ 0x1a4 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* mcasp0_fsr.gpio3[19], INPUT_PULLDOWN | MODE7 */ -+ >; -+ }; -+ -+ i2c0_pins: pinmux_i2c0_pins { -+ pinctrl-single,pins = < -+ 0x188 (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */ -+ 0x18c (PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */ -+ >; -+ }; -+ -+ uart0_pins: pinmux_uart0_pins { -+ pinctrl-single,pins = < -+ 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ -+ 0x174 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ -+ >; -+ }; -+ -+ uart1_pins: pinmux_uart1_pins { -+ pinctrl-single,pins = < -+ 0x168 (PIN_INPUT_PULLUP | MUX_MODE1) -+ 0x16c (PIN_OUTPUT_PULLDOWN | MUX_MODE1) -+ >; -+ }; -+ -+ uart4_pins: pinmux_uart4_pins { -+ pinctrl-single,pins = < -+ 0x180 (PIN_INPUT_PULLUP | MUX_MODE0) -+ 0x184 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) -+ >; -+ }; -+ -+ -+ -+ clkout2_pin: pinmux_clkout2_pin { -+ pinctrl-single,pins = < -+ 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* xdma_event_intr1.clkout2 */ -+ >; -+ }; -+ -+ cpsw_default: cpsw_default { -+ pinctrl-single,pins = < -+ /* Slave 1 */ -+ 0x110 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxerr.mii1_rxerr */ -+ 0x114 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txen.mii1_txen */ -+ 0x118 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxdv.mii1_rxdv */ -+ 0x11c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd3.mii1_txd3 */ -+ 0x120 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd2.mii1_txd2 */ -+ 0x124 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd1.mii1_txd1 */ -+ 0x128 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd0.mii1_txd0 */ -+ 0x12c (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_txclk.mii1_txclk */ -+ 0x130 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxclk.mii1_rxclk */ -+ 0x134 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd3.mii1_rxd3 */ -+ 0x138 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd2.mii1_rxd2 */ -+ 0x13c (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd1.mii1_rxd1 */ -+ 0x140 (PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd0.mii1_rxd0 */ -+ -+ 0x040 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* gpmc_a0.gmii2_txen, OUTPUT_PULLDOWN | MODE1 */ -+ 0x044 (PIN_INPUT_PULLDOWN | MUX_MODE1 ) /* gpmc_a1.gmii2_rxdv, INPUT_PULLDOWN | MODE1 */ -+ 0x048 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* gpmc_a2.gmii2_txd3, OUTPUT_PULLDOWN | MODE1 */ -+ 0x04c (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* gpmc_a3.gmii2_txd2, OUTPUT_PULLDOWN | MODE1 */ -+ 0x050 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* gpmc_a4.gmii2_txd1, OUTPUT_PULLDOWN | MODE1 */ -+ 0x054 (PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* gpmc_a5.gmii2_txd0, OUTPUT_PULLDOWN | MODE1 */ -+ 0x058 (PIN_INPUT_PULLDOWN | MUX_MODE1 ) /* gpmc_a6.gmii2_txclk, INPUT_PULLDOWN | MODE1 */ -+ 0x05c (PIN_INPUT_PULLDOWN | MUX_MODE1 ) /* gpmc_a7.gmii2_rxclk, INPUT_PULLDOWN | MODE1 */ -+ 0x060 (PIN_INPUT_PULLDOWN | MUX_MODE1 ) /* gpmc_a8.gmii2_rxd3, INPUT_PULLDOWN | MODE1 */ -+ 0x064 (PIN_INPUT_PULLDOWN | MUX_MODE1 ) /* gpmc_a9.gmii2_rxd2, INPUT_PULLDOWN | MODE1 */ -+ 0x068 (PIN_INPUT_PULLDOWN | MUX_MODE1 ) /* gpmc_a10.gmii2_rxd1, INPUT_PULLDOWN | MODE1 */ -+ 0x06c (PIN_INPUT_PULLDOWN | MUX_MODE1 ) /* gpmc_a11.gmii2_rxd0, INPUT_PULLDOWN | MODE1 */ -+ 0x070 (PIN_INPUT_PULLUP | MUX_MODE1 ) /* gpmc_wait0.gmii2_crs, INPUT_PULLUP | MODE1 */ -+ 0x074 (PIN_INPUT_PULLUP | MUX_MODE1 ) /* gpmc_wpn.gmii2_rxer, INPUT_PULLUP | MODE1 */ -+ 0x078 (PIN_INPUT_PULLUP | MUX_MODE1 ) /* gpmc_ben1.gmii2_col, INPUT_PULLUP | MODE1 */ -+ >; -+ }; -+ -+ cpsw_sleep: cpsw_sleep { -+ pinctrl-single,pins = < -+ /* Slave 1 reset value */ -+ 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x114 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x118 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x11c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x120 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x124 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x128 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x12c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x130 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x134 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x138 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x13c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x140 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ -+ 0x40 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x44 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x48 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x4c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x50 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x54 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x58 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x5c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x60 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x64 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x68 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x6c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x070 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x074 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x078 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+ davinci_mdio_default: davinci_mdio_default { -+ pinctrl-single,pins = < -+ /* MDIO */ -+ 0x148 (PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ -+ 0x14c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ -+ >; -+ }; -+ -+ davinci_mdio_sleep: davinci_mdio_sleep { -+ pinctrl-single,pins = < -+ /* MDIO reset value */ -+ 0x148 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+ mmc1_pins_default: pinmux_mmc1_pins { -+ pinctrl-single,pins = < -+ 0x0F0 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */ -+ 0x0F4 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */ -+ 0x0F8 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */ -+ 0x0FC (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */ -+ 0x100 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk.mmc0_clk */ -+ 0x104 (PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */ -+ 0x1A0 (PIN_INPUT_PULLUP | MUX_MODE7) /* mcasp0_aclkr.gpio3_18 */ -+ 0x160 (PIN_INPUT | MUX_MODE7) /* spi0_cs1.gpio0_6 */ -+ >; -+ }; -+ -+ mmc1_pins_sleep: pinmux_mmc1_pins_sleep { -+ pinctrl-single,pins = < -+ 0x0F0 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x0F4 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x0F8 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x0FC (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x100 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x104 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x1A0 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ 0x160 (PIN_INPUT_PULLDOWN | MUX_MODE7) -+ >; -+ }; -+ -+ emmc_pins: pinmux_emmc_pins { -+ pinctrl-single,pins = < -+ 0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */ -+ 0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */ -+ 0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */ -+ 0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */ -+ 0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */ -+ 0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */ -+ 0x10 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */ -+ 0x14 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */ -+ 0x18 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */ -+ 0x1c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */ -+ >; -+ }; -+ -+ ecap0_pins_default: backlight_pins { -+ pinctrl-single,pins = < -+ 0x164 0x0 /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */ -+ >; -+ }; -+ -+ ecap0_pins_sleep: ecap0_pins_sleep { -+ pinctrl-single,pins = < -+ 0x164 (PULL_DISABLE | MUX_MODE7) /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out */ -+ >; -+ }; -+ dcan0_default: dcan0_default_pins { -+ pinctrl-single,pins = < -+ 0x178 0x0a /* uart1_ctsn.dcan0_tx_mux2, OUTPUT | MODE2 */ -+ 0x17c 0x2a /* uart1_rtsn.dcan0_rx_mux2, INPUT | MODE2 */ -+ >; -+ }; -+ }; -+ -+&tps { -+ compatible = "ti,tps65217"; -+ regulators { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ dcdc1_reg: regulator@0 { -+ reg = <0>; -+ regulator-always-on; -+ }; -+ -+ dcdc2_reg: regulator@1 { -+ reg = <1>; -+ /* VDD_MPU voltage limits 0.95V - 1.325V with +/-4% tolerance */ -+ regulator-name = "vdd_mpu"; -+ regulator-min-microvolt = <925000>; -+ regulator-max-microvolt = <1378000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ dcdc3_reg: regulator@2 { -+ reg = <2>; -+ /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */ -+ regulator-name = "vdd_core"; -+ regulator-min-microvolt = <925000>; -+ regulator-max-microvolt = <1150000>; -+ regulator-boot-on; -+ regulator-always-on; -+ }; -+ -+ ldo1_reg: regulator@3 { -+ reg = <3>; -+ regulator-always-on; -+ }; -+ -+ ldo2_reg: regulator@4 { -+ reg = <4>; -+ regulator-always-on; -+ }; -+ -+ ldo3_reg: regulator@5 { -+ reg = <5>; -+ regulator-always-on; -+ }; -+ -+ ldo4_reg: regulator@6 { -+ reg = <6>; -+ regulator-always-on; -+ }; -+ }; -+}; -+ -+&cpsw_emac0 { -+ phy_id = <&davinci_mdio>, <0>; -+ phy-mode = "mii"; -+}; -+ -+&cpsw_emac1 { -+ phy_id = <&davinci_mdio>, <1>; -+ phy-mode = "mii"; -+}; -+ -+&mac { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&cpsw_default>; -+ pinctrl-1 = <&cpsw_sleep>; -+ slaves = <2>; -+ dual_emac = <1>; -+ status = "okay"; -+}; -+ -+&davinci_mdio { -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&davinci_mdio_default>; -+ pinctrl-1 = <&davinci_mdio_sleep>; -+ status = "okay"; -+}; -+ -+&mmc1 { -+ status = "okay"; -+ bus-width = <0x4>; -+ pinctrl-names = "default", "sleep"; -+ pinctrl-0 = <&mmc1_pins_default>; -+ pinctrl-1 = <&mmc1_pins_sleep>; -+ cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; -+ cd-inverted; -+}; -+ -+&dcan0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&dcan0_default>; -+ status = "okay"; -+}; -+ -+&tscadc { -+ status = "okay"; -+ tsc { -+ ti,wires = <4>; -+ ti,x-plate-resistance = <200>; -+ ti,coordinate-readouts = <5>; -+ ti,wire-config = <0x00 0x11 0x22 0x33>; -+ }; -+ -+ adc { -+ ti,adc-channels = <0 1 2 3>; -+ }; -+}; -diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi -index f3d51f4..e051b96 100644 ---- a/arch/arm/boot/dts/am33xx.dtsi -+++ b/arch/arm/boot/dts/am33xx.dtsi -@@ -36,6 +36,9 @@ - phy1 = &usb1_phy; - ethernet0 = &cpsw_emac0; - ethernet1 = &cpsw_emac1; -+ mmc0 = &mmc1; -+ mmc1 = &mmc2; -+ mmc2 = &mmc3; - }; - - cpus { -@@ -46,19 +49,7 @@ - device_type = "cpu"; - reg = <0>; - -- /* -- * To consider voltage drop between PMIC and SoC, -- * tolerance value is reduced to 2% from 4% and -- * voltage value is increased as a precaution. -- */ -- operating-points = < -- /* kHz uV */ -- 720000 1285000 -- 600000 1225000 -- 500000 1125000 -- 275000 1125000 -- >; -- voltage-tolerance = <2>; /* 2 percentage */ -+ operating-points-v2 = <&cpu0_opp_table>; - - clocks = <&dpll_mpu_ck>; - clock-names = "cpu"; -@@ -67,6 +58,80 @@ - }; - }; - -+ cpu0_opp_table: opp_table0 { -+ compatible = "operating-points-v2-ti-cpu"; -+ ti,syscon-efuse = <&scm_conf 0x7fc 0x1fff 0>; -+ ti,syscon-rev = <&scm_conf 0x600>; -+ -+ /* -+ * The three following nodes are marked with opp-suspend -+ * because the can not be enabled simultaneously on a -+ * single SoC. -+ */ -+ opp50@300000000 { -+ opp-hz = /bits/ 64 <300000000>; -+ opp-microvolt = <950000 931000 969000>; -+ opp-supported-hw = <0x06 0x0010>; -+ opp-suspend; -+ }; -+ -+ opp100@275000000 { -+ opp-hz = /bits/ 64 <275000000>; -+ opp-microvolt = <1100000 1078000 1122000>; -+ opp-supported-hw = <0x01 0x00FF>; -+ opp-suspend; -+ }; -+ -+ opp100@300000000 { -+ opp-hz = /bits/ 64 <300000000>; -+ opp-microvolt = <1100000 1078000 1122000>; -+ opp-supported-hw = <0x06 0x0020>; -+ opp-suspend; -+ }; -+ -+ opp100@500000000 { -+ opp-hz = /bits/ 64 <500000000>; -+ opp-microvolt = <1100000 1078000 1122000>; -+ opp-supported-hw = <0x01 0xFFFF>; -+ }; -+ -+ opp100@600000000 { -+ opp-hz = /bits/ 64 <600000000>; -+ opp-microvolt = <1100000 1078000 1122000>; -+ opp-supported-hw = <0x06 0x0040>; -+ }; -+ -+ opp120@600000000 { -+ opp-hz = /bits/ 64 <600000000>; -+ opp-microvolt = <1200000 1176000 1224000>; -+ opp-supported-hw = <0x01 0xFFFF>; -+ }; -+ -+ opp120@720000000 { -+ opp-hz = /bits/ 64 <720000000>; -+ opp-microvolt = <1200000 1176000 1224000>; -+ opp-supported-hw = <0x06 0x0080>; -+ }; -+ -+ oppturbo@720000000 { -+ opp-hz = /bits/ 64 <720000000>; -+ opp-microvolt = <1260000 1234800 1285200>; -+ opp-supported-hw = <0x01 0xFFFF>; -+ }; -+ -+ oppturbo@800000000 { -+ opp-hz = /bits/ 64 <800000000>; -+ opp-microvolt = <1260000 1234800 1285200>; -+ opp-supported-hw = <0x06 0x0100>; -+ }; -+ -+ oppnitro@1000000000 { -+ opp-hz = /bits/ 64 <1000000000>; -+ opp-microvolt = <1325000 1298500 1351500>; -+ opp-supported-hw = <0x04 0x0200>; -+ }; -+ }; -+ - pmu { - compatible = "arm,cortex-a8-pmu"; - interrupts = <3>; -@@ -91,7 +156,7 @@ - * for the moment, just use a fake OCP bus entry to represent - * the whole bus hierarchy. - */ -- ocp { -+ ocp: ocp { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; -@@ -500,12 +565,25 @@ - ti,timer-pwm; - }; - -+ pruss: pruss@4a300000 { -+ compatible = "ti,pruss-v2"; -+ ti,hwmods = "pruss"; -+ ti,deassert-hard-reset = "pruss", "pruss"; -+ reg = <0x4a300000 0x080000>; -+ ti,pintc-offset = <0x20000>; -+ interrupt-parent = <&intc>; -+ status = "disabled"; -+ interrupts = <20 21 22 23 24 25 26 27>; -+ }; -+ - rtc: rtc@44e3e000 { - compatible = "ti,am3352-rtc", "ti,da830-rtc"; - reg = <0x44e3e000 0x1000>; - interrupts = <75 - 76>; - ti,hwmods = "rtc"; -+ ti,no-reset-on-init; -+ ti,no-idle-on-init; - }; - - spi0: spi@48030000 { -@@ -691,6 +769,16 @@ - status = "disabled"; - }; - -+ eqep0: eqep@0x48300180 { -+ compatible = "ti,am33xx-eqep"; -+ reg = <0x48300180 0x80>; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ interrupt-parent = <&intc>; -+ interrupts = <79>; -+ status = "disabled"; -+ }; -+ - ehrpwm0: pwm@48300200 { - compatible = "ti,am3352-ehrpwm", - "ti,am33xx-ehrpwm"; -@@ -725,6 +813,17 @@ - status = "disabled"; - }; - -+ -+ eqep1: eqep@0x48302180 { -+ compatible = "ti,am33xx-eqep"; -+ reg = <0x48302180 0x80>; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ interrupt-parent = <&intc>; -+ interrupts = <88>; -+ status = "disabled"; -+ }; -+ - ehrpwm1: pwm@48302200 { - compatible = "ti,am3352-ehrpwm", - "ti,am33xx-ehrpwm"; -@@ -759,6 +858,16 @@ - status = "disabled"; - }; - -+ eqep2: eqep@0x48304180 { -+ compatible = "ti,am33xx-eqep"; -+ reg = <0x48304180 0x80>; -+ clocks = <&l4ls_gclk>; -+ clock-names = "fck"; -+ interrupt-parent = <&intc>; -+ interrupts = <89>; -+ status = "disabled"; -+ }; -+ - ehrpwm2: pwm@48304200 { - compatible = "ti,am3352-ehrpwm", - "ti,am33xx-ehrpwm"; -diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi -index 9435b6c..e2d77fd 100644 ---- a/arch/arm/boot/dts/am4372.dtsi -+++ b/arch/arm/boot/dts/am4372.dtsi -@@ -50,15 +50,15 @@ - clock-names = "cpu"; - - operating-points-v2 = <&cpu0_opp_table>; -- ti,syscon-efuse = <&scm_conf 0x610 0x3f 0>; -- ti,syscon-rev = <&scm_conf 0x600>; - - clock-latency = <300000>; /* From omap-cpufreq driver */ - }; - }; - - cpu0_opp_table: opp_table0 { -- compatible = "operating-points-v2"; -+ compatible = "operating-points-v2-ti-cpu"; -+ ti,syscon-efuse = <&scm_conf 0x610 0x3f 0>; -+ ti,syscon-rev = <&scm_conf 0x600>; - - opp50@300000000 { - opp-hz = /bits/ 64 <300000000>; -diff --git a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi -index 6df7829..a2e4c29 100644 ---- a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi -+++ b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi -@@ -190,6 +190,11 @@ - >; - }; - }; -+ -+&bb2d { -+ status = "okay"; -+}; -+ - &i2c1 { - status = "okay"; - clock-frequency = <400000>; -diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi -index 064d84f..6e63e28 100644 ---- a/arch/arm/boot/dts/dra7.dtsi -+++ b/arch/arm/boot/dts/dra7.dtsi -@@ -81,11 +81,7 @@ - compatible = "arm,cortex-a15"; - reg = <0>; - -- operating-points = < -- /* kHz uV */ -- 1000000 1060000 -- 1176000 1160000 -- >; -+ operating-points-v2 = <&cpu0_opp_table>; - - clocks = <&dpll_mpu_ck>; - clock-names = "cpu"; -@@ -99,6 +95,25 @@ - }; - }; - -+ cpu0_opp_table: opp_table0 { -+ compatible = "operating-points-v2-ti-cpu"; -+ ti,syscon-efuse = <&scm_wkup 0x20c 0xf80000 19>; -+ ti,syscon-rev = <&scm_wkup 0x204>; -+ -+ opp_nom@1000000000 { -+ opp-hz = /bits/ 64 <1000000000>; -+ opp-microvolt = <1060000 850000 1150000>; -+ opp-supported-hw = <0xFF 0x01>; -+ opp-suspend; -+ }; -+ -+ opp_od@1176000000 { -+ opp-hz = /bits/ 64 <1176000000>; -+ opp-microvolt = <1160000 885000 1160000>; -+ opp-supported-hw = <0xFF 0x02>; -+ }; -+ }; -+ - /* - * The soc node represents the soc top level view. It is used for IPs - * that are not memory mapped in the MPU view or for the MPU itself. -@@ -401,6 +416,13 @@ - reg = <0x40d00000 0x100>; - }; - -+ dra7_iodelay_core: padconf@4844a000 { -+ compatible = "ti,dra7-iodelay"; -+ reg = <0x4844a000 0x0d1c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ - sdma: dma-controller@4a056000 { - compatible = "ti,omap4430-sdma"; - reg = <0x4a056000 0x1000>; -@@ -959,6 +981,16 @@ - ti,hwmods = "dmm"; - }; - -+ bb2d: bb2d@59000000 { -+ compatible = "ti,dra7-bb2d","vivante,gc"; -+ reg = <0x59000000 0x0700>; -+ interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; -+ ti,hwmods = "bb2d"; -+ clocks = <&dpll_core_h24x2_ck>; -+ clock-names = "fclk"; -+ status = "disabled"; -+ }; -+ - i2c1: i2c@48070000 { - compatible = "ti,omap4-i2c"; - reg = <0x48070000 0x100>; -@@ -1970,6 +2002,12 @@ - }; - }; - -+ gpu-subsystem { -+ compatible = "vivante,gc-gpu-subsystem"; -+ cores = <&bb2d>; -+ status = "okay"; -+ }; -+ - thermal_zones: thermal-zones { - #include "omap4-cpu-thermal.dtsi" - #include "omap5-gpu-thermal.dtsi" -diff --git a/arch/arm/boot/dts/dra74x.dtsi b/arch/arm/boot/dts/dra74x.dtsi -index 0a78347..24e6746 100644 ---- a/arch/arm/boot/dts/dra74x.dtsi -+++ b/arch/arm/boot/dts/dra74x.dtsi -@@ -17,6 +17,7 @@ - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <1>; -+ operating-points-v2 = <&cpu0_opp_table>; - }; - }; - -@@ -79,6 +80,10 @@ - }; - }; - -+&cpu0_opp_table { -+ opp-shared; -+}; -+ - &dss { - reg = <0x58000000 0x80>, - <0x58004054 0x4>, -diff --git b/arch/arm/boot/dts/exynos5422-artik10-eval.dts b/arch/arm/boot/dts/exynos5422-artik10-eval.dts -new file mode 100644 -index 0000000..1001255 ---- /dev/null -+++ b/arch/arm/boot/dts/exynos5422-artik10-eval.dts -@@ -0,0 +1,278 @@ -+/* -+ * SAMSUNG ARTIK10 board device tree source -+ * -+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. -+ * http://www.samsung.com -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+*/ -+ -+/dts-v1/; -+ -+#include <dt-bindings/clock/samsung,s2mps11.h> -+#include <dt-bindings/interrupt-controller/irq.h> -+#include <dt-bindings/gpio/gpio.h> -+#include <dt-bindings/sound/samsung-i2s.h> -+#include "exynos5800.dtsi" -+#include "exynos5422-cpus.dtsi" -+#include "exynos-mfc-reserved-memory.dtsi" -+ -+/ { -+ model = "Samsung ARTIK10 board based on EXYNOS5422"; -+ compatible = "samsung,artik10", "samsung,exynos5422", "samsung,exynos5"; -+ -+ memory@40000000 { -+ device_type = "memory"; -+ reg = <0x40000000 0x7EA00000>; -+ }; -+ -+ chosen { -+ stdout-path = "serial2:115200n8"; -+ }; -+ -+ firmware@02073000 { -+ compatible = "samsung,secure-firmware"; -+ reg = <0x02073000 0x1000>; -+ }; -+ -+ fixed-rate-clocks { -+ oscclk { -+ compatible = "samsung,exynos5420-oscclk"; -+ clock-frequency = <24000000>; -+ }; -+ }; -+ -+ rtc { -+ status = "okay"; -+ }; -+}; -+ -+&cpu0 { -+ cpu-supply = <&buck6_reg>; -+}; -+ -+&cpu4 { -+ cpu-supply = <&buck2_reg>; -+}; -+ -+&pinctrl_0 { -+ s2mps11_irq: s2mps11-irq { -+ samsung,pins = "gpx3-2"; -+ samsung,pin-pud = <3>; -+ samsung,pin-drv = <3>; -+ }; -+}; -+ -+&hsi2c_4 { -+ clock-frequency = <400000>; -+ status = "okay"; -+ -+ s2mps11_pmic@66 { -+ compatible = "samsung,s2mps11-pmic"; -+ interrupt-parent = <&gpx3>; -+ interrupts = <2 IRQ_TYPE_EDGE_FALLING>; -+ reg = <0x66>; -+ -+ -+ pinctrl-names = "default"; -+ pinctrl-0 = <&s2mps11_irq>; -+ -+ s2mps11_osc: clocks { -+ #clock-cells = <1>; -+ clock-output-names = "s2mps11_ap", -+ "s2mps11_cp", "s2mps11_bt"; -+ }; -+ -+ regulators { -+ ldo4_reg: LDO4 { -+ regulator-name = "vdd_adc"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ }; -+ -+ ldo6_reg: LDO6 { -+ regulator-name = "vdd_ldo6"; -+ regulator-min-microvolt = <1000000>; -+ regulator-max-microvolt = <1000000>; -+ regulator-always-on; -+ }; -+ -+ ldo7_reg: LDO7 { -+ regulator-name = "vdd_ldo7"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ }; -+ -+ ldo13_reg: LDO13 { -+ regulator-name = "vqmmc"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <3300000>; -+ }; -+ -+ ldo17_reg: LDO17 { -+ regulator-name = "vdd_ldo17"; -+ regulator-min-microvolt = <2800000>; -+ regulator-max-microvolt = <2800000>; -+ }; -+ -+ ldo18_reg: LDO18 { -+ regulator-name = "vdd_ldo18"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ }; -+ -+ ldo19_reg: LDO19 { -+ regulator-name = "vmmc"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ }; -+ -+ ldo20_reg: LDO20 { -+ regulator-name = "vdd_ldo20"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ }; -+ -+ ldo23_reg: LDO23 { -+ regulator-name = "vdd_mifs"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1100000>; -+ regulator-always-on; -+ }; -+ -+ ldo24_reg: LDO24 { -+ regulator-name = "vdd_ldo24"; -+ regulator-min-microvolt = <2400000>; -+ regulator-max-microvolt = <2400000>; -+ }; -+ -+ ldo25_reg: LDO25 { -+ regulator-name = "vdd_ldo25"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ }; -+ -+ ldo27_reg: LDO27 { -+ regulator-name = "vdd_g3ds"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1100000>; -+ regulator-always-on; -+ }; -+ -+ ldo28_reg: LDO28 { -+ regulator-name = "vdd_ldo28"; -+ regulator-min-microvolt = <2800000>; -+ regulator-max-microvolt = <2800000>; -+ }; -+ -+ ldo32_reg: LDO32 { -+ regulator-name = "vdd_lcd_1v8"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ }; -+ -+ ldo38_reg: LDO38 { -+ regulator-name = "vdd_ldo38"; -+ regulator-min-microvolt = <2800000>; -+ regulator-max-microvolt = <2800000>; -+ regulator-always-on; -+ }; -+ -+ buck1_reg: BUCK1 { -+ regulator-name = "vdd_mif"; -+ regulator-min-microvolt = <700000>; -+ regulator-max-microvolt = <1300000>; -+ regulator-always-on; -+ }; -+ -+ buck2_reg: BUCK2 { -+ regulator-name = "vdd_eagle"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1500000>; -+ regulator-always-on; -+ }; -+ -+ buck3_reg: BUCK3 { -+ regulator-name = "vdd_int"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-always-on; -+ }; -+ -+ buck4_reg: BUCK4 { -+ regulator-name = "vdd_g3d"; -+ regulator-min-microvolt = <700000>; -+ regulator-max-microvolt = <1400000>; -+ regulator-always-on; -+ }; -+ -+ buck6_reg: BUCK6 { -+ regulator-name = "vdd_kfc"; -+ regulator-min-microvolt = <800000>; -+ regulator-max-microvolt = <1500000>; -+ regulator-always-on; -+ }; -+ -+ buck10_reg: BUCK10 { -+ regulator-name = "vdd_cam_isp_1.0v"; -+ regulator-min-microvolt = <750000>; -+ regulator-max-microvolt = <1500000>; -+ regulator-always-on; -+ }; -+ }; -+ }; -+}; -+ -+&mmc_0 { -+ status = "okay"; -+ broken-cd; -+ card-detect-delay = <200>; -+ samsung,dw-mshc-ciu-div = <3>; -+ samsung,dw-mshc-sdr-timing = <0 4>; -+ samsung,dw-mshc-ddr-timing = <0 2>; -+ samsung,dw-mshc-hs400-timing = <0 2>; -+ samsung,read-strobe-delay = <90>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8 -+ &sd0_rclk>; -+ bus-width = <8>; -+ cap-mmc-highspeed; -+ keep-power-in-suspend; -+ non-removable; -+}; -+ -+&mmc_2 { -+ status = "okay"; -+ card-detect-delay = <200>; -+ samsung,dw-mshc-ciu-div = <3>; -+ samsung,dw-mshc-sdr-timing = <2 3>; -+ samsung,dw-mshc-ddr-timing = <1 2>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>; -+ bus-width = <4>; -+ cap-sd-highspeed; -+ vmmc-supply = <&ldo28_reg>; -+}; -+ -+&nocp_mem0_0 { -+ status = "okay"; -+}; -+ -+&nocp_mem0_1 { -+ status = "okay"; -+}; -+ -+&nocp_mem1_0 { -+ status = "okay"; -+}; -+ -+&nocp_mem1_1 { -+ status = "okay"; -+}; -diff --git b/arch/arm/boot/dts/imx6q-ccimx6sbc.dts b/arch/arm/boot/dts/imx6q-ccimx6sbc.dts -new file mode 100644 -index 0000000..d249240 ---- /dev/null -+++ b/arch/arm/boot/dts/imx6q-ccimx6sbc.dts -@@ -0,0 +1,303 @@ -+/* -+ * Copyright (C) 2015 Robert Nelson (robertcnelson@gmail.com) -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPL or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This file is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License. -+ * -+ * This file is distributed in the hope that it will be useful -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Or, alternatively -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+/dts-v1/; -+ -+#include "imx6q.dtsi" -+#include <dt-bindings/gpio/gpio.h> -+ -+/ { -+ model = "Digi ConnectCore-i.MX6 SBC Board"; -+ compatible = "digi,connectcore/q", "fsl,imx6q"; -+ -+ chosen { -+ stdout-path = &uart4; -+ }; -+ -+ memory { -+ reg = <0x10000000 0x40000000>; -+ }; -+ -+ regulators { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ reg_usbh1_reset: regulator@1 { -+ compatible = "regulator-fixed"; -+ reg = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usbh1>; -+ regulator-name = "usbh1_reset"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ gpio = <&gpio3 10 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ }; -+ -+ reg_usb_otg_vbus: regulator@2 { -+ compatible = "regulator-fixed"; -+ reg = <2>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usbotg>; -+ regulator-name = "usb_otg_vbus"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ }; -+ }; -+}; -+ -+&fec { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_enet>; -+ phy-mode = "rgmii"; -+ phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; -+ status = "okay"; -+}; -+ -+&hdmi { -+ ddc-i2c-bus = <&i2c3>; -+ status = "okay"; -+}; -+ -+&i2c2 { -+ clock-frequency = <400000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_i2c2>; -+ status = "okay"; -+ -+ pmic@58 { -+ compatible = "dlg,da9063"; -+ reg = <0x58>; -+ interrupt-parent = <&gpio1>; -+ interrupts = <17 0x8>; /* active-low GPIO0_17 */ -+ -+ regulators { -+ vdd_3v3_reg: bperi { -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ -+ ldo3_reg: ldo3 { -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ -+ ldo4_reg: ldo4 { -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ -+ ldo6_reg: ldo6 { -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ -+ ldo7_reg: ldo7 { -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ }; -+ -+ ldo8_reg: ldo8 { -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ }; -+ }; -+}; -+ -+&i2c3 { -+ clock-frequency = <100000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_i2c3>; -+ status = "okay"; -+}; -+ -+&iomuxc { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_hog>; -+ -+ imx6qdl-ccimx6sbc { -+ pinctrl_hog: hoggrp { -+ fsl,pins = < -+ /* da9063*/ -+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 -+ >; -+ }; -+ -+ pinctrl_enet: enetgrp { -+ fsl,pins = < -+ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x100b0 -+ MX6QDL_PAD_ENET_MDC__ENET_MDC 0x100b0 -+ MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x100b0 -+ MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x100b0 -+ MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x100b0 -+ MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x100b0 -+ MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x100b0 -+ MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x100b0 -+ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x100b0 -+ MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 -+ MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 -+ MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 -+ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 -+ MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 -+ MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 -+ /* Phy reset */ -+ MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x000b0 -+ >; -+ }; -+ -+ pinctrl_i2c2: i2c2grp { -+ fsl,pins = < -+ MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 -+ MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 -+ >; -+ }; -+ -+ pinctrl_i2c3: i2c3grp { -+ fsl,pins = < -+ MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1 -+ MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 -+ >; -+ }; -+ -+ pinctrl_uart4: uart4grp { -+ fsl,pins = < -+ MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1 -+ MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1 -+ >; -+ }; -+ -+ pinctrl_usbh1: usbh1grp { -+ fsl,pins = < -+ /* need to force low for hub reset */ -+ MX6QDL_PAD_EIM_DA10__GPIO3_IO10 0x10b0 -+ >; -+ }; -+ -+ pinctrl_usbotg: usbotggrp { -+ fsl,pins = < -+ MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 -+ MX6QDL_PAD_EIM_D21__USB_OTG_OC 0x1b0b0 -+ /* power enable, high active */ -+ MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x10b0 -+ >; -+ }; -+ -+ pinctrl_usdhc2: usdhc2grp { -+ fsl,pins = < -+ MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059 -+ MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059 -+ MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059 -+ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059 -+ MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059 -+ MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059 -+ >; -+ }; -+ -+ pinctrl_usdhc4: usdhc4grp { -+ fsl,pins = < -+ MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059 -+ MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059 -+ MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059 -+ MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059 -+ MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059 -+ MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059 -+ MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059 -+ MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059 -+ MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059 -+ MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059 -+ >; -+ }; -+ }; -+}; -+ -+&sata { -+ status = "okay"; -+}; -+ -+&ssi1 { -+ status = "okay"; -+}; -+ -+&uart4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart4>; -+ status = "okay"; -+}; -+ -+&usbh1 { -+ vbus-supply = <®_usbh1_reset>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usbh1>; -+ status = "okay"; -+}; -+ -+&usbotg { -+ vbus-supply = <®_usb_otg_vbus>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usbotg>; -+ status = "okay"; -+}; -+ -+&usdhc2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usdhc2>; -+ bus-width = <4>; -+ broken-cd; /* cd & wp, is not wired up on this board */ -+ status = "okay"; -+}; -+ -+&usdhc4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usdhc4>; -+ bus-width = <8>; -+ non-removable; -+ status = "okay"; -+}; -diff --git a/arch/arm/boot/dts/imx6q-evi.dts b/arch/arm/boot/dts/imx6q-evi.dts -index 6de21ff..3277a06 100644 ---- a/arch/arm/boot/dts/imx6q-evi.dts -+++ b/arch/arm/boot/dts/imx6q-evi.dts -@@ -54,18 +54,6 @@ - reg = <0x10000000 0x40000000>; - }; - -- reg_usbh1_vbus: regulator-usbhubreset { -- compatible = "regulator-fixed"; -- regulator-name = "usbh1_vbus"; -- regulator-min-microvolt = <5000000>; -- regulator-max-microvolt = <5000000>; -- enable-active-high; -- startup-delay-us = <2>; -- pinctrl-names = "default"; -- pinctrl-0 = <&pinctrl_usbh1_hubreset>; -- gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>; -- }; -- - reg_usb_otg_vbus: regulator-usbotgvbus { - compatible = "regulator-fixed"; - regulator-name = "usb_otg_vbus"; -@@ -207,12 +195,18 @@ - }; - - &usbh1 { -- vbus-supply = <®_usbh1_vbus>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usbh1>; - dr_mode = "host"; - disable-over-current; - status = "okay"; -+ -+ usb2415host: hub@1 { -+ compatible = "usb424,2513"; -+ reg = <1>; -+ reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>; -+ reset-duration-us = <3000>; -+ }; - }; - - &usbotg { -@@ -471,11 +465,6 @@ - MX6QDL_PAD_GPIO_3__USB_H1_OC 0x1b0b0 - /* usbh1_b OC */ - MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0 -- >; -- }; -- -- pinctrl_usbh1_hubreset: usbh1hubresetgrp { -- fsl,pins = < - MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0 - >; - }; -diff --git a/arch/arm/boot/dts/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/imx6qdl-udoo.dtsi -index c96c91d..a173de2 100644 ---- a/arch/arm/boot/dts/imx6qdl-udoo.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-udoo.dtsi -@@ -9,6 +9,8 @@ - * - */ - -+#include <dt-bindings/gpio/gpio.h> -+ - / { - aliases { - backlight = &backlight; -@@ -58,17 +60,6 @@ - #address-cells = <1>; - #size-cells = <0>; - -- reg_usb_h1_vbus: regulator@0 { -- compatible = "regulator-fixed"; -- reg = <0>; -- regulator-name = "usb_h1_vbus"; -- regulator-min-microvolt = <5000000>; -- regulator-max-microvolt = <5000000>; -- enable-active-high; -- startup-delay-us = <2>; /* USB2415 requires a POR of 1 us minimum */ -- gpio = <&gpio7 12 0>; -- }; -- - reg_panel: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; -@@ -188,7 +179,7 @@ - - pinctrl_usbh: usbhgrp { - fsl,pins = < -- MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x80000000 -+ MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0 - MX6QDL_PAD_NANDF_CS2__CCM_CLKO2 0x130b0 - >; - }; -@@ -259,9 +250,16 @@ - &usbh1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usbh>; -- vbus-supply = <®_usb_h1_vbus>; -- clocks = <&clks IMX6QDL_CLK_CKO>; - status = "okay"; -+ -+ usb2415: hub@1 { -+ compatible = "usb424,2514"; -+ reg = <1>; -+ -+ clocks = <&clks IMX6QDL_CLK_CKO>; -+ reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>; -+ reset-duration-us = <3000>; -+ }; - }; - - &usdhc3 { -diff --git a/arch/arm/boot/dts/imx6qdl-wandboard-revb1.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard-revb1.dtsi -index ef7fa62..b5d0f58 100644 ---- a/arch/arm/boot/dts/imx6qdl-wandboard-revb1.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-wandboard-revb1.dtsi -@@ -11,6 +11,24 @@ - - #include "imx6qdl-wandboard.dtsi" - -+/ { -+ rfkill { -+ compatible = "wand,imx6qdl-wandboard-rfkill"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <>; -+ -+ bluetooth-on = <&gpio3 13 0>; -+ bluetooth-wake = <&gpio3 14 0>; -+ bluetooth-host-wake = <&gpio3 15 0>; -+ -+ wifi-ref-on = <&gpio2 29 0>; -+ wifi-rst-n = <&gpio5 2 0>; -+ wifi-reg-on = <&gpio1 26 0>; -+ wifi-host-wake = <&gpio1 29 0>; -+ wifi-wake = <&gpio1 30 0>; -+ }; -+}; -+ - &iomuxc { - pinctrl-0 = <&pinctrl_hog>; - -@@ -37,6 +55,5 @@ - &usdhc2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc2>; -- non-removable; - status = "okay"; - }; -diff --git a/arch/arm/boot/dts/imx6qdl-wandboard-revc1.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard-revc1.dtsi -index 8d893a7..b2097ef 100644 ---- a/arch/arm/boot/dts/imx6qdl-wandboard-revc1.dtsi -+++ b/arch/arm/boot/dts/imx6qdl-wandboard-revc1.dtsi -@@ -11,6 +11,24 @@ - - #include "imx6qdl-wandboard.dtsi" - -+/ { -+ rfkill { -+ compatible = "wand,imx6qdl-wandboard-rfkill"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <>; -+ -+ bluetooth-on = <&gpio5 21 0>; -+ bluetooth-wake = <&gpio5 30 0>; -+ bluetooth-host-wake = <&gpio5 20 0>; -+ -+ wifi-ref-on = <&gpio5 31 0>; /* Wifi Power Enable */ -+ wifi-rst-n = <&gpio6 0 0>; /* WIFI_ON reset */ -+ wifi-reg-on = <&gpio1 26 0>; /* WL_REG_ON */ -+ wifi-host-wake = <&gpio1 29 0>; /* WL_HOST_WAKE */ -+ wifi-wake = <&gpio1 30 0>; /* WL_WAKE */ -+ }; -+}; -+ - &iomuxc { - pinctrl-0 = <&pinctrl_hog>; - -diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi -index be2e747..b946245 100644 ---- a/arch/arm/boot/dts/imx6qdl.dtsi -+++ b/arch/arm/boot/dts/imx6qdl.dtsi -@@ -935,6 +935,8 @@ - - usbh1: usb@02184200 { - compatible = "fsl,imx6q-usb", "fsl,imx27-usb"; -+ #address-cells = <1>; -+ #size-cells = <0>; - reg = <0x02184200 0x200>; - interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clks IMX6QDL_CLK_USBOH3>; -@@ -949,6 +951,8 @@ - - usbh2: usb@02184400 { - compatible = "fsl,imx6q-usb", "fsl,imx27-usb"; -+ #address-cells = <1>; -+ #size-cells = <0>; - reg = <0x02184400 0x200>; - interrupts = <0 41 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clks IMX6QDL_CLK_USBOH3>; -@@ -962,6 +966,8 @@ - - usbh3: usb@02184600 { - compatible = "fsl,imx6q-usb", "fsl,imx27-usb"; -+ #address-cells = <1>; -+ #size-cells = <0>; - reg = <0x02184600 0x200>; - interrupts = <0 42 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clks IMX6QDL_CLK_USBOH3>; -diff --git b/arch/arm/boot/dts/imx6ul-14x14-evk-ism43362-b81-evb.dts b/arch/arm/boot/dts/imx6ul-14x14-evk-ism43362-b81-evb.dts -new file mode 100644 -index 0000000..9ba86b8 ---- /dev/null -+++ b/arch/arm/boot/dts/imx6ul-14x14-evk-ism43362-b81-evb.dts -@@ -0,0 +1,516 @@ -+/* -+ * Copyright (C) 2015 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+/dts-v1/; -+ -+#include "imx6ul.dtsi" -+ -+/ { -+ model = "Freescale i.MX6 UltraLite 14x14 EVK Board"; -+ compatible = "fsl,imx6ul-14x14-evk", "fsl,imx6ul"; -+ -+ chosen { -+ stdout-path = &uart1; -+ }; -+ -+ memory { -+ reg = <0x80000000 0x20000000>; -+ }; -+ -+ backlight { -+ compatible = "pwm-backlight"; -+ pwms = <&pwm1 0 5000000>; -+ brightness-levels = <0 4 8 16 32 64 128 255>; -+ default-brightness-level = <6>; -+ status = "okay"; -+ }; -+ -+ regulators { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ reg_sd1_vmmc: sd1_regulator { -+ compatible = "regulator-fixed"; -+ regulator-name = "VSD_3V3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>; -+ enable-active-high; -+ }; -+ -+ wlreg_on: fixedregulator@100 { -+ compatible = "regulator-fixed"; -+ regulator-min-microvolt = <5000000>; -+ regulator-max-microvolt = <5000000>; -+ regulator-name = "wlreg_on"; -+ gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>; -+ startup-delay-us = <100>; -+ enable-active-high; -+ }; -+ }; -+ -+ sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,name = "mx6ul-wm8960"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,bitclock-master = <&dailink_master>; -+ simple-audio-card,frame-master = <&dailink_master>; -+ simple-audio-card,widgets = -+ "Microphone", "Mic Jack", -+ "Line", "Line In", -+ "Line", "Line Out", -+ "Speaker", "Speaker", -+ "Headphone", "Headphone Jack"; -+ simple-audio-card,routing = -+ "Headphone Jack", "HP_L", -+ "Headphone Jack", "HP_R", -+ "Speaker", "SPK_LP", -+ "Speaker", "SPK_LN", -+ "Speaker", "SPK_RP", -+ "Speaker", "SPK_RN", -+ "LINPUT1", "Mic Jack", -+ "LINPUT3", "Mic Jack", -+ "RINPUT1", "Mic Jack", -+ "RINPUT2", "Mic Jack"; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&sai2>; -+ }; -+ -+ dailink_master: simple-audio-card,codec { -+ sound-dai = <&codec>; -+ clocks = <&clks IMX6UL_CLK_SAI2>; -+ }; -+ }; -+}; -+ -+&clks { -+ assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>; -+ assigned-clock-rates = <786432000>; -+}; -+ -+&cpu0 { -+ arm-supply = <®_arm>; -+ soc-supply = <®_soc>; -+}; -+ -+&i2c2 { -+ clock_frequency = <100000>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_i2c2>; -+ status = "okay"; -+ -+ codec: wm8960@1a { -+ #sound-dai-cells = <0>; -+ compatible = "wlf,wm8960"; -+ reg = <0x1a>; -+ wlf,shared-lrclk; -+ }; -+}; -+ -+&fec1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_enet1>; -+ phy-mode = "rmii"; -+ phy-handle = <ðphy0>; -+ status = "okay"; -+}; -+ -+&fec2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_enet2>; -+ phy-mode = "rmii"; -+ phy-handle = <ðphy1>; -+ status = "okay"; -+ -+ mdio { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethphy0: ethernet-phy@2 { -+ reg = <2>; -+ }; -+ -+ ethphy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+ }; -+}; -+ -+ -+&lcdif { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_lcdif_dat -+ &pinctrl_lcdif_ctrl>; -+ display = <&display0>; -+ status = "okay"; -+ -+ display0: display { -+ bits-per-pixel = <16>; -+ bus-width = <24>; -+ -+ display-timings { -+ native-mode = <&timing0>; -+ -+ timing0: timing0 { -+ clock-frequency = <9200000>; -+ hactive = <480>; -+ vactive = <272>; -+ hfront-porch = <8>; -+ hback-porch = <4>; -+ hsync-len = <41>; -+ vback-porch = <2>; -+ vfront-porch = <4>; -+ vsync-len = <10>; -+ hsync-active = <0>; -+ vsync-active = <0>; -+ de-active = <1>; -+ pixelclk-active = <0>; -+ }; -+ }; -+ }; -+}; -+ -+&pwm1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_pwm1>; -+ status = "okay"; -+}; -+ -+&qspi { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_qspi>; -+ status = "okay"; -+ -+ flash0: n25q256a@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "micron,n25q256a"; -+ spi-max-frequency = <29000000>; -+ reg = <0>; -+ }; -+}; -+ -+&sai2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_sai2>; -+ assigned-clocks = <&clks IMX6UL_CLK_SAI2_SEL>, -+ <&clks IMX6UL_CLK_SAI2>; -+ assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>; -+ assigned-clock-rates = <0>, <12288000>; -+ fsl,sai-mclk-direction-output; -+ status = "okay"; -+}; -+ -+&snvs_poweroff { -+ status = "okay"; -+}; -+ -+&tsc { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_tsc>; -+ xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>; -+ measure-delay-time = <0xffff>; -+ pre-charge-time = <0xfff>; -+ status = "okay"; -+}; -+ -+&uart1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart1>; -+ status = "okay"; -+}; -+ -+&uart2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_uart2>; -+ uart-has-rtscts; -+ status = "okay"; -+}; -+ -+&usbotg1 { -+ dr_mode = "peripheral"; -+ status = "okay"; -+}; -+ -+&usbotg2 { -+ dr_mode = "host"; -+ disable-over-current; -+ status = "okay"; -+}; -+ -+®_sd1_vmmc { -+ regulator-always-on; -+}; -+ -+&usdhc1 { -+ pinctrl-names = "default", "state_100mhz", "state_200mhz"; -+ pinctrl-0 = <&pinctrl_usdhc1>; -+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>; -+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>; -+ cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>; -+ no-1-8-v; -+ keep-power-in-suspend; -+ wakeup-source; -+ vmmc-supply = <®_sd1_vmmc>; -+ status = "okay"; -+}; -+ -+&usdhc2 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_usdhc2>; -+ no-1-8-v; -+ keep-power-in-suspend; -+ wakeup-source; -+ status = "okay"; -+}; -+ -+&wdog1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pinctrl_wdog>; -+ fsl,ext-reset-output; -+}; -+ -+&iomuxc { -+ pinctrl-names = "default"; -+ -+ pinctrl_csi1: csi1grp { -+ fsl,pins = < -+ MX6UL_PAD_CSI_MCLK__CSI_MCLK 0x1b088 -+ MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK 0x1b088 -+ MX6UL_PAD_CSI_VSYNC__CSI_VSYNC 0x1b088 -+ MX6UL_PAD_CSI_HSYNC__CSI_HSYNC 0x1b088 -+ MX6UL_PAD_CSI_DATA00__CSI_DATA02 0x1b088 -+ MX6UL_PAD_CSI_DATA01__CSI_DATA03 0x1b088 -+ MX6UL_PAD_CSI_DATA02__CSI_DATA04 0x1b088 -+ MX6UL_PAD_CSI_DATA03__CSI_DATA05 0x1b088 -+ MX6UL_PAD_CSI_DATA04__CSI_DATA06 0x1b088 -+ MX6UL_PAD_CSI_DATA05__CSI_DATA07 0x1b088 -+ MX6UL_PAD_CSI_DATA06__CSI_DATA08 0x1b088 -+ MX6UL_PAD_CSI_DATA07__CSI_DATA09 0x1b088 -+ >; -+ }; -+ -+ pinctrl_enet1: enet1grp { -+ fsl,pins = < -+ MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0 -+ MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0 -+ MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0 -+ MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0 -+ MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0 -+ MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0 -+ MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0 -+ MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031 -+ >; -+ }; -+ -+ pinctrl_enet2: enet2grp { -+ fsl,pins = < -+ MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0 -+ MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0 -+ MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0 -+ MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0 -+ MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0 -+ MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0 -+ MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0 -+ MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0 -+ MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0 -+ MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031 -+ MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x17059 -+ >; -+ }; -+ -+ pinctrl_flexcan1: flexcan1grp{ -+ fsl,pins = < -+ MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX 0x1b020 -+ MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX 0x1b020 -+ >; -+ }; -+ -+ pinctrl_flexcan2: flexcan2grp{ -+ fsl,pins = < -+ MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX 0x1b020 -+ MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX 0x1b020 -+ >; -+ }; -+ -+ pinctrl_i2c1: i2c1grp { -+ fsl,pins = < -+ MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0 -+ MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0 -+ >; -+ }; -+ -+ pinctrl_i2c2: i2c2grp { -+ fsl,pins = < -+ MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0 -+ MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0 -+ >; -+ }; -+ -+ pinctrl_lcdif_dat: lcdifdatgrp { -+ fsl,pins = < -+ MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79 -+ MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79 -+ MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79 -+ MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79 -+ MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79 -+ MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79 -+ MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79 -+ MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79 -+ MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79 -+ MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79 -+ MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79 -+ MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79 -+ MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79 -+ MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79 -+ MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79 -+ MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79 -+ MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79 -+ MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79 -+ MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79 -+ MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79 -+ MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79 -+ MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79 -+ MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79 -+ MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79 -+ >; -+ }; -+ -+ pinctrl_lcdif_ctrl: lcdifctrlgrp { -+ fsl,pins = < -+ MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79 -+ MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79 -+ MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79 -+ MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79 -+ /* used for lcd reset */ -+ MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x79 -+ >; -+ }; -+ -+ pinctrl_qspi: qspigrp { -+ fsl,pins = < -+ MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK 0x70a1 -+ MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00 0x70a1 -+ MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01 0x70a1 -+ MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02 0x70a1 -+ MX6UL_PAD_NAND_CLE__QSPI_A_DATA03 0x70a1 -+ MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B 0x70a1 -+ >; -+ }; -+ -+ pinctrl_sai2: sai2grp { -+ fsl,pins = < -+ MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK 0x17088 -+ MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC 0x17088 -+ MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA 0x11088 -+ MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA 0x11088 -+ MX6UL_PAD_JTAG_TMS__SAI2_MCLK 0x17088 -+ MX6UL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x17059 -+ >; -+ }; -+ -+ pinctrl_pwm1: pwm1grp { -+ fsl,pins = < -+ MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0 -+ >; -+ }; -+ -+ pinctrl_sim2: sim2grp { -+ fsl,pins = < -+ MX6UL_PAD_CSI_DATA03__SIM2_PORT1_PD 0xb808 -+ MX6UL_PAD_CSI_DATA04__SIM2_PORT1_CLK 0x31 -+ MX6UL_PAD_CSI_DATA05__SIM2_PORT1_RST_B 0xb808 -+ MX6UL_PAD_CSI_DATA06__SIM2_PORT1_SVEN 0xb808 -+ MX6UL_PAD_CSI_DATA07__SIM2_PORT1_TRXD 0xb809 -+ MX6UL_PAD_CSI_DATA02__GPIO4_IO23 0x3008 -+ >; -+ }; -+ -+ pinctrl_tsc: tscgrp { -+ fsl,pins = < -+ MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0 -+ MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0xb0 -+ MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0xb0 -+ MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0xb0 -+ >; -+ }; -+ -+ pinctrl_uart1: uart1grp { -+ fsl,pins = < -+ MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1 -+ MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1 -+ >; -+ }; -+ -+ pinctrl_uart2: uart2grp { -+ fsl,pins = < -+ MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x1b0b1 -+ MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x1b0b1 -+ MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS 0x1b0b1 -+ MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS 0x1b0b1 -+ >; -+ }; -+ -+ pinctrl_usdhc1: usdhc1grp { -+ fsl,pins = < -+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059 -+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10071 -+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059 -+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059 -+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059 -+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059 -+ MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */ -+ MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */ -+ MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 /* SD1 RESET */ -+ MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x3029 -+ >; -+ }; -+ -+ pinctrl_usdhc1_100mhz: usdhc1grp100mhz { -+ fsl,pins = < -+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9 -+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9 -+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9 -+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9 -+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9 -+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9 -+ MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x3029 -+ >; -+ }; -+ -+ pinctrl_usdhc1_200mhz: usdhc1grp200mhz { -+ fsl,pins = < -+ MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9 -+ MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9 -+ MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9 -+ MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9 -+ MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9 -+ MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9 -+ MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x3029 -+ >; -+ }; -+ -+ pinctrl_usdhc2: usdhc2grp { -+ fsl,pins = < -+ MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x17059 -+ MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059 -+ MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059 -+ MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059 -+ MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059 -+ MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059 -+ >; -+ }; -+ -+ pinctrl_wdog: wdoggrp { -+ fsl,pins = < -+ MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY 0x30b0 -+ >; -+ }; -+}; -diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts -index 85e297e..226b833 100644 ---- a/arch/arm/boot/dts/omap3-beagle-xm.dts -+++ b/arch/arm/boot/dts/omap3-beagle-xm.dts -@@ -27,6 +27,7 @@ - aliases { - display0 = &dvi0; - display1 = &tv0; -+ ethernet = ðernet; - }; - - leds { -@@ -146,6 +147,7 @@ - }; - - etb@5401b000 { -+ status = "disabled"; - compatible = "arm,coresight-etb10", "arm,primecell"; - reg = <0x5401b000 0x1000>; - -@@ -160,6 +162,7 @@ - }; - - etm@54010000 { -+ status = "disabled"; - compatible = "arm,coresight-etm3x", "arm,primecell"; - reg = <0x54010000 0x1000>; - -@@ -205,6 +208,25 @@ - >; - }; - -+ spi3_pins: pinmux_spi3_pins { -+ pinctrl-single,pins = < -+ 0x128 (PIN_INPUT | MUX_MODE1) /* sdmmc2_clk.mcspi3_clk gpio_130 */ -+ 0x12a (PIN_OUTPUT | MUX_MODE1) /* sdmmc2_cmd.mcspi3_simo gpio_131 */ -+ 0x12c (PIN_INPUT_PULLUP | MUX_MODE1) /* sdmmc2_dat0.mcspi3_somi gpio_132 */ -+ 0x130 (PIN_OUTPUT | MUX_MODE1) /* sdmmc2_dat2.mcspi3_cs1 gpio_134 */ -+ 0x132 (PIN_OUTPUT | MUX_MODE1) /* sdmmc2_dat3.mcspi3_cs0 gpio_135 */ -+ >; -+ }; -+ -+ spi4_pins: pinmux_spi4_pins { -+ pinctrl-single,pins = < -+ 0x15c (PIN_INPUT | MUX_MODE1) /* mcbsp1_clkr.mcspi4_clk gpio_156 */ -+ 0x160 (PIN_OUTPUT | MUX_MODE1) /* mcbsp1_dx.mcspi4_simo gpio_158 */ -+ 0x162 (PIN_INPUT_PULLUP | MUX_MODE1) /* mcbsp1_dr.mcspi4_somi gpio_159 */ -+ 0x166 (PIN_OUTPUT | MUX_MODE1) /* mcbsp1_fsx.mcspi4_cs0 gpio_161 */ -+ >; -+ }; -+ - hsusb2_pins: pinmux_hsusb2_pins { - pinctrl-single,pins = < - OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ -@@ -279,7 +301,7 @@ - }; - - twl_power: power { -- compatible = "ti,twl4030-power-beagleboard-xm", "ti,twl4030-power-idle-osc-off"; -+ compatible = "ti,twl4030-power-reset"; - ti,use_poweroff; - }; - }; -@@ -310,6 +332,36 @@ - status = "disabled"; - }; - -+&mcspi3 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi3_pins>; -+ status = "okay"; -+ -+ spidev0: spi@0 { -+ compatible = "spidev"; -+ reg = <0>; -+ spi-max-frequency = <48000000>; -+ }; -+ -+ spidev1: spi@1 { -+ compatible = "spidev"; -+ reg = <1>; -+ spi-max-frequency = <48000000>; -+ }; -+}; -+ -+&mcspi4 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi4_pins>; -+ status = "okay"; -+ -+ spidev2: spi@0 { -+ compatible = "spidev"; -+ reg = <0>; -+ spi-max-frequency = <48000000>; -+ }; -+}; -+ - &twl_gpio { - ti,use-leds; - /* pullups: BIT(1) */ -@@ -348,6 +400,21 @@ - - &usbhsehci { - phys = <0 &hsusb2_phy>; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hub@2 { -+ compatible = "usb424,9514"; -+ reg = <2>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethernet: usbether@1 { -+ compatible = "usb424,ec00"; -+ reg = <1>; -+ }; -+ }; - }; - - &vaux2 { -diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts -index 4be85ce..049b5e1 100644 ---- a/arch/arm/boot/dts/omap3-beagle.dts -+++ b/arch/arm/boot/dts/omap3-beagle.dts -@@ -141,6 +141,7 @@ - }; - - etb@540000000 { -+ status = "disabled"; - compatible = "arm,coresight-etb10", "arm,primecell"; - reg = <0x5401b000 0x1000>; - -@@ -155,6 +156,7 @@ - }; - - etm@54010000 { -+ status = "disabled"; - compatible = "arm,coresight-etm3x", "arm,primecell"; - reg = <0x54010000 0x1000>; - -@@ -271,9 +273,18 @@ - codec { - }; - }; -+ -+ twl_power: power { -+ compatible = "ti,twl4030-power-reset"; -+ ti,use_poweroff; -+ }; - }; - }; - -+&i2c2 { -+ clock-frequency = <400000>; -+}; -+ - #include "twl4030.dtsi" - #include "twl4030_omap3.dtsi" - -diff --git a/arch/arm/boot/dts/omap4-panda-a4.dts b/arch/arm/boot/dts/omap4-panda-a4.dts -index 78d3631..67ee5b4 100644 ---- a/arch/arm/boot/dts/omap4-panda-a4.dts -+++ b/arch/arm/boot/dts/omap4-panda-a4.dts -@@ -10,6 +10,18 @@ - #include "omap443x.dtsi" - #include "omap4-panda-common.dtsi" - -+&emif1 { -+ cs1-used; -+ device-handle = <&elpida_ECB240ABACN>; -+ status = "ok"; -+}; -+ -+&emif2 { -+ cs1-used; -+ device-handle = <&elpida_ECB240ABACN>; -+ status = "ok"; -+}; -+ - /* Pandaboard Rev A4+ have external pullups on SCL & SDA */ - &dss_hdmi_pins { - pinctrl-single,pins = < -diff --git a/arch/arm/boot/dts/omap4-panda-common.dtsi b/arch/arm/boot/dts/omap4-panda-common.dtsi -index 1673689..c6b90f0 100644 ---- a/arch/arm/boot/dts/omap4-panda-common.dtsi -+++ b/arch/arm/boot/dts/omap4-panda-common.dtsi -@@ -463,16 +463,6 @@ - }; - }; - --&emif1 { -- cs1-used; -- device-handle = <&elpida_ECB240ABACN>; --}; -- --&emif2 { -- cs1-used; -- device-handle = <&elpida_ECB240ABACN>; --}; -- - &mcbsp1 { - pinctrl-names = "default"; - pinctrl-0 = <&mcbsp1_pins>; -diff --git b/arch/arm/boot/dts/omap4-panda-es-b3.dts b/arch/arm/boot/dts/omap4-panda-es-b3.dts -new file mode 100644 -index 0000000..2f1dabc ---- /dev/null -+++ b/arch/arm/boot/dts/omap4-panda-es-b3.dts -@@ -0,0 +1,73 @@ -+/* -+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/dts-v1/; -+ -+#include "omap4460.dtsi" -+#include "omap4-panda-common.dtsi" -+ -+/ { -+ model = "TI OMAP4 PandaBoard-ES"; -+ compatible = "ti,omap4-panda-es", "ti,omap4-panda", "ti,omap4460", "ti,omap4430", "ti,omap4"; -+}; -+ -+/* Audio routing is differnet between PandaBoard4430 and PandaBoardES */ -+&sound { -+ ti,model = "PandaBoardES"; -+ -+ /* Audio routing */ -+ ti,audio-routing = -+ "Headset Stereophone", "HSOL", -+ "Headset Stereophone", "HSOR", -+ "Ext Spk", "HFL", -+ "Ext Spk", "HFR", -+ "Line Out", "AUXL", -+ "Line Out", "AUXR", -+ "AFML", "Line In", -+ "AFMR", "Line In"; -+}; -+ -+/* PandaboardES has external pullups on SCL & SDA */ -+&dss_hdmi_pins { -+ pinctrl-single,pins = < -+ 0x5a (PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ -+ 0x5c (PIN_INPUT | MUX_MODE0) /* hdmi_scl.hdmi_scl */ -+ 0x5e (PIN_INPUT | MUX_MODE0) /* hdmi_sda.hdmi_sda */ -+ >; -+}; -+ -+&omap4_pmx_core { -+ led_gpio_pins: gpio_led_pmx { -+ pinctrl-single,pins = < -+ 0xb6 (PIN_OUTPUT | MUX_MODE3) /* gpio_110 */ -+ >; -+ }; -+}; -+ -+&led_wkgpio_pins { -+ pinctrl-single,pins = < -+ 0x1c (PIN_OUTPUT | MUX_MODE3) /* gpio_wk8 */ -+ >; -+}; -+ -+&leds { -+ pinctrl-0 = < -+ &led_gpio_pins -+ &led_wkgpio_pins -+ >; -+ -+ heartbeat { -+ gpios = <&gpio4 14 GPIO_ACTIVE_HIGH>; -+ }; -+ mmc { -+ gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; -+ }; -+}; -+ -+&gpio1 { -+ ti,no-reset-on-init; -+}; -diff --git a/arch/arm/boot/dts/omap4-panda-es.dts b/arch/arm/boot/dts/omap4-panda-es.dts -index 119f8e6..5c54ccf 100644 ---- a/arch/arm/boot/dts/omap4-panda-es.dts -+++ b/arch/arm/boot/dts/omap4-panda-es.dts -@@ -15,6 +15,18 @@ - compatible = "ti,omap4-panda-es", "ti,omap4-panda", "ti,omap4460", "ti,omap4430", "ti,omap4"; - }; - -+&emif1 { -+ cs1-used; -+ device-handle = <&elpida_ECB240ABACN>; -+ status = "ok"; -+}; -+ -+&emif2 { -+ cs1-used; -+ device-handle = <&elpida_ECB240ABACN>; -+ status = "ok"; -+}; -+ - /* Audio routing is differnet between PandaBoard4430 and PandaBoardES */ - &sound { - ti,model = "PandaBoardES"; -diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts -index a0e28b2..3ee41ef 100644 ---- a/arch/arm/boot/dts/omap4-panda.dts -+++ b/arch/arm/boot/dts/omap4-panda.dts -@@ -14,3 +14,15 @@ - model = "TI OMAP4 PandaBoard"; - compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4"; - }; -+ -+&emif1 { -+ cs1-used; -+ device-handle = <&elpida_ECB240ABACN>; -+ status = "ok"; -+}; -+ -+&emif2 { -+ cs1-used; -+ device-handle = <&elpida_ECB240ABACN>; -+ status = "ok"; -+}; -diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts -index d728ec9..fb2cda4 100644 ---- a/arch/arm/boot/dts/omap4-sdp.dts -+++ b/arch/arm/boot/dts/omap4-sdp.dts -@@ -502,11 +502,13 @@ - &emif1 { - cs1-used; - device-handle = <&elpida_ECB240ABACN>; -+ status = "ok"; - }; - - &emif2 { - cs1-used; - device-handle = <&elpida_ECB240ABACN>; -+ status = "ok"; - }; - - &keypad { -diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi -index 9c289dd..ea0b76b 100644 ---- a/arch/arm/boot/dts/omap4.dtsi -+++ b/arch/arm/boot/dts/omap4.dtsi -@@ -696,6 +696,7 @@ - hw-caps-read-idle-ctrl; - hw-caps-ll-interface; - hw-caps-temp-alert; -+ status = "disabled"; - }; - - emif2: emif@4d000000 { -@@ -708,6 +709,7 @@ - hw-caps-read-idle-ctrl; - hw-caps-ll-interface; - hw-caps-temp-alert; -+ status = "disabled"; - }; - - ocp2scp@4a0ad000 { -diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts -index 5c9b5bf..7c9335d 100644 ---- a/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts -+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-one.dts -@@ -94,6 +94,17 @@ - status = "okay"; - }; - -+&emac { -+ phy = <&phy1>; -+ phy-mode = "mii"; -+ allwinner,use-internal-phy; -+ allwinner,leds-active-low; -+ status = "okay"; -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+}; -+ - &mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; -diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts -index 3ec9712..21acd8a 100644 ---- a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts -+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts -@@ -183,3 +183,14 @@ - /* USB VBUS is always on */ - status = "okay"; - }; -+ -+&emac { -+ phy = <&phy1>; -+ phy-mode = "mii"; -+ allwinner,use-internal-phy; -+ allwinner,leds-active-low; -+ status = "okay"; -+ phy1: ethernet-phy@1 { -+ reg = <1>; -+ }; -+}; -diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi -index f4ba088..43c4a5c 100644 ---- a/arch/arm/boot/dts/sun8i-h3.dtsi -+++ b/arch/arm/boot/dts/sun8i-h3.dtsi -@@ -50,6 +50,10 @@ - / { - interrupt-parent = <&gic>; - -+ aliases { -+ ethernet0 = &emac; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -530,6 +534,20 @@ - #size-cells = <0>; - }; - -+ emac: ethernet@1c30000 { -+ compatible = "allwinner,sun8i-h3-emac"; -+ reg = <0x01c30000 0x104>, <0x01c00030 0x4>; -+ reg-names = "emac", "syscon"; -+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; -+ resets = <&ccu RST_BUS_EMAC>, <&ccu RST_BUS_EPHY>; -+ reset-names = "ahb", "ephy"; -+ clocks = <&ccu CLK_BUS_EMAC>, <&ccu CLK_BUS_EPHY>; -+ clock-names = "ahb", "ephy"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ - gic: interrupt-controller@01c81000 { - compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; - reg = <0x01c81000 0x1000>, -diff --git a/arch/arm/boot/dts/tps65217.dtsi b/arch/arm/boot/dts/tps65217.dtsi -index a632724..02de56b 100644 ---- a/arch/arm/boot/dts/tps65217.dtsi -+++ b/arch/arm/boot/dts/tps65217.dtsi -@@ -13,6 +13,18 @@ - - &tps { - compatible = "ti,tps65217"; -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ -+ charger { -+ compatible = "ti,tps65217-charger"; -+ status = "disabled"; -+ }; -+ -+ pwrbutton { -+ compatible = "ti,tps65217-pwrbutton"; -+ status = "disabled"; -+ }; - - regulators { - #address-cells = <1>; -diff --git a/arch/arm/mach-imx/devices/Kconfig b/arch/arm/mach-imx/devices/Kconfig -index 6ffe572..bb7bd88 100644 ---- a/arch/arm/mach-imx/devices/Kconfig -+++ b/arch/arm/mach-imx/devices/Kconfig -@@ -68,3 +68,9 @@ config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX - - config IMX_HAVE_PLATFORM_SPI_IMX - bool -+ -+config WAND_RFKILL -+ tristate "Wandboard RF Kill support" -+ depends on SOC_IMX6Q -+ default m -+ select RFKILL -diff --git a/arch/arm/mach-imx/devices/Makefile b/arch/arm/mach-imx/devices/Makefile -index aa6cee8..800ce9b 100644 ---- a/arch/arm/mach-imx/devices/Makefile -+++ b/arch/arm/mach-imx/devices/Makefile -@@ -25,3 +25,4 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o - obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o - obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o - obj-$(CONFIG_IMX_HAVE_PLATFORM_MX2_EMMA) += platform-mx2-emma.o -+obj-$(CONFIG_WAND_RFKILL) += wand-rfkill.o -diff --git b/arch/arm/mach-imx/devices/wand-rfkill.c b/arch/arm/mach-imx/devices/wand-rfkill.c -new file mode 100644 -index 0000000..da7ef9f ---- /dev/null -+++ b/arch/arm/mach-imx/devices/wand-rfkill.c -@@ -0,0 +1,290 @@ -+/* -+ * arch/arm/mach-imx/devices/wand-rfkill.c -+ * -+ * Copyright (C) 2013 Vladimir Ermakov <vooon341@gmail.com> -+ * -+ * based on net/rfkill/rfkill-gpio.c -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#include <linux/of.h> -+#include <linux/of_gpio.h> -+#include <linux/of_device.h> -+#include <linux/pinctrl/consumer.h> -+#include <linux/platform_device.h> -+#include <linux/rfkill.h> -+#include <linux/delay.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/slab.h> -+ -+ -+struct wand_rfkill_data { -+ struct rfkill *rfkill_dev; -+ int shutdown_gpio; -+ const char *shutdown_name; -+}; -+ -+static int wand_rfkill_set_block(void *data, bool blocked) -+{ -+ struct wand_rfkill_data *rfkill = data; -+ -+ pr_debug("wandboard-rfkill: set block %d\n", blocked); -+ -+ if (blocked) { -+ if (gpio_is_valid(rfkill->shutdown_gpio)) -+ gpio_direction_output(rfkill->shutdown_gpio, 0); -+ } else { -+ if (gpio_is_valid(rfkill->shutdown_gpio)) -+ gpio_direction_output(rfkill->shutdown_gpio, 1); -+ } -+ -+ return 0; -+} -+ -+static const struct rfkill_ops wand_rfkill_ops = { -+ .set_block = wand_rfkill_set_block, -+}; -+ -+static int wand_rfkill_wifi_probe(struct device *dev, -+ struct device_node *np, -+ struct wand_rfkill_data *rfkill) -+{ -+ int ret; -+ int wl_ref_on, wl_rst_n, wl_reg_on, wl_wake, wl_host_wake; -+ -+ wl_ref_on = of_get_named_gpio(np, "wifi-ref-on", 0); -+ wl_rst_n = of_get_named_gpio(np, "wifi-rst-n", 0); -+ wl_reg_on = of_get_named_gpio(np, "wifi-reg-on", 0); -+ wl_wake = of_get_named_gpio(np, "wifi-wake", 0); -+ wl_host_wake = of_get_named_gpio(np, "wifi-host-wake", 0); -+ -+ if (!gpio_is_valid(wl_rst_n) || !gpio_is_valid(wl_ref_on) || -+ !gpio_is_valid(wl_reg_on) || !gpio_is_valid(wl_wake) || -+ !gpio_is_valid(wl_host_wake)) { -+ -+ dev_err(dev, "incorrect wifi gpios (%d %d %d %d %d)\n", -+ wl_rst_n, wl_ref_on, wl_reg_on, wl_wake, wl_host_wake); -+ return -EINVAL; -+ } -+ -+ dev_info(dev, "initialize wifi chip\n"); -+ -+ gpio_request(wl_rst_n, "wl_rst_n"); -+ gpio_direction_output(wl_rst_n, 0); -+ msleep(11); -+ gpio_set_value(wl_rst_n, 1); -+ -+ gpio_request(wl_ref_on, "wl_ref_on"); -+ gpio_direction_output(wl_ref_on, 1); -+ -+ gpio_request(wl_reg_on, "wl_reg_on"); -+ gpio_direction_output(wl_reg_on, 1); -+ -+ gpio_request(wl_wake, "wl_wake"); -+ gpio_direction_output(wl_wake, 1); -+ -+ gpio_request(wl_host_wake, "wl_host_wake"); -+ gpio_direction_input(wl_host_wake); -+ -+ rfkill->shutdown_name = "wifi_shutdown"; -+ rfkill->shutdown_gpio = wl_wake; -+ -+ rfkill->rfkill_dev = rfkill_alloc("wifi-rfkill", dev, RFKILL_TYPE_WLAN, -+ &wand_rfkill_ops, rfkill); -+ if (!rfkill->rfkill_dev) { -+ ret = -ENOMEM; -+ goto wifi_fail_free_gpio; -+ } -+ -+ ret = rfkill_register(rfkill->rfkill_dev); -+ if (ret < 0) -+ goto wifi_fail_unregister; -+ -+ dev_info(dev, "wifi-rfkill registered.\n"); -+ -+ return 0; -+ -+wifi_fail_unregister: -+ rfkill_destroy(rfkill->rfkill_dev); -+wifi_fail_free_gpio: -+ if (gpio_is_valid(wl_rst_n)) gpio_free(wl_rst_n); -+ if (gpio_is_valid(wl_ref_on)) gpio_free(wl_ref_on); -+ if (gpio_is_valid(wl_reg_on)) gpio_free(wl_reg_on); -+ if (gpio_is_valid(wl_wake)) gpio_free(wl_wake); -+ if (gpio_is_valid(wl_host_wake)) gpio_free(wl_host_wake); -+ -+ return ret; -+} -+ -+static int wand_rfkill_bt_probe(struct device *dev, -+ struct device_node *np, -+ struct wand_rfkill_data *rfkill) -+{ -+ int ret; -+ int bt_on, bt_wake, bt_host_wake; -+ -+ bt_on = of_get_named_gpio(np, "bluetooth-on", 0); -+ bt_wake = of_get_named_gpio(np, "bluetooth-wake", 0); -+ bt_host_wake = of_get_named_gpio(np, "bluetooth-host-wake", 0); -+ -+ if (!gpio_is_valid(bt_on) || !gpio_is_valid(bt_wake) || -+ !gpio_is_valid(bt_host_wake)) { -+ -+ dev_err(dev, "incorrect bt gpios (%d %d %d)\n", -+ bt_on, bt_wake, bt_host_wake); -+ return -EINVAL; -+ } -+ -+ dev_info(dev, "initialize bluetooth chip\n"); -+ -+ gpio_request(bt_on, "bt_on"); -+ gpio_direction_output(bt_on, 0); -+ msleep(11); -+ gpio_set_value(bt_on, 1); -+ -+ gpio_request(bt_wake, "bt_wake"); -+ gpio_direction_output(bt_wake, 1); -+ -+ gpio_request(bt_host_wake, "bt_host_wake"); -+ gpio_direction_input(bt_host_wake); -+ -+ rfkill->shutdown_name = "bluetooth_shutdown"; -+ rfkill->shutdown_gpio = bt_wake; -+ -+ rfkill->rfkill_dev = rfkill_alloc("bluetooth-rfkill", dev, RFKILL_TYPE_BLUETOOTH, -+ &wand_rfkill_ops, rfkill); -+ if (!rfkill->rfkill_dev) { -+ ret = -ENOMEM; -+ goto bt_fail_free_gpio; -+ } -+ -+ ret = rfkill_register(rfkill->rfkill_dev); -+ if (ret < 0) -+ goto bt_fail_unregister; -+ -+ dev_info(dev, "bluetooth-rfkill registered.\n"); -+ -+ return 0; -+ -+bt_fail_unregister: -+ rfkill_destroy(rfkill->rfkill_dev); -+bt_fail_free_gpio: -+ if (gpio_is_valid(bt_on)) gpio_free(bt_on); -+ if (gpio_is_valid(bt_wake)) gpio_free(bt_wake); -+ if (gpio_is_valid(bt_host_wake)) gpio_free(bt_host_wake); -+ -+ return ret; -+} -+ -+static int wand_rfkill_probe(struct platform_device *pdev) -+{ -+ struct wand_rfkill_data *rfkill; -+ struct pinctrl *pinctrl; -+ int ret; -+ -+ dev_info(&pdev->dev, "Wandboard rfkill initialization\n"); -+ -+ if (!pdev->dev.of_node) { -+ dev_err(&pdev->dev, "no device tree node\n"); -+ return -ENODEV; -+ } -+ -+ rfkill = kzalloc(sizeof(*rfkill) * 2, GFP_KERNEL); -+ if (!rfkill) -+ return -ENOMEM; -+ -+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev); -+ if (IS_ERR(pinctrl)) { -+ int ret = PTR_ERR(pinctrl); -+ dev_err(&pdev->dev, "failed to get default pinctrl: %d\n", ret); -+ return ret; -+ } -+ -+ /* setup WiFi */ -+ ret = wand_rfkill_wifi_probe(&pdev->dev, pdev->dev.of_node, &rfkill[0]); -+ if (ret < 0) -+ goto fail_free_rfkill; -+ -+ /* setup bluetooth */ -+ ret = wand_rfkill_bt_probe(&pdev->dev, pdev->dev.of_node, &rfkill[1]); -+ if (ret < 0) -+ goto fail_unregister_wifi; -+ -+ platform_set_drvdata(pdev, rfkill); -+ -+ return 0; -+ -+fail_unregister_wifi: -+ if (rfkill[1].rfkill_dev) { -+ rfkill_unregister(rfkill[1].rfkill_dev); -+ rfkill_destroy(rfkill[1].rfkill_dev); -+ } -+ -+ /* TODO free gpio */ -+ -+fail_free_rfkill: -+ kfree(rfkill); -+ -+ return ret; -+} -+ -+static int wand_rfkill_remove(struct platform_device *pdev) -+{ -+ struct wand_rfkill_data *rfkill = platform_get_drvdata(pdev); -+ -+ dev_info(&pdev->dev, "Module unloading\n"); -+ -+ if (!rfkill) -+ return 0; -+ -+ /* WiFi */ -+ if (gpio_is_valid(rfkill[0].shutdown_gpio)) -+ gpio_free(rfkill[0].shutdown_gpio); -+ -+ rfkill_unregister(rfkill[0].rfkill_dev); -+ rfkill_destroy(rfkill[0].rfkill_dev); -+ -+ /* Bt */ -+ if (gpio_is_valid(rfkill[1].shutdown_gpio)) -+ gpio_free(rfkill[1].shutdown_gpio); -+ -+ rfkill_unregister(rfkill[1].rfkill_dev); -+ rfkill_destroy(rfkill[1].rfkill_dev); -+ -+ kfree(rfkill); -+ -+ return 0; -+} -+ -+static struct of_device_id wand_rfkill_match[] = { -+ { .compatible = "wand,imx6q-wandboard-rfkill", }, -+ { .compatible = "wand,imx6dl-wandboard-rfkill", }, -+ { .compatible = "wand,imx6qdl-wandboard-rfkill", }, -+ {} -+}; -+ -+static struct platform_driver wand_rfkill_driver = { -+ .driver = { -+ .name = "wandboard-rfkill", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(wand_rfkill_match), -+ }, -+ .probe = wand_rfkill_probe, -+ .remove = wand_rfkill_remove -+}; -+ -+module_platform_driver(wand_rfkill_driver); -+ -+MODULE_AUTHOR("Vladimir Ermakov <vooon341@gmail.com>"); -+MODULE_DESCRIPTION("Wandboard rfkill driver"); -+MODULE_LICENSE("GPL v2"); -diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c -index f989145..0679d78 100644 ---- a/arch/arm/mach-omap2/omap_device.c -+++ b/arch/arm/mach-omap2/omap_device.c -@@ -138,8 +138,8 @@ static int omap_device_build_from_dt(struct platform_device *pdev) - struct omap_device *od; - struct omap_hwmod *oh; - struct device_node *node = pdev->dev.of_node; -- const char *oh_name; -- int oh_cnt, i, ret = 0; -+ const char *oh_name, *rst_name; -+ int oh_cnt, dstr_cnt, i, ret = 0; - bool device_active = false; - - oh_cnt = of_property_count_strings(node, "ti,hwmods"); -@@ -190,6 +190,26 @@ static int omap_device_build_from_dt(struct platform_device *pdev) - omap_device_enable(pdev); - pm_runtime_set_active(&pdev->dev); - } -+ dstr_cnt = -+ of_property_count_strings(node, "ti,deassert-hard-reset"); -+ if (dstr_cnt > 0) { -+ for (i = 0; i < dstr_cnt; i += 2) { -+ of_property_read_string_index( -+ node, "ti,deassert-hard-reset", i, -+ &oh_name); -+ of_property_read_string_index( -+ node, "ti,deassert-hard-reset", i+1, -+ &rst_name); -+ oh = omap_hwmod_lookup(oh_name); -+ if (!oh) { -+ dev_warn(&pdev->dev, -+ "Cannot parse deassert property for '%s'\n", -+ oh_name); -+ break; -+ } -+ omap_hwmod_deassert_hardreset(oh, rst_name); -+ } -+ } - - odbfd_exit1: - kfree(hwmods); -@@ -206,12 +226,21 @@ static int _omap_device_notifier_call(struct notifier_block *nb, - { - struct platform_device *pdev = to_platform_device(dev); - struct omap_device *od; -- int err; -+ int i, err; - - switch (event) { - case BUS_NOTIFY_REMOVED_DEVICE: -- if (pdev->archdata.od) -- omap_device_delete(pdev->archdata.od); -+ od = to_omap_device(pdev); -+ if (!od) -+ break; -+ -+ for (i = 0; i < od->hwmods_cnt; i++) { -+ /* shutdown hwmods */ -+ omap_hwmod_shutdown(od->hwmods[i]); -+ /* we don't remove clocks cause there's no API to do so */ -+ /* no harm done, since they will not be created next time */ -+ } -+ omap_device_delete(od); - break; - case BUS_NOTIFY_UNBOUND_DRIVER: - od = to_omap_device(pdev); -@@ -793,6 +822,8 @@ int omap_device_idle(struct platform_device *pdev) - struct omap_device *od; - - od = to_omap_device(pdev); -+ if (!od) -+ return 0; - - if (od->_state != OMAP_DEVICE_STATE_ENABLED) { - dev_warn(&pdev->dev, -diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c -index 6441dfd..f7a5fb4 100644 ---- a/drivers/base/power/opp/core.c -+++ b/drivers/base/power/opp/core.c -@@ -93,6 +93,8 @@ struct opp_table *_find_opp_table(struct device *dev) - * Return: voltage in micro volt corresponding to the opp, else - * return 0 - * -+ * This is useful only for devices with single power supply. -+ * - * Locking: This function must be called under rcu_read_lock(). opp is a rcu - * protected pointer. This means that opp which could have been fetched by - * opp_find_freq_{exact,ceil,floor} functions is valid as long as we are -@@ -112,7 +114,7 @@ unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) - if (IS_ERR_OR_NULL(tmp_opp)) - pr_err("%s: Invalid parameters\n", __func__); - else -- v = tmp_opp->u_volt; -+ v = tmp_opp->supplies[0].u_volt; - - return v; - } -@@ -210,6 +212,24 @@ unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev) - } - EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_clock_latency); - -+static int _get_regulator_count(struct device *dev) -+{ -+ struct opp_table *opp_table; -+ int count; -+ -+ rcu_read_lock(); -+ -+ opp_table = _find_opp_table(dev); -+ if (!IS_ERR(opp_table)) -+ count = opp_table->regulator_count; -+ else -+ count = 0; -+ -+ rcu_read_unlock(); -+ -+ return count; -+} -+ - /** - * dev_pm_opp_get_max_volt_latency() - Get max voltage latency in nanoseconds - * @dev: device for which we do this operation -@@ -222,34 +242,51 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) - { - struct opp_table *opp_table; - struct dev_pm_opp *opp; -- struct regulator *reg; -+ struct regulator *reg, **regulators; - unsigned long latency_ns = 0; -- unsigned long min_uV = ~0, max_uV = 0; -- int ret; -+ int ret, i, count; -+ struct { -+ unsigned long min; -+ unsigned long max; -+ } *uV; -+ -+ count = _get_regulator_count(dev); -+ -+ /* Regulator may not be required for the device */ -+ if (!count) -+ return 0; -+ -+ regulators = kmalloc_array(count, sizeof(*regulators), GFP_KERNEL); -+ if (!regulators) -+ return 0; -+ -+ uV = kmalloc_array(count, sizeof(*uV), GFP_KERNEL); -+ if (!uV) -+ goto free_regulators; - - rcu_read_lock(); - - opp_table = _find_opp_table(dev); - if (IS_ERR(opp_table)) { - rcu_read_unlock(); -- return 0; -+ goto free_uV; - } - -- reg = opp_table->regulator; -- if (IS_ERR(reg)) { -- /* Regulator may not be required for device */ -- rcu_read_unlock(); -- return 0; -- } -+ memcpy(regulators, opp_table->regulators, count * sizeof(*regulators)); - -- list_for_each_entry_rcu(opp, &opp_table->opp_list, node) { -- if (!opp->available) -- continue; -+ for (i = 0; i < count; i++) { -+ uV[i].min = ~0; -+ uV[i].max = 0; - -- if (opp->u_volt_min < min_uV) -- min_uV = opp->u_volt_min; -- if (opp->u_volt_max > max_uV) -- max_uV = opp->u_volt_max; -+ list_for_each_entry_rcu(opp, &opp_table->opp_list, node) { -+ if (!opp->available) -+ continue; -+ -+ if (opp->supplies[i].u_volt_min < uV[i].min) -+ uV[i].min = opp->supplies[i].u_volt_min; -+ if (opp->supplies[i].u_volt_max > uV[i].max) -+ uV[i].max = opp->supplies[i].u_volt_max; -+ } - } - - rcu_read_unlock(); -@@ -258,9 +295,16 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) - * The caller needs to ensure that opp_table (and hence the regulator) - * isn't freed, while we are executing this routine. - */ -- ret = regulator_set_voltage_time(reg, min_uV, max_uV); -- if (ret > 0) -- latency_ns = ret * 1000; -+ for (i = 0; reg = regulators[i], i < count; i++) { -+ ret = regulator_set_voltage_time(reg, uV[i].min, uV[i].max); -+ if (ret > 0) -+ latency_ns += ret * 1000; -+ } -+ -+free_uV: -+ kfree(uV); -+free_regulators: -+ kfree(regulators); - - return latency_ns; - } -@@ -542,8 +586,7 @@ static struct clk *_get_opp_clk(struct device *dev) - } - - static int _set_opp_voltage(struct device *dev, struct regulator *reg, -- unsigned long u_volt, unsigned long u_volt_min, -- unsigned long u_volt_max) -+ struct dev_pm_opp_supply *supply) - { - int ret; - -@@ -554,14 +597,78 @@ static int _set_opp_voltage(struct device *dev, struct regulator *reg, - return 0; - } - -- dev_dbg(dev, "%s: voltages (mV): %lu %lu %lu\n", __func__, u_volt_min, -- u_volt, u_volt_max); -+ dev_dbg(dev, "%s: voltages (mV): %lu %lu %lu\n", __func__, -+ supply->u_volt_min, supply->u_volt, supply->u_volt_max); - -- ret = regulator_set_voltage_triplet(reg, u_volt_min, u_volt, -- u_volt_max); -+ ret = regulator_set_voltage_triplet(reg, supply->u_volt_min, -+ supply->u_volt, supply->u_volt_max); - if (ret) - dev_err(dev, "%s: failed to set voltage (%lu %lu %lu mV): %d\n", -- __func__, u_volt_min, u_volt, u_volt_max, ret); -+ __func__, supply->u_volt_min, supply->u_volt, -+ supply->u_volt_max, ret); -+ -+ return ret; -+} -+ -+static inline int -+_generic_set_opp_clk_only(struct device *dev, struct clk *clk, -+ unsigned long old_freq, unsigned long freq) -+{ -+ int ret; -+ -+ ret = clk_set_rate(clk, freq); -+ if (ret) { -+ dev_err(dev, "%s: failed to set clock rate: %d\n", __func__, -+ ret); -+ } -+ -+ return ret; -+} -+ -+static int _generic_set_opp(struct dev_pm_set_opp_data *data) -+{ -+ struct dev_pm_opp_supply *old_supply = data->old_opp.supplies; -+ struct dev_pm_opp_supply *new_supply = data->new_opp.supplies; -+ unsigned long old_freq = data->old_opp.rate, freq = data->new_opp.rate; -+ struct regulator *reg = data->regulators[0]; -+ struct device *dev= data->dev; -+ int ret; -+ -+ /* This function only supports single regulator per device */ -+ if (WARN_ON(data->regulator_count > 1)) { -+ dev_err(dev, "multiple regulators are not supported\n"); -+ return -EINVAL; -+ } -+ -+ /* Scaling up? Scale voltage before frequency */ -+ if (freq > old_freq) { -+ ret = _set_opp_voltage(dev, reg, new_supply); -+ if (ret) -+ goto restore_voltage; -+ } -+ -+ /* Change frequency */ -+ ret = _generic_set_opp_clk_only(dev, data->clk, old_freq, freq); -+ if (ret) -+ goto restore_voltage; -+ -+ /* Scaling down? Scale voltage after frequency */ -+ if (freq < old_freq) { -+ ret = _set_opp_voltage(dev, reg, new_supply); -+ if (ret) -+ goto restore_freq; -+ } -+ -+ return 0; -+ -+restore_freq: -+ if (_generic_set_opp_clk_only(dev, data->clk, freq, old_freq)) -+ dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n", -+ __func__, old_freq); -+restore_voltage: -+ /* This shouldn't harm even if the voltages weren't updated earlier */ -+ if (old_supply->u_volt) -+ _set_opp_voltage(dev, reg, old_supply); - - return ret; - } -@@ -579,13 +686,13 @@ static int _set_opp_voltage(struct device *dev, struct regulator *reg, - int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) - { - struct opp_table *opp_table; -+ unsigned long freq, old_freq; -+ int (*set_opp)(struct dev_pm_set_opp_data *data); - struct dev_pm_opp *old_opp, *opp; -- struct regulator *reg; -+ struct regulator **regulators; -+ struct dev_pm_set_opp_data *data; - struct clk *clk; -- unsigned long freq, old_freq; -- unsigned long u_volt, u_volt_min, u_volt_max; -- unsigned long old_u_volt, old_u_volt_min, old_u_volt_max; -- int ret; -+ int ret, size; - - if (unlikely(!target_freq)) { - dev_err(dev, "%s: Invalid target frequency %lu\n", __func__, -@@ -634,64 +741,54 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) - return ret; - } - -- if (IS_ERR(old_opp)) { -- old_u_volt = 0; -- } else { -- old_u_volt = old_opp->u_volt; -- old_u_volt_min = old_opp->u_volt_min; -- old_u_volt_max = old_opp->u_volt_max; -- } -- -- u_volt = opp->u_volt; -- u_volt_min = opp->u_volt_min; -- u_volt_max = opp->u_volt_max; -- -- reg = opp_table->regulator; -+ dev_dbg(dev, "%s: switching OPP: %lu Hz --> %lu Hz\n", __func__, -+ old_freq, freq); - -- rcu_read_unlock(); -+ regulators = opp_table->regulators; - -- /* Scaling up? Scale voltage before frequency */ -- if (freq > old_freq) { -- ret = _set_opp_voltage(dev, reg, u_volt, u_volt_min, -- u_volt_max); -- if (ret) -- goto restore_voltage; -- } -+ /* Only frequency scaling */ -+ if (!regulators) { -+ unsigned long u_volt = opp->supplies[0].u_volt; - -- /* Change frequency */ -+ rcu_read_unlock(); - -- dev_dbg(dev, "%s: switching OPP: %lu Hz --> %lu Hz\n", -- __func__, old_freq, freq); -+ /* -+ * DT contained supply ratings? Consider platform failed to set -+ * regulators. -+ */ -+ if (unlikely(u_volt)) { -+ dev_err(dev, "%s: Regulator not registered with OPP core\n", -+ __func__); -+ return -EINVAL; -+ } - -- ret = clk_set_rate(clk, freq); -- if (ret) { -- dev_err(dev, "%s: failed to set clock rate: %d\n", __func__, -- ret); -- goto restore_voltage; -+ return _generic_set_opp_clk_only(dev, clk, old_freq, freq); - } - -- /* Scaling down? Scale voltage after frequency */ -- if (freq < old_freq) { -- ret = _set_opp_voltage(dev, reg, u_volt, u_volt_min, -- u_volt_max); -- if (ret) -- goto restore_freq; -- } -+ if (opp_table->set_opp) -+ set_opp = opp_table->set_opp; -+ else -+ set_opp = _generic_set_opp; -+ -+ data = opp_table->set_opp_data; -+ data->regulators = regulators; -+ data->regulator_count = opp_table->regulator_count; -+ data->clk = clk; -+ data->dev = dev; -+ -+ data->old_opp.rate = old_freq; -+ size = sizeof(*opp->supplies) * opp_table->regulator_count; -+ if (IS_ERR(old_opp)) -+ memset(data->old_opp.supplies, 0, size); -+ else -+ memcpy(data->old_opp.supplies, old_opp->supplies, size); - -- return 0; -+ data->new_opp.rate = freq; -+ memcpy(data->new_opp.supplies, opp->supplies, size); - --restore_freq: -- if (clk_set_rate(clk, old_freq)) -- dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n", -- __func__, old_freq); --restore_voltage: -- /* This shouldn't harm even if the voltages weren't updated earlier */ -- if (old_u_volt) { -- _set_opp_voltage(dev, reg, old_u_volt, old_u_volt_min, -- old_u_volt_max); -- } -+ rcu_read_unlock(); - -- return ret; -+ return set_opp(data); - } - EXPORT_SYMBOL_GPL(dev_pm_opp_set_rate); - -@@ -774,9 +871,6 @@ static struct opp_table *_add_opp_table(struct device *dev) - - _of_init_opp_table(opp_table, dev); - -- /* Set regulator to a non-NULL error value */ -- opp_table->regulator = ERR_PTR(-ENXIO); -- - /* Find clk for the device */ - opp_table->clk = clk_get(dev, NULL); - if (IS_ERR(opp_table->clk)) { -@@ -825,7 +919,10 @@ static void _remove_opp_table(struct opp_table *opp_table) - if (opp_table->prop_name) - return; - -- if (!IS_ERR(opp_table->regulator)) -+ if (opp_table->regulators) -+ return; -+ -+ if (opp_table->set_opp) - return; - - /* Release clk */ -@@ -934,34 +1031,50 @@ struct dev_pm_opp *_allocate_opp(struct device *dev, - struct opp_table **opp_table) - { - struct dev_pm_opp *opp; -+ int count, supply_size; -+ struct opp_table *table; - -- /* allocate new OPP node */ -- opp = kzalloc(sizeof(*opp), GFP_KERNEL); -- if (!opp) -+ table = _add_opp_table(dev); -+ if (!table) - return NULL; - -- INIT_LIST_HEAD(&opp->node); -+ /* Allocate space for at least one supply */ -+ count = table->regulator_count ? table->regulator_count : 1; -+ supply_size = sizeof(*opp->supplies) * count; - -- *opp_table = _add_opp_table(dev); -- if (!*opp_table) { -- kfree(opp); -+ /* allocate new OPP node and supplies structures */ -+ opp = kzalloc(sizeof(*opp) + supply_size, GFP_KERNEL); -+ if (!opp) { -+ kfree(table); - return NULL; - } - -+ /* Put the supplies at the end of the OPP structure as an empty array */ -+ opp->supplies = (struct dev_pm_opp_supply *)(opp + 1); -+ INIT_LIST_HEAD(&opp->node); -+ -+ *opp_table = table; -+ - return opp; - } - - static bool _opp_supported_by_regulators(struct dev_pm_opp *opp, - struct opp_table *opp_table) - { -- struct regulator *reg = opp_table->regulator; -- -- if (!IS_ERR(reg) && -- !regulator_is_supported_voltage(reg, opp->u_volt_min, -- opp->u_volt_max)) { -- pr_warn("%s: OPP minuV: %lu maxuV: %lu, not supported by regulator\n", -- __func__, opp->u_volt_min, opp->u_volt_max); -- return false; -+ struct regulator *reg; -+ int i; -+ -+ for (i = 0; i < opp_table->regulator_count; i++) { -+ reg = opp_table->regulators[i]; -+ -+ if (!regulator_is_supported_voltage(reg, -+ opp->supplies[i].u_volt_min, -+ opp->supplies[i].u_volt_max)) { -+ pr_warn("%s: OPP minuV: %lu maxuV: %lu, not supported by regulator\n", -+ __func__, opp->supplies[i].u_volt_min, -+ opp->supplies[i].u_volt_max); -+ return false; -+ } - } - - return true; -@@ -993,11 +1106,13 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, - - /* Duplicate OPPs */ - dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %lu, volt: %lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n", -- __func__, opp->rate, opp->u_volt, opp->available, -- new_opp->rate, new_opp->u_volt, new_opp->available); -+ __func__, opp->rate, opp->supplies[0].u_volt, -+ opp->available, new_opp->rate, -+ new_opp->supplies[0].u_volt, new_opp->available); - -- return opp->available && new_opp->u_volt == opp->u_volt ? -- 0 : -EEXIST; -+ /* Should we compare voltages for all regulators here ? */ -+ return opp->available && -+ new_opp->supplies[0].u_volt == opp->supplies[0].u_volt ? 0 : -EEXIST; - } - - new_opp->opp_table = opp_table; -@@ -1064,9 +1179,9 @@ int _opp_add_v1(struct device *dev, unsigned long freq, long u_volt, - /* populate the opp table */ - new_opp->rate = freq; - tol = u_volt * opp_table->voltage_tolerance_v1 / 100; -- new_opp->u_volt = u_volt; -- new_opp->u_volt_min = u_volt - tol; -- new_opp->u_volt_max = u_volt + tol; -+ new_opp->supplies[0].u_volt = u_volt; -+ new_opp->supplies[0].u_volt_min = u_volt - tol; -+ new_opp->supplies[0].u_volt_max = u_volt + tol; - new_opp->available = true; - new_opp->dynamic = dynamic; - -@@ -1310,13 +1425,47 @@ void dev_pm_opp_put_prop_name(struct device *dev) - } - EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name); - -+static int _allocate_set_opp_data(struct opp_table *opp_table) -+{ -+ struct dev_pm_set_opp_data *data; -+ int len, count = opp_table->regulator_count; -+ -+ if (WARN_ON(!count)) -+ return -EINVAL; -+ -+ /* space for set_opp_data */ -+ len = sizeof(*data); -+ -+ /* space for old_opp.supplies and new_opp.supplies */ -+ len += 2 * sizeof(struct dev_pm_opp_supply) * count; -+ -+ data = kzalloc(len, GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ data->old_opp.supplies = (void *)(data + 1); -+ data->new_opp.supplies = data->old_opp.supplies + count; -+ -+ opp_table->set_opp_data = data; -+ -+ return 0; -+} -+ -+static void _free_set_opp_data(struct opp_table *opp_table) -+{ -+ kfree(opp_table->set_opp_data); -+ opp_table->set_opp_data = NULL; -+} -+ - /** -- * dev_pm_opp_set_regulator() - Set regulator name for the device -+ * dev_pm_opp_set_regulators() - Set regulator names for the device - * @dev: Device for which regulator name is being set. -- * @name: Name of the regulator. -+ * @names: Array of pointers to the names of the regulator. -+ * @count: Number of regulators. - * - * In order to support OPP switching, OPP layer needs to know the name of the -- * device's regulator, as the core would be required to switch voltages as well. -+ * device's regulators, as the core would be required to switch voltages as -+ * well. - * - * This must be called before any OPPs are initialized for the device. - * -@@ -1326,11 +1475,12 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name); - * that this function is *NOT* called under RCU protection or in contexts where - * mutex cannot be locked. - */ --struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name) -+int dev_pm_opp_set_regulators(struct device *dev, const char * const names[], -+ unsigned int count) - { - struct opp_table *opp_table; - struct regulator *reg; -- int ret; -+ int ret, i; - - mutex_lock(&opp_table_lock); - -@@ -1346,38 +1496,62 @@ struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name) - goto err; - } - -- /* Already have a regulator set */ -- if (WARN_ON(!IS_ERR(opp_table->regulator))) { -+ /* Already have regulators set */ -+ if (opp_table->regulators) { - ret = -EBUSY; - goto err; - } -- /* Allocate the regulator */ -- reg = regulator_get_optional(dev, name); -- if (IS_ERR(reg)) { -- ret = PTR_ERR(reg); -- if (ret != -EPROBE_DEFER) -- dev_err(dev, "%s: no regulator (%s) found: %d\n", -- __func__, name, ret); -+ -+ opp_table->regulators = kmalloc_array(count, -+ sizeof(*opp_table->regulators), -+ GFP_KERNEL); -+ if (!opp_table->regulators) { -+ ret = -ENOMEM; - goto err; - } - -- opp_table->regulator = reg; -+ for (i = 0; i < count; i++) { -+ reg = regulator_get_optional(dev, names[i]); -+ if (IS_ERR(reg)) { -+ ret = PTR_ERR(reg); -+ if (ret != -EPROBE_DEFER) -+ dev_err(dev, "%s: regulator (%s) not found: %d\n", -+ __func__, names[i], ret); -+ goto free_regulators; -+ } -+ -+ opp_table->regulators[i] = reg; -+ } -+ -+ opp_table->regulator_count = count; -+ -+ /* Allocate block only once to pass to set_opp() routines */ -+ ret = _allocate_set_opp_data(opp_table); -+ if (ret) -+ goto free_regulators; - - mutex_unlock(&opp_table_lock); -- return opp_table; -+ return 0; - -+free_regulators: -+ while (i != 0) -+ regulator_put(opp_table->regulators[--i]); -+ -+ kfree(opp_table->regulators); -+ opp_table->regulators = NULL; -+ opp_table->regulator_count = 0; - err: - _remove_opp_table(opp_table); - unlock: - mutex_unlock(&opp_table_lock); - -- return ERR_PTR(ret); -+ return ret; - } --EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulator); -+EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulators); - - /** -- * dev_pm_opp_put_regulator() - Releases resources blocked for regulator -- * @opp_table: OPP table returned from dev_pm_opp_set_regulator(). -+ * dev_pm_opp_put_regulators() - Releases resources blocked for regulators -+ * @dev: Device for which regulators were set. - * - * Locking: The internal opp_table and opp structures are RCU protected. - * Hence this function internally uses RCU updater strategy with mutex locks -@@ -1385,20 +1559,140 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulator); - * that this function is *NOT* called under RCU protection or in contexts where - * mutex cannot be locked. - */ --void dev_pm_opp_put_regulator(struct opp_table *opp_table) -+void dev_pm_opp_put_regulators(struct device *dev) - { -+ struct opp_table *opp_table; -+ int i; -+ - mutex_lock(&opp_table_lock); - -- if (IS_ERR(opp_table->regulator)) { -- pr_err("%s: Doesn't have regulator set\n", __func__); -+ /* Check for existing table for 'dev' first */ -+ opp_table = _find_opp_table(dev); -+ if (IS_ERR(opp_table)) { -+ dev_err(dev, "Failed to find opp_table: %ld\n", -+ PTR_ERR(opp_table)); -+ goto unlock; -+ } -+ -+ if (!opp_table->regulators) { -+ dev_err(dev, "%s: Doesn't have regulators set\n", __func__); -+ goto unlock; -+ } -+ -+ /* Make sure there are no concurrent readers while updating opp_table */ -+ WARN_ON(!list_empty(&opp_table->opp_list)); -+ -+ for (i = opp_table->regulator_count - 1; i >= 0; i--) -+ regulator_put(opp_table->regulators[i]); -+ -+ _free_set_opp_data(opp_table); -+ -+ kfree(opp_table->regulators); -+ opp_table->regulators = NULL; -+ opp_table->regulator_count = 0; -+ -+ /* Try freeing opp_table if this was the last blocking resource */ -+ _remove_opp_table(opp_table); -+ -+unlock: -+ mutex_unlock(&opp_table_lock); -+} -+EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators); -+ -+/** -+ * dev_pm_opp_register_set_opp_helper() - Register custom set OPP helper -+ * @dev: Device for which the helper is getting registered. -+ * @set_opp: Custom set OPP helper. -+ * -+ * This is useful to support complex platforms (like platforms with multiple -+ * regulators per device), instead of the generic OPP set rate helper. -+ * -+ * This must be called before any OPPs are initialized for the device. -+ * -+ * Locking: The internal opp_table and opp structures are RCU protected. -+ * Hence this function internally uses RCU updater strategy with mutex locks -+ * to keep the integrity of the internal data structures. Callers should ensure -+ * that this function is *NOT* called under RCU protection or in contexts where -+ * mutex cannot be locked. -+ */ -+int dev_pm_opp_register_set_opp_helper(struct device *dev, -+ int (*set_opp)(struct dev_pm_set_opp_data *data)) -+{ -+ struct opp_table *opp_table; -+ int ret; -+ -+ if (!set_opp) -+ return -EINVAL; -+ -+ mutex_lock(&opp_table_lock); -+ -+ opp_table = _add_opp_table(dev); -+ if (!opp_table) { -+ ret = -ENOMEM; -+ goto unlock; -+ } -+ -+ /* This should be called before OPPs are initialized */ -+ if (WARN_ON(!list_empty(&opp_table->opp_list))) { -+ ret = -EBUSY; -+ goto err; -+ } -+ -+ /* Already have custom set_opp helper */ -+ if (WARN_ON(opp_table->set_opp)) { -+ ret = -EBUSY; -+ goto err; -+ } -+ -+ opp_table->set_opp = set_opp; -+ -+ mutex_unlock(&opp_table_lock); -+ return 0; -+ -+err: -+ _remove_opp_table(opp_table); -+unlock: -+ mutex_unlock(&opp_table_lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(dev_pm_opp_register_set_opp_helper); -+ -+/** -+ * dev_pm_opp_register_put_opp_helper() - Releases resources blocked for -+ * set_opp helper -+ * @dev: Device for which custom set_opp helper has to be cleared. -+ * -+ * Locking: The internal opp_table and opp structures are RCU protected. -+ * Hence this function internally uses RCU updater strategy with mutex locks -+ * to keep the integrity of the internal data structures. Callers should ensure -+ * that this function is *NOT* called under RCU protection or in contexts where -+ * mutex cannot be locked. -+ */ -+void dev_pm_opp_register_put_opp_helper(struct device *dev) -+{ -+ struct opp_table *opp_table; -+ -+ mutex_lock(&opp_table_lock); -+ -+ /* Check for existing table for 'dev' first */ -+ opp_table = _find_opp_table(dev); -+ if (IS_ERR(opp_table)) { -+ dev_err(dev, "Failed to find opp_table: %ld\n", -+ PTR_ERR(opp_table)); -+ goto unlock; -+ } -+ -+ if (!opp_table->set_opp) { -+ dev_err(dev, "%s: Doesn't have custom set_opp helper set\n", -+ __func__); - goto unlock; - } - - /* Make sure there are no concurrent readers while updating opp_table */ - WARN_ON(!list_empty(&opp_table->opp_list)); - -- regulator_put(opp_table->regulator); -- opp_table->regulator = ERR_PTR(-ENXIO); -+ opp_table->set_opp = NULL; - - /* Try freeing opp_table if this was the last blocking resource */ - _remove_opp_table(opp_table); -@@ -1406,7 +1700,7 @@ void dev_pm_opp_put_regulator(struct opp_table *opp_table) - unlock: - mutex_unlock(&opp_table_lock); - } --EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulator); -+EXPORT_SYMBOL_GPL(dev_pm_opp_register_put_opp_helper); - - /** - * dev_pm_opp_add() - Add an OPP table from a table definitions -diff --git a/drivers/base/power/opp/debugfs.c b/drivers/base/power/opp/debugfs.c -index ef1ae6b..95f433d 100644 ---- a/drivers/base/power/opp/debugfs.c -+++ b/drivers/base/power/opp/debugfs.c -@@ -15,6 +15,7 @@ - #include <linux/err.h> - #include <linux/init.h> - #include <linux/limits.h> -+#include <linux/slab.h> - - #include "opp.h" - -@@ -34,6 +35,46 @@ void opp_debug_remove_one(struct dev_pm_opp *opp) - debugfs_remove_recursive(opp->dentry); - } - -+static bool opp_debug_create_supplies(struct dev_pm_opp *opp, -+ struct opp_table *opp_table, -+ struct dentry *pdentry) -+{ -+ struct dentry *d; -+ int i = 0; -+ char *name; -+ -+ /* Always create at least supply-0 directory */ -+ do { -+ name = kasprintf(GFP_KERNEL, "supply-%d", i); -+ -+ /* Create per-opp directory */ -+ d = debugfs_create_dir(name, pdentry); -+ -+ kfree(name); -+ -+ if (!d) -+ return false; -+ -+ if (!debugfs_create_ulong("u_volt_target", S_IRUGO, d, -+ &opp->supplies[i].u_volt)) -+ return false; -+ -+ if (!debugfs_create_ulong("u_volt_min", S_IRUGO, d, -+ &opp->supplies[i].u_volt_min)) -+ return false; -+ -+ if (!debugfs_create_ulong("u_volt_max", S_IRUGO, d, -+ &opp->supplies[i].u_volt_max)) -+ return false; -+ -+ if (!debugfs_create_ulong("u_amp", S_IRUGO, d, -+ &opp->supplies[i].u_amp)) -+ return false; -+ } while (++i < opp_table->regulator_count); -+ -+ return true; -+} -+ - int opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table) - { - struct dentry *pdentry = opp_table->dentry; -@@ -63,16 +104,7 @@ int opp_debug_create_one(struct dev_pm_opp *opp, struct opp_table *opp_table) - if (!debugfs_create_ulong("rate_hz", S_IRUGO, d, &opp->rate)) - return -ENOMEM; - -- if (!debugfs_create_ulong("u_volt_target", S_IRUGO, d, &opp->u_volt)) -- return -ENOMEM; -- -- if (!debugfs_create_ulong("u_volt_min", S_IRUGO, d, &opp->u_volt_min)) -- return -ENOMEM; -- -- if (!debugfs_create_ulong("u_volt_max", S_IRUGO, d, &opp->u_volt_max)) -- return -ENOMEM; -- -- if (!debugfs_create_ulong("u_amp", S_IRUGO, d, &opp->u_amp)) -+ if (!opp_debug_create_supplies(opp, opp_table, d)) - return -ENOMEM; - - if (!debugfs_create_ulong("clock_latency_ns", S_IRUGO, d, -diff --git a/drivers/base/power/opp/of.c b/drivers/base/power/opp/of.c -index 5552211..8c869aa 100644 ---- a/drivers/base/power/opp/of.c -+++ b/drivers/base/power/opp/of.c -@@ -17,6 +17,7 @@ - #include <linux/errno.h> - #include <linux/device.h> - #include <linux/of.h> -+#include <linux/slab.h> - #include <linux/export.h> - - #include "opp.h" -@@ -101,16 +102,16 @@ static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table, - return true; - } - --/* TODO: Support multiple regulators */ - static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, - struct opp_table *opp_table) - { -- u32 microvolt[3] = {0}; -- u32 val; -- int count, ret; -+ u32 *microvolt, *microamp = NULL; -+ int supplies, vcount, icount, ret, i, j; - struct property *prop = NULL; - char name[NAME_MAX]; - -+ supplies = opp_table->regulator_count ? opp_table->regulator_count : 1; -+ - /* Search for "opp-microvolt-<name>" */ - if (opp_table->prop_name) { - snprintf(name, sizeof(name), "opp-microvolt-%s", -@@ -128,34 +129,29 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, - return 0; - } - -- count = of_property_count_u32_elems(opp->np, name); -- if (count < 0) { -+ vcount = of_property_count_u32_elems(opp->np, name); -+ if (vcount < 0) { - dev_err(dev, "%s: Invalid %s property (%d)\n", -- __func__, name, count); -- return count; -+ __func__, name, vcount); -+ return vcount; - } - -- /* There can be one or three elements here */ -- if (count != 1 && count != 3) { -- dev_err(dev, "%s: Invalid number of elements in %s property (%d)\n", -- __func__, name, count); -+ /* There can be one or three elements per supply */ -+ if (vcount != supplies && vcount != supplies * 3) { -+ dev_err(dev, "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n", -+ __func__, name, vcount, supplies); - return -EINVAL; - } - -- ret = of_property_read_u32_array(opp->np, name, microvolt, count); -+ microvolt = kmalloc_array(vcount, sizeof(*microvolt), GFP_KERNEL); -+ if (!microvolt) -+ return -ENOMEM; -+ -+ ret = of_property_read_u32_array(opp->np, name, microvolt, vcount); - if (ret) { - dev_err(dev, "%s: error parsing %s: %d\n", __func__, name, ret); -- return -EINVAL; -- } -- -- opp->u_volt = microvolt[0]; -- -- if (count == 1) { -- opp->u_volt_min = opp->u_volt; -- opp->u_volt_max = opp->u_volt; -- } else { -- opp->u_volt_min = microvolt[1]; -- opp->u_volt_max = microvolt[2]; -+ ret = -EINVAL; -+ goto free_microvolt; - } - - /* Search for "opp-microamp-<name>" */ -@@ -172,10 +168,59 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, - prop = of_find_property(opp->np, name, NULL); - } - -- if (prop && !of_property_read_u32(opp->np, name, &val)) -- opp->u_amp = val; -+ if (prop) { -+ icount = of_property_count_u32_elems(opp->np, name); -+ if (icount < 0) { -+ dev_err(dev, "%s: Invalid %s property (%d)\n", __func__, -+ name, icount); -+ ret = icount; -+ goto free_microvolt; -+ } - -- return 0; -+ if (icount != supplies) { -+ dev_err(dev, "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n", -+ __func__, name, icount, supplies); -+ ret = -EINVAL; -+ goto free_microvolt; -+ } -+ -+ microamp = kmalloc_array(icount, sizeof(*microamp), GFP_KERNEL); -+ if (!microamp) { -+ ret = -EINVAL; -+ goto free_microvolt; -+ } -+ -+ ret = of_property_read_u32_array(opp->np, name, microamp, -+ icount); -+ if (ret) { -+ dev_err(dev, "%s: error parsing %s: %d\n", __func__, -+ name, ret); -+ ret = -EINVAL; -+ goto free_microamp; -+ } -+ } -+ -+ for (i = 0, j = 0; i < supplies; i++) { -+ opp->supplies[i].u_volt = microvolt[j++]; -+ -+ if (vcount == supplies) { -+ opp->supplies[i].u_volt_min = opp->supplies[i].u_volt; -+ opp->supplies[i].u_volt_max = opp->supplies[i].u_volt; -+ } else { -+ opp->supplies[i].u_volt_min = microvolt[j++]; -+ opp->supplies[i].u_volt_max = microvolt[j++]; -+ } -+ -+ if (microamp) -+ opp->supplies[i].u_amp = microamp[i]; -+ } -+ -+free_microamp: -+ kfree(microamp); -+free_microvolt: -+ kfree(microvolt); -+ -+ return ret; - } - - /** -@@ -198,7 +243,7 @@ void dev_pm_opp_of_remove_table(struct device *dev) - EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table); - - /* Returns opp descriptor node for a device, caller must do of_node_put() */ --struct device_node *_of_get_opp_desc_node(struct device *dev) -+struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev) - { - /* - * TODO: Support for multiple OPP tables. -@@ -209,6 +254,7 @@ struct device_node *_of_get_opp_desc_node(struct device *dev) - - return of_parse_phandle(dev->of_node, "operating-points-v2", 0); - } -+EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_opp_desc_node); - - /** - * _opp_add_static_v2() - Allocate static OPPs (As per 'v2' DT bindings) -@@ -303,9 +349,9 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np) - mutex_unlock(&opp_table_lock); - - pr_debug("%s: turbo:%d rate:%lu uv:%lu uvmin:%lu uvmax:%lu latency:%lu\n", -- __func__, new_opp->turbo, new_opp->rate, new_opp->u_volt, -- new_opp->u_volt_min, new_opp->u_volt_max, -- new_opp->clock_latency_ns); -+ __func__, new_opp->turbo, new_opp->rate, -+ new_opp->supplies[0].u_volt, new_opp->supplies[0].u_volt_min, -+ new_opp->supplies[0].u_volt_max, new_opp->clock_latency_ns); - - /* - * Notify the changes in the availability of the operable -@@ -450,7 +496,7 @@ int dev_pm_opp_of_add_table(struct device *dev) - * OPPs have two version of bindings now. The older one is deprecated, - * try for the new binding first. - */ -- opp_np = _of_get_opp_desc_node(dev); -+ opp_np = dev_pm_opp_of_get_opp_desc_node(dev); - if (!opp_np) { - /* - * Try old-deprecated bindings for backward compatibility with -@@ -560,7 +606,7 @@ int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, - int cpu, ret = 0; - - /* Get OPP descriptor node */ -- np = _of_get_opp_desc_node(cpu_dev); -+ np = dev_pm_opp_of_get_opp_desc_node(cpu_dev); - if (!np) { - dev_dbg(cpu_dev, "%s: Couldn't find cpu_dev node.\n", __func__); - return -ENOENT; -@@ -585,7 +631,7 @@ int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, - } - - /* Get OPP descriptor node */ -- tmp_np = _of_get_opp_desc_node(tcpu_dev); -+ tmp_np = dev_pm_opp_of_get_opp_desc_node(tcpu_dev); - if (!tmp_np) { - dev_err(tcpu_dev, "%s: Couldn't find tcpu_dev node.\n", - __func__); -diff --git a/drivers/base/power/opp/opp.h b/drivers/base/power/opp/opp.h -index fabd5ca..af9f2b8 100644 ---- a/drivers/base/power/opp/opp.h -+++ b/drivers/base/power/opp/opp.h -@@ -61,10 +61,7 @@ extern struct list_head opp_tables; - * @turbo: true if turbo (boost) OPP - * @suspend: true if suspend OPP - * @rate: Frequency in hertz -- * @u_volt: Target voltage in microvolts corresponding to this OPP -- * @u_volt_min: Minimum voltage in microvolts corresponding to this OPP -- * @u_volt_max: Maximum voltage in microvolts corresponding to this OPP -- * @u_amp: Maximum current drawn by the device in microamperes -+ * @supplies: Power supplies voltage/current values - * @clock_latency_ns: Latency (in nanoseconds) of switching to this OPP's - * frequency from any other OPP's frequency. - * @opp_table: points back to the opp_table struct this opp belongs to -@@ -83,10 +80,8 @@ struct dev_pm_opp { - bool suspend; - unsigned long rate; - -- unsigned long u_volt; -- unsigned long u_volt_min; -- unsigned long u_volt_max; -- unsigned long u_amp; -+ struct dev_pm_opp_supply *supplies; -+ - unsigned long clock_latency_ns; - - struct opp_table *opp_table; -@@ -144,7 +139,10 @@ enum opp_table_access { - * @supported_hw_count: Number of elements in supported_hw array. - * @prop_name: A name to postfix to many DT properties, while parsing them. - * @clk: Device's clock handle -- * @regulator: Supply regulator -+ * @regulators: Supply regulators -+ * @regulator_count: Number of power supply regulators -+ * @set_opp: Platform specific set_opp callback -+ * @set_opp_data: Data to be passed to set_opp callback - * @dentry: debugfs dentry pointer of the real device directory (not links). - * @dentry_name: Name of the real dentry. - * -@@ -179,7 +177,11 @@ struct opp_table { - unsigned int supported_hw_count; - const char *prop_name; - struct clk *clk; -- struct regulator *regulator; -+ struct regulator **regulators; -+ unsigned int regulator_count; -+ -+ int (*set_opp)(struct dev_pm_set_opp_data *data); -+ struct dev_pm_set_opp_data *set_opp_data; - - #ifdef CONFIG_DEBUG_FS - struct dentry *dentry; -@@ -190,7 +192,6 @@ struct opp_table { - /* Routines internal to opp core */ - struct opp_table *_find_opp_table(struct device *dev); - struct opp_device *_add_opp_dev(const struct device *dev, struct opp_table *opp_table); --struct device_node *_of_get_opp_desc_node(struct device *dev); - void _dev_pm_opp_remove_table(struct device *dev, bool remove_all); - struct dev_pm_opp *_allocate_opp(struct device *dev, struct opp_table **opp_table); - int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_table *opp_table); -diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig -index 7875105..bbd5afd 100644 ---- a/drivers/bus/Kconfig -+++ b/drivers/bus/Kconfig -@@ -120,7 +120,6 @@ config QCOM_EBI2 - config SIMPLE_PM_BUS - bool "Simple Power-Managed Bus Driver" - depends on OF && PM -- depends on ARCH_RENESAS || COMPILE_TEST - help - Driver for transparent busses that don't need a real driver, but - where the bus controller is part of a PM domain, or under the control -diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm -index bc3917d..a7b3795 100644 ---- a/drivers/cpufreq/Kconfig.arm -+++ b/drivers/cpufreq/Kconfig.arm -@@ -234,6 +234,17 @@ config ARM_TEGRA124_CPUFREQ - help - This adds the CPUFreq driver support for Tegra124 SOCs. - -+config ARM_TI_CPUFREQ -+ bool "Texas Instruments CPUFreq support" -+ depends on ARCH_OMAP2PLUS -+ help -+ This driver enables valid OPPs on the running platform based on -+ values contained within the SoC in use. Enable this in order to -+ use the cpufreq-dt driver on all Texas Instruments platforms that -+ provide dt based operating-points-v2 tables with opp-supported-hw -+ data provided. Required for cpufreq support on AM335x, AM437x, -+ DRA7x, and AM57x platforms. -+ - config ARM_PXA2xx_CPUFREQ - tristate "Intel PXA2xx CPUfreq driver" - depends on PXA27x || PXA25x -diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile -index 0a9b6a0..5b1b6ec 100644 ---- a/drivers/cpufreq/Makefile -+++ b/drivers/cpufreq/Makefile -@@ -77,6 +77,7 @@ obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o - obj-$(CONFIG_ARM_STI_CPUFREQ) += sti-cpufreq.o - obj-$(CONFIG_ARM_TEGRA20_CPUFREQ) += tegra20-cpufreq.o - obj-$(CONFIG_ARM_TEGRA124_CPUFREQ) += tegra124-cpufreq.o -+obj-$(CONFIG_ARM_TI_CPUFREQ) += ti-cpufreq.o - obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o - obj-$(CONFIG_ACPI_CPPC_CPUFREQ) += cppc_cpufreq.o - obj-$(CONFIG_MACH_MVEBU_V7) += mvebu-cpufreq.o -diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c -index 7126762..d2637e1 100644 ---- a/drivers/cpufreq/cpufreq-dt-platdev.c -+++ b/drivers/cpufreq/cpufreq-dt-platdev.c -@@ -72,8 +72,6 @@ static const struct of_device_id machines[] __initconst = { - - { .compatible = "sigma,tango4" }, - -- { .compatible = "ti,am33xx", }, -- { .compatible = "ti,dra7", }, - { .compatible = "ti,omap2", }, - { .compatible = "ti,omap3", }, - { .compatible = "ti,omap4", }, -diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c -index 4d3ec92..15cb261 100644 ---- a/drivers/cpufreq/cpufreq-dt.c -+++ b/drivers/cpufreq/cpufreq-dt.c -@@ -28,7 +28,6 @@ - #include "cpufreq-dt.h" - - struct private_data { -- struct opp_table *opp_table; - struct device *cpu_dev; - struct thermal_cooling_device *cdev; - const char *reg_name; -@@ -144,7 +143,6 @@ static int resources_available(void) - static int cpufreq_init(struct cpufreq_policy *policy) - { - struct cpufreq_frequency_table *freq_table; -- struct opp_table *opp_table = NULL; - struct private_data *priv; - struct device *cpu_dev; - struct clk *cpu_clk; -@@ -188,9 +186,11 @@ static int cpufreq_init(struct cpufreq_policy *policy) - */ - name = find_supply_name(cpu_dev); - if (name) { -- opp_table = dev_pm_opp_set_regulator(cpu_dev, name); -- if (IS_ERR(opp_table)) { -- ret = PTR_ERR(opp_table); -+ const char *names[] = {name}; -+ -+ ret = dev_pm_opp_set_regulators(cpu_dev, names, -+ ARRAY_SIZE(names)); -+ if (ret) { - dev_err(cpu_dev, "Failed to set regulator for cpu%d: %d\n", - policy->cpu, ret); - goto out_put_clk; -@@ -240,7 +240,6 @@ static int cpufreq_init(struct cpufreq_policy *policy) - } - - priv->reg_name = name; -- priv->opp_table = opp_table; - - ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); - if (ret) { -@@ -289,7 +288,7 @@ static int cpufreq_init(struct cpufreq_policy *policy) - out_free_opp: - dev_pm_opp_of_cpumask_remove_table(policy->cpus); - if (name) -- dev_pm_opp_put_regulator(opp_table); -+ dev_pm_opp_put_regulators(cpu_dev); - out_put_clk: - clk_put(cpu_clk); - -@@ -304,7 +303,7 @@ static int cpufreq_exit(struct cpufreq_policy *policy) - dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); - dev_pm_opp_of_cpumask_remove_table(policy->related_cpus); - if (priv->reg_name) -- dev_pm_opp_put_regulator(priv->opp_table); -+ dev_pm_opp_put_regulators(priv->cpu_dev); - - clk_put(policy->clk); - kfree(priv); -diff --git b/drivers/cpufreq/ti-cpufreq.c b/drivers/cpufreq/ti-cpufreq.c -new file mode 100644 -index 0000000..afbaef9 ---- /dev/null -+++ b/drivers/cpufreq/ti-cpufreq.c -@@ -0,0 +1,288 @@ -+/* -+ * TI CPUFreq/OPP hw-supported driver -+ * -+ * Copyright (C) 2016 Texas Instruments, Inc. -+ * Dave Gerlach <d-gerlach@ti.com> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/cpu.h> -+#include <linux/io.h> -+#include <linux/mfd/syscon.h> -+#include <linux/module.h> -+#include <linux/of.h> -+#include <linux/of_platform.h> -+#include <linux/pm_opp.h> -+#include <linux/regmap.h> -+#include <linux/slab.h> -+ -+#define REVISION_MASK 0xF -+#define REVISION_SHIFT 28 -+ -+#define AM33XX_800M_ARM_MPU_MAX_FREQ 0x1E2F -+#define AM43XX_600M_ARM_MPU_MAX_FREQ 0xFFA -+ -+#define DRA7_EFUSE_HAS_OD_MPU_OPP 11 -+#define DRA7_EFUSE_HAS_HIGH_MPU_OPP 15 -+#define DRA7_EFUSE_HAS_ALL_MPU_OPP 23 -+ -+#define DRA7_EFUSE_NOM_MPU_OPP BIT(0) -+#define DRA7_EFUSE_OD_MPU_OPP BIT(1) -+#define DRA7_EFUSE_HIGH_MPU_OPP BIT(2) -+ -+#define VERSION_COUNT 2 -+ -+struct ti_cpufreq_data; -+ -+struct ti_cpufreq_soc_data { -+ unsigned long (*efuse_xlate)(struct ti_cpufreq_data *opp_data, -+ unsigned long efuse); -+ unsigned long efuse_fallback; -+}; -+ -+struct ti_cpufreq_data { -+ struct device *cpu_dev; -+ struct device_node *opp_node; -+ struct regmap *opp_efuse; -+ struct regmap *revision; -+ const struct ti_cpufreq_soc_data *soc_data; -+}; -+ -+static unsigned long amx3_efuse_xlate(struct ti_cpufreq_data *opp_data, -+ unsigned long efuse) -+{ -+ if (!efuse) -+ efuse = opp_data->soc_data->efuse_fallback; -+ /* AM335x and AM437x use "OPP disable" bits, so invert */ -+ return ~efuse; -+} -+ -+static unsigned long dra7_efuse_xlate(struct ti_cpufreq_data *opp_data, -+ unsigned long efuse) -+{ -+ unsigned long calculated_efuse = DRA7_EFUSE_NOM_MPU_OPP; -+ -+ /* -+ * The efuse on dra7 and am57 parts contains a specific -+ * value indicating the highest available OPP. -+ */ -+ -+ switch (efuse) { -+ case DRA7_EFUSE_HAS_ALL_MPU_OPP: -+ case DRA7_EFUSE_HAS_HIGH_MPU_OPP: -+ calculated_efuse |= DRA7_EFUSE_HIGH_MPU_OPP; -+ case DRA7_EFUSE_HAS_OD_MPU_OPP: -+ calculated_efuse |= DRA7_EFUSE_OD_MPU_OPP; -+ } -+ -+ return calculated_efuse; -+} -+ -+static struct ti_cpufreq_soc_data am3x_soc_data = { -+ .efuse_xlate = amx3_efuse_xlate, -+ .efuse_fallback = AM33XX_800M_ARM_MPU_MAX_FREQ, -+}; -+ -+static struct ti_cpufreq_soc_data am4x_soc_data = { -+ .efuse_xlate = amx3_efuse_xlate, -+ .efuse_fallback = AM43XX_600M_ARM_MPU_MAX_FREQ, -+}; -+ -+static struct ti_cpufreq_soc_data dra7_soc_data = { -+ .efuse_xlate = dra7_efuse_xlate, -+}; -+ -+/** -+ * ti_cpufreq_get_efuse() - Parse and return efuse value present on SoC -+ * @opp_data: pointer to ti_cpufreq_data context -+ * @efuse_value: Set to the value parsed from efuse -+ * -+ * Returns error code if efuse not read properly. -+ */ -+static int ti_cpufreq_get_efuse(struct ti_cpufreq_data *opp_data, -+ u32 *efuse_value) -+{ -+ struct device *dev = opp_data->cpu_dev; -+ struct device_node *np = opp_data->opp_node; -+ unsigned int efuse_offset; -+ u32 efuse, efuse_mask, efuse_shift, vals[4]; -+ int ret; -+ -+ ret = of_property_read_u32_array(np, "ti,syscon-efuse", vals, 4); -+ if (ret) { -+ dev_err(dev, "ti,syscon-efuse cannot be read %s: %d\n", -+ np->full_name, ret); -+ return ret; -+ } -+ -+ efuse_offset = vals[1]; -+ efuse_mask = vals[2]; -+ efuse_shift = vals[3]; -+ -+ ret = regmap_read(opp_data->opp_efuse, efuse_offset, &efuse); -+ if (ret) { -+ dev_err(dev, -+ "Failed to read the efuse value from syscon: %d\n", -+ ret); -+ return ret; -+ } -+ -+ efuse = (efuse & efuse_mask) >> efuse_shift; -+ -+ *efuse_value = opp_data->soc_data->efuse_xlate(opp_data, efuse); -+ -+ return 0; -+} -+ -+/** -+ * ti_cpufreq_get_rev() - Parse and return rev value present on SoC -+ * @opp_data: pointer to ti_cpufreq_data context -+ * @revision_value: Set to the value parsed from revision register -+ * -+ * Returns error code if revision not read properly. -+ */ -+static int ti_cpufreq_get_rev(struct ti_cpufreq_data *opp_data, -+ u32 *revision_value) -+{ -+ struct device *dev = opp_data->cpu_dev; -+ struct device_node *np = opp_data->opp_node; -+ unsigned int revision_offset; -+ u32 revision; -+ int ret; -+ -+ ret = of_property_read_u32_index(np, "ti,syscon-rev", -+ 1, &revision_offset); -+ if (ret) { -+ dev_err(dev, -+ "No revision offset provided %s [%d]\n", -+ np->full_name, ret); -+ return ret; -+ } -+ -+ ret = regmap_read(opp_data->revision, revision_offset, &revision); -+ if (ret) { -+ dev_err(dev, -+ "Failed to read the revision number from syscon: %d\n", -+ ret); -+ return ret; -+ } -+ -+ *revision_value = BIT((revision >> REVISION_SHIFT) & REVISION_MASK); -+ -+ return 0; -+} -+ -+static int ti_cpufreq_setup_syscon_registers(struct ti_cpufreq_data *opp_data) -+{ -+ struct device *dev = opp_data->cpu_dev; -+ struct device_node *np = opp_data->opp_node; -+ -+ opp_data->opp_efuse = syscon_regmap_lookup_by_phandle(np, -+ "ti,syscon-efuse"); -+ if (IS_ERR(opp_data->opp_efuse)) { -+ dev_err(dev, -+ "\"ti,syscon-efuse\" is missing, cannot use OPPv2 table.\n"); -+ return PTR_ERR(opp_data->opp_efuse); -+ } -+ -+ opp_data->revision = syscon_regmap_lookup_by_phandle(np, -+ "ti,syscon-rev"); -+ if (IS_ERR(opp_data->revision)) { -+ dev_err(dev, -+ "\"ti,syscon-rev\" is missing, cannot use OPPv2 table.\n"); -+ return PTR_ERR(opp_data->revision); -+ } -+ -+ return 0; -+} -+ -+static const struct of_device_id ti_cpufreq_of_match[] = { -+ { .compatible = "ti,am33xx", .data = &am3x_soc_data, }, -+ { .compatible = "ti,am4372", .data = &am4x_soc_data, }, -+ { .compatible = "ti,dra7", .data = &dra7_soc_data }, -+ {}, -+}; -+ -+static int ti_cpufreq_init(void) -+{ -+ u32 version[VERSION_COUNT]; -+ struct device_node *np; -+ const struct of_device_id *match; -+ struct ti_cpufreq_data *opp_data; -+ int ret; -+ -+ np = of_find_node_by_path("/"); -+ match = of_match_node(ti_cpufreq_of_match, np); -+ if (!match) -+ return -ENODEV; -+ -+ opp_data = kzalloc(sizeof(*opp_data), GFP_KERNEL); -+ if (!opp_data) -+ return -ENOMEM; -+ -+ opp_data->soc_data = match->data; -+ -+ opp_data->cpu_dev = get_cpu_device(0); -+ if (!opp_data->cpu_dev) { -+ pr_err("%s: Failed to get device for CPU0\n", __func__); -+ return -ENODEV; -+ } -+ -+ opp_data->opp_node = dev_pm_opp_of_get_opp_desc_node(opp_data->cpu_dev); -+ if (!opp_data->opp_node) { -+ dev_info(opp_data->cpu_dev, -+ "OPP-v2 not supported, cpufreq-dt will attempt to use legacy tables.\n"); -+ goto register_cpufreq_dt; -+ } -+ -+ ret = ti_cpufreq_setup_syscon_registers(opp_data); -+ if (ret) -+ goto fail_put_node; -+ -+ /* -+ * OPPs determine whether or not they are supported based on -+ * two metrics: -+ * 0 - SoC Revision -+ * 1 - eFuse value -+ */ -+ ret = ti_cpufreq_get_rev(opp_data, &version[0]); -+ if (ret) -+ goto fail_put_node; -+ -+ ret = ti_cpufreq_get_efuse(opp_data, &version[1]); -+ if (ret) -+ goto fail_put_node; -+ -+ of_node_put(opp_data->opp_node); -+ -+ ret = dev_pm_opp_set_supported_hw(opp_data->cpu_dev, version, -+ VERSION_COUNT); -+ if (ret) { -+ dev_err(opp_data->cpu_dev, -+ "Failed to set supported hardware\n"); -+ goto fail_put_node; -+ } -+ -+register_cpufreq_dt: -+ platform_device_register_simple("cpufreq-dt", -1, NULL, 0); -+ -+ return 0; -+ -+fail_put_node: -+ of_node_put(opp_data->opp_node); -+ -+ return ret; -+} -+module_init(ti_cpufreq_init); -+ -+MODULE_DESCRIPTION("TI CPUFreq/OPP hw-supported driver"); -+MODULE_AUTHOR("Dave Gerlach <d-gerlach@ti.com>"); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig -index ed37e59..a118ef6 100644 ---- a/drivers/gpio/Kconfig -+++ b/drivers/gpio/Kconfig -@@ -61,6 +61,20 @@ config GPIO_SYSFS - Kernel drivers may also request that a particular GPIO be - exported to userspace; this can be useful when debugging. - -+config GPIO_OF_HELPER -+ bool "GPIO OF helper device (EXPERIMENTAL)" -+ depends on OF_GPIO -+ help -+ Say Y here to add an GPIO OF helper driver -+ -+ Allows you specify a GPIO helper based on OF -+ which allows simple export of GPIO functionality -+ in user-space. -+ -+ Features include, value set/get, direction control, -+ interrupt/value change poll support, event counting -+ and others. -+ - config GPIO_GENERIC - depends on HAS_IOMEM # Only for IOMEM drivers - tristate -diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile -index d074c22..e4e13b8 100644 ---- a/drivers/gpio/Makefile -+++ b/drivers/gpio/Makefile -@@ -8,6 +8,7 @@ obj-$(CONFIG_GPIOLIB) += gpiolib-legacy.o - obj-$(CONFIG_OF_GPIO) += gpiolib-of.o - obj-$(CONFIG_GPIO_SYSFS) += gpiolib-sysfs.o - obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o -+obj-$(CONFIG_GPIO_OF_HELPER) += gpio-of-helper.o - - # Device drivers. Generally keep list sorted alphabetically - obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o -diff --git b/drivers/gpio/gpio-of-helper.c b/drivers/gpio/gpio-of-helper.c -new file mode 100644 -index 0000000..83f362f ---- /dev/null -+++ b/drivers/gpio/gpio-of-helper.c -@@ -0,0 +1,435 @@ -+/* -+ * GPIO OF based helper -+ * -+ * A simple DT based driver to provide access to GPIO functionality -+ * to user-space via sysfs. -+ * -+ * Copyright (C) 2013 Pantelis Antoniou <panto@antoniou-consulting.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/string.h> -+#include <linux/timer.h> -+#include <linux/errno.h> -+#include <linux/init.h> -+#include <linux/delay.h> -+#include <linux/bitops.h> -+#include <linux/err.h> -+#include <linux/of.h> -+#include <linux/of_device.h> -+#include <linux/of_gpio.h> -+#include <linux/pinctrl/pinctrl.h> -+#include <linux/pinctrl/pinmux.h> -+#include <linux/pinctrl/consumer.h> -+#include <linux/atomic.h> -+#include <linux/clk.h> -+#include <linux/interrupt.h> -+#include <linux/math64.h> -+#include <linux/atomic.h> -+#include <linux/idr.h> -+ -+/* fwd decl. */ -+struct gpio_of_helper_info; -+ -+enum gpio_type { -+ GPIO_TYPE_INPUT = 0, -+ GPIO_TYPE_OUTPUT = 1, -+}; -+ -+struct gpio_of_entry { -+ int id; -+ struct gpio_of_helper_info *info; -+ struct device_node *node; -+ enum gpio_type type; -+ int gpio; -+ int irq; -+ const char *name; -+ atomic64_t counter; -+ unsigned int count_flags; -+#define COUNT_RISING_EDGE (1 << 0) -+#define COUNT_FALLING_EDGE (1 << 1) -+}; -+ -+struct gpio_of_helper_info { -+ struct platform_device *pdev; -+ struct idr idr; -+}; -+ -+static const struct of_device_id gpio_of_helper_of_match[] = { -+ { -+ .compatible = "gpio-of-helper", -+ }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, gpio_of_helper_of_match); -+ -+static ssize_t gpio_of_helper_show_status(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct gpio_of_helper_info *info = platform_get_drvdata(pdev); -+ struct gpio_of_entry *entry; -+ char *p, *e; -+ int id, n; -+ -+ p = buf; -+ e = p + PAGE_SIZE; -+ n = 0; -+ idr_for_each_entry(&info->idr, entry, id) { -+ switch (entry->type) { -+ case GPIO_TYPE_INPUT: -+ n = snprintf(p, e - p, "%2d %-24s %3d %-3s %llu\n", -+ entry->id, entry->name, entry->gpio, "IN", -+ (unsigned long long) -+ atomic64_read(&entry->counter)); -+ break; -+ case GPIO_TYPE_OUTPUT: -+ n = snprintf(p, e - p, "%2d %-24s %3d %-3s\n", -+ entry->id, entry->name, entry->gpio, "OUT"); -+ break; -+ } -+ p += n; -+ } -+ -+ return p - buf; -+} -+ -+static DEVICE_ATTR(status, S_IRUGO, -+ gpio_of_helper_show_status, NULL); -+ -+static irqreturn_t gpio_of_helper_handler(int irq, void *ptr) -+{ -+ struct gpio_of_entry *entry = ptr; -+ -+ /* caution - low speed interfaces only! */ -+ atomic64_inc(&entry->counter); -+ -+ return IRQ_HANDLED; -+} -+ -+static struct gpio_of_entry * -+gpio_of_entry_create(struct gpio_of_helper_info *info, -+ struct device_node *node) -+{ -+ struct platform_device *pdev = info->pdev; -+ struct device *dev = &pdev->dev; -+ struct gpio_of_entry *entry; -+ int err, gpio, irq; -+ unsigned int req_flags, count_flags, irq_flags; -+ enum gpio_type type; -+ enum of_gpio_flags gpio_flags; -+ const char *name; -+ -+ /* get the type of the node first */ -+ if (of_property_read_bool(node, "input")) -+ type = GPIO_TYPE_INPUT; -+ else if (of_property_read_bool(node, "output") -+ || of_property_read_bool(node, "init-low") -+ || of_property_read_bool(node, "init-high")) -+ type = GPIO_TYPE_OUTPUT; -+ else { -+ dev_err(dev, "Not valid gpio node type\n"); -+ err = -EINVAL; -+ goto err_bad_node; -+ } -+ -+ /* get the name */ -+ if (of_property_read_string(node, "line-name", &name)) -+ if (of_property_read_string(node, "gpio-name", &name)) -+ name = node->name; -+ -+ err = of_get_named_gpio_flags(node, "gpio", 0, &gpio_flags); -+ if (IS_ERR_VALUE(err)) { -+ dev_err(dev, "Failed to get gpio property of '%s'\n", name); -+ goto err_bad_node; -+ } -+ gpio = err; -+ -+ req_flags = 0; -+ count_flags = 0; -+ -+ /* set the request flags */ -+ switch (type) { -+ case GPIO_TYPE_INPUT: -+ req_flags = GPIOF_DIR_IN | GPIOF_EXPORT; -+ if (of_property_read_bool(node, "count-falling-edge")) -+ count_flags |= COUNT_FALLING_EDGE; -+ if (of_property_read_bool(node, "count-rising-edge")) -+ count_flags |= COUNT_RISING_EDGE; -+ break; -+ case GPIO_TYPE_OUTPUT: -+ req_flags = GPIOF_DIR_OUT | GPIOF_EXPORT; -+ if (of_property_read_bool(node, "init-high")) -+ req_flags |= GPIOF_OUT_INIT_HIGH; -+ else if (of_property_read_bool(node, "init-low")) -+ req_flags |= GPIOF_OUT_INIT_LOW; -+ break; -+ } -+ if (of_property_read_bool(node, "dir-changeable")) -+ req_flags |= GPIOF_EXPORT_CHANGEABLE; -+ if (gpio_flags & OF_GPIO_ACTIVE_LOW) -+ req_flags |= GPIOF_ACTIVE_LOW; -+ if (gpio_flags & OF_GPIO_SINGLE_ENDED) { -+ if (gpio_flags & OF_GPIO_ACTIVE_LOW) -+ req_flags |= GPIOF_OPEN_DRAIN; -+ else -+ req_flags |= GPIOF_OPEN_SOURCE; -+ } -+ -+ /* request the gpio */ -+ err = devm_gpio_request_one(dev, gpio, req_flags, name); -+ if (err != 0) { -+ dev_err(dev, "Failed to request gpio '%s'\n", name); -+ goto err_bad_node; -+ } -+ -+ irq = -1; -+ irq_flags = 0; -+ -+ /* counter mode requested - need an interrupt */ -+ if (count_flags != 0) { -+ irq = gpio_to_irq(gpio); -+ if (IS_ERR_VALUE(irq)) { -+ dev_err(dev, "Failed to request gpio '%s'\n", name); -+ goto err_bad_node; -+ } -+ -+ if (count_flags & COUNT_RISING_EDGE) -+ irq_flags |= IRQF_TRIGGER_RISING; -+ if (count_flags & COUNT_FALLING_EDGE) -+ irq_flags |= IRQF_TRIGGER_FALLING; -+ } -+ -+// if (!idr_pre_get(&info->idr, GFP_KERNEL)) { -+// dev_err(dev, "Failed on idr_pre_get of '%s'\n", name); -+// err = -ENOMEM; -+// goto err_no_mem; -+// } -+ -+ idr_preload(GFP_KERNEL); -+ -+ entry = devm_kzalloc(dev, sizeof(*entry), GFP_KERNEL); -+ if (entry == NULL) { -+ dev_err(dev, "Failed to allocate gpio entry of '%s'\n", name); -+ err = -ENOMEM; -+ goto err_no_mem; -+ } -+ -+ entry->id = -1; -+ entry->info = info; -+ entry->node = of_node_get(node); /* get node reference */ -+ entry->type = type; -+ entry->gpio = gpio; -+ entry->irq = irq; -+ entry->name = name; -+ -+ /* interrupt enable is last thing done */ -+ if (irq >= 0) { -+ atomic64_set(&entry->counter, 0); -+ entry->count_flags = count_flags; -+ err = devm_request_irq(dev, irq, gpio_of_helper_handler, -+ irq_flags, name, entry); -+ if (err != 0) { -+ dev_err(dev, "Failed to request irq of '%s'\n", name); -+ goto err_no_irq; -+ } -+ } -+ -+ /* all done; insert */ -+// err = idr_get_new(&info->idr, entry, &entry->id); -+// if (IS_ERR_VALUE(err)) { -+// dev_err(dev, "Failed to idr_get_new of '%s'\n", name); -+// goto err_fail_idr; -+// } -+ -+ err = idr_alloc(&info->idr, entry, 0, 0, GFP_NOWAIT); -+ if (err >= 0) -+ entry->id = err; -+ -+ idr_preload_end(); -+ -+ if (err < 0) { -+ dev_err(dev, "Failed to idr_get_new of '%s'\n", name); -+ goto err_fail_idr; -+ } -+ -+ dev_dbg(dev, "Allocated GPIO id=%d name='%s'\n", entry->id, name); -+ -+ return entry; -+ -+err_fail_idr: -+ /* nothing to do */ -+err_no_irq: -+ /* release node ref */ -+ of_node_put(node); -+ /* nothing else needs to be done, devres handles it */ -+err_no_mem: -+err_bad_node: -+ return ERR_PTR(err); -+} -+ -+static int gpio_of_entry_destroy(struct gpio_of_entry *entry) -+{ -+ struct gpio_of_helper_info *info = entry->info; -+ struct platform_device *pdev = info->pdev; -+ struct device *dev = &pdev->dev; -+ -+ dev_dbg(dev, "Destroying GPIO id=%d\n", entry->id); -+ -+ /* remove from the IDR */ -+ idr_remove(&info->idr, entry->id); -+ -+ /* remove node ref */ -+ of_node_put(entry->node); -+ -+ /* free gpio */ -+ devm_gpio_free(dev, entry->gpio); -+ -+ /* gree irq */ -+ if (entry->irq >= 0) -+ devm_free_irq(dev, entry->irq, entry); -+ -+ /* and free */ -+ devm_kfree(dev, entry); -+ -+ return 0; -+} -+ -+static int gpio_of_helper_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct gpio_of_helper_info *info; -+ struct gpio_of_entry *entry; -+ struct device_node *pnode = pdev->dev.of_node; -+ struct device_node *cnode; -+ struct pinctrl *pinctrl; -+ int err; -+ -+ /* we only support OF */ -+ if (pnode == NULL) { -+ dev_err(&pdev->dev, "No platform of_node!\n"); -+ return -ENODEV; -+ } -+ -+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev); -+ if (IS_ERR(pinctrl)) { -+ /* special handling for probe defer */ -+ if (PTR_ERR(pinctrl) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ -+ dev_warn(&pdev->dev, -+ "pins are not configured from the driver\n"); -+ } -+ -+ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); -+ if (info == NULL) { -+ dev_err(&pdev->dev, "Failed to allocate info\n"); -+ err = -ENOMEM; -+ goto err_no_mem; -+ } -+ platform_set_drvdata(pdev, info); -+ info->pdev = pdev; -+ -+ idr_init(&info->idr); -+ -+ err = device_create_file(dev, &dev_attr_status); -+ if (err != 0) { -+ dev_err(dev, "Failed to create status sysfs attribute\n"); -+ goto err_no_sysfs; -+ } -+ -+ for_each_child_of_node(pnode, cnode) { -+ -+ entry = gpio_of_entry_create(info, cnode); -+ if (IS_ERR_OR_NULL(entry)) { -+ dev_err(dev, "Failed to create gpio entry\n"); -+ err = PTR_ERR(entry); -+ goto err_fail_entry; -+ } -+ } -+ -+ dev_info(&pdev->dev, "ready\n"); -+ -+ return 0; -+err_fail_entry: -+ device_remove_file(&pdev->dev, &dev_attr_status); -+err_no_sysfs: -+err_no_mem: -+ return err; -+} -+ -+static int gpio_of_helper_remove(struct platform_device *pdev) -+{ -+ struct gpio_of_helper_info *info = platform_get_drvdata(pdev); -+ struct gpio_of_entry *entry; -+ int id; -+ -+ dev_info(&pdev->dev, "removing\n"); -+ -+ device_remove_file(&pdev->dev, &dev_attr_status); -+ -+ id = 0; -+ idr_for_each_entry(&info->idr, entry, id) { -+ /* destroy each and every one */ -+ gpio_of_entry_destroy(entry); -+ } -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+//#ifdef CONFIG_PM_RUNTIME -+static int gpio_of_helper_runtime_suspend(struct device *dev) -+{ -+ /* place holder */ -+ return 0; -+} -+ -+static int gpio_of_helper_runtime_resume(struct device *dev) -+{ -+ /* place holder */ -+ return 0; -+} -+//#endif /* CONFIG_PM_RUNTIME */ -+ -+static struct dev_pm_ops gpio_of_helper_pm_ops = { -+ SET_RUNTIME_PM_OPS(gpio_of_helper_runtime_suspend, -+ gpio_of_helper_runtime_resume, NULL) -+}; -+#define GPIO_OF_HELPER_PM_OPS (&gpio_of_helper_pm_ops) -+#else -+#define GPIO_OF_HELPER_PM_OPS NULL -+#endif /* CONFIG_PM */ -+ -+struct platform_driver gpio_of_helper_driver = { -+ .probe = gpio_of_helper_probe, -+ .remove = gpio_of_helper_remove, -+ .driver = { -+ .name = "gpio-of-helper", -+ .owner = THIS_MODULE, -+ .pm = GPIO_OF_HELPER_PM_OPS, -+ .of_match_table = gpio_of_helper_of_match, -+ }, -+}; -+ -+module_platform_driver(gpio_of_helper_driver); -+ -+MODULE_AUTHOR("Pantelis Antoniou <panto@antoniou-consulting.com>"); -+MODULE_DESCRIPTION("GPIO OF Helper driver"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:gpio-of-helper"); -diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c -index 4b44dd9..9c6de28 100644 ---- a/drivers/gpio/gpiolib-sysfs.c -+++ b/drivers/gpio/gpiolib-sysfs.c -@@ -35,10 +35,10 @@ static DEFINE_MUTEX(sysfs_lock); - /* - * /sys/class/gpio/gpioN... only for GPIOs that are exported - * /direction -- * * MAY BE OMITTED if kernel won't allow direction changes - * * is read/write as "in" or "out" - * * may also be written as "high" or "low", initializing - * output value as specified ("out" implies "low") -+ * * read-only if kernel won't allow direction changes - * /value - * * always readable, subject to hardware behavior - * * may be writable, as zero/nonzero -@@ -51,6 +51,8 @@ static DEFINE_MUTEX(sysfs_lock); - * * is read/write as zero/nonzero - * * also affects existing and subsequent "falling" and "rising" - * /edge configuration -+ * /label -+ * * descriptor label - */ - - static ssize_t direction_show(struct device *dev, -@@ -81,7 +83,9 @@ static ssize_t direction_store(struct device *dev, - - mutex_lock(&data->mutex); - -- if (sysfs_streq(buf, "high")) -+ if (!data->direction_can_change) -+ status = -EPERM; -+ else if (sysfs_streq(buf, "high")) - status = gpiod_direction_output_raw(desc, 1); - else if (sysfs_streq(buf, "out") || sysfs_streq(buf, "low")) - status = gpiod_direction_output_raw(desc, 0); -@@ -350,6 +354,23 @@ static ssize_t active_low_store(struct device *dev, - } - static DEVICE_ATTR_RW(active_low); - -+static ssize_t label_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct gpiod_data *data = dev_get_drvdata(dev); -+ struct gpio_desc *desc = data->desc; -+ ssize_t status; -+ -+ mutex_lock(&data->mutex); -+ -+ status = sprintf(buf, "%s\n", desc->label); -+ -+ mutex_unlock(&data->mutex); -+ -+ return status; -+} -+static DEVICE_ATTR_RO(label); -+ - static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr, - int n) - { -@@ -361,12 +382,15 @@ static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr, - - if (attr == &dev_attr_direction.attr) { - if (!show_direction) -- mode = 0; -+ mode &= 0444; - } else if (attr == &dev_attr_edge.attr) { - if (gpiod_to_irq(desc) < 0) - mode = 0; - if (!show_direction && test_bit(FLAG_IS_OUT, &desc->flags)) - mode = 0; -+ } else if (attr == &dev_attr_value.attr) { -+ if (!show_direction && !test_bit(FLAG_IS_OUT, &desc->flags)) -+ mode &= 0444; - } - - return mode; -@@ -377,6 +401,7 @@ static struct attribute *gpio_attrs[] = { - &dev_attr_edge.attr, - &dev_attr_value.attr, - &dev_attr_active_low.attr, -+ &dev_attr_label.attr, - NULL, - }; - -@@ -390,6 +415,10 @@ static const struct attribute_group *gpio_groups[] = { - NULL - }; - -+/* bwlegh, a second device in the same file... get out of my namespace! */ -+#define dev_attr_label dev_attr_chip_label -+#define label_show chip_label_show -+ - /* - * /sys/class/gpio/gpiochipN/ - * /base ... matching gpio_chip.base (N) -diff --git a/drivers/gpu/drm/etnaviv/Kconfig b/drivers/gpu/drm/etnaviv/Kconfig -index 2cde7a5..b776f41 100644 ---- a/drivers/gpu/drm/etnaviv/Kconfig -+++ b/drivers/gpu/drm/etnaviv/Kconfig -@@ -2,7 +2,7 @@ - config DRM_ETNAVIV - tristate "ETNAVIV (DRM support for Vivante GPU IP cores)" - depends on DRM -- depends on ARCH_MXC || ARCH_DOVE -+ depends on ARCH_MXC || ARCH_DOVE || ARCH_OMAP2PLUS - select SHMEM - select TMPFS - select IOMMU_API -diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c -index aa68766..20d20ca 100644 ---- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c -+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c -@@ -654,6 +654,7 @@ static int etnaviv_pdev_remove(struct platform_device *pdev) - static const struct of_device_id dt_match[] = { - { .compatible = "fsl,imx-gpu-subsystem" }, - { .compatible = "marvell,dove-gpu-subsystem" }, -+ { .compatible = "vivante,gc-gpu-subsystem"}, - {} - }; - MODULE_DEVICE_TABLE(of, dt_match); -diff --git a/drivers/gpu/drm/i2c/Kconfig b/drivers/gpu/drm/i2c/Kconfig -index a6c92be..66ff8e3 100644 ---- a/drivers/gpu/drm/i2c/Kconfig -+++ b/drivers/gpu/drm/i2c/Kconfig -@@ -1,6 +1,12 @@ - menu "I2C encoder or helper chips" - depends on DRM && DRM_KMS_HELPER && I2C - -+config DRM_I2C_ADIHDMI -+ tristate "ADI HDMI encoder" -+ default m if DRM_TILCDC -+ help -+ Support for ADI HDMI encoder. -+ - config DRM_I2C_CH7006 - tristate "Chrontel ch7006 TV encoder" - default m if DRM_NOUVEAU -diff --git a/drivers/gpu/drm/i2c/Makefile b/drivers/gpu/drm/i2c/Makefile -index 43aa33b..62a4eea 100644 ---- a/drivers/gpu/drm/i2c/Makefile -+++ b/drivers/gpu/drm/i2c/Makefile -@@ -8,3 +8,6 @@ obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o - - tda998x-y := tda998x_drv.o - obj-$(CONFIG_DRM_I2C_NXP_TDA998X) += tda998x.o -+ -+adihdmi-y := adihdmi_drv.o -+obj-$(CONFIG_DRM_I2C_ADIHDMI) += adihdmi.o -diff --git b/drivers/gpu/drm/i2c/adihdmi.h b/drivers/gpu/drm/i2c/adihdmi.h -new file mode 100644 -index 0000000..58d9a2b ---- /dev/null -+++ b/drivers/gpu/drm/i2c/adihdmi.h -@@ -0,0 +1,289 @@ -+/* -+ * Analog Devices ADIHDMI HDMI transmitter driver -+ * -+ * Copyright 2012 Analog Devices Inc. -+ * -+ * Licensed under the GPL-2. -+ */ -+ -+#ifndef __DRM_I2C_ADIHDMI_H__ -+#define __DRM_I2C_ADIHDMI_H__ -+ -+#include <linux/hdmi.h> -+ -+#define ADIHDMI_REG_CHIP_REVISION 0x00 -+#define ADIHDMI_REG_N0 0x01 -+#define ADIHDMI_REG_N1 0x02 -+#define ADIHDMI_REG_N2 0x03 -+#define ADIHDMI_REG_SPDIF_FREQ 0x04 -+#define ADIHDMI_REG_CTS_AUTOMATIC1 0x05 -+#define ADIHDMI_REG_CTS_AUTOMATIC2 0x06 -+#define ADIHDMI_REG_CTS_MANUAL0 0x07 -+#define ADIHDMI_REG_CTS_MANUAL1 0x08 -+#define ADIHDMI_REG_CTS_MANUAL2 0x09 -+#define ADIHDMI_REG_AUDIO_SOURCE 0x0a -+#define ADIHDMI_REG_AUDIO_CONFIG 0x0b -+#define ADIHDMI_REG_I2S_CONFIG 0x0c -+#define ADIHDMI_REG_I2S_WIDTH 0x0d -+#define ADIHDMI_REG_AUDIO_SUB_SRC0 0x0e -+#define ADIHDMI_REG_AUDIO_SUB_SRC1 0x0f -+#define ADIHDMI_REG_AUDIO_SUB_SRC2 0x10 -+#define ADIHDMI_REG_AUDIO_SUB_SRC3 0x11 -+#define ADIHDMI_REG_AUDIO_CFG1 0x12 -+#define ADIHDMI_REG_AUDIO_CFG2 0x13 -+#define ADIHDMI_REG_AUDIO_CFG3 0x14 -+#define ADIHDMI_REG_I2C_FREQ_ID_CFG 0x15 -+#define ADIHDMI_REG_VIDEO_INPUT_CFG1 0x16 -+#define ADIHDMI_REG_CSC_UPPER(x) (0x18 + (x) * 2) -+#define ADIHDMI_REG_CSC_LOWER(x) (0x19 + (x) * 2) -+#define ADIHDMI_REG_SYNC_DECODER(x) (0x30 + (x)) -+#define ADIHDMI_REG_DE_GENERATOR (0x35 + (x)) -+#define ADIHDMI_REG_PIXEL_REPETITION 0x3b -+#define ADIHDMI_REG_VIC_MANUAL 0x3c -+#define ADIHDMI_REG_VIC_SEND 0x3d -+#define ADIHDMI_REG_VIC_DETECTED 0x3e -+#define ADIHDMI_REG_AUX_VIC_DETECTED 0x3f -+#define ADIHDMI_REG_PACKET_ENABLE0 0x40 -+#define ADIHDMI_REG_POWER 0x41 -+#define ADIHDMI_REG_STATUS 0x42 -+#define ADIHDMI_REG_EDID_I2C_ADDR 0x43 -+#define ADIHDMI_REG_PACKET_ENABLE1 0x44 -+#define ADIHDMI_REG_PACKET_I2C_ADDR 0x45 -+#define ADIHDMI_REG_DSD_ENABLE 0x46 -+#define ADIHDMI_REG_VIDEO_INPUT_CFG2 0x48 -+#define ADIHDMI_REG_INFOFRAME_UPDATE 0x4a -+#define ADIHDMI_REG_GC(x) (0x4b + (x)) /* 0x4b - 0x51 */ -+#define ADIHDMI_REG_AVI_INFOFRAME_VERSION 0x52 -+#define ADIHDMI_REG_AVI_INFOFRAME_LENGTH 0x53 -+#define ADIHDMI_REG_AVI_INFOFRAME_CHECKSUM 0x54 -+#define ADIHDMI_REG_AVI_INFOFRAME(x) (0x55 + (x)) /* 0x55 - 0x6f */ -+#define ADIHDMI_REG_AUDIO_INFOFRAME_VERSION 0x70 -+#define ADIHDMI_REG_AUDIO_INFOFRAME_LENGTH 0x71 -+#define ADIHDMI_REG_AUDIO_INFOFRAME_CHECKSUM 0x72 -+#define ADIHDMI_REG_AUDIO_INFOFRAME(x) (0x73 + (x)) /* 0x73 - 0x7c */ -+#define ADIHDMI_REG_INT_ENABLE(x) (0x94 + (x)) -+#define ADIHDMI_REG_INT(x) (0x96 + (x)) -+#define ADIHDMI_REG_INPUT_CLK_DIV 0x9d -+#define ADIHDMI_REG_PLL_STATUS 0x9e -+#define ADIHDMI_REG_HDMI_POWER 0xa1 -+#define ADIHDMI_REG_HDCP_HDMI_CFG 0xaf -+#define ADIHDMI_REG_AN(x) (0xb0 + (x)) /* 0xb0 - 0xb7 */ -+#define ADIHDMI_REG_HDCP_STATUS 0xb8 -+#define ADIHDMI_REG_BCAPS 0xbe -+#define ADIHDMI_REG_BKSV(x) (0xc0 + (x)) /* 0xc0 - 0xc3 */ -+#define ADIHDMI_REG_EDID_SEGMENT 0xc4 -+#define ADIHDMI_REG_DDC_STATUS 0xc8 -+#define ADIHDMI_REG_EDID_READ_CTRL 0xc9 -+#define ADIHDMI_REG_BSTATUS(x) (0xca + (x)) /* 0xca - 0xcb */ -+#define ADIHDMI_REG_TIMING_GEN_SEQ 0xd0 -+#define ADIHDMI_REG_POWER2 0xd6 -+#define ADIHDMI_REG_HSYNC_PLACEMENT_MSB 0xfa -+ -+#define ADIHDMI_REG_SYNC_ADJUSTMENT(x) (0xd7 + (x)) /* 0xd7 - 0xdc */ -+#define ADIHDMI_REG_TMDS_CLOCK_INV 0xde -+#define ADIHDMI_REG_ARC_CTRL 0xdf -+#define ADIHDMI_REG_CEC_I2C_ADDR 0xe1 -+#define ADIHDMI_REG_CEC_CTRL 0xe2 -+#define ADIHDMI_REG_CHIP_ID_HIGH 0xf5 -+#define ADIHDMI_REG_CHIP_ID_LOW 0xf6 -+ -+#define ADIHDMI_CSC_ENABLE BIT(7) -+#define ADIHDMI_CSC_UPDATE_MODE BIT(5) -+ -+#define ADIHDMI_INT0_HDP BIT(7) -+#define ADIHDMI_INT0_VSYNC BIT(5) -+#define ADIHDMI_INT0_AUDIO_FIFO_FULL BIT(4) -+#define ADIHDMI_INT0_EDID_READY BIT(2) -+#define ADIHDMI_INT0_HDCP_AUTHENTICATED BIT(1) -+ -+#define ADIHDMI_INT1_DDC_ERROR BIT(7) -+#define ADIHDMI_INT1_BKSV BIT(6) -+#define ADIHDMI_INT1_CEC_TX_READY BIT(5) -+#define ADIHDMI_INT1_CEC_TX_ARBIT_LOST BIT(4) -+#define ADIHDMI_INT1_CEC_TX_RETRY_TIMEOUT BIT(3) -+#define ADIHDMI_INT1_CEC_RX_READY3 BIT(2) -+#define ADIHDMI_INT1_CEC_RX_READY2 BIT(1) -+#define ADIHDMI_INT1_CEC_RX_READY1 BIT(0) -+ -+#define ADIHDMI_ARC_CTRL_POWER_DOWN BIT(0) -+ -+#define ADIHDMI_CEC_CTRL_POWER_DOWN BIT(0) -+ -+#define ADIHDMI_POWER_POWER_DOWN BIT(6) -+ -+#define ADIHDMI_HDMI_CFG_MODE_MASK 0x2 -+#define ADIHDMI_HDMI_CFG_MODE_DVI 0x0 -+#define ADIHDMI_HDMI_CFG_MODE_HDMI 0x2 -+ -+#define ADIHDMI_AUDIO_SELECT_I2C 0x0 -+#define ADIHDMI_AUDIO_SELECT_SPDIF 0x1 -+#define ADIHDMI_AUDIO_SELECT_DSD 0x2 -+#define ADIHDMI_AUDIO_SELECT_HBR 0x3 -+#define ADIHDMI_AUDIO_SELECT_DST 0x4 -+ -+#define ADIHDMI_I2S_SAMPLE_LEN_16 0x2 -+#define ADIHDMI_I2S_SAMPLE_LEN_20 0x3 -+#define ADIHDMI_I2S_SAMPLE_LEN_18 0x4 -+#define ADIHDMI_I2S_SAMPLE_LEN_22 0x5 -+#define ADIHDMI_I2S_SAMPLE_LEN_19 0x8 -+#define ADIHDMI_I2S_SAMPLE_LEN_23 0x9 -+#define ADIHDMI_I2S_SAMPLE_LEN_24 0xb -+#define ADIHDMI_I2S_SAMPLE_LEN_17 0xc -+#define ADIHDMI_I2S_SAMPLE_LEN_21 0xd -+ -+#define ADIHDMI_SAMPLE_FREQ_44100 0x0 -+#define ADIHDMI_SAMPLE_FREQ_48000 0x2 -+#define ADIHDMI_SAMPLE_FREQ_32000 0x3 -+#define ADIHDMI_SAMPLE_FREQ_88200 0x8 -+#define ADIHDMI_SAMPLE_FREQ_96000 0xa -+#define ADIHDMI_SAMPLE_FREQ_176400 0xc -+#define ADIHDMI_SAMPLE_FREQ_192000 0xe -+ -+#define ADIHDMI_STATUS_POWER_DOWN_POLARITY BIT(7) -+#define ADIHDMI_STATUS_HPD BIT(6) -+#define ADIHDMI_STATUS_MONITOR_SENSE BIT(5) -+#define ADIHDMI_STATUS_I2S_32BIT_MODE BIT(3) -+ -+#define ADIHDMI_PACKET_ENABLE_N_CTS BIT(8+6) -+#define ADIHDMI_PACKET_ENABLE_AUDIO_SAMPLE BIT(8+5) -+#define ADIHDMI_PACKET_ENABLE_AVI_INFOFRAME BIT(8+4) -+#define ADIHDMI_PACKET_ENABLE_AUDIO_INFOFRAME BIT(8+3) -+#define ADIHDMI_PACKET_ENABLE_GC BIT(7) -+#define ADIHDMI_PACKET_ENABLE_SPD BIT(6) -+#define ADIHDMI_PACKET_ENABLE_MPEG BIT(5) -+#define ADIHDMI_PACKET_ENABLE_ACP BIT(4) -+#define ADIHDMI_PACKET_ENABLE_ISRC BIT(3) -+#define ADIHDMI_PACKET_ENABLE_GM BIT(2) -+#define ADIHDMI_PACKET_ENABLE_SPARE2 BIT(1) -+#define ADIHDMI_PACKET_ENABLE_SPARE1 BIT(0) -+ -+#define ADIHDMI_REG_POWER2_HDP_SRC_MASK 0xc0 -+#define ADIHDMI_REG_POWER2_HDP_SRC_BOTH 0x00 -+#define ADIHDMI_REG_POWER2_HDP_SRC_HDP 0x40 -+#define ADIHDMI_REG_POWER2_HDP_SRC_CEC 0x80 -+#define ADIHDMI_REG_POWER2_HDP_SRC_NONE 0xc0 -+#define ADIHDMI_REG_POWER2_TDMS_ENABLE BIT(4) -+#define ADIHDMI_REG_POWER2_GATE_INPUT_CLK BIT(0) -+ -+#define ADIHDMI_LOW_REFRESH_RATE_NONE 0x0 -+#define ADIHDMI_LOW_REFRESH_RATE_24HZ 0x1 -+#define ADIHDMI_LOW_REFRESH_RATE_25HZ 0x2 -+#define ADIHDMI_LOW_REFRESH_RATE_30HZ 0x3 -+ -+#define ADIHDMI_AUDIO_CFG3_LEN_MASK 0x0f -+#define ADIHDMI_I2C_FREQ_ID_CFG_RATE_MASK 0xf0 -+ -+#define ADIHDMI_AUDIO_SOURCE_I2S 0 -+#define ADIHDMI_AUDIO_SOURCE_SPDIF 1 -+ -+#define ADIHDMI_I2S_FORMAT_I2S 0 -+#define ADIHDMI_I2S_FORMAT_RIGHT_J 1 -+#define ADIHDMI_I2S_FORMAT_LEFT_J 2 -+ -+#define ADIHDMI_PACKET(p, x) ((p) * 0x20 + (x)) -+#define ADIHDMI_PACKET_SDP(x) ADIHDMI_PACKET(0, x) -+#define ADIHDMI_PACKET_MPEG(x) ADIHDMI_PACKET(1, x) -+#define ADIHDMI_PACKET_ACP(x) ADIHDMI_PACKET(2, x) -+#define ADIHDMI_PACKET_ISRC1(x) ADIHDMI_PACKET(3, x) -+#define ADIHDMI_PACKET_ISRC2(x) ADIHDMI_PACKET(4, x) -+#define ADIHDMI_PACKET_GM(x) ADIHDMI_PACKET(5, x) -+#define ADIHDMI_PACKET_SPARE(x) ADIHDMI_PACKET(6, x) -+ -+enum adihdmi_input_clock { -+ ADIHDMI_INPUT_CLOCK_1X, -+ ADIHDMI_INPUT_CLOCK_2X, -+ ADIHDMI_INPUT_CLOCK_DDR, -+}; -+ -+enum adihdmi_input_justification { -+ ADIHDMI_INPUT_JUSTIFICATION_EVENLY = 0, -+ ADIHDMI_INPUT_JUSTIFICATION_RIGHT = 1, -+ ADIHDMI_INPUT_JUSTIFICATION_LEFT = 2, -+}; -+ -+enum adihdmi_input_sync_pulse { -+ ADIHDMI_INPUT_SYNC_PULSE_DE = 0, -+ ADIHDMI_INPUT_SYNC_PULSE_HSYNC = 1, -+ ADIHDMI_INPUT_SYNC_PULSE_VSYNC = 2, -+ ADIHDMI_INPUT_SYNC_PULSE_NONE = 3, -+}; -+ -+/** -+ * enum adihdmi_sync_polarity - Polarity for the input sync signals -+ * @ADIHDMI_SYNC_POLARITY_PASSTHROUGH: Sync polarity matches that of -+ * the currently configured mode. -+ * @ADIHDMI_SYNC_POLARITY_LOW: Sync polarity is low -+ * @ADIHDMI_SYNC_POLARITY_HIGH: Sync polarity is high -+ * -+ * If the polarity is set to either LOW or HIGH the driver will configure the -+ * ADIHDMI to internally invert the sync signal if required to match the sync -+ * polarity setting for the currently selected output mode. -+ * -+ * If the polarity is set to PASSTHROUGH, the ADIHDMI will route the signal -+ * unchanged. This is used when the upstream graphics core already generates -+ * the sync signals with the correct polarity. -+ */ -+enum adihdmi_sync_polarity { -+ ADIHDMI_SYNC_POLARITY_PASSTHROUGH, -+ ADIHDMI_SYNC_POLARITY_LOW, -+ ADIHDMI_SYNC_POLARITY_HIGH, -+}; -+ -+/** -+ * struct adihdmi_link_config - Describes adihdmi hardware configuration -+ * @input_color_depth: Number of bits per color component (8, 10 or 12) -+ * @input_colorspace: The input colorspace (RGB, YUV444, YUV422) -+ * @input_clock: The input video clock style (1x, 2x, DDR) -+ * @input_style: The input component arrangement variant -+ * @input_justification: Video input format bit justification -+ * @clock_delay: Clock delay for the input clock (in ps) -+ * @embedded_sync: Video input uses BT.656-style embedded sync -+ * @sync_pulse: Select the sync pulse -+ * @vsync_polarity: vsync input signal configuration -+ * @hsync_polarity: hsync input signal configuration -+ */ -+struct adihdmi_link_config { -+ unsigned int input_color_depth; -+ enum hdmi_colorspace input_colorspace; -+ enum adihdmi_input_clock input_clock; -+ unsigned int input_style; -+ enum adihdmi_input_justification input_justification; -+ -+ int clock_delay; -+ -+ bool embedded_sync; -+ enum adihdmi_input_sync_pulse sync_pulse; -+ enum adihdmi_sync_polarity vsync_polarity; -+ enum adihdmi_sync_polarity hsync_polarity; -+}; -+ -+/** -+ * enum adihdmi_csc_scaling - Scaling factor for the ADIHDMI CSC -+ * @ADIHDMI_CSC_SCALING_1: CSC results are not scaled -+ * @ADIHDMI_CSC_SCALING_2: CSC results are scaled by a factor of two -+ * @ADIHDMI_CSC_SCALING_4: CSC results are scalled by a factor of four -+ */ -+enum adihdmi_csc_scaling { -+ ADIHDMI_CSC_SCALING_1 = 0, -+ ADIHDMI_CSC_SCALING_2 = 1, -+ ADIHDMI_CSC_SCALING_4 = 2, -+}; -+ -+/** -+ * struct adihdmi_video_config - Describes adihdmi hardware configuration -+ * @csc_enable: Whether to enable color space conversion -+ * @csc_scaling_factor: Color space conversion scaling factor -+ * @csc_coefficents: Color space conversion coefficents -+ * @hdmi_mode: Whether to use HDMI or DVI output mode -+ * @avi_infoframe: HDMI infoframe -+ */ -+struct adihdmi_video_config { -+ bool csc_enable; -+ enum adihdmi_csc_scaling csc_scaling_factor; -+ const uint16_t *csc_coefficents; -+ -+ bool hdmi_mode; -+ struct hdmi_avi_infoframe avi_infoframe; -+}; -+ -+#endif /* __DRM_I2C_ADIHDMI_H__ */ -diff --git b/drivers/gpu/drm/i2c/adihdmi_drv.c b/drivers/gpu/drm/i2c/adihdmi_drv.c -new file mode 100644 -index 0000000..6792224 ---- /dev/null -+++ b/drivers/gpu/drm/i2c/adihdmi_drv.c -@@ -0,0 +1,1268 @@ -+/* -+ * Analog Devices ADIHDMI HDMI transmitter driver -+ * -+ * Copyright 2012 Analog Devices Inc. -+ * Copyright 2015 Konsulko Group -+ * -+ * Licensed under the GPL-2. -+ */ -+ -+#include <linux/component.h> -+#include <linux/device.h> -+#include <linux/gpio/consumer.h> -+#include <linux/i2c.h> -+#include <linux/module.h> -+#include <linux/regmap.h> -+#include <linux/slab.h> -+ -+#include <drm/drmP.h> -+#include <drm/drm_crtc_helper.h> -+#include <drm/drm_edid.h> -+#include <drm/drm_encoder_slave.h> -+#include <drm_of.h> -+ -+#include "adihdmi.h" -+ -+#define ADIHDMI_INFOFRAME_PACKETS (0x7900) -+ -+struct adihdmi { -+ struct i2c_client *i2c_main; -+ struct i2c_client *i2c_edid; -+ -+ struct regmap *regmap; -+ struct regmap *packet_memory_regmap; -+ enum drm_connector_status status; -+ bool powered; -+ -+ unsigned int f_tmds; -+ -+ unsigned int current_edid_segment; -+ uint8_t edid_buf[256]; -+ bool edid_read; -+ -+ wait_queue_head_t wq; -+ struct drm_encoder *encoder; -+ -+ bool embedded_sync; -+ enum adihdmi_sync_polarity vsync_polarity; -+ enum adihdmi_sync_polarity hsync_polarity; -+ bool rgb; -+ -+ struct edid *edid; -+ -+ struct gpio_desc *gpio_pd; -+}; -+ -+struct adihdmi2 { -+ struct adihdmi base; -+ struct drm_encoder encoder; -+ struct drm_connector connector; -+}; -+ -+/* ADI recommended values for proper operation. */ -+static const struct reg_sequence adihdmi_fixed_registers[] = { -+ { 0x98, 0x03 }, -+ { 0x9a, 0xe0 }, -+ { 0x9c, 0x30 }, -+ { 0x9d, 0x61 }, -+ { 0xa2, 0xa4 }, -+ { 0xa3, 0xa4 }, -+ { 0xe0, 0xd0 }, -+ { 0xf9, 0x00 }, -+ { 0x55, 0x02 }, -+}; -+ -+/* ----------------------------------------------------------------------------- -+ * Register access -+ */ -+ -+static const uint8_t adihdmi_register_defaults[] = { -+ 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00 */ -+ 0x00, 0x00, 0x01, 0x0e, 0xbc, 0x18, 0x01, 0x13, -+ 0x25, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10 */ -+ 0x46, 0x62, 0x04, 0xa8, 0x00, 0x00, 0x1c, 0x84, -+ 0x1c, 0xbf, 0x04, 0xa8, 0x1e, 0x70, 0x02, 0x1e, /* 20 */ -+ 0x00, 0x00, 0x04, 0xa8, 0x08, 0x12, 0x1b, 0xac, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 */ -+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, -+ 0x00, 0x50, 0x90, 0x7e, 0x79, 0x70, 0x00, 0x00, /* 40 */ -+ 0x00, 0xa8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x02, 0x0d, 0x00, 0x00, 0x00, 0x00, /* 50 */ -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 60 */ -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 70 */ -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 80 */ -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 90 */ -+ 0x0b, 0x02, 0x00, 0x18, 0x5a, 0x60, 0x00, 0x00, -+ 0x00, 0x00, 0x80, 0x80, 0x08, 0x04, 0x00, 0x00, /* a0 */ -+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x14, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b0 */ -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c0 */ -+ 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x01, 0x04, -+ 0x30, 0xff, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, /* d0 */ -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, -+ 0x80, 0x75, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, /* e0 */ -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x11, 0x00, /* f0 */ -+ 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+}; -+ -+static bool adihdmi_register_volatile(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case ADIHDMI_REG_CHIP_REVISION: -+ case ADIHDMI_REG_SPDIF_FREQ: -+ case ADIHDMI_REG_CTS_AUTOMATIC1: -+ case ADIHDMI_REG_CTS_AUTOMATIC2: -+ case ADIHDMI_REG_VIC_DETECTED: -+ case ADIHDMI_REG_VIC_SEND: -+ case ADIHDMI_REG_AUX_VIC_DETECTED: -+ case ADIHDMI_REG_STATUS: -+ case ADIHDMI_REG_GC(1): -+ case ADIHDMI_REG_INT(0): -+ case ADIHDMI_REG_INT(1): -+ case ADIHDMI_REG_PLL_STATUS: -+ case ADIHDMI_REG_AN(0): -+ case ADIHDMI_REG_AN(1): -+ case ADIHDMI_REG_AN(2): -+ case ADIHDMI_REG_AN(3): -+ case ADIHDMI_REG_AN(4): -+ case ADIHDMI_REG_AN(5): -+ case ADIHDMI_REG_AN(6): -+ case ADIHDMI_REG_AN(7): -+ case ADIHDMI_REG_HDCP_STATUS: -+ case ADIHDMI_REG_BCAPS: -+ case ADIHDMI_REG_BKSV(0): -+ case ADIHDMI_REG_BKSV(1): -+ case ADIHDMI_REG_BKSV(2): -+ case ADIHDMI_REG_BKSV(3): -+ case ADIHDMI_REG_BKSV(4): -+ case ADIHDMI_REG_DDC_STATUS: -+ case ADIHDMI_REG_BSTATUS(0): -+ case ADIHDMI_REG_BSTATUS(1): -+ case ADIHDMI_REG_CHIP_ID_HIGH: -+ case ADIHDMI_REG_CHIP_ID_LOW: -+ return true; -+ } -+ -+ return false; -+} -+ -+static const struct regmap_config adihdmi_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ -+ .max_register = 0xff, -+ .cache_type = REGCACHE_RBTREE, -+ .reg_defaults_raw = adihdmi_register_defaults, -+ .num_reg_defaults_raw = ARRAY_SIZE(adihdmi_register_defaults), -+ -+ .volatile_reg = adihdmi_register_volatile, -+}; -+ -+/* ----------------------------------------------------------------------------- -+ * Hardware configuration -+ */ -+ -+ static void adihdmi_audio_setup(struct adihdmi * adihdmi) -+{ -+ /* Select I2S. */ -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_AUDIO_SOURCE, 0x01); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_I2S_CONFIG, 0x84); -+ -+ /* Setup clocks for 48KHz. */ -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_N0, 0x00); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_N1, 0x18); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_N2, 0x00); -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_I2C_FREQ_ID_CFG, 0xF0, 0x20); -+ -+ /* Set audio word length to 24 bits. */ -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_AUDIO_CFG3, 0x0F, 0x0B); -+ -+ /* Update audio infoframe. */ -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_INFOFRAME_UPDATE, 0x20, 0x20); -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_AUDIO_INFOFRAME(0), 0x07, 0x01); -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_AUDIO_INFOFRAME(3), 0x1F, 0x00); -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_INFOFRAME_UPDATE, 0x20, 0x00); -+} -+ -+static void adihdmi_set_colormap(struct adihdmi *adihdmi, bool enable, -+ const uint16_t *coeff, -+ unsigned int scaling_factor) -+{ -+ unsigned int i; -+ -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_CSC_UPPER(1), -+ ADIHDMI_CSC_UPDATE_MODE, ADIHDMI_CSC_UPDATE_MODE); -+ -+ if (enable) { -+ for (i = 0; i < 12; ++i) { -+ regmap_update_bits(adihdmi->regmap, -+ ADIHDMI_REG_CSC_UPPER(i), -+ 0x1f, coeff[i] >> 8); -+ regmap_write(adihdmi->regmap, -+ ADIHDMI_REG_CSC_LOWER(i), -+ coeff[i] & 0xff); -+ } -+ } -+ -+ if (enable) -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_CSC_UPPER(0), -+ 0xe0, 0x80 | (scaling_factor << 5)); -+ else -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_CSC_UPPER(0), -+ 0x80, 0x00); -+ -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_CSC_UPPER(1), -+ ADIHDMI_CSC_UPDATE_MODE, 0); -+} -+ -+static int adihdmi_packet_enable(struct adihdmi *adihdmi, unsigned int packet) -+{ -+ if (packet & 0xff) -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_PACKET_ENABLE0, -+ packet, 0xff); -+ -+ if (packet & 0xff00) { -+ packet >>= 8; -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_PACKET_ENABLE1, -+ packet, 0xff); -+ } -+ -+ return 0; -+} -+ -+static int adihdmi_packet_disable(struct adihdmi *adihdmi, unsigned int packet) -+{ -+ if (packet & 0xff) -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_PACKET_ENABLE0, -+ packet, 0x00); -+ -+ if (packet & 0xff00) { -+ packet >>= 8; -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_PACKET_ENABLE1, -+ packet, 0x00); -+ } -+ -+ return 0; -+} -+ -+/* Coefficients for adihdmi color space conversion */ -+static const uint16_t adihdmi_csc_ycbcr_to_rgb[] = { -+ 0x0734, 0x04ad, 0x0000, 0x1c1b, -+ 0x1ddc, 0x04ad, 0x1f24, 0x0135, -+ 0x0000, 0x04ad, 0x087c, 0x1b77, -+}; -+ -+static void adihdmi_set_config_csc(struct adihdmi *adihdmi, -+ struct drm_connector *connector, -+ bool rgb) -+{ -+ struct adihdmi_video_config config; -+ bool output_format_422, output_format_ycbcr; -+ unsigned int mode; -+ uint8_t infoframe[17]; -+ -+ if (adihdmi->edid) -+ config.hdmi_mode = drm_detect_hdmi_monitor(adihdmi->edid); -+ else -+ config.hdmi_mode = false; -+ -+ hdmi_avi_infoframe_init(&config.avi_infoframe); -+ -+ config.avi_infoframe.scan_mode = HDMI_SCAN_MODE_UNDERSCAN; -+ -+ if (rgb) { -+ config.csc_enable = false; -+ config.avi_infoframe.colorspace = HDMI_COLORSPACE_RGB; -+ } else { -+ config.csc_scaling_factor = ADIHDMI_CSC_SCALING_4; -+ config.csc_coefficents = adihdmi_csc_ycbcr_to_rgb; -+ -+ if ((connector->display_info.color_formats & -+ DRM_COLOR_FORMAT_YCRCB422) && -+ config.hdmi_mode) { -+ config.csc_enable = false; -+ config.avi_infoframe.colorspace = -+ HDMI_COLORSPACE_YUV422; -+ } else { -+ config.csc_enable = true; -+ config.avi_infoframe.colorspace = HDMI_COLORSPACE_RGB; -+ } -+ } -+ -+ if (config.hdmi_mode) { -+ mode = ADIHDMI_HDMI_CFG_MODE_HDMI; -+ -+ switch (config.avi_infoframe.colorspace) { -+ case HDMI_COLORSPACE_YUV444: -+ output_format_422 = false; -+ output_format_ycbcr = true; -+ break; -+ case HDMI_COLORSPACE_YUV422: -+ output_format_422 = true; -+ output_format_ycbcr = true; -+ break; -+ default: -+ output_format_422 = false; -+ output_format_ycbcr = false; -+ break; -+ } -+ } else { -+ mode = ADIHDMI_HDMI_CFG_MODE_DVI; -+ output_format_422 = false; -+ output_format_ycbcr = false; -+ } -+ -+ adihdmi_packet_disable(adihdmi, ADIHDMI_INFOFRAME_PACKETS); -+ -+ adihdmi_set_colormap(adihdmi, config.csc_enable, -+ config.csc_coefficents, -+ config.csc_scaling_factor); -+ -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_VIDEO_INPUT_CFG1, 0x81, -+ (output_format_422 << 7) | output_format_ycbcr); -+ -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_HDCP_HDMI_CFG, -+ ADIHDMI_HDMI_CFG_MODE_MASK, mode); -+ -+ hdmi_avi_infoframe_pack(&config.avi_infoframe, infoframe, -+ sizeof(infoframe)); -+ -+ /* The AVI infoframe id is not configurable */ -+ regmap_bulk_write(adihdmi->regmap, ADIHDMI_REG_AVI_INFOFRAME_VERSION, -+ infoframe + 1, sizeof(infoframe) - 1); -+ -+ adihdmi_packet_enable(adihdmi, ADIHDMI_INFOFRAME_PACKETS); -+} -+ -+static void adihdmi_set_link_config(struct adihdmi *adihdmi, -+ const struct adihdmi_link_config *config) -+{ -+ /* -+ * The input style values documented in the datasheet don't match the -+ * hardware register field values :-( -+ */ -+ static const unsigned int input_styles[4] = { 0, 2, 1, 3 }; -+ -+ unsigned int clock_delay; -+ unsigned int color_depth; -+ unsigned int input_id; -+ -+ clock_delay = (config->clock_delay + 1200) / 400; -+ color_depth = config->input_color_depth == 8 ? 3 -+ : (config->input_color_depth == 10 ? 1 : 2); -+ -+ /* TODO Support input ID 6 */ -+ if (config->input_colorspace != HDMI_COLORSPACE_YUV422) -+ input_id = config->input_clock == ADIHDMI_INPUT_CLOCK_DDR -+ ? 5 : 0; -+ else if (config->input_clock == ADIHDMI_INPUT_CLOCK_DDR) -+ input_id = config->embedded_sync ? 8 : 7; -+ else if (config->input_clock == ADIHDMI_INPUT_CLOCK_2X) -+ input_id = config->embedded_sync ? 4 : 3; -+ else -+ input_id = config->embedded_sync ? 2 : 1; -+ -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_I2C_FREQ_ID_CFG, 0xf, -+ input_id); -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_VIDEO_INPUT_CFG1, 0x7e, -+ (color_depth << 4) | -+ (input_styles[config->input_style] << 2)); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_VIDEO_INPUT_CFG2, -+ config->input_justification << 3); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_TIMING_GEN_SEQ, -+ config->sync_pulse << 2); -+ -+ regmap_write(adihdmi->regmap, 0xba, clock_delay << 5); -+ -+ adihdmi->embedded_sync = config->embedded_sync; -+ adihdmi->hsync_polarity = config->hsync_polarity; -+ adihdmi->vsync_polarity = config->vsync_polarity; -+ adihdmi->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB; -+} -+ -+static void adihdmi_power_on(struct adihdmi *adihdmi) -+{ -+ adihdmi->current_edid_segment = -1; -+ -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_INT(0), -+ ADIHDMI_INT0_EDID_READY); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_INT(1), -+ ADIHDMI_INT1_DDC_ERROR); -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_POWER, -+ ADIHDMI_POWER_POWER_DOWN, 0); -+ -+ /* -+ * Per spec it is allowed to pulse the HDP signal to indicate that the -+ * EDID information has changed. Some monitors do this when they wakeup -+ * from standby or are enabled. When the HDP goes low the adihdmi is -+ * reset and the outputs are disabled which might cause the monitor to -+ * go to standby again. To avoid this we ignore the HDP pin for the -+ * first few seconds after enabling the output. -+ */ -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_POWER2, -+ ADIHDMI_REG_POWER2_HDP_SRC_MASK, -+ ADIHDMI_REG_POWER2_HDP_SRC_NONE); -+ -+ /* -+ * Most of the registers are reset during power down or when HPD is low. -+ */ -+ regcache_sync(adihdmi->regmap); -+ -+ adihdmi->powered = true; -+} -+ -+static void adihdmi_power_off(struct adihdmi *adihdmi) -+{ -+ /* TODO: setup additional power down modes */ -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_POWER, -+ ADIHDMI_POWER_POWER_DOWN, -+ ADIHDMI_POWER_POWER_DOWN); -+ regcache_mark_dirty(adihdmi->regmap); -+ -+ adihdmi->powered = false; -+} -+ -+/* ----------------------------------------------------------------------------- -+ * Interrupt and hotplug detection -+ */ -+ -+static bool adihdmi_hpd(struct adihdmi *adihdmi) -+{ -+ unsigned int irq0; -+ int ret; -+ -+ ret = regmap_read(adihdmi->regmap, ADIHDMI_REG_INT(0), &irq0); -+ if (ret < 0) -+ return false; -+ -+ if (irq0 & ADIHDMI_INT0_HDP) { -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_INT(0), -+ ADIHDMI_INT0_HDP); -+ return true; -+ } -+ -+ return false; -+} -+ -+static int adihdmi_irq_process(struct adihdmi *adihdmi) -+{ -+ unsigned int irq0, irq1; -+ int ret; -+ -+ ret = regmap_read(adihdmi->regmap, ADIHDMI_REG_INT(0), &irq0); -+ if (ret < 0) -+ return ret; -+ -+ ret = regmap_read(adihdmi->regmap, ADIHDMI_REG_INT(1), &irq1); -+ if (ret < 0) -+ return ret; -+ -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_INT(0), irq0); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_INT(1), irq1); -+ -+ if (irq0 & ADIHDMI_INT0_HDP) -+ drm_helper_hpd_irq_event(adihdmi->encoder->dev); -+ -+ if (irq0 & ADIHDMI_INT0_EDID_READY || irq1 & ADIHDMI_INT1_DDC_ERROR) { -+ adihdmi->edid_read = true; -+ -+ if (adihdmi->i2c_main->irq) -+ wake_up_all(&adihdmi->wq); -+ } -+ -+ return 0; -+} -+ -+static irqreturn_t adihdmi_irq_handler(int irq, void *devid) -+{ -+ struct adihdmi *adihdmi = devid; -+ int ret; -+ -+ ret = adihdmi_irq_process(adihdmi); -+ return ret < 0 ? IRQ_NONE : IRQ_HANDLED; -+} -+ -+/* ----------------------------------------------------------------------------- -+ * EDID retrieval -+ */ -+ -+static int adihdmi_wait_for_edid(struct adihdmi *adihdmi, int timeout) -+{ -+ int ret; -+ -+ if (adihdmi->i2c_main->irq) { -+ ret = wait_event_interruptible_timeout(adihdmi->wq, -+ adihdmi->edid_read, msecs_to_jiffies(timeout)); -+ } else { -+ for (; timeout > 0; timeout -= 25) { -+ ret = adihdmi_irq_process(adihdmi); -+ if (ret < 0) -+ break; -+ -+ if (adihdmi->edid_read) -+ break; -+ -+ msleep(25); -+ } -+ } -+ -+ return adihdmi->edid_read ? 0 : -EIO; -+} -+ -+static int adihdmi_get_edid_block(void *data, u8 *buf, unsigned int block, -+ size_t len) -+{ -+ struct adihdmi *adihdmi = data; -+ struct i2c_msg xfer[2]; -+ uint8_t offset; -+ unsigned int i; -+ int ret; -+ -+ if (len > 128) -+ return -EINVAL; -+ -+ if (adihdmi->current_edid_segment != block / 2) { -+ unsigned int status; -+ -+ ret = regmap_read(adihdmi->regmap, ADIHDMI_REG_DDC_STATUS, -+ &status); -+ if (ret < 0) -+ return ret; -+ -+ if (status != 2) { -+ adihdmi->edid_read = false; -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_EDID_SEGMENT, -+ block); -+ ret = adihdmi_wait_for_edid(adihdmi, 200); -+ if (ret < 0) -+ return ret; -+ } -+ -+ /* Break this apart, hopefully more I2C controllers will -+ * support 64 byte transfers than 256 byte transfers -+ */ -+ -+ xfer[0].addr = adihdmi->i2c_edid->addr; -+ xfer[0].flags = 0; -+ xfer[0].len = 1; -+ xfer[0].buf = &offset; -+ xfer[1].addr = adihdmi->i2c_edid->addr; -+ xfer[1].flags = I2C_M_RD; -+ xfer[1].len = 64; -+ xfer[1].buf = adihdmi->edid_buf; -+ -+ offset = 0; -+ -+ for (i = 0; i < 4; ++i) { -+ ret = i2c_transfer(adihdmi->i2c_edid->adapter, xfer, -+ ARRAY_SIZE(xfer)); -+ if (ret < 0) -+ return ret; -+ else if (ret != 2) -+ return -EIO; -+ -+ xfer[1].buf += 64; -+ offset += 64; -+ } -+ -+ adihdmi->current_edid_segment = block / 2; -+ } -+ -+ if (block % 2 == 0) -+ memcpy(buf, adihdmi->edid_buf, len); -+ else -+ memcpy(buf, adihdmi->edid_buf + 128, len); -+ -+ return 0; -+} -+ -+static int adihdmi_mode_valid(struct drm_display_mode *mode) -+{ -+ if (mode->clock > 165000) -+ return MODE_CLOCK_HIGH; -+ -+ return MODE_OK; -+} -+ -+/* ----------------------------------------------------------------------------- -+ * DT and private structure operations -+ */ -+ -+#define conn_to_adihdmi2(x) \ -+ container_of(x, struct adihdmi2, connector); -+ -+#define enc_to_adihdmi2(x) \ -+ container_of(x, struct adihdmi2, encoder); -+ -+#define enc_to_adihdmi(x) \ -+ (&(container_of(x, struct adihdmi2, encoder)->base)) -+ -+static int adihdmi_parse_dt(struct device_node *np, -+ struct adihdmi_link_config *config) -+{ -+ memset(config, 0, sizeof(*config)); -+ -+ config->input_color_depth = 8; -+ -+ config->input_colorspace = HDMI_COLORSPACE_RGB; -+ //config->input_colorspace = HDMI_COLORSPACE_YUV422; -+ //config->input_colorspace = HDMI_COLORSPACE_YUV444; -+ -+ config->input_clock = ADIHDMI_INPUT_CLOCK_1X; -+ //config->input_clock = ADIHDMI_INPUT_CLOCK_2X; -+ //config->input_clock = ADIHDMI_INPUT_CLOCK_DDR; -+ -+ if (config->input_colorspace == HDMI_COLORSPACE_YUV422 || -+ config->input_clock != ADIHDMI_INPUT_CLOCK_1X) { -+ -+ config->input_style = 1; -+ //config->input_justification = ADIHDMI_INPUT_JUSTIFICATION_LEFT; -+ config->input_justification = ADIHDMI_INPUT_JUSTIFICATION_EVENLY; -+ //config->input_justification = ADIHDMI_INPUT_JUSTIFICATION_RIGHT; -+ -+ } else { -+ config->input_style = 1; -+ config->input_justification = ADIHDMI_INPUT_JUSTIFICATION_LEFT; -+ } -+ -+ config->clock_delay = 0; -+ config->embedded_sync = 0; -+ -+ /* Hardcode the sync pulse configurations for now. */ -+ config->sync_pulse = ADIHDMI_INPUT_SYNC_PULSE_NONE; -+ config->vsync_polarity = ADIHDMI_SYNC_POLARITY_PASSTHROUGH; -+ config->hsync_polarity = ADIHDMI_SYNC_POLARITY_PASSTHROUGH; -+ -+ return 0; -+} -+ -+static const int edid_i2c_addr = 0x7e; -+static const int packet_i2c_addr = 0x70; -+static const int cec_i2c_addr = 0x78; -+ -+static int adihdmi_create(struct i2c_client *i2c, struct adihdmi *adihdmi) -+{ -+ struct adihdmi_link_config link_config; -+ struct device *dev = &i2c->dev; -+ unsigned int val; -+ int ret; -+ -+ adihdmi->powered = false; -+ adihdmi->status = connector_status_disconnected; -+ -+ ret = adihdmi_parse_dt(NULL, &link_config); -+ if (ret) -+ { -+ pr_err("%s - %d - Bad parse\n", __FUNCTION__, __LINE__); -+ return -EINVAL; -+ } -+ -+ /* -+ * The power down GPIO is optional. If present, toggle it from active to -+ * inactive to wake up the encoder. -+ */ -+ adihdmi->gpio_pd = devm_gpiod_get_optional(dev, "pd", GPIOD_OUT_HIGH); -+ if (IS_ERR(adihdmi->gpio_pd)) -+ { -+ pr_err("%s - %d - Bad PD GPIO\n", __FUNCTION__, __LINE__); -+ return PTR_ERR(adihdmi->gpio_pd); -+ } -+ -+ if (adihdmi->gpio_pd) { -+ mdelay(5); -+ gpiod_set_value_cansleep(adihdmi->gpio_pd, 0); -+ } -+ -+ adihdmi->regmap = devm_regmap_init_i2c(i2c, &adihdmi_regmap_config); -+ if (IS_ERR(adihdmi->regmap)) -+ { -+ pr_err("%s - %d - Bad reg map init\n", __FUNCTION__, __LINE__); -+ return PTR_ERR(adihdmi->regmap); -+ } -+ -+ ret = regmap_read(adihdmi->regmap, ADIHDMI_REG_CHIP_REVISION, &val); -+ if (ret) -+ { -+ pr_err("%s - %d - Bad reg map read\n", __FUNCTION__, __LINE__); -+ return ret; -+ } -+ dev_dbg(dev, "Rev. %d\n", val); -+ -+ ret = regmap_register_patch(adihdmi->regmap, adihdmi_fixed_registers, -+ ARRAY_SIZE(adihdmi_fixed_registers)); -+ if (ret) -+ { -+ pr_err("%s - %d - Bad reg map patch\n", __FUNCTION__, __LINE__); -+ return ret; -+ } -+ -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_EDID_I2C_ADDR, edid_i2c_addr); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_PACKET_I2C_ADDR, -+ packet_i2c_addr); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_CEC_I2C_ADDR, cec_i2c_addr); -+ adihdmi_packet_disable(adihdmi, 0xffff); -+ -+ adihdmi->i2c_main = i2c; -+ adihdmi->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1); -+ if (!adihdmi->i2c_edid) -+ { -+ pr_err("%s - %d - No mem for EDID\n", __FUNCTION__, __LINE__); -+ return -ENOMEM; -+ } -+ -+ if (i2c->irq) { -+ init_waitqueue_head(&adihdmi->wq); -+ -+ ret = devm_request_threaded_irq(dev, i2c->irq, NULL, -+ adihdmi_irq_handler, -+ IRQF_ONESHOT, dev_name(dev), -+ adihdmi); -+ if (ret) -+ { -+ pr_err("%s - %d - Bad IRQ thread request\n", __FUNCTION__, __LINE__); -+ goto err_i2c_unregister_device; -+ } -+ } -+ -+ /* CEC is unused for now */ -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_CEC_CTRL, -+ ADIHDMI_CEC_CTRL_POWER_DOWN); -+ -+ adihdmi_power_off(adihdmi); -+ -+ adihdmi_set_link_config(adihdmi, &link_config); -+ -+ adihdmi_audio_setup(adihdmi); -+ -+ return 0; -+ -+err_i2c_unregister_device: -+ i2c_unregister_device(adihdmi->i2c_edid); -+ -+ return ret; -+} -+ -+static void adihdmi_destroy(struct adihdmi *priv) -+{ -+ i2c_unregister_device(priv->i2c_edid); -+} -+ -+/* ----------------------------------------------------------------------------- -+ * Encoder operations -+ */ -+ -+static int adihdmi_encoder_get_modes(struct adihdmi *adihdmi, -+ struct drm_connector *connector) -+{ -+ struct edid *edid; -+ unsigned int count; -+ -+ /* Reading the EDID only works if the device is powered */ -+ if (!adihdmi->powered) { -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_INT(0), -+ ADIHDMI_INT0_EDID_READY); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_INT(1), -+ ADIHDMI_INT1_DDC_ERROR); -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_POWER, -+ ADIHDMI_POWER_POWER_DOWN, 0); -+ adihdmi->current_edid_segment = -1; -+ } -+ -+ edid = drm_do_get_edid(connector, adihdmi_get_edid_block, adihdmi); -+ -+ if (!adihdmi->powered) -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_POWER, -+ ADIHDMI_POWER_POWER_DOWN, -+ ADIHDMI_POWER_POWER_DOWN); -+ -+ kfree(adihdmi->edid); -+ adihdmi->edid = edid; -+ if (!edid) -+ { -+ pr_err("%s - %d - No EDID\n", __FUNCTION__, __LINE__); -+ return 0; -+ } -+ -+ drm_mode_connector_update_edid_property(connector, edid); -+ count = drm_add_edid_modes(connector, edid); -+ -+ adihdmi_set_config_csc(adihdmi, connector, adihdmi->rgb); -+ -+ return count; -+} -+ -+static void adihdmi_encoder_dpms(struct drm_encoder *encoder, int mode) -+{ -+ struct adihdmi2 *priv2 = enc_to_adihdmi2(encoder); -+ -+ if (mode == DRM_MODE_DPMS_ON) -+ adihdmi_power_on(&priv2->base); -+ else -+ adihdmi_power_off(&priv2->base); -+} -+ -+ static enum drm_connector_status -+adihdmi_encoder_detect(struct adihdmi *adihdmi, -+ struct drm_connector *connector) -+{ -+ enum drm_connector_status status; -+ unsigned int val; -+ bool hpd; -+ int ret; -+ -+ ret = regmap_read(adihdmi->regmap, ADIHDMI_REG_STATUS, &val); -+ if (ret < 0) -+ { -+ pr_err("%s - %d - Disconnected\n", __FUNCTION__, __LINE__); -+ return connector_status_disconnected; -+ } -+ -+ if (val & ADIHDMI_STATUS_HPD) -+ status = connector_status_connected; -+ else -+ status = connector_status_disconnected; -+ -+ hpd = adihdmi_hpd(adihdmi); -+ -+ /* The chip resets itself when the cable is disconnected, so in case -+ * there is a pending HPD interrupt and the cable is connected there was -+ * at least one transition from disconnected to connected and the chip -+ * has to be reinitialized. */ -+ if (status == connector_status_connected && hpd && adihdmi->powered) { -+ regcache_mark_dirty(adihdmi->regmap); -+ adihdmi_power_on(adihdmi); -+ adihdmi_encoder_get_modes(adihdmi, connector); -+ if (adihdmi->status == connector_status_connected) -+ status = connector_status_disconnected; -+ } else { -+ /* Renable HDP sensing */ -+ regmap_update_bits(adihdmi->regmap, ADIHDMI_REG_POWER2, -+ ADIHDMI_REG_POWER2_HDP_SRC_MASK, -+ ADIHDMI_REG_POWER2_HDP_SRC_BOTH); -+ } -+ -+ adihdmi->status = status; -+ return status; -+} -+ -+static bool adihdmi_encoder_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) -+{ -+ return true; -+} -+ -+static int adihdmi_encoder_mode_valid(struct drm_encoder *encoder, struct drm_display_mode *mode) -+{ -+ return adihdmi_mode_valid(mode); -+} -+ -+static void adihdmi_encoder_mode_set(struct drm_encoder *encoder, -+ struct drm_display_mode *mode, -+ struct drm_display_mode *adj_mode) -+{ -+ unsigned int low_refresh_rate; -+ unsigned int hsync_polarity = 0; -+ unsigned int vsync_polarity = 0; -+ struct adihdmi *adihdmi = enc_to_adihdmi(encoder); -+ -+ if (adihdmi->embedded_sync) { -+ unsigned int hsync_offset, hsync_len; -+ unsigned int vsync_offset, vsync_len; -+ -+ hsync_offset = adj_mode->crtc_hsync_start - -+ adj_mode->crtc_hdisplay; -+ vsync_offset = adj_mode->crtc_vsync_start - -+ adj_mode->crtc_vdisplay; -+ hsync_len = adj_mode->crtc_hsync_end - -+ adj_mode->crtc_hsync_start; -+ vsync_len = adj_mode->crtc_vsync_end - -+ adj_mode->crtc_vsync_start; -+ -+ /* The hardware vsync generator has a off-by-one bug */ -+ vsync_offset += 1; -+ -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_HSYNC_PLACEMENT_MSB, -+ ((hsync_offset >> 10) & 0x7) << 5); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_SYNC_DECODER(0), -+ (hsync_offset >> 2) & 0xff); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_SYNC_DECODER(1), -+ ((hsync_offset & 0x3) << 6) | -+ ((hsync_len >> 4) & 0x3f)); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_SYNC_DECODER(2), -+ ((hsync_len & 0xf) << 4) | -+ ((vsync_offset >> 6) & 0xf)); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_SYNC_DECODER(3), -+ ((vsync_offset & 0x3f) << 2) | -+ ((vsync_len >> 8) & 0x3)); -+ regmap_write(adihdmi->regmap, ADIHDMI_REG_SYNC_DECODER(4), -+ vsync_len & 0xff); -+ -+ hsync_polarity = !(adj_mode->flags & DRM_MODE_FLAG_PHSYNC); -+ vsync_polarity = !(adj_mode->flags & DRM_MODE_FLAG_PVSYNC); -+ } else { -+ enum adihdmi_sync_polarity mode_hsync_polarity; -+ enum adihdmi_sync_polarity mode_vsync_polarity; -+ -+ /** -+ * If the input signal is always low or always high we want to -+ * invert or let it passthrough depending on the polarity of the -+ * current mode. -+ **/ -+ if (adj_mode->flags & DRM_MODE_FLAG_NHSYNC) -+ mode_hsync_polarity = ADIHDMI_SYNC_POLARITY_LOW; -+ else -+ mode_hsync_polarity = ADIHDMI_SYNC_POLARITY_HIGH; -+ -+ if (adj_mode->flags & DRM_MODE_FLAG_NVSYNC) -+ mode_vsync_polarity = ADIHDMI_SYNC_POLARITY_LOW; -+ else -+ mode_vsync_polarity = ADIHDMI_SYNC_POLARITY_HIGH; -+ -+ if (adihdmi->hsync_polarity != mode_hsync_polarity && -+ adihdmi->hsync_polarity != -+ ADIHDMI_SYNC_POLARITY_PASSTHROUGH) -+ hsync_polarity = 1; -+ -+ if (adihdmi->vsync_polarity != mode_vsync_polarity && -+ adihdmi->vsync_polarity != -+ ADIHDMI_SYNC_POLARITY_PASSTHROUGH) -+ vsync_polarity = 1; -+ } -+ -+ if (mode->vrefresh <= 24000) -+ low_refresh_rate = ADIHDMI_LOW_REFRESH_RATE_24HZ; -+ else if (mode->vrefresh <= 25000) -+ low_refresh_rate = ADIHDMI_LOW_REFRESH_RATE_25HZ; -+ else if (mode->vrefresh <= 30000) -+ low_refresh_rate = ADIHDMI_LOW_REFRESH_RATE_30HZ; -+ else -+ low_refresh_rate = ADIHDMI_LOW_REFRESH_RATE_NONE; -+ -+ regmap_update_bits(adihdmi->regmap, 0xfb, -+ 0x6, low_refresh_rate << 1); -+ regmap_update_bits(adihdmi->regmap, 0x17, -+ 0x60, (vsync_polarity << 6) | (hsync_polarity << 5)); -+ -+ /* -+ * TODO Test first order 4:2:2 to 4:4:4 up conversion method, which is -+ * supposed to give better results. -+ */ -+ -+ adihdmi->f_tmds = mode->clock; -+} -+ -+static void adihdmi_encoder_prepare(struct drm_encoder *encoder) -+{ -+ adihdmi_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); -+} -+ -+static void adihdmi_encoder_commit(struct drm_encoder *encoder) -+{ -+ adihdmi_encoder_dpms(encoder, DRM_MODE_DPMS_ON); -+} -+ -+static struct drm_encoder_helper_funcs adihdmi_encoder_helper_funcs = { -+ .dpms = adihdmi_encoder_dpms, -+ .mode_fixup = adihdmi_encoder_mode_fixup, -+ .prepare = adihdmi_encoder_prepare, -+ .commit = adihdmi_encoder_commit, -+ .mode_set = adihdmi_encoder_mode_set, -+}; -+ -+static void adihdmi_encoder_destroy(struct drm_encoder *encoder) -+{ -+ struct adihdmi2 *priv = enc_to_adihdmi2(encoder); -+ -+ adihdmi_destroy(&priv->base); -+ drm_encoder_cleanup(encoder); -+} -+ -+static const struct drm_encoder_funcs adihdmi_encoder_funcs = { -+ .destroy = adihdmi_encoder_destroy, -+}; -+ -+/* ----------------------------------------------------------------------------- -+ * Slave operations -+ */ -+ -+static int adihdmi_encoder_slave_create_resources(struct drm_encoder *encoder, struct drm_connector *connector) -+{ -+ pr_debug("%s - %d\n", __FUNCTION__, __LINE__); -+ return 0; -+} -+ -+static void adihdmi_encoder_slave_destroy(struct drm_encoder *encoder) -+{ -+ pr_debug("%s - %d\n", __FUNCTION__, __LINE__); -+} -+ -+ static enum drm_connector_status -+adihdmi_encoder_slave_detect(struct drm_encoder *encoder, -+ struct drm_connector *connector) -+{ -+ return adihdmi_encoder_detect(enc_to_adihdmi(encoder), -+ connector); -+} -+ -+static int adihdmi_encoder_slave_get_modes(struct drm_encoder *encoder, -+ struct drm_connector *connector) -+{ -+ return adihdmi_encoder_get_modes(enc_to_adihdmi(encoder), -+ connector); -+} -+ -+ -+static void adihdmi_encoder_slave_set_config(struct drm_encoder *encoder, void *params) -+{ -+ pr_debug("%s - %d\n", __FUNCTION__, __LINE__); -+} -+ -+static int adihdmi_encoder_set_property(struct drm_encoder *encoder, struct drm_connector *connector, struct drm_property *property, uint64_t val) -+{ -+ pr_debug("%s - %d\n", __FUNCTION__, __LINE__); -+ return 0; -+} -+ -+static struct drm_encoder_slave_funcs adihdmi_encoder_slave_funcs = { -+ .create_resources = adihdmi_encoder_slave_create_resources, -+ .destroy = adihdmi_encoder_slave_destroy, -+ .detect = adihdmi_encoder_slave_detect, -+ .dpms = adihdmi_encoder_dpms, -+ .get_modes = adihdmi_encoder_slave_get_modes, -+ .mode_fixup = adihdmi_encoder_mode_fixup, -+ .mode_set = adihdmi_encoder_mode_set, -+ .mode_valid = adihdmi_encoder_mode_valid, -+ .set_config = adihdmi_encoder_slave_set_config, -+ .set_property = adihdmi_encoder_set_property, -+}; -+ -+/* ----------------------------------------------------------------------------- -+ * Connector operations -+ */ -+ -+static int adihdmi_connector_get_modes(struct drm_connector *connector) -+{ -+ struct adihdmi2 *priv = conn_to_adihdmi2(connector); -+ -+ return adihdmi_encoder_get_modes(&priv->base, connector); -+} -+ -+static int adihdmi_connector_mode_valid(struct drm_connector *connector, -+ struct drm_display_mode *mode) -+{ -+ return adihdmi_mode_valid(mode); -+} -+ -+ static struct drm_encoder * -+adihdmi_connector_best_encoder(struct drm_connector *connector) -+{ -+ struct adihdmi2 *priv = conn_to_adihdmi2(connector); -+ -+ return &priv->encoder; -+} -+ -+static struct drm_connector_helper_funcs adihdmi_connector_helper_funcs = { -+ .get_modes = adihdmi_connector_get_modes, -+ .mode_valid = adihdmi_connector_mode_valid, -+ .best_encoder = adihdmi_connector_best_encoder, -+}; -+ -+ static enum drm_connector_status -+adihdmi_connector_detect(struct drm_connector *connector, bool force) -+{ -+ struct adihdmi2 *priv = conn_to_adihdmi2(connector); -+ -+ return adihdmi_encoder_detect(&priv->base, connector); -+} -+ -+static void adihdmi_connector_destroy(struct drm_connector *connector) -+{ -+ drm_connector_unregister(connector); -+ drm_connector_cleanup(connector); -+} -+ -+static struct drm_connector_funcs adihdmi_connector_funcs = { -+ .dpms = drm_helper_connector_dpms, -+ .fill_modes = drm_helper_probe_single_connector_modes, -+ .detect = adihdmi_connector_detect, -+ .destroy = adihdmi_connector_destroy, -+}; -+ -+/* ----------------------------------------------------------------------------- -+ * Component operations -+ */ -+ -+static int adihdmi_bind(struct device *dev, struct device *master, void *data) -+{ -+ struct i2c_client *client = to_i2c_client(dev); -+ struct drm_device *drm = data; -+ struct adihdmi2 *priv; -+ uint32_t crtcs = 0; -+ int ret; -+ -+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); -+ if (!priv) -+ { -+ pr_err("%s - %d - No memory for ADIHDMI\n", __FUNCTION__, __LINE__); -+ return -ENOMEM; -+ } -+ -+ dev_set_drvdata(dev, priv); -+ -+ if (dev->of_node) -+ crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); -+ -+ /* If no CRTCs were found, fall back to our old behaviour */ -+ if (crtcs == 0) { -+ dev_warn(dev, "Falling back to first CRTC\n"); -+ crtcs = 1 << 0; -+ } -+ -+ priv->base.encoder = &priv->encoder; -+ priv->connector.interlace_allowed = 1; -+ priv->encoder.possible_crtcs = crtcs; -+ -+ ret = adihdmi_create(client, &priv->base); -+ if (ret) -+ return ret; -+ -+ drm_encoder_helper_add(&priv->encoder, &adihdmi_encoder_helper_funcs); -+ ret = drm_encoder_init(drm, &priv->encoder, &adihdmi_encoder_funcs, -+ DRM_MODE_ENCODER_TMDS, NULL); -+ if (ret) -+ goto err_encoder; -+ -+ drm_connector_helper_add(&priv->connector, -+ &adihdmi_connector_helper_funcs); -+ ret = drm_connector_init(drm, &priv->connector, -+ &adihdmi_connector_funcs, -+ DRM_MODE_CONNECTOR_HDMIA); -+ if (ret) -+ goto err_connector; -+ -+ ret = drm_connector_register(&priv->connector); -+ if (ret) -+ goto err_sysfs; -+ -+ priv->connector.encoder = &priv->encoder; -+ drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); -+ -+ return 0; -+ -+err_sysfs: -+ drm_connector_cleanup(&priv->connector); -+err_connector: -+ drm_encoder_cleanup(&priv->encoder); -+err_encoder: -+ adihdmi_destroy(&priv->base); -+ return ret; -+ -+ -+} -+ -+static void adihdmi_unbind(struct device *dev, struct device *master, void *data) -+{ -+ struct adihdmi2 *priv = dev_get_drvdata(dev); -+ -+ drm_connector_cleanup(&priv->connector); -+ drm_encoder_cleanup(&priv->encoder); -+ adihdmi_destroy(&priv->base); -+} -+ -+static const struct component_ops adihdmi_ops = -+{ -+ .bind = adihdmi_bind, -+ .unbind = adihdmi_unbind, -+}; -+ -+/* ----------------------------------------------------------------------------- -+ * Init operations -+ */ -+ -+static int adihdmi_probe(struct i2c_client *i2c, const struct i2c_device_id *id) -+{ -+ return component_add(&i2c->dev, &adihdmi_ops); -+} -+ -+static int adihdmi_remove(struct i2c_client *i2c) -+{ -+ component_del(&i2c->dev, &adihdmi_ops); -+ -+ return 0; -+} -+ -+static int adihdmi_encoder_init(struct i2c_client *i2c, struct drm_device *dev, -+ struct drm_encoder_slave *encoder_slave) -+{ -+ -+ struct adihdmi *adihdmi; -+ int ret; -+ -+ adihdmi = kzalloc(sizeof(*adihdmi), GFP_KERNEL); -+ if (!adihdmi) -+ return -ENOMEM; -+ -+ adihdmi->encoder = &encoder_slave->base; -+ -+ ret = adihdmi_create(i2c, adihdmi); -+ if (ret) { -+ kfree(adihdmi); -+ return ret; -+ } -+ -+ encoder_slave->slave_priv = adihdmi; -+ encoder_slave->slave_funcs = &adihdmi_encoder_slave_funcs; -+ -+ return 0; -+} -+ -+static const struct i2c_device_id adihdmi_i2c_ids[] = { -+ { "adv7511", 0 }, -+ { "adv7511w", 0 }, -+ { "adv7513", 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, adihdmi_i2c_ids); -+ -+static const struct of_device_id adihdmi_of_ids[] = { -+ { .compatible = "adi,adv7511", }, -+ { .compatible = "adi,adv7511w", }, -+ { .compatible = "adi,adv7513", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, adihdmi_of_ids); -+ -+static struct drm_i2c_encoder_driver adihdmi_driver = { -+ .i2c_driver = { -+ .driver = { -+ .name = "adihdmi", -+ .of_match_table = adihdmi_of_ids, -+ }, -+ .id_table = adihdmi_i2c_ids, -+ .probe = adihdmi_probe, -+ .remove = adihdmi_remove, -+ }, -+ -+ .encoder_init = adihdmi_encoder_init, -+}; -+ -+static int __init adihdmi_init(void) -+{ -+ return drm_i2c_encoder_register(THIS_MODULE, &adihdmi_driver); -+} -+module_init(adihdmi_init); -+ -+static void __exit adihdmi_exit(void) -+{ -+ drm_i2c_encoder_unregister(&adihdmi_driver); -+} -+module_exit(adihdmi_exit); -+ -+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); -+MODULE_DESCRIPTION("ADIHDMI HDMI transmitter driver"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c -index 46855c8..d189426 100644 ---- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c -+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c -@@ -234,25 +234,30 @@ static int tpd_probe(struct platform_device *pdev) - if (r) - return r; - -- - gpio = devm_gpiod_get_index_optional(&pdev->dev, NULL, 0, - GPIOD_OUT_LOW); -- if (IS_ERR(gpio)) -+ if (IS_ERR(gpio)) { -+ r = PTR_ERR(gpio); - goto err_gpio; -+ } - - ddata->ct_cp_hpd_gpio = gpio; - - gpio = devm_gpiod_get_index_optional(&pdev->dev, NULL, 1, - GPIOD_OUT_LOW); -- if (IS_ERR(gpio)) -+ if (IS_ERR(gpio)) { -+ r = PTR_ERR(gpio); - goto err_gpio; -+ } - - ddata->ls_oe_gpio = gpio; - - gpio = devm_gpiod_get_index(&pdev->dev, NULL, 2, - GPIOD_IN); -- if (IS_ERR(gpio)) -+ if (IS_ERR(gpio)) { -+ r = PTR_ERR(gpio); - goto err_gpio; -+ } - - ddata->hpd_gpio = gpio; - -diff --git a/drivers/input/misc/tps65218-pwrbutton.c b/drivers/input/misc/tps65218-pwrbutton.c -index 3273217..6f26022 100644 ---- a/drivers/input/misc/tps65218-pwrbutton.c -+++ b/drivers/input/misc/tps65218-pwrbutton.c -@@ -36,7 +36,7 @@ struct tps6521x_data { - static const struct tps6521x_data tps65217_data = { - .reg_status = TPS65217_REG_STATUS, - .pb_mask = TPS65217_STATUS_PB, -- .name = "tps65217_pwrbutton", -+ .name = "tps65217_pwr_but", - }; - - static const struct tps6521x_data tps65218_data = { -diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig -index 64971ba..0fbd1c5 100644 ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -766,6 +766,36 @@ config PANEL_BOOT_MESSAGE - An empty message will only clear the display at driver init time. Any other - printf()-formatted message is valid with newline and escape codes. - -+config BONE_CAPEMGR -+ tristate "Beaglebone cape manager" -+ depends on ARCH_OMAP2PLUS && OF -+ select EEPROM -+ select OF_OVERLAY -+ help -+ Say Y here to include support for automatic loading of -+ beaglebone capes. Select M to build as a module which -+ will be named bone_capemgr. -+ -+config DEV_OVERLAYMGR -+ tristate "Device overlay manager" -+ depends on OF -+ select OF_OVERLAY -+ default n -+ help -+ Say Y here to include support for the automagical dev -+ overlay manager. -+ -+config TIEQEP -+ tristate "EQEP Hardware quadrature encoder controller" -+ depends on SOC_AM33XX -+ select PWM_TIPWMSS -+ help -+ Driver support for the EQEP quadrature encoder controller AM33XX -+ TI SOC -+ -+ To compile this driver as a module, choose M here: the module -+ will be called tieqep. -+ - source "drivers/misc/c2port/Kconfig" - source "drivers/misc/eeprom/Kconfig" - source "drivers/misc/cb710/Kconfig" -@@ -775,7 +805,9 @@ source "drivers/misc/altera-stapl/Kconfig" - source "drivers/misc/mei/Kconfig" - source "drivers/misc/vmw_vmci/Kconfig" - source "drivers/misc/mic/Kconfig" -+source "drivers/misc/cape_bone_argus/Kconfig" - source "drivers/misc/genwqe/Kconfig" -+source "drivers/misc/cape/Kconfig" - source "drivers/misc/echo/Kconfig" - source "drivers/misc/cxl/Kconfig" - endmenu -diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile -index 3198336..7fc8cfd 100644 ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -48,11 +48,16 @@ obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ - obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o - obj-$(CONFIG_SRAM) += sram.o - obj-y += mic/ -+obj-y += cape_bone_argus/ - obj-$(CONFIG_GENWQE) += genwqe/ -+obj-y += cape/ - obj-$(CONFIG_ECHO) += echo/ - obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o - obj-$(CONFIG_CXL_BASE) += cxl/ - obj-$(CONFIG_PANEL) += panel.o -+obj-$(CONFIG_TIEQEP) += tieqep.o -+obj-$(CONFIG_BONE_CAPEMGR) += bone_capemgr.o -+obj-$(CONFIG_DEV_OVERLAYMGR) += devovmgr.o - - lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o - lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o -diff --git b/drivers/misc/bone_capemgr.c b/drivers/misc/bone_capemgr.c -new file mode 100644 -index 0000000..78c5f44 ---- /dev/null -+++ b/drivers/misc/bone_capemgr.c -@@ -0,0 +1,1898 @@ -+/* -+ * TI Beaglebone cape manager -+ * -+ * Copyright (C) 2012 Texas Instruments Inc. -+ * Copyright (C) 2012-2015 Konsulko Group. -+ * Author: Pantelis Antoniou <pantelis.antoniou@konsulko.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/module.h> -+#include <linux/delay.h> -+#include <linux/err.h> -+#include <linux/interrupt.h> -+#include <linux/completion.h> -+#include <linux/platform_device.h> -+#include <linux/clk.h> -+#include <linux/io.h> -+#include <linux/of.h> -+#include <linux/of_device.h> -+#include <linux/of_fdt.h> -+#include <linux/slab.h> -+#include <linux/pm_runtime.h> -+#include <linux/pinctrl/consumer.h> -+#include <linux/firmware.h> -+#include <linux/err.h> -+#include <linux/ctype.h> -+#include <linux/string.h> -+#include <linux/memory.h> -+#include <linux/kthread.h> -+#include <linux/wait.h> -+#include <linux/file.h> -+#include <linux/fs.h> -+#include <linux/nvmem-consumer.h> -+ -+/* disabled capes */ -+static char *disable_partno; -+module_param(disable_partno, charp, 0444); -+MODULE_PARM_DESC(disable_partno, -+ "Comma delimited list of PART-NUMBER[:REV] of disabled capes"); -+ -+/* enable capes */ -+static char *enable_partno; -+module_param(enable_partno, charp, 0444); -+MODULE_PARM_DESC(enable_partno, -+ "Comma delimited list of PART-NUMBER[:REV] of enabled capes"); -+ -+/* delay to scan on boot until rootfs appears */ -+static int boot_scan_period = 1000; -+module_param(boot_scan_period, int, 0444); -+MODULE_PARM_DESC(boot_scan_period, -+ "boot scan period until rootfs firmware is available"); -+ -+static int uboot_capemgr_enabled = 0; -+module_param(uboot_capemgr_enabled, int, 0444); -+MODULE_PARM_DESC(uboot_capemgr_enabled, -+ "U-Boot Cape Manager is enabled (0=Kernel Cape Manager [default], 1=Disable Kernel Cape Manager)"); -+ -+struct capemgr_info; -+ -+struct slot_ee_attribute { -+ struct device_attribute devattr; -+ unsigned int field; -+ struct bone_cape_slot *slot; /* this is filled when instantiated */ -+}; -+#define to_slot_ee_attribute(x) \ -+ container_of((x), struct slot_ee_attribute, devattr) -+ -+struct bbrd_ee_attribute { -+ struct device_attribute devattr; -+ unsigned int field; -+}; -+#define to_bbrd_ee_attribute(x) \ -+ container_of((x), struct bbrd_ee_attribute, devattr) -+ -+struct bone_cape_slot { -+ struct list_head node; -+ struct capemgr_info *info; -+ int slotno; -+ struct nvmem_cell *nvmem_cell; -+ -+ char text_id[256]; -+ char signature[256]; -+ /* quick access */ -+ char board_name[32+1]; -+ char version[4+1]; -+ char manufacturer[16+1]; -+ char part_number[16+1]; -+ -+ /* attribute group */ -+ char *ee_attr_name; -+ int ee_attrs_count; -+ struct slot_ee_attribute *ee_attrs; -+ struct attribute **ee_attrs_tab; -+ struct attribute_group attrgroup; -+ -+ /* state flags */ -+ unsigned int probed : 1; -+ unsigned int probe_failed : 1; -+ unsigned int override : 1; -+ unsigned int loading : 1; -+ unsigned int loaded : 1; -+ unsigned int retry_loading : 1; -+ unsigned int disabled : 1; -+ -+ char *dtbo; -+ const struct firmware *fw; -+ struct device_node *overlay; -+ int overlay_id; -+ -+ /* loader thread */ -+ struct task_struct *loader_thread; -+ -+ /* load priority */ -+ int priority; -+}; -+ -+struct bone_baseboard { -+ -+ /* from the matched boardmap node */ -+ char *compatible_name; -+ -+ /* filled in by reading the eeprom */ -+ char signature[256]; -+ char text_id[64+1]; -+ -+ /* quick access */ -+ char board_name[8+1]; -+ char revision[4+1]; -+ char serial_number[12+1]; -+ -+ /* access to the eeprom */ -+ struct nvmem_cell *nvmem_cell; -+}; -+ -+struct capemgr_info { -+ struct platform_device *pdev; -+ -+ atomic_t next_slot_nr; -+ struct list_head slot_list; -+ struct mutex slots_list_mutex; -+ -+ /* baseboard EEPROM data */ -+ struct bone_baseboard baseboard; -+ -+ /* wait queue for keeping the priorities straight */ -+ wait_queue_head_t load_wq; -+}; -+ -+static int bone_slot_fill_override(struct bone_cape_slot *slot, -+ const char *part_number, const char *version); -+static struct bone_cape_slot *capemgr_add_slot( -+ struct capemgr_info *info, const char *slot_name, -+ const char *part_number, const char *version, int prio); -+static int capemgr_remove_slot_no_lock(struct bone_cape_slot *slot); -+static int capemgr_remove_slot(struct bone_cape_slot *slot); -+static int capemgr_load_slot(struct bone_cape_slot *slot); -+static int capemgr_unload_slot(struct bone_cape_slot *slot); -+ -+/* baseboard EEPROM field definition */ -+#define BBRD_EE_FIELD_HEADER 0 -+#define BBRD_EE_FIELD_BOARD_NAME 1 -+#define BBRD_EE_FIELD_REVISION 2 -+#define BBRD_EE_FIELD_SERIAL_NUMBER 3 -+#define BBRD_EE_FIELD_CONFIG_OPTION 4 -+#define BBRD_EE_FILED_RSVD1 5 -+#define BBRD_EE_FILED_RSVD2 6 -+#define BBRD_EE_FILED_RSVD3 7 -+ -+/* cape EEPROM field definitions */ -+#define CAPE_EE_FIELD_HEADER 0 -+#define CAPE_EE_FIELD_EEPROM_REV 1 -+#define CAPE_EE_FIELD_BOARD_NAME 2 -+#define CAPE_EE_FIELD_VERSION 3 -+#define CAPE_EE_FIELD_MANUFACTURER 4 -+#define CAPE_EE_FIELD_PART_NUMBER 5 -+#define CAPE_EE_FIELD_NUMBER_OF_PINS 6 -+#define CAPE_EE_FIELD_SERIAL_NUMBER 7 -+#define CAPE_EE_FIELD_PIN_USAGE 8 -+#define CAPE_EE_FIELD_VDD_3V3EXP 9 -+#define CAPE_EE_FIELD_VDD_5V 10 -+#define CAPE_EE_FIELD_SYS_5V 11 -+#define CAPE_EE_FIELD_DC_SUPPLIED 12 -+#define CAPE_EE_FIELD_FIELDS_NR 13 -+ -+#define EE_FIELD_MAKE_HEADER(p) \ -+ ({ \ -+ const u8 *_p = (p); \ -+ (((u32)_p[0] << 24) | ((u32)_p[1] << 16) | \ -+ ((u32)_p[2] << 8) | (u32)_p[3]); \ -+ }) -+ -+#define EE_FIELD_HEADER_VALID 0xaa5533ee -+ -+struct ee_field { -+ const char *name; -+ int start; -+ int size; -+ unsigned int ascii : 1; -+ unsigned int strip_trailing_dots : 1; -+ const char *override; -+}; -+ -+/* baseboard EEPROM definitions */ -+static const struct ee_field bbrd_sig_fields[] = { -+ [BBRD_EE_FIELD_HEADER] = { -+ .name = "header", -+ .start = 0, -+ .size = 4, -+ .ascii = 0, -+ .override = "\xaa\x55\x33\xee", /* AA 55 33 EE */ -+ }, -+ [BBRD_EE_FIELD_BOARD_NAME] = { -+ .name = "board-name", -+ .start = 4, -+ .size = 8, -+ .ascii = 1, -+ .strip_trailing_dots = 1, -+ .override = "Board Name", -+ }, -+ [BBRD_EE_FIELD_REVISION] = { -+ .name = "revision", -+ .start = 12, -+ .size = 4, -+ .ascii = 1, -+ .override = "00A0", -+ }, -+ [BBRD_EE_FIELD_SERIAL_NUMBER] = { -+ .name = "serial-number", -+ .start = 16, -+ .size = 12, -+ .ascii = 1, -+ .override = "0000000000", -+ }, -+ [BBRD_EE_FIELD_CONFIG_OPTION] = { -+ .name = "config-option", -+ .start = 28, -+ .size = 32, -+ }, -+}; -+ -+/* cape EEPROM definitions */ -+static const struct ee_field cape_sig_fields[] = { -+ [CAPE_EE_FIELD_HEADER] = { -+ .name = "header", -+ .start = 0, -+ .size = 4, -+ .ascii = 0, -+ .override = "\xaa\x55\x33\xee", /* AA 55 33 EE */ -+ }, -+ [CAPE_EE_FIELD_EEPROM_REV] = { -+ .name = "eeprom-format-revision", -+ .start = 4, -+ .size = 2, -+ .ascii = 1, -+ .override = "A0", -+ }, -+ [CAPE_EE_FIELD_BOARD_NAME] = { -+ .name = "board-name", -+ .start = 6, -+ .size = 32, -+ .ascii = 1, -+ .strip_trailing_dots = 1, -+ .override = "Override Board Name", -+ }, -+ [CAPE_EE_FIELD_VERSION] = { -+ .name = "version", -+ .start = 38, -+ .size = 4, -+ .ascii = 1, -+ .override = "00A0", -+ }, -+ [CAPE_EE_FIELD_MANUFACTURER] = { -+ .name = "manufacturer", -+ .start = 42, -+ .size = 16, -+ .ascii = 1, -+ .strip_trailing_dots = 1, -+ .override = "Override Manuf", -+ }, -+ [CAPE_EE_FIELD_PART_NUMBER] = { -+ .name = "part-number", -+ .start = 58, -+ .size = 16, -+ .ascii = 1, -+ .strip_trailing_dots = 1, -+ .override = "Override Part#", -+ }, -+ [CAPE_EE_FIELD_NUMBER_OF_PINS] = { -+ .name = "number-of-pins", -+ .start = 74, -+ .size = 2, -+ .ascii = 0, -+ .override = NULL, -+ }, -+ [CAPE_EE_FIELD_SERIAL_NUMBER] = { -+ .name = "serial-number", -+ .start = 76, -+ .size = 12, -+ .ascii = 1, -+ .override = "0000000000", -+ }, -+ [CAPE_EE_FIELD_PIN_USAGE] = { -+ .name = "pin-usage", -+ .start = 88, -+ .size = 140, -+ .ascii = 0, -+ .override = NULL, -+ }, -+ [CAPE_EE_FIELD_VDD_3V3EXP] = { -+ .name = "vdd-3v3exp", -+ .start = 228, -+ .size = 2, -+ .ascii = 0, -+ .override = NULL, -+ }, -+ [CAPE_EE_FIELD_VDD_5V] = { -+ .name = "vdd-5v", -+ .start = 230, -+ .size = 2, -+ .ascii = 0, -+ .override = NULL, -+ }, -+ [CAPE_EE_FIELD_SYS_5V] = { -+ .name = "sys-5v", -+ .start = 232, -+ .size = 2, -+ .ascii = 0, -+ .override = NULL, -+ }, -+ [CAPE_EE_FIELD_DC_SUPPLIED] = { -+ .name = "dc-supplied", -+ .start = 234, -+ .size = 2, -+ .ascii = 0, -+ .override = NULL, -+ }, -+}; -+ -+static char *ee_field_get(const struct ee_field *sig_field, -+ const void *data, int field, char *buf, int bufsz) -+{ -+ int len; -+ -+ /* enough space? */ -+ if (bufsz < sig_field->size + sig_field->ascii) -+ return NULL; -+ -+ memcpy(buf, (char *)data + sig_field->start, sig_field->size); -+ -+ /* terminate ascii field */ -+ if (sig_field->ascii) -+ buf[sig_field->size] = '\0'; -+ -+ if (sig_field->strip_trailing_dots) { -+ len = strlen(buf); -+ while (len > 1 && buf[len - 1] == '.') -+ buf[--len] = '\0'; -+ } -+ -+ return buf; -+} -+ -+char *bbrd_ee_field_get(const void *data, -+ int field, char *buf, int bufsz) -+{ -+ if ((unsigned int)field >= ARRAY_SIZE(bbrd_sig_fields)) -+ return NULL; -+ -+ return ee_field_get(&bbrd_sig_fields[field], data, field, buf, bufsz); -+} -+ -+char *cape_ee_field_get(const void *data, -+ int field, char *buf, int bufsz) -+{ -+ if ((unsigned int)field >= ARRAY_SIZE(cape_sig_fields)) -+ return NULL; -+ -+ return ee_field_get(&cape_sig_fields[field], data, field, buf, bufsz); -+} -+ -+#ifdef CONFIG_OF -+static const struct of_device_id capemgr_of_match[] = { -+ { -+ .compatible = "ti,bone-capemgr", -+ }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, capemgr_of_match); -+ -+#endif -+ -+static int bone_baseboard_scan(struct bone_baseboard *bbrd) -+{ -+ struct capemgr_info *info = container_of(bbrd, -+ struct capemgr_info, baseboard); -+ const u8 *p; -+ int ret; -+ size_t len; -+ -+ p = nvmem_cell_read(bbrd->nvmem_cell, &len); -+ if (IS_ERR(p)) { -+ ret = PTR_ERR(p); -+ dev_err(&info->pdev->dev, -+ "Cannot read cell (ret=%d)\n", ret); -+ return ret; -+ } -+ if (len < sizeof(bbrd->signature)) { -+ dev_info(&info->pdev->dev, -+ "Short read %d (should be >= %d bytes)\n", -+ len, sizeof(bbrd->signature)); -+ return -EINVAL; -+ } -+ memcpy(bbrd->signature, p, sizeof(bbrd->signature)); -+ -+ p = bbrd->signature; -+ if (EE_FIELD_MAKE_HEADER(p) != EE_FIELD_HEADER_VALID) { -+ dev_err(&info->pdev->dev, "Invalid board signature '%08x'\n", -+ EE_FIELD_MAKE_HEADER(p)); -+ return -ENODEV; -+ } -+ -+ bbrd_ee_field_get(bbrd->signature, -+ BBRD_EE_FIELD_BOARD_NAME, -+ bbrd->board_name, sizeof(bbrd->board_name)); -+ bbrd_ee_field_get(bbrd->signature, -+ BBRD_EE_FIELD_REVISION, -+ bbrd->revision, sizeof(bbrd->revision)); -+ bbrd_ee_field_get(bbrd->signature, -+ BBRD_EE_FIELD_SERIAL_NUMBER, -+ bbrd->serial_number, sizeof(bbrd->serial_number)); -+ -+ /* board_name,version,manufacturer,part_number */ -+ snprintf(bbrd->text_id, sizeof(bbrd->text_id) - 1, -+ "%s,%s,%s", bbrd->board_name, bbrd->revision, -+ bbrd->serial_number); -+ -+ /* terminate always */ -+ bbrd->text_id[sizeof(bbrd->text_id) - 1] = '\0'; -+ -+ return 0; -+} -+ -+static int bone_slot_scan(struct bone_cape_slot *slot) -+{ -+ struct capemgr_info *info = slot->info; -+ const u8 *p; -+ int r; -+ ssize_t len; -+ -+ /* need to read EEPROM? */ -+ if (slot->probed) -+ goto slot_fail_check; -+ -+ if (uboot_capemgr_enabled) -+ goto slot_fail_check; -+ -+ slot->probed = 1; -+ -+ if (!slot->override) { -+ -+ p = nvmem_cell_read(slot->nvmem_cell, &len); -+ if (IS_ERR(p)) { -+ r = PTR_ERR(p); -+ slot->probe_failed = 1; -+ -+ /* timeout is normal when no cape is present */ -+ if (r != -ETIMEDOUT) -+ dev_err(&info->pdev->dev, -+ "Cannot read cell (ret=%d)\n", r); -+ return r; -+ } -+ if (len < sizeof(slot->signature)) { -+ dev_info(&info->pdev->dev, -+ "Short read %d (should be >= %d bytes)\n", -+ len, sizeof(slot->signature)); -+ return -EINVAL; -+ } -+ memcpy(slot->signature, p, sizeof(slot->signature)); -+ -+ } else -+ dev_info(&info->pdev->dev, -+ "Using override eeprom data at slot %d\n", -+ slot->slotno); -+ -+ p = slot->signature; -+ if (EE_FIELD_MAKE_HEADER(p) != EE_FIELD_HEADER_VALID) { -+ dev_err(&info->pdev->dev, -+ "Invalid signature '%08x' at slot %d\n", -+ EE_FIELD_MAKE_HEADER(p), slot->slotno); -+ slot->probe_failed = 1; -+ return -ENODEV; -+ } -+ -+ cape_ee_field_get(slot->signature, -+ CAPE_EE_FIELD_BOARD_NAME, -+ slot->board_name, sizeof(slot->board_name)); -+ cape_ee_field_get(slot->signature, -+ CAPE_EE_FIELD_VERSION, -+ slot->version, sizeof(slot->version)); -+ cape_ee_field_get(slot->signature, -+ CAPE_EE_FIELD_MANUFACTURER, -+ slot->manufacturer, sizeof(slot->manufacturer)); -+ cape_ee_field_get(slot->signature, -+ CAPE_EE_FIELD_PART_NUMBER, -+ slot->part_number, sizeof(slot->part_number)); -+ -+ /* board_name,version,manufacturer,part_number */ -+ snprintf(slot->text_id, sizeof(slot->text_id) - 1, -+ "%s,%s,%s,%s", slot->board_name, slot->version, -+ slot->manufacturer, slot->part_number); -+ -+ /* terminate always */ -+ slot->text_id[sizeof(slot->text_id) - 1] = '\0'; -+ -+slot_fail_check: -+ /* slot has failed and we don't support hotpluging */ -+ if (slot->probe_failed) -+ return -ENODEV; -+ -+ return 0; -+} -+ -+/* return 0 if not matched,, 1 if matched */ -+static int bone_match_cape(const char *match, -+ const char *part_number, const char *version) -+{ -+ char *tmp_part_number, *tmp_version; -+ char *buf, *s, *e, *sn; -+ int found; -+ -+ if (match == NULL || part_number == NULL) -+ return 0; -+ -+ /* copy the argument to work on it */ -+ buf = kstrdup(match, GFP_KERNEL); -+ -+ /* no memory, too bad... */ -+ if (buf == NULL) -+ return 0; -+ -+ found = 0; -+ s = buf; -+ e = s + strlen(s); -+ while (s < e) { -+ /* find comma separator */ -+ sn = strchr(s, ','); -+ if (sn != NULL) -+ *sn++ = '\0'; -+ else -+ sn = e; -+ tmp_part_number = s; -+ tmp_version = strchr(tmp_part_number, ':'); -+ if (tmp_version != NULL) -+ *tmp_version++ = '\0'; -+ s = sn; -+ -+ /* the part names must match */ -+ if (strcmp(tmp_part_number, part_number) != 0) -+ continue; -+ -+ /* if there's no version, match any */ -+ if (version == NULL || tmp_version == NULL || -+ strcmp(version, tmp_version) == 0) { -+ found = 1; -+ break; -+ } -+ } -+ -+ kfree(buf); -+ -+ return found; -+} -+ -+/* helper method */ -+static int of_multi_prop_cmp(const struct property *prop, const char *value) -+{ -+ const char *cp; -+ int cplen, vlen, l; -+ -+ /* check if it's directly compatible */ -+ cp = prop->value; -+ cplen = prop->length; -+ vlen = strlen(value); -+ -+ while (cplen > 0) { -+ /* compatible? */ -+ if (of_compat_cmp(cp, value, vlen) == 0) -+ return 0; -+ l = strlen(cp) + 1; -+ cp += l; -+ cplen -= l; -+ } -+ return -1; -+} -+ -+static ssize_t slot_ee_attr_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct slot_ee_attribute *ee_attr = to_slot_ee_attribute(attr); -+ struct bone_cape_slot *slot = ee_attr->slot; -+ const struct ee_field *sig_field; -+ int i, len; -+ char *p, *s; -+ u16 val; -+ -+ /* add newline for ascii fields */ -+ sig_field = &cape_sig_fields[ee_attr->field]; -+ -+ len = sig_field->size + sig_field->ascii; -+ p = kmalloc(len, GFP_KERNEL); -+ if (p == NULL) -+ return -ENOMEM; -+ -+ s = cape_ee_field_get(slot->signature, ee_attr->field, p, len); -+ if (s == NULL) -+ return -EINVAL; -+ -+ /* add newline for ascii fields and return */ -+ if (sig_field->ascii) { -+ len = sprintf(buf, "%s\n", s); -+ goto out; -+ } -+ -+ /* case by case handling */ -+ switch (ee_attr->field) { -+ case CAPE_EE_FIELD_HEADER: -+ len = sprintf(buf, "%02x %02x %02x %02x\n", -+ s[0], s[1], s[2], s[3]); -+ break; -+ -+ /* 2 bytes */ -+ case CAPE_EE_FIELD_NUMBER_OF_PINS: -+ case CAPE_EE_FIELD_VDD_3V3EXP: -+ case CAPE_EE_FIELD_VDD_5V: -+ case CAPE_EE_FIELD_SYS_5V: -+ case CAPE_EE_FIELD_DC_SUPPLIED: -+ /* the bone is LE */ -+ val = s[0] & (s[1] << 8); -+ len = sprintf(buf, "%u\n", (unsigned int)val & 0xffff); -+ break; -+ -+ case CAPE_EE_FIELD_PIN_USAGE: -+ -+ len = 0; -+ for (i = 0; i < sig_field->size / 2; i++) { -+ /* the bone is LE */ -+ val = s[0] & (s[1] << 8); -+ sprintf(buf, "%04x\n", val); -+ buf += 5; -+ len += 5; -+ s += 2; -+ } -+ -+ break; -+ -+ default: -+ *buf = '\0'; -+ len = 0; -+ break; -+ } -+ -+out: -+ kfree(p); -+ -+ return len; -+} -+ -+#define SLOT_EE_ATTR(_name, _field) \ -+ { \ -+ .devattr = __ATTR(_name, S_IRUGO, slot_ee_attr_show, NULL), \ -+ .field = CAPE_EE_FIELD_##_field, \ -+ .slot = NULL, \ -+ } -+ -+static const struct slot_ee_attribute slot_ee_attrs[] = { -+ SLOT_EE_ATTR(header, HEADER), -+ SLOT_EE_ATTR(eeprom-format-revision, EEPROM_REV), -+ SLOT_EE_ATTR(board-name, BOARD_NAME), -+ SLOT_EE_ATTR(version, VERSION), -+ SLOT_EE_ATTR(manufacturer, MANUFACTURER), -+ SLOT_EE_ATTR(part-number, PART_NUMBER), -+ SLOT_EE_ATTR(number-of-pins, NUMBER_OF_PINS), -+ SLOT_EE_ATTR(serial-number, SERIAL_NUMBER), -+ SLOT_EE_ATTR(pin-usage, PIN_USAGE), -+ SLOT_EE_ATTR(vdd-3v3exp, VDD_3V3EXP), -+ SLOT_EE_ATTR(vdd-5v, VDD_5V), -+ SLOT_EE_ATTR(sys-5v, SYS_5V), -+ SLOT_EE_ATTR(dc-supplied, DC_SUPPLIED), -+}; -+ -+static int bone_cape_slot_sysfs_register(struct bone_cape_slot *slot) -+{ -+ struct capemgr_info *info = slot->info; -+ struct device *dev = &info->pdev->dev; -+ struct slot_ee_attribute *ee_attr; -+ struct attribute_group *attrgroup; -+ int i, err, sz; -+ -+ slot->ee_attr_name = kasprintf(GFP_KERNEL, "slot-%d", slot->slotno); -+ if (slot->ee_attr_name == NULL) { -+ dev_err(dev, "slot #%d: Failed to allocate ee_attr_name\n", -+ slot->slotno); -+ err = -ENOMEM; -+ goto err_fail_no_ee_attr_name; -+ } -+ -+ slot->ee_attrs_count = ARRAY_SIZE(slot_ee_attrs); -+ -+ sz = slot->ee_attrs_count * sizeof(*slot->ee_attrs); -+ slot->ee_attrs = kmalloc(sz, GFP_KERNEL); -+ if (slot->ee_attrs == NULL) { -+ dev_err(dev, "slot #%d: Failed to allocate ee_attrs\n", -+ slot->slotno); -+ err = -ENOMEM; -+ goto err_fail_no_ee_attrs; -+ } -+ -+ attrgroup = &slot->attrgroup; -+ memset(attrgroup, 0, sizeof(*attrgroup)); -+ attrgroup->name = slot->ee_attr_name; -+ -+ sz = sizeof(*slot->ee_attrs_tab) * (slot->ee_attrs_count + 1); -+ attrgroup->attrs = kmalloc(sz, GFP_KERNEL); -+ if (attrgroup->attrs == NULL) { -+ dev_err(dev, "slot #%d: Failed to allocate ee_attrs_tab\n", -+ slot->slotno); -+ err = -ENOMEM; -+ goto err_fail_no_ee_attrs_tab; -+ } -+ /* copy everything over */ -+ memcpy(slot->ee_attrs, slot_ee_attrs, sizeof(slot_ee_attrs)); -+ -+ /* bind this attr to the slot */ -+ for (i = 0; i < slot->ee_attrs_count; i++) { -+ ee_attr = &slot->ee_attrs[i]; -+ ee_attr->slot = slot; -+ attrgroup->attrs[i] = &ee_attr->devattr.attr; -+ } -+ attrgroup->attrs[i] = NULL; -+ -+ /* make lockdep happy */ -+ for (i = 0; i < slot->ee_attrs_count; i++) { -+ ee_attr = &slot->ee_attrs[i]; -+ sysfs_attr_init(&ee_attr->devattr.attr); -+ } -+ -+ err = sysfs_create_group(&dev->kobj, attrgroup); -+ if (err != 0) { -+ dev_err(dev, "slot #%d: Failed to allocate ee_attrs_tab\n", -+ slot->slotno); -+ err = -ENOMEM; -+ goto err_fail_no_ee_attrs_group; -+ } -+ -+ return 0; -+ -+err_fail_no_ee_attrs_group: -+ kfree(slot->ee_attrs_tab); -+err_fail_no_ee_attrs_tab: -+ kfree(slot->ee_attrs); -+err_fail_no_ee_attrs: -+ kfree(slot->ee_attr_name); -+err_fail_no_ee_attr_name: -+ return err; -+} -+ -+static void bone_cape_slot_sysfs_unregister(struct bone_cape_slot *slot) -+{ -+ struct capemgr_info *info = slot->info; -+ struct device *dev = &info->pdev->dev; -+ -+ sysfs_remove_group(&dev->kobj, &slot->attrgroup); -+ kfree(slot->ee_attrs_tab); -+ kfree(slot->ee_attrs); -+ kfree(slot->ee_attr_name); -+} -+ -+static ssize_t bbrd_ee_attr_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct bbrd_ee_attribute *ee_attr = to_bbrd_ee_attribute(attr); -+ struct platform_device *pdev = to_platform_device(dev); -+ struct capemgr_info *info = platform_get_drvdata(pdev); -+ struct bone_baseboard *bbrd = &info->baseboard; -+ const struct ee_field *sig_field; -+ u16 val; -+ int i, len; -+ char *p, *s; -+ -+ /* add newline for ascii fields */ -+ sig_field = &bbrd_sig_fields[ee_attr->field]; -+ -+ len = sig_field->size + sig_field->ascii; -+ p = kmalloc(len, GFP_KERNEL); -+ if (p == NULL) -+ return -ENOMEM; -+ -+ s = bbrd_ee_field_get(bbrd->signature, ee_attr->field, p, len); -+ if (s == NULL) -+ return -EINVAL; -+ -+ /* add newline for ascii fields and return */ -+ if (sig_field->ascii) { -+ len = sprintf(buf, "%s\n", s); -+ goto out; -+ } -+ -+ /* case by case handling */ -+ switch (ee_attr->field) { -+ case BBRD_EE_FIELD_HEADER: -+ len = sprintf(buf, "%02x %02x %02x %02x\n", -+ s[0], s[1], s[2], s[3]); -+ break; -+ -+ case BBRD_EE_FIELD_CONFIG_OPTION: -+ len = 0; -+ for (i = 0; i < sig_field->size / 2; i++) { -+ /* the bone is LE */ -+ val = s[0] & (s[1] << 8); -+ sprintf(buf, "%04x\n", val); -+ buf += 5; -+ len += 5; -+ s += 2; -+ } -+ break; -+ -+ default: -+ *buf = '\0'; -+ len = 0; -+ break; -+ } -+ -+out: -+ kfree(p); -+ -+ return len; -+} -+ -+#define BBRD_EE_ATTR(_name, _field) \ -+ { \ -+ .devattr = __ATTR(_name, 0440, bbrd_ee_attr_show, NULL), \ -+ .field = BBRD_EE_FIELD_##_field, \ -+ } -+ -+static struct bbrd_ee_attribute bbrd_ee_attrs[] = { -+ BBRD_EE_ATTR(header, HEADER), -+ BBRD_EE_ATTR(board-name, BOARD_NAME), -+ BBRD_EE_ATTR(revision, REVISION), -+ BBRD_EE_ATTR(serial-number, SERIAL_NUMBER), -+ BBRD_EE_ATTR(config-option, CONFIG_OPTION), -+}; -+ -+static struct attribute *bbrd_attrs_flat[] = { -+ &bbrd_ee_attrs[BBRD_EE_FIELD_HEADER].devattr.attr, -+ &bbrd_ee_attrs[BBRD_EE_FIELD_BOARD_NAME].devattr.attr, -+ &bbrd_ee_attrs[BBRD_EE_FIELD_REVISION].devattr.attr, -+ &bbrd_ee_attrs[BBRD_EE_FIELD_SERIAL_NUMBER].devattr.attr, -+ &bbrd_ee_attrs[BBRD_EE_FIELD_CONFIG_OPTION].devattr.attr, -+ NULL, -+}; -+ -+static const struct attribute_group bbrd_attr_group = { -+ .name = "baseboard", -+ .attrs = bbrd_attrs_flat, -+}; -+ -+static ssize_t slots_show(struct device *dev, struct device_attribute *attr, -+ char *buf); -+static ssize_t slots_store(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count); -+ -+static DEVICE_ATTR(slots, 0644, slots_show, slots_store); -+ -+static struct attribute *root_attrs_flat[] = { -+ &dev_attr_slots.attr, -+ NULL, -+}; -+ -+static const struct attribute_group root_attr_group = { -+ .attrs = root_attrs_flat, -+}; -+ -+static const struct attribute_group *attr_groups[] = { -+ &root_attr_group, -+ &bbrd_attr_group, -+ NULL, -+}; -+ -+static ssize_t slots_show(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct capemgr_info *info = platform_get_drvdata(pdev); -+ struct bone_cape_slot *slot; -+ ssize_t len, sz; -+ -+ mutex_lock(&info->slots_list_mutex); -+ sz = 0; -+ list_for_each_entry(slot, &info->slot_list, node) { -+ -+ len = sprintf(buf, "%2d: %c%c%c%c%c%c %3d %s\n", -+ slot->slotno, -+ slot->probed ? 'P' : '-', -+ slot->probe_failed ? 'F' : '-', -+ slot->override ? 'O' : '-', -+ slot->loading ? 'l' : '-', -+ slot->loaded ? 'L' : '-', -+ slot->disabled ? 'D' : '-', -+ slot->overlay_id, slot->text_id); -+ -+ buf += len; -+ sz += len; -+ } -+ mutex_unlock(&info->slots_list_mutex); -+ -+ return sz; -+} -+ -+static ssize_t slots_store(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct capemgr_info *info = platform_get_drvdata(pdev); -+ struct bone_cape_slot *slot; -+ struct device_node *pnode, *node; -+ char *s, *part_number, *version; -+ int ret; -+ int slotno; -+ -+ /* check for remove slot */ -+ if (strlen(buf) > 0 && buf[0] == '-') { -+ ret = kstrtoint(buf + 1, 10, &slotno); -+ if (ret != 0) -+ return ret; -+ -+ /* now load each (take lock to be sure */ -+ mutex_lock(&info->slots_list_mutex); -+ list_for_each_entry(slot, &info->slot_list, node) { -+ if (slotno == slot->slotno) -+ goto found; -+ } -+ -+ mutex_unlock(&info->slots_list_mutex); -+ return -ENODEV; -+found: -+ /* the hardware slots just get unloaded */ -+ if (!slot->override) { -+ ret = capemgr_unload_slot(slot); -+ if (ret == 0) -+ dev_info(&pdev->dev, -+ "Unloaded slot #%d\n", slotno); -+ else -+ dev_err(&pdev->dev, -+ "Failed to unload slot #%d\n", slotno); -+ } else { -+ ret = capemgr_remove_slot_no_lock(slot); -+ if (ret == 0) -+ dev_info(&pdev->dev, -+ "Removed slot #%d\n", slotno); -+ else -+ dev_err(&pdev->dev, -+ "Failed to remove slot #%d\n", slotno); -+ } -+ mutex_unlock(&info->slots_list_mutex); -+ -+ return ret == 0 ? strlen(buf) : ret; -+ } -+ -+ part_number = kstrdup(buf, GFP_KERNEL); -+ if (part_number == NULL) -+ return -ENOMEM; -+ -+ /* remove trailing spaces dots and newlines */ -+ s = part_number + strlen(part_number); -+ while (s > part_number && -+ (isspace(s[-1]) || s[-1] == '\n' || s[-1] == '.')) -+ *--s = '\0'; -+ -+ version = strchr(part_number, ':'); -+ if (version != NULL) -+ *version++ = '\0'; -+ -+ dev_info(&pdev->dev, "part_number '%s', version '%s'\n", -+ part_number, version ? version : "N/A"); -+ -+ pnode = pdev->dev.of_node; -+ node = NULL; -+ slot = NULL; -+ ret = 0; -+ -+ /* no specific slot found, try immediate */ -+ slot = capemgr_add_slot(info, NULL, part_number, version, 0); -+ -+ if (IS_ERR_OR_NULL(slot)) { -+ dev_err(&pdev->dev, "Failed to add slot #%d\n", -+ atomic_read(&info->next_slot_nr) - 1); -+ ret = slot ? PTR_ERR(slot) : -ENODEV; -+ slot = NULL; -+ goto err_fail; -+ } -+ -+ kfree(part_number); -+ -+ ret = capemgr_load_slot(slot); -+ if (ret != 0) -+ capemgr_remove_slot(slot); -+ -+ return ret == 0 ? strlen(buf) : ret; -+err_fail: -+ of_node_put(node); -+ kfree(part_number); -+ return ret; -+} -+ -+/* verify the overlay */ -+static int capemgr_verify_overlay(struct bone_cape_slot *slot) -+{ -+ struct capemgr_info *info = slot->info; -+ struct device *dev = &info->pdev->dev; -+ struct bone_baseboard *bbrd = &info->baseboard; -+ struct device_node *node = slot->overlay; -+ struct property *prop; -+ struct bone_cape_slot *slotn; -+ int err, counta, countb, i, j; -+ const char *ra, *rb; -+ -+ /* validate */ -+ if (node == NULL) { -+ dev_err(dev, "slot #%d: No overlay for '%s'\n", -+ slot->slotno, slot->part_number); -+ return -EINVAL; -+ } -+ -+ /* check if the slot is compatible with the board */ -+ prop = of_find_property(node, "compatible", NULL); -+ -+ /* no compatible property? */ -+ if (prop == NULL) { -+ dev_err(dev, "slot #%d: No compatible property for '%s'\n", -+ slot->slotno, slot->part_number); -+ return -EINVAL; -+ } -+ -+ /* verify that the cape is baseboard compatible */ -+ if (of_multi_prop_cmp(prop, bbrd->compatible_name) != 0) { -+ dev_err(dev, "slot #%d: Incompatible with baseboard for '%s'\n", -+ slot->slotno, slot->part_number); -+ return -EINVAL; -+ } -+ -+ /* count the strings */ -+ counta = of_property_count_strings(node, "exclusive-use"); -+ /* no valid property, or no resources; no matter, it's OK */ -+ if (counta <= 0) -+ return 0; -+ -+ /* and now check if there's a resource conflict */ -+ err = 0; -+ mutex_lock(&info->slots_list_mutex); -+ for (i = 0; i < counta; i++) { -+ -+ ra = NULL; -+ err = of_property_read_string_index(node, "exclusive-use", -+ i, &ra); -+ if (err != 0) { -+ dev_err(dev, "slot #%d: Could not read string #%d\n", -+ slot->slotno, i); -+ break; -+ } -+ -+ list_for_each_entry(slotn, &info->slot_list, node) { -+ -+ /* don't check against self */ -+ if (slot == slotn) -+ continue; -+ -+ /* only check against loaded or loading slots */ -+ if (!slotn->loaded && !slotn->loading) -+ continue; -+ -+ countb = of_property_count_strings(slotn->overlay, -+ "exclusive-use"); -+ /* no valid property, or resources; it's OK */ -+ if (countb <= 0) -+ continue; -+ -+ -+ for (j = 0; j < countb; j++) { -+ -+ /* count the resources */ -+ rb = NULL; -+ err = of_property_read_string_index( -+ slotn->overlay, "exclusive-use", -+ j, &rb); -+ if (err != 0) { -+ /* error, but we don't care */ -+ err = 0; -+ break; -+ } -+ -+ /* ignore case; just in case ;) */ -+ if (strcasecmp(ra, rb) == 0) { -+ -+ /* resource conflict */ -+ err = -EEXIST; -+ dev_err(dev, -+ "slot #%d: %s conflict %s (#%d:%s)\n", -+ slot->slotno, -+ slot->part_number, ra, -+ slotn->slotno, -+ slotn->part_number); -+ goto out; -+ } -+ } -+ } -+ } -+out: -+ mutex_unlock(&info->slots_list_mutex); -+ -+ return err; -+} -+ -+static int capemgr_load_slot(struct bone_cape_slot *slot) -+{ -+ struct capemgr_info *info = slot->info; -+ struct device *dev = &info->pdev->dev; -+ const char *dtbo; -+ int err; -+ -+ if (slot->probe_failed) { -+ dev_err(dev, "slot #%d: probe failed for '%s'\n", -+ slot->slotno, slot->part_number); -+ return -ENODEV; -+ } -+ -+ if (slot->loaded) { -+ dev_err(dev, "slot #%d: already loaded for '%s'\n", -+ slot->slotno, slot->part_number); -+ return -EAGAIN; -+ } -+ -+ /* make sure we don't leak this on repeated calls */ -+ kfree(slot->dtbo); -+ slot->dtbo = NULL; -+ -+ dev_dbg(dev, "slot #%d: Requesting part number/version based '%s-%s.dtbo\n", -+ slot->slotno, slot->part_number, slot->version); -+ -+ /* request the part number + .dtbo*/ -+ slot->dtbo = kasprintf(GFP_KERNEL, "%s-%s.dtbo", -+ slot->part_number, slot->version); -+ if (slot->dtbo == NULL) { -+ dev_err(dev, "slot #%d: Failed to get dtbo '%s'\n", -+ slot->slotno, dtbo); -+ return -ENOMEM; -+ } -+ -+ dev_dbg(dev, "slot #%d: Requesting firmware '%s' for board-name '%s', version '%s'%s\n", -+ slot->slotno, -+ slot->dtbo, slot->board_name, slot->version, -+ system_state == SYSTEM_BOOTING ? " - booting" : ""); -+ -+ err = request_firmware_direct(&slot->fw, slot->dtbo, dev); -+ if (err != 0) { -+ dev_dbg(dev, "failed to load firmware '%s'\n", slot->dtbo); -+ goto err_fail_no_fw; -+ } -+ -+ dev_dbg(dev, "slot #%d: dtbo '%s' loaded; converting to live tree\n", -+ slot->slotno, slot->dtbo); -+ -+ of_fdt_unflatten_tree((unsigned long *)slot->fw->data, NULL, -+ &slot->overlay); -+ if (slot->overlay == NULL) { -+ dev_err(dev, "slot #%d: Failed to unflatten\n", -+ slot->slotno); -+ err = -EINVAL; -+ goto err_fail; -+ } -+ -+ /* mark it as detached */ -+ of_node_set_flag(slot->overlay, OF_DETACHED); -+ -+ /* perform resolution */ -+ err = of_resolve_phandles(slot->overlay); -+ if (err != 0) { -+ dev_err(dev, "slot #%d: Failed to resolve tree\n", -+ slot->slotno); -+ goto err_fail; -+ } -+ -+ err = capemgr_verify_overlay(slot); -+ if (err != 0) { -+ dev_err(dev, "slot #%d: Failed verification\n", -+ slot->slotno); -+ goto err_fail; -+ } -+ -+ err = of_overlay_create(slot->overlay); -+ if (err < 0) { -+ dev_err(dev, "slot #%d: Failed to create overlay\n", -+ slot->slotno); -+ goto err_fail; -+ } -+ slot->overlay_id = err; -+ -+ slot->loading = 0; -+ slot->loaded = 1; -+ -+ dev_info(dev, "slot #%d: dtbo '%s' loaded; overlay id #%d\n", -+ slot->slotno, slot->dtbo, slot->overlay_id); -+ -+ return 0; -+ -+err_fail: -+ -+ /* TODO: free the overlay, we can't right now cause -+ * the unflatten method does not track it */ -+ slot->overlay = NULL; -+ -+ release_firmware(slot->fw); -+ slot->fw = NULL; -+ -+err_fail_no_fw: -+ slot->loading = 0; -+ return err; -+} -+ -+static int capemgr_unload_slot(struct bone_cape_slot *slot) -+{ -+ if (!slot->loaded || slot->overlay_id == -1) -+ return -EINVAL; -+ -+ of_overlay_destroy(slot->overlay_id); -+ slot->overlay_id = -1; -+ -+ slot->loaded = 0; -+ -+ return 0; -+ -+} -+ -+/* slots_list_mutex must be taken */ -+static int capemgr_remove_slot_no_lock(struct bone_cape_slot *slot) -+{ -+ struct capemgr_info *info = slot->info; -+ struct device *dev = &info->pdev->dev; -+ int ret; -+ -+ if (slot == NULL) -+ return 0; -+ -+ if (slot->loaded && slot->overlay_id >= 0) { -+ /* unload just in case */ -+ ret = capemgr_unload_slot(slot); -+ if (ret != 0) { -+ dev_err(dev, "Unable to unload slot #%d\n", -+ slot->slotno); -+ return ret; -+ } -+ } -+ -+ /* if probed OK, remove the sysfs nodes */ -+ if (slot->probed && !slot->probe_failed) -+ bone_cape_slot_sysfs_unregister(slot); -+ -+ /* remove it from the list */ -+ list_del(&slot->node); -+ -+ if (slot->nvmem_cell) -+ nvmem_cell_put(slot->nvmem_cell); -+ devm_kfree(dev, slot); -+ return 0; -+} -+ -+static int capemgr_remove_slot(struct bone_cape_slot *slot) -+{ -+ struct capemgr_info *info = slot->info; -+ int ret; -+ -+ mutex_lock(&info->slots_list_mutex); -+ ret = capemgr_remove_slot_no_lock(slot); -+ mutex_unlock(&info->slots_list_mutex); -+ -+ return ret; -+} -+ -+static int bone_slot_fill_override(struct bone_cape_slot *slot, -+ const char *part_number, const char *version) -+{ -+ const struct ee_field *sig_field; -+ int i, len, has_part_number; -+ char *p; -+ -+ slot->probe_failed = 0; -+ slot->probed = 0; -+ -+ /* zero out signature */ -+ memset(slot->signature, 0, -+ sizeof(slot->signature)); -+ -+ /* first, fill in all with override defaults */ -+ for (i = 0; i < ARRAY_SIZE(cape_sig_fields); i++) { -+ -+ sig_field = &cape_sig_fields[i]; -+ -+ /* point to the entry */ -+ p = slot->signature + sig_field->start; -+ -+ if (sig_field->override) -+ memcpy(p, sig_field->override, -+ sig_field->size); -+ else -+ memset(p, 0, sig_field->size); -+ } -+ -+ /* if a part_number is supplied use it */ -+ len = part_number ? strlen(part_number) : 0; -+ if (len > 0) { -+ sig_field = &cape_sig_fields[CAPE_EE_FIELD_PART_NUMBER]; -+ -+ /* point to the entry */ -+ p = slot->signature + sig_field->start; -+ -+ /* copy and zero out any remainder */ -+ if (len > sig_field->size) -+ len = sig_field->size; -+ memcpy(p, part_number, len); -+ if (len < sig_field->size) -+ memset(p + len, 0, sig_field->size - len); -+ -+ has_part_number = 1; -+ } -+ -+ /* if a version is supplied use it */ -+ len = version ? strlen(version) : 0; -+ if (len > 0) { -+ sig_field = &cape_sig_fields[CAPE_EE_FIELD_VERSION]; -+ -+ /* point to the entry */ -+ p = slot->signature + sig_field->start; -+ -+ /* copy and zero out any remainder */ -+ if (len > sig_field->size) -+ len = sig_field->size; -+ memcpy(p, version, len); -+ if (len < sig_field->size) -+ memset(p + len, 0, sig_field->size - len); -+ } -+ -+ /* we must have a part number */ -+ if (!has_part_number) -+ return -EINVAL; -+ -+ slot->override = 1; -+ -+ return 0; -+} -+ -+static struct bone_cape_slot * -+capemgr_add_slot(struct capemgr_info *info, const char *slot_name, -+ const char *part_number, const char *version, int prio) -+{ -+ struct bone_cape_slot *slot; -+ struct device *dev = &info->pdev->dev; -+ int slotno; -+ int ret; -+ -+ slotno = atomic_inc_return(&info->next_slot_nr) - 1; -+ -+ slot = devm_kzalloc(dev, sizeof(*slot), GFP_KERNEL); -+ if (slot == NULL) -+ return ERR_PTR(-ENOMEM); -+ -+ slot->info = info; -+ slot->slotno = slotno; -+ slot->priority = prio; -+ slot->overlay_id = -1; -+ -+ if (slot_name) { -+ slot->nvmem_cell = nvmem_cell_get(dev, slot_name); -+ if (IS_ERR(slot->nvmem_cell)) { -+ ret = PTR_ERR(slot->nvmem_cell); -+ if (ret != -EPROBE_DEFER) -+ dev_err(dev, "Failed to get slot eeprom cell\n"); -+ slot->nvmem_cell = NULL; -+ goto err_out; -+ } -+ } else { -+ dev_err(dev, "slot #%d: override\n", slotno); -+ -+ /* fill in everything with defaults first */ -+ ret = bone_slot_fill_override(slot, part_number, version); -+ if (ret != 0) { -+ dev_err(dev, "slot #%d: override failed\n", slotno); -+ goto err_out; -+ } -+ } -+ -+ ret = bone_slot_scan(slot); -+ if (ret != 0) { -+ -+ if (!slot->probe_failed) { -+ dev_err(dev, "slot #%d: scan failed\n", -+ slotno); -+ goto err_out; -+ } -+ -+ dev_err(dev, "slot #%d: No cape found\n", slotno); -+ /* but all is fine */ -+ } else { -+ if (uboot_capemgr_enabled == 0) { -+ dev_err(dev, "slot #%d: '%s'\n", -+ slotno, slot->text_id); -+ -+ ret = bone_cape_slot_sysfs_register(slot); -+ if (ret != 0) { -+ dev_err(dev, "slot #%d: sysfs register failed\n", -+ slotno); -+ goto err_out; -+ } -+ } else { -+ dev_err(dev, "slot #%d: auto loading handled by U-Boot\n", slotno); -+ } -+ } -+ -+ /* add to the slot list */ -+ mutex_lock(&info->slots_list_mutex); -+ list_add_tail(&slot->node, &info->slot_list); -+ mutex_unlock(&info->slots_list_mutex); -+ -+ return slot; -+ -+err_out: -+ if (slot->nvmem_cell) -+ nvmem_cell_put(slot->nvmem_cell); -+ devm_kfree(dev, slot); -+ return ERR_PTR(ret); -+} -+ -+/* return 1 if it makes sense to retry loading */ -+static int retry_loading_condition(struct bone_cape_slot *slot) -+{ -+ struct capemgr_info *info = slot->info; -+ struct device *dev = &info->pdev->dev; -+ struct bone_cape_slot *slotn; -+ int ret; -+ -+ dev_dbg(dev, "loader: retry_loading slot-%d %s:%s (prio %d)\n", -+ slot->slotno, slot->part_number, slot->version, -+ slot->priority); -+ -+ mutex_lock(&info->slots_list_mutex); -+ ret = 0; -+ list_for_each_entry(slotn, &info->slot_list, node) { -+ /* if same slot or not loading skip */ -+ if (!slotn->loading || slotn->retry_loading) -+ continue; -+ /* at least one cape is still loading (without retrying) */ -+ ret = 1; -+ } -+ mutex_unlock(&info->slots_list_mutex); -+ return ret; -+} -+ -+/* return 1 if this slot is clear to try to load now */ -+static int clear_to_load_condition(struct bone_cape_slot *slot) -+{ -+ struct capemgr_info *info = slot->info; -+ int my_prio = slot->priority; -+ struct device *dev = &info->pdev->dev; -+ int ret; -+ -+ dev_dbg(dev, "loader: check slot-%d %s:%s (prio %d)\n", slot->slotno, -+ slot->part_number, slot->version, slot->priority); -+ -+ mutex_lock(&info->slots_list_mutex); -+ ret = 1; -+ list_for_each_entry(slot, &info->slot_list, node) { -+ /* if any slot is loading with lowest priority */ -+ if (!slot->loading) -+ continue; -+ if (slot->priority < my_prio) { -+ ret = 0; -+ break; -+ } -+ } -+ mutex_unlock(&info->slots_list_mutex); -+ return ret; -+} -+ -+static int capemgr_loader(void *data) -+{ -+ struct bone_cape_slot *slot = data; -+ struct capemgr_info *info = slot->info; -+ struct device *dev = &info->pdev->dev; -+ int ret, done, other_loading, booting; -+ -+ done = 0; -+ -+ slot->retry_loading = 0; -+ -+ dev_dbg(dev, "loader: before slot-%d %s:%s (prio %d)\n", slot->slotno, -+ slot->part_number, slot->version, slot->priority); -+ -+ /* -+ * We have a basic priority based arbitration system -+ * Slots have priorities, so the lower priority ones -+ * should start loading first. So each time we end up -+ * here. -+ */ -+ ret = wait_event_interruptible(info->load_wq, -+ clear_to_load_condition(slot)); -+ if (ret < 0) { -+ dev_warn(dev, "loader, Signal pending\n"); -+ return ret; -+ } -+ -+ dev_dbg(dev, "loader: after slot-%d %s:%s (prio %d)\n", slot->slotno, -+ slot->part_number, slot->version, slot->priority); -+ -+ /* using the return value */ -+ ret = capemgr_load_slot(slot); -+ -+ /* wake up all just in case */ -+ wake_up_interruptible_all(&info->load_wq); -+ -+ if (ret == 0) -+ goto done; -+ -+ dev_dbg(dev, "loader: retrying slot-%d %s:%s (prio %d)\n", slot->slotno, -+ slot->part_number, slot->version, slot->priority); -+ -+ /* first attempt has failed; now try each time there's any change */ -+ slot->retry_loading = 1; -+ -+ for (;;) { -+ booting = (system_state == SYSTEM_BOOTING); -+ other_loading = retry_loading_condition(slot); -+ if (!booting && !other_loading) -+ break; -+ -+ /* simple wait for someone to kick us */ -+ if (other_loading) { -+ DEFINE_WAIT(__wait); -+ -+ prepare_to_wait(&info->load_wq, &__wait, -+ TASK_INTERRUPTIBLE); -+ finish_wait(&info->load_wq, &__wait); -+ } else { -+ /* always delay when booting */ -+ msleep(boot_scan_period); -+ } -+ -+ if (signal_pending(current)) { -+ dev_warn(dev, "loader, Signal pending\n"); -+ ret = -ERESTARTSYS; -+ goto done; -+ } -+ -+ /* using the return value */ -+ ret = capemgr_load_slot(slot); -+ if (ret == 0) -+ goto done; -+ -+ /* wake up all just in case */ -+ wake_up_interruptible_all(&info->load_wq); -+ } -+ -+done: -+ slot->loading = 0; -+ slot->retry_loading = 0; -+ -+ if (ret == 0) { -+ dev_dbg(dev, "loader: done slot-%d %s:%s (prio %d)\n", -+ slot->slotno, slot->part_number, slot->version, -+ slot->priority); -+ } else { -+ dev_err(dev, "loader: failed to load slot-%d %s:%s (prio %d)\n", -+ slot->slotno, slot->part_number, slot->version, -+ slot->priority); -+ -+ /* if it's a override slot remove it */ -+ if (slot->override) -+ capemgr_remove_slot(slot); -+ } -+ -+ return ret; -+} -+ -+static int -+capemgr_probe(struct platform_device *pdev) -+{ -+ struct capemgr_info *info; -+ struct bone_baseboard *bbrd; -+ struct bone_cape_slot *slot; -+ struct device_node *pnode = pdev->dev.of_node; -+ struct device_node *baseboardmaps_node; -+ struct device_node *node; -+ const char *part_number; -+ const char *version; -+ const char *board_name; -+ const char *compatible_name; -+ char slot_name[16]; -+ u32 slots_nr; -+ int i, ret, len, prio; -+ long val; -+ char *wbuf, *s, *p, *e; -+ -+ if (uboot_capemgr_enabled) -+ return 0; -+ -+ /* we don't use platform_data at all; we require OF */ -+ if (pnode == NULL) -+ return -ENOTSUPP; -+ -+ info = devm_kzalloc(&pdev->dev, -+ sizeof(struct capemgr_info), GFP_KERNEL); -+ if (!info) -+ return -ENOMEM; -+ -+ info->pdev = pdev; -+ platform_set_drvdata(pdev, info); -+ -+ atomic_set(&info->next_slot_nr, 0); -+ INIT_LIST_HEAD(&info->slot_list); -+ mutex_init(&info->slots_list_mutex); -+ -+ init_waitqueue_head(&info->load_wq); -+ -+ baseboardmaps_node = NULL; -+ -+ /* find the baseboard */ -+ bbrd = &info->baseboard; -+ -+ baseboardmaps_node = of_get_child_by_name(pnode, "baseboardmaps"); -+ if (baseboardmaps_node == NULL) { -+ dev_err(&pdev->dev, "Failed to get baseboardmaps node"); -+ ret = -ENODEV; -+ goto err_exit; -+ } -+ -+ bbrd->nvmem_cell = nvmem_cell_get(&pdev->dev, "baseboard"); -+ if (IS_ERR(bbrd->nvmem_cell)) { -+ ret = PTR_ERR(bbrd->nvmem_cell); -+ if (ret != -EPROBE_DEFER) -+ dev_err(&pdev->dev, "Failed to get baseboard eeprom cell\n"); -+ bbrd->nvmem_cell = NULL; -+ goto err_exit; -+ } -+ -+ ret = bone_baseboard_scan(bbrd); -+ if (ret != 0) { -+ dev_err(&pdev->dev, "Failed to scan baseboard eeprom\n"); -+ goto err_exit; -+ } -+ -+ dev_info(&pdev->dev, "Baseboard: '%s'\n", bbrd->text_id); -+ -+ board_name = NULL; -+ compatible_name = NULL; -+ for_each_child_of_node(baseboardmaps_node, node) { -+ /* there must be board-name */ -+ if (of_property_read_string(node, "board-name", -+ &board_name) != 0 || -+ of_property_read_string(node, "compatible-name", -+ &compatible_name) != 0) -+ continue; -+ -+ if (strcmp(bbrd->board_name, board_name) == 0) -+ break; -+ } -+ of_node_put(baseboardmaps_node); -+ baseboardmaps_node = NULL; -+ -+ if (node == NULL) { -+ dev_err(&pdev->dev, "Failed to find compatible map for %s\n", -+ bbrd->board_name); -+ ret = -ENODEV; -+ goto err_exit; -+ } -+ bbrd->compatible_name = kstrdup(compatible_name, GFP_KERNEL); -+ if (bbrd->compatible_name == NULL) { -+ ret = -ENOMEM; -+ goto err_exit; -+ } -+ of_node_put(node); -+ -+ /* get slot number */ -+ ret = of_property_read_u32(pnode, "#slots", &slots_nr); -+ if (ret != 0) -+ slots_nr = 0; -+ -+ dev_info(&pdev->dev, "compatible-baseboard=%s - #slots=%d\n", -+ bbrd->compatible_name, slots_nr); -+ -+ for (i = 0; i < slots_nr; i++) { -+ snprintf(slot_name, sizeof(slot_name), "slot%d", i); -+ slot = capemgr_add_slot(info, slot_name, NULL, NULL, 0); -+ if (IS_ERR(slot)) { -+ dev_err(&pdev->dev, "Failed to add slot #%d\n", -+ atomic_read(&info->next_slot_nr)); -+ ret = PTR_ERR(slot); -+ goto err_exit; -+ } -+ } -+ -+ /* iterate over enable_partno (if there) */ -+ if (enable_partno && strlen(enable_partno) > 0) { -+ -+ /* allocate a temporary buffer */ -+ wbuf = devm_kzalloc(&pdev->dev, PAGE_SIZE, GFP_KERNEL); -+ if (wbuf == NULL) { -+ ret = -ENOMEM; -+ goto err_exit; -+ } -+ -+ /* add any enable_partno capes */ -+ s = enable_partno; -+ while (*s) { -+ /* form is PART[:REV[:PRIO]],PART.. */ -+ p = strchr(s, ','); -+ if (p == NULL) -+ e = s + strlen(s); -+ else -+ e = p; -+ -+ /* copy to temp buffer */ -+ len = e - s; -+ if (len >= PAGE_SIZE - 1) -+ len = PAGE_SIZE - 1; -+ memcpy(wbuf, s, len); -+ wbuf[len] = '\0'; -+ -+ /* move to the next */ -+ s = *e ? e + 1 : e; -+ -+ part_number = wbuf; -+ -+ /* default version is NULL & prio is 0 */ -+ version = NULL; -+ prio = 0; -+ -+ /* now split the rev & prio part */ -+ p = strchr(wbuf, ':'); -+ if (p != NULL) { -+ *p++ = '\0'; -+ if (*p != ':') -+ version = p; -+ p = strchr(p, ':'); -+ if (p != NULL) { -+ *p++ = '\0'; -+ ret = kstrtol(p, 10, &val); -+ if (ret == 0) -+ prio = val; -+ } -+ } -+ -+ dev_info(&pdev->dev, -+ "enabled_partno PARTNO '%s' VER '%s' PR '%d'\n", -+ part_number, -+ version ? version : "N/A", prio); -+ -+ /* only immediate slots are allowed here */ -+ slot = capemgr_add_slot(info, NULL, -+ part_number, version, prio); -+ -+ /* we continue even in case of an error */ -+ if (IS_ERR_OR_NULL(slot)) { -+ dev_warn(&pdev->dev, "Failed to add slot #%d\n", -+ atomic_read(&info->next_slot_nr) - 1); -+ } -+ } -+ -+ devm_kfree(&pdev->dev, wbuf); -+ } -+ -+ pm_runtime_enable(&pdev->dev); -+ ret = pm_runtime_get_sync(&pdev->dev); -+ if (IS_ERR_VALUE(ret)) { -+ dev_err(&pdev->dev, "Failed to pm_runtime_get_sync()\n"); -+ goto err_exit; -+ } -+ -+ pm_runtime_put(&pdev->dev); -+ -+ /* it is safe to create the attribute groups */ -+ ret = sysfs_create_groups(&pdev->dev.kobj, attr_groups); -+ if (ret != 0) { -+ dev_err(&pdev->dev, "Failed to create sysfs attributes\n"); -+ goto err_exit; -+ } -+ /* automatically cleared by driver core now */ -+ pdev->dev.groups = attr_groups; -+ -+ /* now load each (take lock to be sure */ -+ mutex_lock(&info->slots_list_mutex); -+ -+ list_for_each_entry(slot, &info->slot_list, node) { -+ -+ /* if matches the disabled ones skip */ -+ if (bone_match_cape(disable_partno, slot->part_number, -+ slot->version)) { -+ dev_info(&pdev->dev, -+ "Skipping loading of disabled cape with part# %s\n", -+ slot->part_number); -+ slot->disabled = 1; -+ continue; -+ } -+ -+ if (!slot->probe_failed && !slot->loaded) -+ slot->loading = 1; -+ } -+ -+ /* now start the loader thread(s) (all at once) */ -+ list_for_each_entry(slot, &info->slot_list, node) { -+ -+ if (!slot->loading) -+ continue; -+ -+ slot->loader_thread = kthread_run(capemgr_loader, -+ slot, "capemgr-loader-%d", -+ slot->slotno); -+ if (IS_ERR(slot->loader_thread)) { -+ dev_warn(&pdev->dev, "slot #%d: Failed to start loader\n", -+ slot->slotno); -+ slot->loader_thread = NULL; -+ } -+ } -+ mutex_unlock(&info->slots_list_mutex); -+ -+ dev_info(&pdev->dev, "initialized OK.\n"); -+ -+ return 0; -+ -+err_exit: -+ if (bbrd->nvmem_cell) -+ nvmem_cell_put(bbrd->nvmem_cell); -+ of_node_put(baseboardmaps_node); -+ platform_set_drvdata(pdev, NULL); -+ devm_kfree(&pdev->dev, info); -+ -+ return ret; -+} -+ -+static int capemgr_remove(struct platform_device *pdev) -+{ -+ struct capemgr_info *info = platform_get_drvdata(pdev); -+ struct bone_baseboard *bbrd = &info->baseboard; -+ struct bone_cape_slot *slot, *slotn; -+ int ret; -+ -+ mutex_lock(&info->slots_list_mutex); -+ list_for_each_entry_safe(slot, slotn, &info->slot_list, node) -+ capemgr_remove_slot_no_lock(slot); -+ mutex_unlock(&info->slots_list_mutex); -+ -+ platform_set_drvdata(pdev, NULL); -+ -+ ret = pm_runtime_get_sync(&pdev->dev); -+ if (IS_ERR_VALUE(ret)) -+ return ret; -+ -+ pm_runtime_put(&pdev->dev); -+ pm_runtime_disable(&pdev->dev); -+ -+ if (bbrd->nvmem_cell) -+ nvmem_cell_put(bbrd->nvmem_cell); -+ devm_kfree(&pdev->dev, info); -+ -+ return 0; -+} -+ -+static struct platform_driver capemgr_driver = { -+ .probe = capemgr_probe, -+ .remove = capemgr_remove, -+ .driver = { -+ .name = "bone_capemgr", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(capemgr_of_match), -+ }, -+}; -+ -+module_platform_driver(capemgr_driver); -+ -+MODULE_AUTHOR("Pantelis Antoniou"); -+MODULE_DESCRIPTION("Beaglebone cape manager"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:bone_capemgr"); -diff --git b/drivers/misc/cape/Kconfig b/drivers/misc/cape/Kconfig -new file mode 100644 -index 0000000..a2ef85e ---- /dev/null -+++ b/drivers/misc/cape/Kconfig -@@ -0,0 +1,5 @@ -+# -+# Capes -+# -+ -+source "drivers/misc/cape/beaglebone/Kconfig" -diff --git b/drivers/misc/cape/Makefile b/drivers/misc/cape/Makefile -new file mode 100644 -index 0000000..7c4eb96 ---- /dev/null -+++ b/drivers/misc/cape/Makefile -@@ -0,0 +1,5 @@ -+# -+# Makefile for cape like devices -+# -+ -+obj-y += beaglebone/ -diff --git b/drivers/misc/cape/beaglebone/Kconfig b/drivers/misc/cape/beaglebone/Kconfig -new file mode 100644 -index 0000000..eeb6782 ---- /dev/null -+++ b/drivers/misc/cape/beaglebone/Kconfig -@@ -0,0 +1,10 @@ -+# -+# Beaglebone capes -+# -+ -+config BEAGLEBONE_PINMUX_HELPER -+ tristate "Beaglebone Pinmux Helper" -+ depends on ARCH_OMAP2PLUS && OF -+ default n -+ help -+ Say Y here to include support for the pinmux helper -diff --git b/drivers/misc/cape/beaglebone/Makefile b/drivers/misc/cape/beaglebone/Makefile -new file mode 100644 -index 0000000..7f4617a ---- /dev/null -+++ b/drivers/misc/cape/beaglebone/Makefile -@@ -0,0 +1,5 @@ -+# -+# Makefile for beaglebone capes -+# -+ -+obj-$(CONFIG_BEAGLEBONE_PINMUX_HELPER) += bone-pinmux-helper.o -diff --git b/drivers/misc/cape/beaglebone/bone-pinmux-helper.c b/drivers/misc/cape/beaglebone/bone-pinmux-helper.c -new file mode 100644 -index 0000000..d81363a ---- /dev/null -+++ b/drivers/misc/cape/beaglebone/bone-pinmux-helper.c -@@ -0,0 +1,242 @@ -+/* -+ * Pinmux helper driver -+ * -+ * Copyright (C) 2013 Pantelis Antoniou <panto@antoniou-consulting.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/errno.h> -+#include <linux/init.h> -+#include <linux/err.h> -+#include <linux/of.h> -+#include <linux/of_device.h> -+#include <linux/of_gpio.h> -+#include <linux/slab.h> -+#include <linux/pinctrl/pinctrl.h> -+#include <linux/pinctrl/pinmux.h> -+#include <linux/pinctrl/consumer.h> -+ -+static const struct of_device_id bone_pinmux_helper_of_match[] = { -+ { -+ .compatible = "bone-pinmux-helper", -+ }, -+ { }, -+}; -+MODULE_DEVICE_TABLE(of, bone_pinmux_helper_of_match); -+ -+struct pinmux_helper_data { -+ struct pinctrl *pinctrl; -+ char *selected_state_name; -+}; -+ -+static ssize_t pinmux_helper_show_state(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct pinmux_helper_data *data = platform_get_drvdata(pdev); -+ const char *name; -+ -+ name = data->selected_state_name; -+ if (name == NULL || strlen(name) == 0) -+ name = "none"; -+ return sprintf(buf, "%s\n", name); -+} -+ -+static ssize_t pinmux_helper_store_state(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct pinmux_helper_data *data = platform_get_drvdata(pdev); -+ struct pinctrl_state *state; -+ char *state_name; -+ char *s; -+ int err; -+ -+ /* duplicate (as a null terminated string) */ -+ state_name = kmalloc(count + 1, GFP_KERNEL); -+ if (state_name == NULL) -+ return -ENOMEM; -+ memcpy(state_name, buf, count); -+ state_name[count] = '\0'; -+ -+ /* and chop off newline */ -+ s = strchr(state_name, '\n'); -+ if (s != NULL) -+ *s = '\0'; -+ -+ /* try to select default state at first (if it exists) */ -+ state = pinctrl_lookup_state(data->pinctrl, state_name); -+ if (!IS_ERR(state)) { -+ err = pinctrl_select_state(data->pinctrl, state); -+ if (err != 0) -+ dev_err(dev, "Failed to select state %s\n", -+ state_name); -+ } else { -+ dev_err(dev, "Failed to find state %s\n", state_name); -+ err = PTR_RET(state); -+ } -+ -+ if (err == 0) { -+ kfree(data->selected_state_name); -+ data->selected_state_name = state_name; -+ } -+ -+ return err ? err : count; -+} -+ -+static DEVICE_ATTR(state, S_IWUSR | S_IRUGO, -+ pinmux_helper_show_state, pinmux_helper_store_state); -+ -+static struct attribute *pinmux_helper_attributes[] = { -+ &dev_attr_state.attr, -+ NULL -+}; -+ -+static const struct attribute_group pinmux_helper_attr_group = { -+ .attrs = pinmux_helper_attributes, -+}; -+ -+static int bone_pinmux_helper_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct pinmux_helper_data *data; -+ struct pinctrl_state *state; -+ char *state_name; -+ const char *mode_name; -+ int mode_len; -+ int err; -+ -+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); -+ if (data == NULL) { -+ dev_err(dev, "Failed to allocate data\n"); -+ err = -ENOMEM; -+ goto err_no_mem; -+ } -+ -+ state_name = kmalloc(strlen(PINCTRL_STATE_DEFAULT) + 1, -+ GFP_KERNEL); -+ if (state_name == NULL) { -+ dev_err(dev, "Failed to allocate state name\n"); -+ err = -ENOMEM; -+ goto err_no_state_mem; -+ } -+ data->selected_state_name = state_name; -+ strcpy(data->selected_state_name, PINCTRL_STATE_DEFAULT); -+ -+ platform_set_drvdata(pdev, data); -+ -+ data->pinctrl = devm_pinctrl_get(dev); -+ if (IS_ERR(data->pinctrl)) { -+ dev_err(dev, "Failed to get pinctrl\n"); -+ err = PTR_RET(data->pinctrl); -+ goto err_no_pinctrl; -+ } -+ -+ /* See if an initial mode is specified in the device tree */ -+ mode_name = of_get_property(dev->of_node, "mode", &mode_len); -+ -+ err = -1; -+ if (mode_name != NULL ) { -+ state_name = kmalloc(mode_len + 1, GFP_KERNEL); -+ if (state_name == NULL) { -+ dev_err(dev, "Failed to allocate state name\n"); -+ err = -ENOMEM; -+ goto err_no_mode_mem; -+ } -+ strncpy(state_name, mode_name, mode_len); -+ -+ /* try to select requested mode */ -+ state = pinctrl_lookup_state(data->pinctrl, state_name); -+ if (!IS_ERR(state)) { -+ err = pinctrl_select_state(data->pinctrl, state); -+ if (err != 0) { -+ dev_warn(dev, "Unable to select requested mode %s\n", state_name); -+ kfree(state_name); -+ } else { -+ kfree(data->selected_state_name); -+ data->selected_state_name = state_name; -+ dev_notice(dev, "Set initial pinmux mode to %s\n", state_name); -+ } -+ } -+ } -+ -+ /* try to select default state if mode_name failed */ -+ if ( err != 0) { -+ state = pinctrl_lookup_state(data->pinctrl, -+ data->selected_state_name); -+ if (!IS_ERR(state)) { -+ err = pinctrl_select_state(data->pinctrl, state); -+ if (err != 0) { -+ dev_err(dev, "Failed to select default state\n"); -+ goto err_no_state; -+ } -+ } else { -+ data->selected_state_name = '\0'; -+ } -+ } -+ -+ /* Register sysfs hooks */ -+ err = sysfs_create_group(&dev->kobj, &pinmux_helper_attr_group); -+ if (err) { -+ dev_err(dev, "Failed to create sysfs group\n"); -+ goto err_no_sysfs; -+ } -+ -+ return 0; -+ -+err_no_sysfs: -+err_no_state: -+err_no_mode_mem: -+ devm_pinctrl_put(data->pinctrl); -+err_no_pinctrl: -+ devm_kfree(dev, data->selected_state_name); -+err_no_state_mem: -+ devm_kfree(dev, data); -+err_no_mem: -+ return err; -+} -+ -+static int bone_pinmux_helper_remove(struct platform_device *pdev) -+{ -+ struct pinmux_helper_data *data = platform_get_drvdata(pdev); -+ struct device *dev = &pdev->dev; -+ -+ sysfs_remove_group(&dev->kobj, &pinmux_helper_attr_group); -+ kfree(data->selected_state_name); -+ devm_pinctrl_put(data->pinctrl); -+ devm_kfree(dev, data); -+ -+ return 0; -+} -+ -+struct platform_driver bone_pinmux_helper_driver = { -+ .probe = bone_pinmux_helper_probe, -+ .remove = bone_pinmux_helper_remove, -+ .driver = { -+ .name = "bone-pinmux-helper", -+ .owner = THIS_MODULE, -+ .of_match_table = bone_pinmux_helper_of_match, -+ }, -+}; -+ -+module_platform_driver(bone_pinmux_helper_driver); -+ -+MODULE_AUTHOR("Pantelis Antoniou"); -+MODULE_DESCRIPTION("Beaglebone pinmux helper driver"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:bone-pinmux-helper"); -diff --git b/drivers/misc/cape_bone_argus/Kconfig b/drivers/misc/cape_bone_argus/Kconfig -new file mode 100644 -index 0000000..1b39661 ---- /dev/null -+++ b/drivers/misc/cape_bone_argus/Kconfig -@@ -0,0 +1,7 @@ -+comment "Argus cape driver for beaglebone black" -+ -+config CAPE_BONE_ARGUS -+ tristate "Argus Cape Driver" -+ default M -+ help -+ Argus Cape Driver -diff --git b/drivers/misc/cape_bone_argus/Makefile b/drivers/misc/cape_bone_argus/Makefile -new file mode 100644 -index 0000000..5482562 ---- /dev/null -+++ b/drivers/misc/cape_bone_argus/Makefile -@@ -0,0 +1,5 @@ -+# -+# Makefile for Argus cape -+# -+ -+obj-$(CONFIG_CAPE_BONE_ARGUS) += cape_bone_argus.o -diff --git b/drivers/misc/cape_bone_argus/cape_bone_argus.c b/drivers/misc/cape_bone_argus/cape_bone_argus.c -new file mode 100644 -index 0000000..c434218 ---- /dev/null -+++ b/drivers/misc/cape_bone_argus/cape_bone_argus.c -@@ -0,0 +1,415 @@ -+/* -*- linux-c -*- */ -+ -+/* Linux Kernel Module for Breakaway Systems UPS control. -+ * -+ * PUBLIC DOMAIN -+ */ -+ -+#include <linux/syscalls.h> -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/reboot.h> -+#include <linux/fs.h> -+#include <linux/uaccess.h> -+#include <linux/delay.h> -+#include <linux/gpio.h> -+#include <linux/mount.h> -+#include <linux/workqueue.h> -+#include <linux/cdev.h> -+#include <linux/platform_device.h> -+#include <linux/of.h> -+#include <linux/of_device.h> -+#include <linux/pinctrl/pinctrl.h> -+#include <linux/pinctrl/pinmux.h> -+#include <linux/pinctrl/consumer.h> -+#include <linux/of_gpio.h> -+ -+/* Module to sync file systems leaving them mounted read-only, -+ * then signal the UPS that it is safe to remove -+ * power, and finally halt the processor. -+ * Also to allow kicking the watchdog from user mode. -+ */ -+#undef DEBUG_ARGUS -+ -+#define N_GPIOS 9 /* Total number of GPIOS used */ -+ -+#define REQ_GPIO_IDX 0 /* Indices got GPIOS */ -+#define ACK_GPIO_IDX 1 -+#define WDG_GPIO_IDX 2 -+#define LED1_GREEN_IDX 3 -+#define LED1_RED_IDX 4 -+#define LED2_GREEN_IDX 5 -+#define LED2_RED_IDX 6 -+#define GEN_OUT1_IDX 7 -+#define GEN_OUT2_IDX 8 -+ -+static struct argus_ups_info { /* As there is only one UPS device we can make this static */ -+ struct fasync_struct *async_queue; /* asynchronous readers */ -+ struct platform_device *pdev; -+ struct pwm_device *pwm_dev; -+ struct gpio gpios[N_GPIOS]; -+} info = {NULL, NULL, NULL, /* Some fields filled in by device tree, probe, etc. */ -+ { -+ {-1, GPIOF_IN, "Powerdown request"}, -+ {-1, GPIOF_OUT_INIT_LOW, "Powerdown acknowledge" }, -+ {-1, GPIOF_OUT_INIT_LOW, "Watchdog"}, -+ {-1, GPIOF_OUT_INIT_LOW, "LED 1 Green"}, -+ {-1, GPIOF_OUT_INIT_LOW, "LED 1 Red"}, -+ {-1, GPIOF_OUT_INIT_LOW, "LED 2 Green"}, -+ {-1, GPIOF_OUT_INIT_LOW, "LED 2 Red"}, -+ {-1, GPIOF_OUT_INIT_LOW, "General Output #1"}, -+ {-1, GPIOF_OUT_INIT_LOW, "General Output #2"} -+ }, -+}; -+ -+ -+static const struct of_device_id argus_ups_of_ids[] = { -+ { .compatible = "argus-ups" }, -+ { } -+}; -+ -+static int argus_ups_major; /* Major device number */ -+ -+static struct class *argus_ups_class; /* /sys/class */ -+ -+dev_t argus_ups_dev; /* Device number */ -+ -+static struct cdev *argus_ups_cdev; /* Character device details */ -+ -+static void argus_ups_function(struct work_struct *ignored); /* Work function */ -+ -+static DECLARE_DELAYED_WORK(argus_ups_work, argus_ups_function); /* Kernel workqueue glue */ -+ -+static struct workqueue_struct *argus_ups_workqueue; /* Kernel workqueue */ -+ -+static int debug = 0; -+module_param(debug, int, S_IRUGO); -+MODULE_PARM_DESC(debug, "Debug flag"); -+ -+static int shutdown = 1; -+module_param(shutdown, int, S_IRUGO); -+MODULE_PARM_DESC(shutdown, "Shutdown flag"); -+ -+#ifdef DEBUG_ARGUS -+static char* fs_type_names[] = {"vfat", "ext4"}; /* File system names that may need syncing. */ -+#endif -+ -+/* Just kick watchdog */ -+ -+static ssize_t argus_ups_write(struct file *filp, const char __user *buf, size_t count, -+ loff_t *f_pos) -+{ -+ int i; -+ if (debug >= 3) { -+ printk("Writing to watchdog - count:%d\n", count); -+ } -+ for (i = 0; i < count; i++) { -+ gpio_set_value(info.gpios[WDG_GPIO_IDX].gpio, 1); /* Set it */ -+ msleep(10); /* Wait */ -+ gpio_set_value(info.gpios[WDG_GPIO_IDX].gpio, 0); /* End clearing it */ -+ msleep(10); -+ } -+ return count; /* Always returns what we sent, regardsless */ -+} -+ -+static long argus_ups_ioctl(struct file *file, -+ unsigned int ioctl, -+ unsigned long param) -+{ -+ if (debug >= 4) { -+ printk(KERN_ERR "ioctl: %d, param: %ld\n", ioctl, param); -+ } -+ switch(ioctl) { -+ case 10001: { -+ debug = param; -+ printk("Debug set to %d\n", debug); -+ break; -+ } -+ case 10002: { -+ unsigned char value = param & 0x0F; -+ unsigned char mask = (param >> 4) & 0x0F; -+ int i; /* Loop iterator */ -+ if (mask == 0) { -+ printk(KERN_ERR "Pointless mask of zero!\n"); -+ } -+ for (i = 0; i < 4; i++) { /* For all four LEDS */ -+ if (mask & (1 << i)) { /* Only masked values */ -+ if (value & (1 << i)) { /* On - so gpio is hi */ -+ if (debug >= 4) { -+ printk("Setting %d hi, ", -+ info.gpios[LED1_GREEN_IDX + i].gpio); -+ } -+ gpio_set_value(info.gpios[LED1_GREEN_IDX + i].gpio, 1); -+ } -+ else { /* Off - so gpio is lo */ -+ if (debug >= 4) { -+ printk("Setting %d lo, ", -+ info.gpios[LED1_GREEN_IDX + i].gpio); -+ } -+ gpio_set_value(info.gpios[LED1_GREEN_IDX + i].gpio, 0); -+ } -+ } -+ } -+ if (debug >= 4) { -+ printk("\n"); -+ } -+ break; -+ } -+ case 10003: { -+ gpio_set_value(info.gpios[GEN_OUT1_IDX].gpio, param & 1); -+ break; -+ } -+ case 10004: { -+ gpio_set_value(info.gpios[GEN_OUT2_IDX].gpio, param & 1); -+ break; -+ } -+ default: -+ { -+ printk(KERN_ERR "Invalid ioctl %d\n", ioctl); -+ return -1; -+ } -+ } -+ return 0; -+} -+ -+static int argus_ups_fasync(int fd, struct file *filp, int mode) -+{ -+ printk(KERN_ERR "In argus_ups_fasync() fd:%d, filp:%p, mode:%d\n", fd, filp, mode); -+ return fasync_helper(fd, filp, mode, &info.async_queue); -+} -+ -+static struct file_operations argus_ups_fops = { /* Only file operation is to kick watchdog via a write */ -+ .owner = THIS_MODULE, -+ .llseek = NULL, -+ .read = NULL, -+ .unlocked_ioctl = argus_ups_ioctl, -+ .write = argus_ups_write, -+ .open = NULL, -+ .release = NULL, -+ .fasync = argus_ups_fasync, -+}; -+ -+#ifdef DEBUG_ARGUS -+static void remount_sb(struct super_block *sb) -+{ -+ int flags = MS_RDONLY; -+ int result = sb->s_op->remount_fs(sb, &flags, ""); -+ if (debug) { -+ printk("Processing superblock %p\n", sb); -+ printk("Remount operation returned %d\n", result); -+ } -+} -+#endif -+ -+static void argus_ups_function(struct work_struct *ignored) -+{ -+ static int testdata = 0; /* Data for test */ -+ int i; /* Iterator */ -+ testdata++; -+ if (!gpio_get_value(info.gpios[REQ_GPIO_IDX].gpio)) { -+ queue_delayed_work(argus_ups_workqueue, &argus_ups_work, HZ/100); /* Re-queue in 10mS*/ -+ return; -+ } -+ printk(KERN_ERR "Request received\n"); -+ if (debug) { -+ printk("Shutdown request received from UPS\n"); -+ } -+ if (!shutdown) { -+ printk("Shutdown request ignored\n"); -+ return; -+ } -+ -+ if (debug) { -+ printk("Sending async kill SIGIO to %p\n", info.async_queue); -+ } -+ if (info.async_queue) { /* Try and tell usermode to halt system */ -+ kill_fasync(&info.async_queue, SIGIO, POLL_IN); -+ } -+ gpio_set_value(info.gpios[LED1_GREEN_IDX].gpio, 0); /* Turn off green LED1 */ -+ for (i = 0; i < 300; i++) { /* Toggle acknowledge at 10 Hz for 15 seconds */ -+ if (debug >= 2) { -+ printk("Waiting for first shutdown request:%d\n", i); -+ } -+ gpio_set_value(info.gpios[ACK_GPIO_IDX].gpio, i & 1); /* Toggle acknowledge */ -+ gpio_set_value(info.gpios[LED1_RED_IDX].gpio, i & 1); /* and LED1 red */ -+ msleep(50); /* Wait in 50ms increments */ -+ } -+ -+ { -+ char *argv[] = { "/sbin/halt", NULL }; -+ static char *envp[] = { -+ "HOME=/", -+ "TERM=linux", -+ "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin", NULL }; -+ -+ call_usermodehelper( argv[0], argv, envp, UMH_WAIT_PROC ); -+ } -+ for (i = 0; i < 300; i++) { /* Toggle acknowledge at 10 Hz for 15 more seconds */ -+ if (debug >= 2) { -+ printk("Waiting for second shutdown request:%d\n", i); -+ } -+ gpio_set_value(info.gpios[ACK_GPIO_IDX].gpio, i & 1); /* Toggle acknowledge */ -+ gpio_set_value(info.gpios[LED1_RED_IDX].gpio, i & 1); /* and LED1 red */ -+ msleep(50); /* Wait in 50ms increments */ -+ } -+ printk(KERN_ERR "Usermode failed to halt system\n"); -+ kernel_halt(); /* Last resort - may give some oopss */ -+} -+ -+ -+static int argus_ups_probe(struct platform_device *pdev) /* Entry point */ -+{ -+ struct pinctrl *pinctrl; -+ struct device_node *pnode = pdev->dev.of_node; -+ int i; -+ int ret; -+ printk("Init UPS module - debug=%d, shutdown=%d\n", -+ debug, shutdown); -+ platform_set_drvdata(pdev, &info); -+ info.pdev = pdev; -+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev); -+ if (IS_ERR(pinctrl)) { -+ dev_warn(&pdev->dev, -+ "pins are not configured from the driver\n"); -+ return -1; -+ } -+ ret = of_property_read_u32(pnode, "debug", &debug); -+ if (ret != 0) { -+ dev_err(&pdev->dev, "Unable to read debug parameter\n"); -+ } -+ else { -+ printk("Debug parameter read from DT:%d\n", debug); -+ } -+ -+ ret = of_property_read_u32(pnode, "shutdown", &shutdown); -+ if (ret != 0) { -+ dev_err(&pdev->dev, "Unable to read shutdown parameter\n"); -+ } -+ else { -+ printk("Shutdown parameter read from DT:%d\n", shutdown); -+ } -+ -+ ret = of_gpio_count(pnode); -+ -+ if (ret != N_GPIOS) { -+ printk(KERN_ERR "Wrong number of gpios"); -+ return -1; -+ } -+ -+ for (i = 0; i < of_gpio_count(pnode); i++) { -+ ret = of_get_gpio_flags(pnode, i, NULL); -+ if (debug) { -+ printk("GPIO#%d:%d\n", i, ret); -+ } -+ if (IS_ERR_VALUE(ret)) { -+ dev_err(&pdev->dev, "unable to get GPIO %d\n", i); -+ goto err_no_gpio; -+ } -+ info.gpios[i].gpio = ret; -+ } -+ -+ -+ ret = alloc_chrdev_region(&argus_ups_dev, 0, 2, "argus_ups"); -+ argus_ups_major = MAJOR(argus_ups_dev); -+ if (ret) { -+ printk(KERN_ERR "Error %d adding argus_ups\n", ret); -+ return -1; -+ } -+ if (debug) { -+ printk("argus_ups major: %d\n", argus_ups_major); -+ } -+ argus_ups_cdev = cdev_alloc(); /* Make this a character device */ -+ argus_ups_cdev->ops = &argus_ups_fops; /* File operations */ -+ argus_ups_cdev->owner = THIS_MODULE; /* Top level device */ -+ ret = cdev_add(argus_ups_cdev, argus_ups_dev, 1); /* Add it to the kernel */ -+ if (ret) { -+ printk(KERN_ERR "cdev_add returned %d\n", ret); -+ unregister_chrdev_region(0, 1); -+ return -1; -+ } -+ ret = gpio_request_array(info.gpios, N_GPIOS); -+ if (ret) { -+ printk(KERN_ERR "Error %d requesting GPIOs\n", ret); -+ unregister_chrdev_region(0, 1); -+ return -1; -+ } -+ -+ argus_ups_class = class_create(THIS_MODULE, "argus_ups"); /* /sys/class entry for udev */ -+ if (IS_ERR(argus_ups_class)) { -+ printk(KERN_ERR "Error creating argus_ups_class\n"); -+ unregister_chrdev_region(0, 1); -+ return -1; -+ } -+ device_create(argus_ups_class, NULL, MKDEV(argus_ups_major, 0), NULL, "argus_ups"); -+ argus_ups_workqueue = create_singlethread_workqueue("argus_ups"); -+ INIT_DELAYED_WORK(&argus_ups_work, argus_ups_function); -+ queue_delayed_work(argus_ups_workqueue, &argus_ups_work, 0); /* Start work immediately */ -+ -+ return 0; -+err_no_gpio: -+ return ret; -+ -+} -+ -+ -+static void argus_ups_cleanup(void) -+{ -+ printk("Module cleanup called\n"); -+ while (cancel_delayed_work(&argus_ups_work) == 0) { -+ flush_workqueue(argus_ups_workqueue); /* Make sure all work is completed */ -+ } -+ destroy_workqueue(argus_ups_workqueue); -+ gpio_free_array(info.gpios, N_GPIOS); -+ device_destroy(argus_ups_class, argus_ups_dev); -+ class_destroy(argus_ups_class); -+ unregister_chrdev_region(argus_ups_dev, 1); -+ cdev_del(argus_ups_cdev); -+} -+ -+ -+ -+static int argus_ups_remove(struct platform_device *pdev) -+{ -+ printk("In argus_ups_remove()\n"); -+ argus_ups_cleanup(); -+ printk("After cleanup\n"); -+ return 0; -+} -+ -+#define ARGUS_UPS_PM_OPS NULL -+ -+struct platform_driver argus_ups_driver = { -+ .probe = argus_ups_probe, -+ .remove = argus_ups_remove, -+ .driver = { -+ .name = "argus-ups", -+ .owner = THIS_MODULE, -+ .pm = ARGUS_UPS_PM_OPS, -+ .of_match_table = argus_ups_of_ids, -+ }, -+}; -+ -+ -+static int __init argus_ups_init(void) -+{ -+ return platform_driver_probe(&argus_ups_driver, -+ argus_ups_probe); -+} -+ -+static void __exit argus_ups_exit(void) -+{ -+ platform_driver_unregister(&argus_ups_driver); -+ printk("After driver unregister\n"); -+} -+ -+module_init(argus_ups_init); -+module_exit(argus_ups_exit); -+ -+/* -+ * Get rid of taint message. -+ */ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("David Lambert"); /* Who wrote this module? */ -+MODULE_DESCRIPTION("Argus UPS control"); /* What does this module do */ -+MODULE_ALIAS("platform:argus-ups"); -+MODULE_DEVICE_TABLE(of, argus_ups_of_ids); -diff --git b/drivers/misc/devovmgr.c b/drivers/misc/devovmgr.c -new file mode 100644 -index 0000000..d5c8d1d ---- /dev/null -+++ b/drivers/misc/devovmgr.c -@@ -0,0 +1,1306 @@ -+/* -+ * Device overlay manager -+ * -+ * Copyright (C) 2015 Konsulko Group -+ * Pantelis Antoniou <pantelis.antoniou@konsulko.com> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+#include <linux/ctype.h> -+#include <linux/cpu.h> -+#include <linux/module.h> -+#include <linux/of.h> -+#include <linux/of_fdt.h> -+#include <linux/spinlock.h> -+#include <linux/sizes.h> -+#include <linux/slab.h> -+#include <linux/proc_fs.h> -+#include <linux/configfs.h> -+#include <linux/types.h> -+#include <linux/stat.h> -+#include <linux/limits.h> -+#include <linux/file.h> -+#include <linux/vmalloc.h> -+#include <linux/firmware.h> -+#include <linux/pci.h> -+#include <linux/usb.h> -+#include <linux/mod_devicetable.h> -+#include <linux/workqueue.h> -+#include <linux/firmware.h> -+ -+enum dovmgr_type { -+ ITEM_PCI, -+ ITEM_USB -+}; -+ -+struct dovmgr_item; -+ -+struct dovmgr_dev_item { -+ struct dovmgr_item *item; -+ struct list_head node; -+ struct device *dev; -+ const struct firmware *fw; -+ struct device_node *overlay; -+ int overlay_id; -+ struct work_struct work; -+}; -+ -+struct dovmgr_item { -+ struct config_item item; -+ char *path; -+ bool enable; -+ char *overlay_name; -+ struct mutex dev_item_mutex; -+ struct list_head dev_item_list; -+ enum dovmgr_type type; -+ union { -+ struct pci_device_id pci; -+ struct usb_device_id usb; -+ }; -+}; -+ -+struct config_group dovmgr_pci_group; -+struct config_group dovmgr_usb_group; -+ -+static inline struct dovmgr_item *to_dovmgr_item(struct config_item *cfsitem) -+{ -+ if (!cfsitem) -+ return NULL; -+ -+ return container_of(cfsitem, struct dovmgr_item, item); -+} -+ -+static int dovmgr_notifier_action(struct config_group *group, -+ unsigned long action, struct device *dev, -+ int (*do_match)(struct dovmgr_item *item, struct device *dev), -+ int (*do_action)(struct dovmgr_item *item, unsigned long action, -+ struct device *dev)) -+{ -+ struct config_item *cfsitem; -+ struct dovmgr_item *item; -+ int ret; -+ -+ /* only handle device notifiers */ -+ if (action != BUS_NOTIFY_ADD_DEVICE && -+ action != BUS_NOTIFY_DEL_DEVICE && -+ action != BUS_NOTIFY_REMOVED_DEVICE) -+ return 0; -+ -+ ret = 0; -+ list_for_each_entry(cfsitem, &group->cg_children, ci_entry) { -+ item = to_dovmgr_item(cfsitem); -+ if (!item->enable || !(*do_match)(item, dev)) -+ continue; -+ -+ ret = (*do_action)(item, action, dev); -+ if (ret != 0) -+ break; -+ } -+ return ret; -+} -+ -+#if IS_ENABLED(CONFIG_PCI) -+/* copy of drivers/pci/pci.h */ -+static inline const struct pci_device_id * -+pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev) -+{ -+ if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) && -+ (id->device == PCI_ANY_ID || id->device == dev->device) && -+ (id->subvendor == PCI_ANY_ID || -+ id->subvendor == dev->subsystem_vendor) && -+ (id->subdevice == PCI_ANY_ID || -+ id->subdevice == dev->subsystem_device) && -+ !((id->class ^ dev->class) & id->class_mask)) -+ return id; -+ return NULL; -+} -+ -+static int dovmgr_pci_item_match(struct dovmgr_item *item, struct device *dev) -+{ -+ struct pci_dev *pdev; -+ -+ BUG_ON(item->type != ITEM_PCI); -+ pdev = to_pci_dev(dev); -+ -+ return pci_match_one_device(&item->pci, pdev) != NULL; -+} -+#endif -+ -+#if IS_ENABLED(CONFIG_USB) -+/* in drivers/usb/core/driver.c */ -+extern int usb_match_device(struct usb_device *dev, -+ const struct usb_device_id *id); -+ -+static int dovmgr_usb_item_match(struct dovmgr_item *item, struct device *dev) -+{ -+ struct usb_device *udev; -+ -+ BUG_ON(item->type != ITEM_USB); -+ udev = to_usb_device(dev); -+ -+ return usb_match_device(udev, &item->usb); -+} -+#endif -+ -+static struct dovmgr_dev_item *dovmgr_lookup_dev_item(struct dovmgr_item *item, -+ struct device *dev) -+{ -+ struct dovmgr_dev_item *ditem; -+ -+ list_for_each_entry(ditem, &item->dev_item_list, node) -+ if (ditem->dev == dev) -+ return ditem; -+ return NULL; -+} -+ -+static void dovmgr_item_work_func(struct work_struct *work) -+{ -+ struct dovmgr_dev_item *ditem = container_of(work, -+ struct dovmgr_dev_item, work); -+ struct dovmgr_item *item = ditem->item; -+ struct device *dev; -+ struct device_node *np; -+ int err; -+ -+ mutex_lock(&item->dev_item_mutex); -+ -+ dev = ditem->dev; -+ np = dev->of_node; -+ if (!dev || !np || !item->overlay_name || ditem->overlay_id >= 0) -+ goto out_unlock; -+ -+ pr_info("%s: %s %s\n", __func__, -+ kobject_name(&dev->kobj), of_node_full_name(np)); -+ -+ err = request_firmware_direct(&ditem->fw, item->overlay_name, dev); -+ if (err != 0) { -+ pr_err("%s: %s failed to load firmware '%s'\n", __func__, -+ kobject_name(&dev->kobj), item->overlay_name); -+ goto out_unlock; -+ } -+ -+ of_fdt_unflatten_tree((void *)ditem->fw->data, &ditem->overlay); -+ if (ditem->overlay == NULL) { -+ pr_err("%s: %s failed to load firmware '%s'\n", __func__, -+ kobject_name(&dev->kobj), item->overlay_name); -+ goto out_release_fw; -+ } -+ -+ /* mark it as detached */ -+ of_node_set_flag(ditem->overlay, OF_DETACHED); -+ -+ /* perform resolution */ -+ err = of_resolve_phandles(ditem->overlay); -+ if (err != 0) { -+ pr_err("%s: %s failed to resolve tree\n", __func__, -+ kobject_name(&dev->kobj)); -+ goto out_release_overlay; -+ } -+ -+ err = of_overlay_create_target_root(ditem->overlay, np); -+ if (err < 0) { -+ pr_err("%s: %s failed to create overlay\n", __func__, -+ kobject_name(&dev->kobj)); -+ goto out_release_overlay; -+ } -+ ditem->overlay_id = err; -+ -+out_unlock: -+ mutex_unlock(&item->dev_item_mutex); -+ return; -+ -+out_release_overlay: -+ /* TODO: free the overlay, we can't right now cause -+ * the unflatten method does not track it */ -+ ditem->overlay = NULL; -+out_release_fw: -+ release_firmware(ditem->fw); -+ ditem->fw = NULL; -+ goto out_unlock; -+} -+ -+/* dev item list mutex lock must be held */ -+static int dovmgr_add_dev_item(struct dovmgr_item *item, struct device *dev) -+{ -+ struct dovmgr_dev_item *ditem; -+ -+ /* first make sure there's no duplicate */ -+ if (dovmgr_lookup_dev_item(item, dev)) -+ return -EEXIST; -+ -+ /* add the device item */ -+ ditem = kzalloc(sizeof(*ditem), GFP_KERNEL); -+ if (!ditem) -+ return -ENOMEM; -+ ditem->overlay_id = -1; -+ ditem->dev = get_device(dev); -+ INIT_WORK(&ditem->work, dovmgr_item_work_func); -+ ditem->item = item; -+ -+ list_add_tail(&ditem->node, &item->dev_item_list); -+ -+ pr_info("%s: added device %s from item's %s list\n", __func__, -+ kobject_name(&dev->kobj), -+ config_item_name(&item->item)); -+ -+ /* now schedule the overlay application */ -+ if (item->overlay_name) -+ schedule_work(&ditem->work); -+ -+ return 0; -+} -+ -+static int dovmgr_remove_dev_item(struct dovmgr_item *item, struct device *dev) -+{ -+ struct dovmgr_dev_item *ditem; -+ -+ /* find it */ -+ ditem = dovmgr_lookup_dev_item(item, dev); -+ if (!ditem) -+ return -ENODEV; -+ -+ if (work_pending(&ditem->work)) -+ cancel_work_sync(&ditem->work); -+ -+ if (ditem->overlay_id >= 0) { -+ of_overlay_destroy(ditem->overlay_id); -+ ditem->overlay_id = -1; -+ -+ } -+ -+ if (ditem->overlay) { -+ /* TODO: free the overlay, we can't right now cause -+ * the unflatten method does not track it */ -+ ditem->overlay = NULL; -+ } -+ -+ if (ditem->fw) { -+ /* TODO release_firmware(ditem->fw); */ -+ release_firmware(ditem->fw); -+ ditem->fw = NULL; -+ } -+ -+ put_device(ditem->dev); -+ list_del(&ditem->node); -+ -+ kfree(ditem); -+ -+ pr_info("%s: removed device %s from item's %s list\n", __func__, -+ kobject_name(&dev->kobj), -+ config_item_name(&item->item)); -+ -+ return 0; -+} -+ -+static int dovmgr_item_notify(struct dovmgr_item *item, -+ unsigned long action, struct device *dev) -+{ -+ int ret; -+ -+ ret = 0; -+ mutex_lock(&item->dev_item_mutex); -+ -+ switch (action) { -+ case BUS_NOTIFY_ADD_DEVICE: -+ pr_info("%s: BUS_NOTIFY_ADD_DEVICE for %s\n", __func__, -+ kobject_name(&dev->kobj)); -+ -+ ret = dovmgr_add_dev_item(item, dev); -+ if (ret != 0) -+ goto out_unlock; -+ -+ break; -+ -+ case BUS_NOTIFY_DEL_DEVICE: -+ pr_info("%s: BUS_NOTIFY_DEL_DEVICE for %s\n", __func__, -+ kobject_name(&dev->kobj)); -+ break; -+ -+ case BUS_NOTIFY_REMOVED_DEVICE: -+ pr_info("%s: BUS_NOTIFY_REMOVE_DEVICE for %s\n", __func__, -+ kobject_name(&dev->kobj)); -+ -+ ret = dovmgr_remove_dev_item(item, dev); -+ if (ret != 0) -+ goto out_unlock; -+ -+ break; -+ } -+ -+out_unlock: -+ mutex_unlock(&item->dev_item_mutex); -+ -+ return ret; -+} -+ -+#if IS_ENABLED(CONFIG_PCI) -+static int dovmgr_pci_add_iterator(struct device *dev, void *data) -+{ -+ struct dovmgr_item *item = data; -+ -+ /* do add match */ -+ if (!item->enable || !dovmgr_pci_item_match(item, dev)) -+ return 0; -+ -+ pr_info("%s: dev=%s\n", __func__, kobject_name(&dev->kobj)); -+ -+ return dovmgr_item_notify(item, BUS_NOTIFY_ADD_DEVICE, dev); -+} -+ -+static int dovmgr_pci_removed_iterator(struct device *dev, void *data) -+{ -+ struct dovmgr_item *item = data; -+ -+ /* do add match */ -+ if (item->enable || !dovmgr_pci_item_match(item, dev)) -+ return 0; -+ -+ pr_info("%s: dev=%s\n", __func__, kobject_name(&dev->kobj)); -+ -+ return dovmgr_item_notify(item, BUS_NOTIFY_REMOVED_DEVICE, dev); -+} -+#endif -+ -+#if IS_ENABLED(CONFIG_USB) -+static int dovmgr_usb_add_iterator(struct device *dev, void *data) -+{ -+ struct dovmgr_item *item = data; -+ -+ /* do add match */ -+ if (item->enable || !dovmgr_usb_item_match(item, dev)) -+ return 0; -+ -+ pr_info("%s: dev=%s\n", __func__, kobject_name(&dev->kobj)); -+ -+ return dovmgr_item_notify(item, BUS_NOTIFY_ADD_DEVICE, dev); -+} -+ -+static int dovmgr_usb_removed_iterator(struct device *dev, void *data) -+{ -+ struct dovmgr_item *item = data; -+ -+ /* do add match */ -+ if (!item->enable || !dovmgr_usb_item_match(item, dev)) -+ return 0; -+ -+ pr_info("%s: dev=%s\n", __func__, kobject_name(&dev->kobj)); -+ -+ return dovmgr_item_notify(item, BUS_NOTIFY_REMOVED_DEVICE, dev); -+} -+#endif -+ -+static int dovmgr_item_set_enable(struct dovmgr_item *item, bool new_enable) -+{ -+ int ret; -+ -+ if (new_enable == item->enable) -+ return 0; -+ -+ item->enable = new_enable; -+ switch (item->type) { -+#if IS_ENABLED(CONFIG_PCI) -+ case ITEM_PCI: -+ ret = bus_for_each_dev(&pci_bus_type, NULL, item, -+ new_enable ? dovmgr_pci_add_iterator : -+ dovmgr_pci_removed_iterator); -+ if (ret != 0) -+ return ret; -+ break; -+#endif -+#if IS_ENABLED(CONFIG_USB) -+ case ITEM_USB: -+ ret = bus_for_each_dev(&usb_bus_type, NULL, item, -+ new_enable ? dovmgr_usb_add_iterator : -+ dovmgr_usb_removed_iterator); -+ if (ret != 0) -+ return ret; -+ break; -+#endif -+ default: -+ break; -+ } -+ return 0; -+} -+ -+ -+static ssize_t dovmgr_item_str_show(struct dovmgr_item *item, -+ char *page, char **strp) -+{ -+ return snprintf(page, PAGE_SIZE, "%s\n", -+ *strp ? *strp : ""); -+} -+ -+static ssize_t dovmgr_item_str_store(struct dovmgr_item *item, -+ const char *page, size_t count, char **strp) -+{ -+ const char *s; -+ int len; -+ -+ /* copy to path buffer (and make sure it's always zero terminated */ -+ len = strnlen(page, PAGE_SIZE); -+ if (len >= PAGE_SIZE) -+ return -EINVAL; -+ s = page + len; -+ while (len > 0 && *--s == '\n') -+ len--; -+ if (len == 0) -+ return -EINVAL; -+ -+ if (*strp) -+ kfree(*strp); -+ *strp = kmalloc(len + 1, GFP_KERNEL); -+ if (!*strp) -+ return -ENOMEM; -+ memcpy(*strp, page, len); -+ (*strp)[len + 1] = '\0'; -+ -+ return count; -+} -+ -+static ssize_t dovmgr_item_path_show(struct config_item *citem, char *page) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ return dovmgr_item_str_show(item, page, &item->path); -+} -+ -+static ssize_t dovmgr_item_path_store(struct config_item *citem, -+ const char *page, size_t count) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ return dovmgr_item_str_store(item, page, count, &item->path); -+} -+ -+static ssize_t dovmgr_item_enable_show(struct config_item *citem, char *page) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ return snprintf(page, PAGE_SIZE, "%u\n", !!item->enable); -+} -+ -+static ssize_t dovmgr_item_enable_store(struct config_item *citem, -+ const char *page, size_t count) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ int ret; -+ unsigned int val; -+ -+ ret = kstrtouint(page, 0, &val); -+ if (ret != 0) -+ return ret; -+ -+ ret = dovmgr_item_set_enable(item, !!val); -+ if (ret != 0) -+ return ret; -+ -+ return count; -+} -+ -+static ssize_t dovmgr_item_overlay_show(struct config_item *citem, char *page) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ ssize_t ret; -+ -+ mutex_lock(&item->dev_item_mutex); -+ ret = snprintf(page, PAGE_SIZE, "%s\n", item->overlay_name ? -+ item->overlay_name : ""); -+ mutex_unlock(&item->dev_item_mutex); -+ return ret; -+}; -+ -+ -+static ssize_t dovmgr_item_overlay_store(struct config_item *citem, -+ const char *page, size_t count) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ ssize_t ret; -+ -+ mutex_lock(&item->dev_item_mutex); -+ kfree(item->overlay_name); -+ item->overlay_name = kstrndup(page, PAGE_SIZE, GFP_KERNEL); -+ if (!item->overlay_name) -+ ret = -ENOMEM; -+ else -+ ret = count; -+ mutex_unlock(&item->dev_item_mutex); -+ return ret; -+} -+ -+static ssize_t dovmgr_item_status_show(struct config_item *citem, char *page) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ struct dovmgr_dev_item *ditem; -+ char *p, *e; -+ int len; -+ -+ p = page; -+ e = page + PAGE_SIZE; -+ -+ mutex_lock(&item->dev_item_mutex); -+ list_for_each_entry(ditem, &item->dev_item_list, node) { -+ len = snprintf(p, e - p, "%s:%s:%d\n", -+ kobject_name(&ditem->dev->kobj), -+ of_node_full_name(ditem->dev->of_node), -+ ditem->overlay_id); -+ p += len; -+ if (p >= e - 1) -+ break; -+ } -+ mutex_unlock(&item->dev_item_mutex); -+ -+ return p - page; -+} -+ -+CONFIGFS_ATTR(dovmgr_item_, path); -+CONFIGFS_ATTR_RO(dovmgr_item_, status); -+CONFIGFS_ATTR(dovmgr_item_, enable); -+CONFIGFS_ATTR(dovmgr_item_, overlay); -+ -+#if IS_ENABLED(CONFIG_PCI) -+static ssize_t dovmgr_item_pci_device_show(struct config_item *citem, -+ char *page) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ return snprintf(page, PAGE_SIZE, "0x%04x\n", item->pci.device); -+} -+ -+static ssize_t dovmgr_item_pci_device_store(struct config_item *citem, -+ const char *page, size_t count) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ int ret; -+ unsigned int val; -+ -+ ret = kstrtouint(page, 0, &val); -+ if (ret != 0) -+ return ret; -+ item->pci.device = val; -+ return count; -+} -+ -+static ssize_t dovmgr_item_pci_vendor_show(struct config_item *citem, -+ char *page) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ return snprintf(page, PAGE_SIZE, "0x%04x\n", item->pci.vendor); -+} -+ -+static ssize_t dovmgr_item_pci_vendor_store(struct config_item *citem, -+ const char *page, size_t count) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ int ret; -+ unsigned int val; -+ -+ /* cannot modify when item is enabled */ -+ if (item->enable) -+ return -EBUSY; -+ -+ ret = kstrtouint(page, 0, &val); -+ if (ret != 0) -+ return ret; -+ item->pci.vendor = val; -+ return count; -+} -+ -+static ssize_t dovmgr_item_pci_subdevice_show(struct config_item *citem, -+ char *page) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ return snprintf(page, PAGE_SIZE, "0x%08x\n", item->pci.subdevice); -+} -+ -+static ssize_t dovmgr_item_pci_subdevice_store(struct config_item *citem, -+ const char *page, size_t count) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ int ret; -+ unsigned int val; -+ -+ /* cannot modify when item is enabled */ -+ if (item->enable) -+ return -EBUSY; -+ -+ ret = kstrtouint(page, 0, &val); -+ if (ret != 0) -+ return ret; -+ item->pci.subdevice = val; -+ return count; -+} -+ -+static ssize_t dovmgr_item_pci_subvendor_show(struct config_item *citem, -+ char *page) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ return snprintf(page, PAGE_SIZE, "0x%08x\n", item->pci.subvendor); -+} -+ -+static ssize_t dovmgr_item_pci_subvendor_store(struct config_item *citem, -+ const char *page, size_t count) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ int ret; -+ unsigned int val; -+ -+ /* cannot modify when item is enabled */ -+ if (item->enable) -+ return -EBUSY; -+ -+ ret = kstrtouint(page, 0, &val); -+ if (ret != 0) -+ return ret; -+ item->pci.subvendor = val; -+ return count; -+} -+ -+static ssize_t dovmgr_item_pci_class_show(struct config_item *citem, char *page) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ return snprintf(page, PAGE_SIZE, "0x%04x\n", item->pci.class); -+} -+ -+static ssize_t dovmgr_item_pci_class_store(struct config_item *citem, -+ const char *page, size_t count) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ int ret; -+ unsigned int val; -+ -+ /* cannot modify when item is enabled */ -+ if (item->enable) -+ return -EBUSY; -+ -+ ret = kstrtouint(page, 0, &val); -+ if (ret != 0) -+ return ret; -+ item->pci.class = val; -+ return count; -+} -+ -+static ssize_t dovmgr_item_pci_class_mask_show(struct config_item *citem, -+ char *page) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ return snprintf(page, PAGE_SIZE, "0x%04x\n", item->pci.class_mask); -+} -+ -+static ssize_t dovmgr_item_pci_class_mask_store(struct config_item *citem, -+ const char *page, size_t count) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ int ret; -+ unsigned int val; -+ -+ /* cannot modify when item is enabled */ -+ if (item->enable) -+ return -EBUSY; -+ -+ ret = kstrtouint(page, 0, &val); -+ if (ret != 0) -+ return ret; -+ item->pci.class_mask = val; -+ return count; -+} -+ -+CONFIGFS_ATTR(dovmgr_item_pci_, device); -+CONFIGFS_ATTR(dovmgr_item_pci_, vendor); -+CONFIGFS_ATTR(dovmgr_item_pci_, subdevice); -+CONFIGFS_ATTR(dovmgr_item_pci_, subvendor); -+CONFIGFS_ATTR(dovmgr_item_pci_, class); -+CONFIGFS_ATTR(dovmgr_item_pci_, class_mask); -+#endif -+ -+#if IS_ENABLED(CONFIG_USB) -+static ssize_t dovmgr_item_usb_idProduct_show(struct config_item *citem, -+ char *page) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ return snprintf(page, PAGE_SIZE, "0x%04x\n", -+ item->usb.idProduct); -+} -+ -+static ssize_t dovmgr_item_usb_idProduct_store(struct config_item *citem, -+ const char *page, size_t count) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ int ret; -+ unsigned int val; -+ -+ /* cannot modify when item is enabled */ -+ if (item->enable) -+ return -EBUSY; -+ -+ ret = kstrtouint(page, 0, &val); -+ if (ret != 0) -+ return ret; -+ item->usb.idProduct = val; -+ return count; -+} -+ -+static ssize_t dovmgr_item_usb_idVendor_show(struct config_item *citem, -+ char *page) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ return snprintf(page, PAGE_SIZE, "0x%04x\n", -+ item->usb.idVendor); -+} -+ -+static ssize_t dovmgr_item_usb_idVendor_store(struct config_item *citem, -+ const char *page, size_t count) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(citem); -+ int ret; -+ unsigned int val; -+ -+ /* cannot modify when item is enabled */ -+ if (item->enable) -+ return -EBUSY; -+ -+ ret = kstrtouint(page, 0, &val); -+ if (ret != 0) -+ return ret; -+ item->usb.idVendor = val; -+ return count; -+} -+ -+CONFIGFS_ATTR(dovmgr_item_usb_, idProduct); -+CONFIGFS_ATTR(dovmgr_item_usb_, idVendor); -+#endif -+ -+#if IS_ENABLED(CONFIG_PCI) -+static struct configfs_attribute *dovmgr_pci_attrs[] = { -+ &dovmgr_item_attr_path, -+ &dovmgr_item_attr_status, -+ &dovmgr_item_attr_enable, -+ &dovmgr_item_attr_overlay, -+ &dovmgr_item_pci_attr_device, -+ &dovmgr_item_pci_attr_vendor, -+ &dovmgr_item_pci_attr_subdevice, -+ &dovmgr_item_pci_attr_subvendor, -+ &dovmgr_item_pci_attr_class, -+ &dovmgr_item_pci_attr_class_mask, -+ NULL, -+}; -+#endif -+ -+#if IS_ENABLED(CONFIG_USB) -+static struct configfs_attribute *dovmgr_usb_attrs[] = { -+ &dovmgr_item_attr_path, -+ &dovmgr_item_attr_enable, -+ &dovmgr_item_attr_status, -+ &dovmgr_item_attr_overlay, -+ &dovmgr_item_usb_attr_idVendor, -+ &dovmgr_item_usb_attr_idProduct, -+ NULL, -+}; -+#endif -+ -+static void dovmgr_release(struct config_item *cfsitem) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(cfsitem); -+ -+ /* disable item (this removes the overlay and all) */ -+ dovmgr_item_set_enable(item, false); -+ -+ kfree(item->path); -+ kfree(item); -+} -+ -+static struct configfs_item_operations dovmgr_item_ops = { -+ .release = dovmgr_release, -+}; -+ -+#if IS_ENABLED(CONFIG_PCI) -+static struct config_item_type dovmgr_pci_item_type = { -+ .ct_item_ops = &dovmgr_item_ops, -+ .ct_attrs = dovmgr_pci_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+#endif -+ -+#if IS_ENABLED(CONFIG_USB) -+static struct config_item_type dovmgr_usb_item_type = { -+ .ct_item_ops = &dovmgr_item_ops, -+ .ct_attrs = dovmgr_usb_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+#endif -+ -+static struct config_item *dovmgr_group_make_item( -+ struct config_group *group, const char *name, -+ enum dovmgr_type type) -+{ -+ struct dovmgr_item *item; -+ struct config_item_type *item_type; -+ -+ switch (type) { -+#if IS_ENABLED(CONFIG_PCI) -+ case ITEM_PCI: -+ item_type = &dovmgr_pci_item_type; -+ break; -+#endif -+#if IS_ENABLED(CONFIG_USB) -+ case ITEM_USB: -+ item_type = &dovmgr_usb_item_type; -+ break; -+#endif -+ default: -+ return ERR_PTR(-EINVAL); -+ }; -+ -+ item = kzalloc(sizeof(*item), GFP_KERNEL); -+ if (!item) -+ return ERR_PTR(-ENOMEM); -+ -+ item->type = type; -+ item->enable = false; -+ mutex_init(&item->dev_item_mutex); -+ INIT_LIST_HEAD(&item->dev_item_list); -+ -+ switch (type) { -+#if IS_ENABLED(CONFIG_PCI) -+ case ITEM_PCI: -+ /* default for matching device/vendor */ -+ item->pci.vendor = PCI_ANY_ID; -+ item->pci.device = PCI_ANY_ID; -+ item->pci.subvendor = PCI_ANY_ID; -+ item->pci.subdevice = PCI_ANY_ID; -+ item->pci.class = 0; -+ item->pci.class_mask = 0; -+ break; -+#endif -+#if IS_ENABLED(CONFIG_USB) -+ case ITEM_USB: -+ /* default */ -+ item->usb.match_flags = USB_DEVICE_ID_MATCH_DEVICE; -+ break; -+#endif -+ default: -+ return ERR_PTR(-EINVAL); -+ }; -+ -+ config_item_init_type_name(&item->item, name, item_type); -+ return &item->item; -+} -+ -+#if IS_ENABLED(CONFIG_PCI) -+static struct config_item *dovmgr_group_pci_make_item( -+ struct config_group *group, const char *name) -+{ -+ return dovmgr_group_make_item(group, name, ITEM_PCI); -+} -+#endif -+ -+#if IS_ENABLED(CONFIG_USB) -+static struct config_item *dovmgr_group_usb_make_item( -+ struct config_group *group, const char *name) -+{ -+ return dovmgr_group_make_item(group, name, ITEM_USB); -+} -+#endif -+ -+static void dovmgr_group_drop_item(struct config_group *group, -+ struct config_item *cfsitem) -+{ -+ struct dovmgr_item *item = to_dovmgr_item(cfsitem); -+ -+ switch (item->type) { -+#if IS_ENABLED(CONFIG_PCI) -+ case ITEM_PCI: -+ break; -+#endif -+#if IS_ENABLED(CONFIG_USB) -+ case ITEM_USB: -+ break; -+#endif -+ default: -+ break; -+ } -+ config_item_put(&item->item); -+} -+ -+#if IS_ENABLED(CONFIG_PCI) -+static struct configfs_group_operations dovmgr_pci_group_ops = { -+ .make_item = dovmgr_group_pci_make_item, -+ .drop_item = dovmgr_group_drop_item, -+}; -+ -+static struct config_item_type dovmgr_pci_type = { -+ .ct_group_ops = &dovmgr_pci_group_ops, -+ .ct_owner = THIS_MODULE, -+}; -+#endif -+ -+#if IS_ENABLED(CONFIG_USB) -+static struct configfs_group_operations dovmgr_usb_group_ops = { -+ .make_item = dovmgr_group_usb_make_item, -+ .drop_item = dovmgr_group_drop_item, -+}; -+ -+static struct config_item_type dovmgr_usb_type = { -+ .ct_group_ops = &dovmgr_usb_group_ops, -+ .ct_owner = THIS_MODULE, -+}; -+#endif -+ -+static struct configfs_group_operations dovmgr_ops = { -+ /* empty - we don't allow anything to be created */ -+}; -+ -+static struct config_item_type dovmgr_type = { -+ .ct_group_ops = &dovmgr_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+struct config_group *dovmgr_def_groups[] = { -+#if IS_ENABLED(CONFIG_PCI) -+ &dovmgr_pci_group, -+#endif -+#if IS_ENABLED(CONFIG_USB) -+ &dovmgr_usb_group, -+#endif -+ NULL -+}; -+ -+static struct configfs_subsystem dovmgr_subsys = { -+ .su_group = { -+ .cg_item = { -+ .ci_namebuf = "dovmgr", -+ .ci_type = &dovmgr_type, -+ }, -+ .default_groups = dovmgr_def_groups, -+ }, -+ .su_mutex = __MUTEX_INITIALIZER(dovmgr_subsys.su_mutex), -+}; -+ -+#if IS_ENABLED(CONFIG_PCI) -+static int pci_dev_instantiate(struct pci_dev *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device *bus_dev; -+ struct of_changeset cset; -+ struct device_node *np, *npb; -+ int ret; -+ -+ npb = NULL; -+ -+ /* already instantiated */ -+ if (dev->of_node) { -+ pr_debug("%s: dev=%s of_node=%s\n", __func__, -+ kobject_name(&dev->kobj), -+ of_node_full_name(dev->of_node)); -+ return 0; -+ } -+ -+ bus_dev = &pdev->bus->dev; -+ -+ pr_debug("%s: %s: %02x:%02x.%02x - node %s%s\n", __func__, -+ kobject_name(&dev->kobj), -+ pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), -+ bus_dev->of_node ? of_node_full_name(bus_dev->of_node) : "<NULL>", -+ pci_is_bridge(pdev) ? " bridge" : ""); -+ -+ /* to create the node, the bus must be present */ -+ if (!bus_dev->of_node) { -+ pr_err("%s: No node for %s because no bus device node\n", -+ __func__, kobject_name(&dev->kobj)); -+ return 0; -+ } -+ -+ of_changeset_init(&cset); -+ -+ np = of_changeset_create_device_node(&cset, bus_dev->of_node, -+ "%s/pci-%04x-%02x-%02x.%d", -+ of_node_full_name(bus_dev->of_node), -+ pci_domain_nr(pdev->bus), pdev->bus->number, -+ PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); -+ if (IS_ERR(np)) { -+ ret = PTR_ERR(np); -+ goto out_cset_fail; -+ } -+ -+ ret = of_changeset_add_property_stringf(&cset, np, "compatible", -+ "pciclass,%04x", (pdev->class >> 8) & 0xffffff); -+ if (ret != 0) -+ goto out_cset_fail; -+ -+ ret = of_changeset_add_property_u32(&cset, np, "vendor", -+ pdev->vendor); -+ if (ret != 0) -+ goto out_cset_fail; -+ -+ ret = of_changeset_add_property_u32(&cset, np, "device", -+ pdev->device); -+ if (ret != 0) -+ goto out_cset_fail; -+ -+ ret = of_changeset_add_property_string(&cset, np, "status", "okay"); -+ if (ret != 0) -+ goto out_cset_fail; -+ -+ ret = of_changeset_add_property_bool(&cset, np, "auto-generated"); -+ if (ret != 0) -+ goto out_cset_fail; -+ -+ ret = of_changeset_attach_node(&cset, np); -+ if (ret != 0) -+ goto out_cset_fail; -+ -+ /* are we creating a bridge; swell */ -+ npb = NULL; -+ if (pci_is_bridge(pdev) && !pdev->subordinate->dev.of_node) { -+ -+ pr_debug("%s: %s: bus->dev=%s subordinate=%s\n", __func__, -+ kobject_name(&dev->kobj), -+ kobject_name(&pdev->bus->dev.kobj), -+ kobject_name(&pdev->subordinate->dev.kobj)); -+ -+ npb = of_changeset_create_device_node(&cset, bus_dev->of_node, -+ "%s/pci-%04x-%02x", -+ of_node_full_name(bus_dev->of_node), -+ pci_domain_nr(pdev->subordinate), -+ pdev->subordinate->number); -+ if (IS_ERR(npb)) { -+ ret = PTR_ERR(npb); -+ goto out_cset_fail; -+ } -+ -+ ret = of_changeset_add_property_string(&cset, npb, "compatible", "generic,pci-bus"); -+ if (ret != 0) -+ goto out_cset_fail; -+ -+ ret = of_changeset_add_property_string(&cset, npb, "device_type", "pci"); -+ if (ret != 0) -+ goto out_cset_fail; -+ -+ ret = of_changeset_add_property_string(&cset, npb, "status", "okay"); -+ if (ret != 0) -+ goto out_cset_fail; -+ -+ ret = of_changeset_add_property_bool(&cset, npb, "auto-generated"); -+ if (ret != 0) -+ goto out_cset_fail; -+ -+ ret = of_changeset_attach_node(&cset, npb); -+ if (ret != 0) -+ goto out_cset_fail; -+ } -+ -+ ret = of_changeset_apply(&cset); -+ if (ret != 0) -+ goto out_cset_fail; -+ -+ /* permanently commit */ -+ of_changeset_destroy(&cset); -+ -+ /* bind the node to the device */ -+ dev->of_node = np; -+ ret = sysfs_create_link(&dev->kobj, &dev->of_node->kobj, -+ "of_node"); -+ if (ret) -+ pr_warn("%s: %s Error %d creating of_node link\n", -+ __func__, kobject_name(&dev->kobj), ret); -+ -+ if (npb) { -+ pdev->subordinate->dev.of_node = npb; -+ ret = sysfs_create_link(&pdev->subordinate->dev.kobj, &npb->kobj, -+ "of_node"); -+ if (ret) -+ pr_warn("%s: %s Error %d creating of_node link\n", -+ __func__, kobject_name(&dev->kobj), ret); -+ } -+ -+ -+ return 0; -+ -+out_cset_fail: -+ pr_err("%s: %s Failed to apply changeset (err=%d)\n", __func__, -+ kobject_name(&dev->kobj), ret); -+ of_changeset_destroy(&cset); -+ return ret; -+} -+ -+static int pci_dev_uninstantiate(struct pci_dev *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np, *npb; -+ struct of_changeset cset; -+ int ret; -+ -+ /* device node must exist */ -+ np = dev->of_node; -+ if (!np) -+ return 0; -+ -+ /* and the auto-generated property */ -+ if (!of_property_read_bool(np, "auto-generated")) -+ return 0; -+ -+ of_changeset_init(&cset); -+ -+ ret = of_changeset_detach_node(&cset, np); -+ if (ret != 0) -+ goto out_cset_fail; -+ -+ npb = NULL; -+ if (pci_is_bridge(pdev)) -+ npb = pdev->subordinate->dev.of_node; -+ -+ if (npb != NULL) { -+ ret = of_changeset_detach_node(&cset, npb); -+ if (ret != 0) -+ goto out_cset_fail; -+ } -+ -+ ret = of_changeset_apply(&cset); -+ if (ret != 0) -+ goto out_cset_fail; -+ -+ dev->of_node = NULL; -+ if (npb != NULL) -+ pdev->subordinate->dev.of_node = NULL; -+ -+ pr_debug("%s: %s: %02x:%02x.%02x\n", __func__, -+ kobject_name(&dev->kobj), -+ pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); -+ -+ /* TODO iterate over the properties and free */ -+ -+ return 0; -+ -+out_cset_fail: -+ of_changeset_destroy(&cset); -+ -+ return ret; -+} -+ -+static int dovmgr_pci_notify(struct notifier_block *nb, -+ unsigned long action, void *arg) -+{ -+ int ret; -+ -+ if (action == BUS_NOTIFY_ADD_DEVICE) -+ pci_dev_instantiate(to_pci_dev(arg)); -+ -+ ret = dovmgr_notifier_action(&dovmgr_pci_group, action, arg, -+ dovmgr_pci_item_match, dovmgr_item_notify); -+ -+ if (action == BUS_NOTIFY_REMOVED_DEVICE) -+ pci_dev_uninstantiate(to_pci_dev(arg)); -+ -+ return ret; -+} -+ -+static struct notifier_block dovmgr_pci_notifier = { -+ .notifier_call = dovmgr_pci_notify, -+}; -+ -+static int pci_instantiate_iterator(struct device *dev, void *data) -+{ -+ return pci_dev_instantiate(to_pci_dev(dev)); -+} -+ -+static int dovmgr_pci_init(void) -+{ -+ int ret; -+ -+ config_group_init_type_name(&dovmgr_pci_group, "pci", &dovmgr_pci_type); -+ ret = bus_register_notifier(&pci_bus_type, &dovmgr_pci_notifier); -+ if (ret != 0) { -+ pr_err("%s: bus_register_notifier() failed\n", __func__); -+ return ret; -+ } -+ -+ ret = bus_for_each_dev(&pci_bus_type, NULL, NULL, -+ pci_instantiate_iterator); -+ if (ret != 0) { -+ pr_err("%s: bus_for_each_dev() failed\n", __func__); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void dovmgr_pci_cleanup(void) -+{ -+ bus_unregister_notifier(&pci_bus_type, &dovmgr_pci_notifier); -+} -+#endif -+ -+#if IS_ENABLED(CONFIG_USB) -+static int dovmgr_usb_notify(struct notifier_block *nb, -+ unsigned long action, void *arg) -+{ -+ return dovmgr_notifier_action(&dovmgr_usb_group, action, arg, -+ dovmgr_usb_item_match, dovmgr_item_notify); -+} -+ -+static struct notifier_block dovmgr_usb_notifier = { -+ .notifier_call = dovmgr_usb_notify, -+}; -+ -+static int dovmgr_usb_init(void) -+{ -+ int ret; -+ -+ config_group_init_type_name(&dovmgr_usb_group, "usb", &dovmgr_usb_type); -+ ret = bus_register_notifier(&usb_bus_type, &dovmgr_usb_notifier); -+ if (ret != 0) { -+ pr_err("%s: bus_register_notifier() failed\n", __func__); -+ return ret; -+ } -+ return 0; -+} -+ -+static void dovmgr_usb_cleanup(void) -+{ -+ bus_unregister_notifier(&usb_bus_type, &dovmgr_usb_notifier); -+} -+#endif -+ -+static int __init dovmgr_init(void) -+{ -+ int ret; -+ -+ config_group_init(&dovmgr_subsys.su_group); -+#if IS_ENABLED(CONFIG_PCI) -+ configfs_add_default_group(&dovmgr_pci_group, -+ &dovmgr_subsys.su_group); -+#endif -+#if IS_ENABLED(CONFIG_USB) -+ configfs_add_default_group(&dovmgr_usb_group, -+ &dovmgr_subsys.su_group); -+#endif -+ -+#if IS_ENABLED(CONFIG_PCI) -+ ret = dovmgr_pci_init(); -+ if (ret != 0) -+ goto err_no_pci_init; -+#endif -+#if IS_ENABLED(CONFIG_USB) -+ ret = dovmgr_usb_init(); -+ if (ret != 0) -+ goto err_no_usb_init; -+#endif -+ -+ ret = configfs_register_subsystem(&dovmgr_subsys); -+ if (ret != 0) { -+ pr_err("%s: failed to register subsys\n", __func__); -+ goto err_no_configfs; -+ } -+ pr_info("%s: OK\n", __func__); -+ return 0; -+ -+err_no_configfs: -+#if IS_ENABLED(CONFIG_USB) -+ dovmgr_usb_cleanup(); -+err_no_usb_init: -+#endif -+#if IS_ENABLED(CONFIG_PCI) -+ dovmgr_pci_cleanup(); -+err_no_pci_init: -+#endif -+ return ret; -+} -+late_initcall(dovmgr_init); -diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c -index 051b147..3cdf8e1 100644 ---- a/drivers/misc/eeprom/at24.c -+++ b/drivers/misc/eeprom/at24.c -@@ -593,7 +593,6 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) - struct at24_data *at24; - int err; - unsigned i, num_addresses; -- u8 test_byte; - - if (client->dev.platform_data) { - chip = *(struct at24_platform_data *)client->dev.platform_data; -@@ -744,18 +743,6 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) - } - } - -- i2c_set_clientdata(client, at24); -- -- /* -- * Perform a one-byte test read to verify that the -- * chip is functional. -- */ -- err = at24_read(at24, 0, &test_byte, 1); -- if (err) { -- err = -ENODEV; -- goto err_clients; -- } -- - at24->nvmem_config.name = dev_name(&client->dev); - at24->nvmem_config.dev = &client->dev; - at24->nvmem_config.read_only = !writable; -@@ -777,6 +764,8 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) - goto err_clients; - } - -+ i2c_set_clientdata(client, at24); -+ - dev_info(&client->dev, "%u byte %s EEPROM, %s, %u bytes/write\n", - chip.byte_len, client->name, - writable ? "writable" : "read-only", at24->write_max); -diff --git b/drivers/misc/tieqep.c b/drivers/misc/tieqep.c -new file mode 100644 -index 0000000..bb69ad4 ---- /dev/null -+++ b/drivers/misc/tieqep.c -@@ -0,0 +1,754 @@ -+/* -+ * TI eQEP driver for AM33xx devices -+ * -+ * Copyright (C) 2013 Nathaniel R. Lewis - http://teknoman117.wordpress.com/ -+ * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ * -+ * sysfs entries -+ * - position = absolute - current position; relative - last latched value -+ * - mode => 0 - absolute; 1 - relative -+ * - period => sampling period for the hardware -+ * - enable => 0 - eQEP disabled, 1 - eQEP enabled -+ */ -+ -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/interrupt.h> -+#include <linux/io.h> -+#include <linux/err.h> -+#include <linux/clk.h> -+#include <linux/pm_runtime.h> -+#include <linux/of_device.h> -+#include <linux/pinctrl/consumer.h> -+#include <linux/input.h> -+ -+/* eQEP register offsets from its base IO address */ -+#define QPOSCNT 0x0000 -+#define QPOSINIT 0x0004 -+#define QPOSMAX 0x0008 -+#define QPOSCMP 0x000C -+#define QPOSILAT 0x0010 -+#define QPOSSLAT 0x0014 -+#define QPOSLAT 0x0018 -+#define QUTMR 0x001C -+#define QUPRD 0x0020 -+#define QWDTMR 0x0024 -+#define QWDPRD 0x0026 -+#define QDECCTL 0x0028 -+#define QEPCTL 0x002A -+#define QCAPCTL 0x002C -+#define QPOSCTL 0x002E -+#define QEINT 0x0030 -+#define QFLG 0x0032 -+#define QCLR 0x0034 -+#define QFRC 0x0036 -+#define QEPSTS 0x0038 -+#define QCTMR 0x003A -+#define QCPRD 0x003C -+#define QCTMRLAT 0x003E -+#define QCPRDLAT 0x0040 -+#define QREVID 0x005C -+ -+#if 0 /* if you wanted another way to modify IP registers... */ -+typedef volatile u32 REG32; -+typedef volatile u16 REG16; -+struct EQEP_REGS { -+ REG32 q_poscnt; /* 0x00 position counter */ -+ REG32 q_posinit; /* 0x04 position counter initialization */ -+ REG32 q_posmax; /* 0x08 maximum position count */ -+ REG32 q_poscmp; /* 0x0C position compare */ -+ REG32 q_posilat; /* 0x10 index position latch */ -+ REG32 q_posslat; /* 0x14 strobe position latch */ -+ REG32 q_poslat; /* 0x18 position counter latch */ -+ REG32 q_utmr; /* 0x1C unit timer */ -+ REG32 q_uprd; /* 0x20 unit period */ -+ REG16 q_wdtmr; /* 0x24 watchdog timer */ -+ REG16 q_wdprd; /* 0x26 watchdog period */ -+ REG16 q_decctl; /* 0x28 decoder control */ -+ REG16 q_epctl; /* 0x2A control register */ -+ REG16 q_capctl; /* 0x2C capture control */ -+ REG16 q_posctl; /* 0x2E position compare control */ -+ REG16 q_eint; /* 0x30 interrupt enable */ -+ REG16 q_flg; /* 0x32 interrupt flag */ -+ REG16 q_clr; /* 0x34 interrupt clear */ -+ REG16 q_frc; /* 0x36 interrupt force */ -+ REG16 q_epsts; /* 0x38 status */ -+ REG16 q_ctmr; /* 0x3A capture timer */ -+ REG16 q_cprd; /* 0x3C capture period */ -+ REG16 q_ctmrlat; /* 0x3E capture timer latch */ -+ REG16 q_prdlat; /* 0x40 capture period latch */ -+ char q_fill1[0x5c-0x40]; -+ REG32 q_revid; /* 0x5C revision id */ -+}; -+#endif -+ -+ -+/* Bits for the QDECTL register */ -+#define QSRC1 (1 << 15) -+#define QSRC0 (1 << 14) -+#define SOEN (1 << 13) -+#define SPSEL (1 << 12) -+#define XCR (1 << 11) -+#define SWAP (1 << 10) -+#define IGATE (1 << 9) -+#define QAP (1 << 8) -+#define QBP (1 << 7) -+#define QIP (1 << 6) -+#define QSP (1 << 5) -+ -+/* Bits for the QEPCTL register */ -+#define FREESOFT1 (1 << 15) -+#define FREESOFT0 (1 << 14) -+#define PCRM1 (1 << 13) -+#define PCRM0 (1 << 12) -+#define SEI1 (1 << 11) -+#define SEI0 (1 << 10) -+#define IEI1 (1 << 9) -+#define IEI0 (1 << 8) -+#define SWI (1 << 7) -+#define SEL (1 << 6) -+#define IEL1 (1 << 5) -+#define IEL0 (1 << 4) -+#define PHEN (1 << 3) -+#define QCLM (1 << 2) -+#define UTE (1 << 1) -+#define WDE (1 << 0) -+ -+/* Bits for the QCAPCTL register */ -+#define CEN (1 << 15) -+#define CCPS2 (1 << 6) -+#define CCPS0 (1 << 5) -+#define CCPS1 (1 << 4) -+#define UPPS3 (1 << 3) -+#define UPPS2 (1 << 2) -+#define UPPS1 (1 << 1) -+#define UPPS0 (1 << 0) -+ -+/* Bits for the QPOSCTL register */ -+#define PCSHDW (1 << 15) -+#define PCLOAD (1 << 14) -+#define PCPOL (1 << 13) -+#define PCE (1 << 12) -+#define PCSPW11 (1 << 11) -+#define PCSPW10 (1 << 10) -+#define PCSPW9 (1 << 9) -+#define PCSPW8 (1 << 8) -+#define PCSPW7 (1 << 7) -+#define PCSPW6 (1 << 6) -+#define PCSPW5 (1 << 5) -+#define PCSPW4 (1 << 4) -+#define PCSPW3 (1 << 3) -+#define PCSPW2 (1 << 2) -+#define PCSPW1 (1 << 1) -+#define PCSPW0 (1 << 0) -+ -+/* Bits for the interrupt registers */ -+#define EQEP_INTERRUPT_MASK 0x0FFF -+#define UTOF (1 << 11) -+ -+/* Bits to control the clock in the PWMSS subsystem */ -+#define PWMSS_EQEPCLK_EN BIT(4) -+#define PWMSS_EQEPCLK_STOP_REQ BIT(5) -+#define PWMSS_EQEPCLK_EN_ACK BIT(4) -+ -+/* -+ * Modes for the eQEP unit -+ * Absolute - the position entry represents the current position of the encoder. -+ * Poll this value and it will be notified every period nanoseconds -+ * Relative - the position entry represents the last latched position of the encoder -+ * This value is latched every period nanoseconds and the internal counter -+ * is subsequenty reset -+ */ -+#define TIEQEP_MODE_ABSOLUTE 0 -+#define TIEQEP_MODE_RELATIVE 1 -+ -+/* Structure defining the characteristics of the eQEP unit */ -+struct eqep_chip -+{ -+ /* Platform device for this eQEP unit */ -+ struct platform_device *pdev; -+ -+ /* Pointer to the base of the memory of the eQEP unit */ -+ void __iomem *mmio_base; -+ -+ /* SYSCLKOUT to the eQEP unit */ -+ u32 clk_rate; -+ -+ /* IRQ for the eQEP unit */ -+ u16 irq; -+ -+ /* Mode of the eQEP unit */ -+ u8 op_mode; -+ -+ /* work stuct for the notify userspace work */ -+ struct work_struct notify_work; -+ -+ /* Backup for driver suspension */ -+ u16 prior_qepctl; -+ u16 prior_qeint; -+}; -+ -+/* Notify userspace work */ -+static void notify_handler(struct work_struct *work) -+{ -+ /* Get a reference to the eQEP driver */ -+ struct eqep_chip *eqep = container_of(work, struct eqep_chip, notify_work); -+ -+ /* Notify the userspace */ -+ sysfs_notify(&eqep->pdev->dev.kobj, NULL, "position"); -+} -+ -+/* eQEP Interrupt handler */ -+static irqreturn_t eqep_irq_handler(int irq, void *dev_id) -+{ -+ /* Get the instance information */ -+ struct platform_device *pdev = dev_id; -+ struct eqep_chip *eqep = platform_get_drvdata(pdev); -+ -+ /* Get the interrupt flags */ -+ u16 iflags = readw(eqep->mmio_base + QFLG) & EQEP_INTERRUPT_MASK; -+ -+ /* Check the interrupt source(s) */ -+ if (iflags & UTOF) { -+ /* Handle the unit timer overflow interrupt by notifying any potential pollers */ -+ schedule_work(&eqep->notify_work); -+ } -+ -+ /* Clear interrupt flags (write back triggered flags to the clear register) */ -+ writew(iflags, eqep->mmio_base + QCLR); -+ -+ /* Return that the IRQ was handled successfully */ -+ return IRQ_HANDLED; -+} -+ -+/* Function to read whether the eQEP unit is enabled or disabled */ -+static ssize_t eqep_get_enabled(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ /* Get the instance structure */ -+ struct eqep_chip *eqep = dev_get_drvdata(dev); -+ u16 enabled = 0; -+ -+ /* Increment the device usage count and run pm_runtime_resume() */ -+ pm_runtime_get_sync(dev); -+ -+ /* Read the qep control register and mask all but the enabled bit */ -+ enabled = readw(eqep->mmio_base + QEPCTL) & PHEN; -+ -+ /* Return the target in string format */ -+ return sprintf(buf, "%u\n", (enabled) ? 1 : 0); -+} -+ -+/* Function to set if the eQEP is enabled */ -+static ssize_t eqep_set_enabled(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -+{ -+ /* Get the instance structure */ -+ int rc; -+ u16 val; -+ u8 enabled; -+ struct eqep_chip *eqep = dev_get_drvdata(dev); -+ -+ /* Convert the input string to an 8 bit uint */ -+ if ((rc = kstrtou8(buf, 0, &enabled))) -+ return rc; -+ -+ /* Increment the device usage count and run pm_runtime_resume() */ -+ pm_runtime_get_sync(dev); -+ /* Get the existing state of QEPCTL */ -+ val = readw(eqep->mmio_base + QEPCTL); -+ -+ /* If we passed a number that is not 0, enable the eQEP */ -+ if (enabled) -+ /* Enable the eQEP (Set PHEN in QEPCTL) */ -+ val |= PHEN; -+ else -+ /* Disable the eQEP (Clear PHEN in QEPCTL) */ -+ val &= ~PHEN; -+ -+ /* Write flags back to control register */ -+ writew(val, eqep->mmio_base + QEPCTL); -+ -+ /* Return buffer length consumed (all) */ -+ return count; -+} -+ -+/* Function to read the current position of the eQEP */ -+static ssize_t eqep_get_position(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct eqep_chip *eqep = dev_get_drvdata(dev); -+ -+ s32 position = 0; -+ /* Increment the device usage count and run pm_runtime_resume() */ -+ pm_runtime_get_sync(dev); -+ -+ if (eqep->op_mode == TIEQEP_MODE_ABSOLUTE) { -+ position = readl(eqep->mmio_base + QPOSCNT); -+ } else if (eqep->op_mode == TIEQEP_MODE_RELATIVE) { -+ /* in relative mode, use the last latched value of the eQEP hardware */ -+ position = readl(eqep->mmio_base + QPOSLAT); -+ dev_dbg(dev, "get_position:0x%08x\n", position); -+ } -+ -+ return sprintf(buf, "%d\n", position); -+} -+ -+/* Function to set the position of the eQEP hardware */ -+static ssize_t eqep_set_position(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -+{ -+ int rc; -+ s32 position; -+ struct eqep_chip *eqep = dev_get_drvdata(dev); -+ -+ if ((rc = kstrtos32(buf, 0, &position))) -+ return rc; -+ -+ /* Increment the device usage count and run pm_runtime_resume() */ -+ pm_runtime_get_sync(dev); -+ /* -+ * If we are in absolute mode, set the position of the encoder, -+ * discard relative mode because thats pointless -+ */ -+ if (eqep->op_mode == TIEQEP_MODE_ABSOLUTE) { -+ /* If absolute mode, set the current value of the eQEP hardware */ -+ writel(position, eqep->mmio_base + QPOSCNT); -+ } -+ -+ /* Return buffer length consumed (all) */ -+ return count; -+} -+ -+/* Function to read the period of the unit time event timer */ -+static ssize_t eqep_get_timer_period(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct eqep_chip *eqep = dev_get_drvdata(dev); -+ u64 period; -+ -+ /* Increment the device usage count and run pm_runtime_resume() */ -+ pm_runtime_get_sync(dev); -+ /* Convert from counts per interrupt back into period_ns */ -+ period = readl(eqep->mmio_base + QUPRD); -+ period = period * NSEC_PER_SEC; -+ do_div(period, eqep->clk_rate); -+ -+ /* Otherwise write out the data */ -+ return sprintf(buf, "%llu\n", period); -+} -+ -+/* Function to set the unit timer period. 0 = off, greater than zero sets the period */ -+static ssize_t eqep_set_timer_period(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -+{ -+ int rc; -+ u16 tmp; -+ u64 period; -+ -+ struct eqep_chip *eqep = dev_get_drvdata(dev); -+ -+ if ((rc = kstrtou64(buf, 0, &period))) -+ return rc; -+ -+ /* Increment the device usage count and run pm_runtime_resume() */ -+ pm_runtime_get_sync(dev); -+ /* Disable the unit timer before modifying its period register */ -+ tmp = readw(eqep->mmio_base + QEPCTL); -+ tmp &= ~(UTE | QCLM); -+ writew(tmp, eqep->mmio_base + QEPCTL); -+ -+ /* Zero the unit timer counter register */ -+ writel(0, eqep->mmio_base + QUTMR); -+ -+ /* If the timer is enabled (a non-zero period has been passed) */ -+ if (period) { -+ /* update the period */ -+ period = period * eqep->clk_rate; -+ do_div(period, NSEC_PER_SEC); -+ -+ dev_dbg(dev, "eqep_set_timer_period:%llu\n", period); -+ -+ writel(period, eqep->mmio_base + QUPRD); -+ -+ /* Enable unit timer, and latch QPOSLAT to QPOSCNT on timer expiration */ -+ tmp |= UTE | QCLM; -+ writew(tmp, eqep->mmio_base + QEPCTL); -+ } -+ -+ return count; -+} -+ -+/* Function to read the mode of the eQEP hardware */ -+static ssize_t eqep_get_mode(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct eqep_chip *eqep = dev_get_drvdata(dev); -+ -+ return sprintf(buf, "%u\n", eqep->op_mode); -+} -+ -+/* Function to set the mode of the eQEP hardware */ -+static ssize_t eqep_set_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) -+{ -+ int rc; -+ u16 val; -+ u8 tmp_mode; -+ struct eqep_chip *eqep = dev_get_drvdata(dev); -+ -+ if ((rc = kstrtou8(buf, 0, &tmp_mode))) -+ return rc; -+ -+ dev_dbg(dev, "eqep_set_mode:%d\n", tmp_mode); -+ -+ /* Increment the device usage count and run pm_runtime_resume() */ -+ pm_runtime_get_sync(dev); -+ val = readw(eqep->mmio_base + QEPCTL); -+ -+ if (tmp_mode == TIEQEP_MODE_ABSOLUTE) { -+ /* -+ * In absolute mode, don't reset the hardware based on time, -+ * so disable the unit timer position reset (Set PCRM[1:0] = 0) -+ */ -+ val &= ~(PCRM1 | PCRM0); -+ -+ eqep->op_mode = TIEQEP_MODE_ABSOLUTE; -+ } else if (tmp_mode == TIEQEP_MODE_RELATIVE) { -+ /* -+ * In relative mode, latch the value of the eQEP hardware on the -+ * overflow of the unit timer. So enable the unit timer position reset -+ * (Set PCRM[1:0] = 3) -+ */ -+ val |= PCRM1 | PCRM0; -+ -+ eqep->op_mode = TIEQEP_MODE_RELATIVE; -+ } -+ -+ writew(val, eqep->mmio_base + QEPCTL); -+ -+ return count; -+} -+ -+/* Bind read/write functions to sysfs entries */ -+static DEVICE_ATTR(enabled, 0644, eqep_get_enabled, eqep_set_enabled); -+static DEVICE_ATTR(position, 0644, eqep_get_position, eqep_set_position); -+static DEVICE_ATTR(period, 0644, eqep_get_timer_period, eqep_set_timer_period); -+static DEVICE_ATTR(mode, 0644, eqep_get_mode, eqep_set_mode); -+ -+/* Array holding all of the sysfs entries */ -+static const struct attribute *eqep_attrs[] = { -+ &dev_attr_enabled.attr, -+ &dev_attr_position.attr, -+ &dev_attr_period.attr, -+ &dev_attr_mode.attr, -+ NULL, -+}; -+ -+/* Driver function group */ -+static const struct attribute_group eqep_device_attr_group = { -+ .attrs = (struct attribute **) eqep_attrs, -+}; -+ -+/* Driver compatibility list */ -+static struct of_device_id eqep_of_match[] = -+{ -+ { .compatible = "ti,am33xx-eqep" }, -+ { } -+}; -+ -+/* Register our compatibilities for device trees */ -+MODULE_DEVICE_TABLE(of, eqep_of_match); -+ -+/* Create an instance of the eQEP driver */ -+static int eqep_probe(struct platform_device *pdev) -+{ -+ struct resource *r; -+ struct clk *clk; -+ struct eqep_chip *eqep; -+ struct pinctrl *pinctrl; -+ -+ u64 period; -+ u16 status; -+ u32 value; -+ -+ dev_info(&pdev->dev, "ver. 1.0\n"); -+ -+ /* Select pins provided through the device tree */ -+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev); -+ if (IS_ERR(pinctrl)) -+ { -+ dev_warn(&pdev->dev, "unable to select pin group\n"); -+ } -+ -+ /* Allocate a eqep_driver object */ -+ eqep = devm_kzalloc(&pdev->dev, sizeof(struct eqep_chip), GFP_KERNEL); -+ if (!eqep) { -+ dev_err(&pdev->dev, "failed to allocate memory\n"); -+ return -ENOMEM; -+ } -+ -+ /* Get a handle to the system clock object */ -+ clk = devm_clk_get(pdev->dev.parent, "fck"); -+ if (IS_ERR(clk)) { -+ dev_err(&pdev->dev, "failed to get clock\n"); -+ return PTR_ERR(clk); -+ } -+ -+ /* Get the frequency of the system clock */ -+ eqep->clk_rate = clk_get_rate(clk); -+ if (!eqep->clk_rate) { -+ dev_err(&pdev->dev, "failed to get clock rate\n"); -+ return -EINVAL; -+ } -+ -+ /* Get a resource containing the IRQ for this eQEP controller */ -+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -+ if (unlikely(!r)) { -+ dev_err(&pdev->dev, "Invalid IRQ resource\n"); -+ return -ENODEV; -+ } -+ -+ /* Store the irq */ -+ eqep->irq = r->start; -+ -+ /* Get a resource containing the requested (from DT) memory address and range of eQEP controller */ -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!r) { -+ dev_err(&pdev->dev, "no memory resource defined\n"); -+ return -ENODEV; -+ } -+ -+ /* Remap the eQEP controller memory into our own memory space */ -+ eqep->mmio_base = devm_ioremap_resource(&pdev->dev, r); -+ if (IS_ERR(eqep->mmio_base)) -+ return PTR_ERR(eqep->mmio_base); -+ -+ /* Store the platform device in our eQEP data structure for later usage */ -+ eqep->pdev = pdev; -+ -+ /* Subscribe to the eQEP interrupt */ -+ if (request_irq(eqep->irq, eqep_irq_handler, IRQF_IRQPOLL, "eqep_interrupt", pdev)) -+ { -+ dev_err(&pdev->dev, "unable to request irq for eQEP\n"); -+ return -ENODEV; -+ } -+ -+ /* Register controls to sysfs */ -+ if (sysfs_create_group(&pdev->dev.kobj, &eqep_device_attr_group)) -+ { -+ dev_err(&pdev->dev, "sysfs creation failed\n"); -+ return -EINVAL; -+ } -+ -+ /* set QDECCTL */ -+ status = 0; /* default to Quadrature count mode, QSRC1 & QSRC0 = 0 */ -+ -+ /* set QSRC1 & QSRC0 bits, one of 4 count_modes. */ -+ if (!of_property_read_u32(pdev->dev.of_node, "count_mode", &value) && value <= 3) { -+ status |= value << 14; -+ -+ /* -+ * in count up or count down mode, count on rising edge only -+ * not on both edges. -+ */ -+ if (value >= 2) -+ status |= XCR; -+ } -+ dev_info(&pdev->dev, "count_mode:%d\n", value); -+ -+ /* Should we invert the qa input */ -+ if (!of_property_read_u32(pdev->dev.of_node, "invert_qa", &value)) -+ status = value ? status | QAP : status & ~QAP; -+ dev_info(&pdev->dev, "invert_qa:%d\n", value); -+ -+ /* Should we invert the qb input */ -+ if (!of_property_read_u32(pdev->dev.of_node, "invert_qb", &value)) -+ status = value ? status | QBP : status & ~QBP; -+ dev_info(&pdev->dev, "invert_qb:%d\n", value); -+ -+ /* Should we invert the index input */ -+ if (!of_property_read_u32(pdev->dev.of_node, "invert_qi", &value)) -+ status = value ? status | QIP : status & ~QIP; -+ dev_info(&pdev->dev, "invert_qi:%d\n", value); -+ -+ /* Should we invert the strobe input */ -+ if (!of_property_read_u32(pdev->dev.of_node, "invert_qs", &value)) -+ status = value ? status | QSP : status & ~QSP; -+ dev_info(&pdev->dev, "invert_qs:%d\n", value); -+ -+ /* Should we swap the cha and chb inputs */ -+ if (!of_property_read_u32(pdev->dev.of_node, "swap_inputs", &value)) -+ status = value ? status | SWAP : status & ~SWAP; -+ dev_info(&pdev->dev, "swap_inputs:%d\n", value); -+ -+ dev_info(&pdev->dev, "QDECCTL:0x%04x\n", status); -+ -+ /* Write the decoder control settings back to the control register */ -+ writew(status, eqep->mmio_base + QDECCTL); -+ -+ writel( 0, eqep->mmio_base + QPOSINIT); -+ writel(~0, eqep->mmio_base + QPOSMAX); -+ writel( 0, eqep->mmio_base + QPOSCNT); -+ -+ dev_info(&pdev->dev, "QPOSINIT:0x%08x\n", readl(eqep->mmio_base + QPOSINIT)); -+ dev_info(&pdev->dev, "QPOSMAX:0x%08x\n", readl(eqep->mmio_base + QPOSMAX)); -+ dev_info(&pdev->dev, "QPOSCNT:0x%08x\n", readl(eqep->mmio_base + QPOSCNT)); -+ -+ status = UTOF; /* Enable Unit Time Period interrupt. */ -+ if (!of_property_read_u32(pdev->dev.of_node, "omit_interrupt", &value) && value) { -+ status = 0; /* no interrupt */ -+ } -+ writew(status, eqep->mmio_base + QEINT); -+ dev_info(&pdev->dev, "omit_interrupt:%d\n", value); -+ dev_info(&pdev->dev, "QEINT:0x%04x\n", status); -+ -+ /* Calculate the timer ticks per second */ -+ period = 1000000000; -+ period = period * eqep->clk_rate; -+ do_div(period, NSEC_PER_SEC); -+ -+ /* Set this period into the unit timer period register */ -+ writel(period, eqep->mmio_base + QUPRD); -+ dev_info(&pdev->dev, "QUPRD:0x%08x\n", (u32) period); -+ -+ /* -+ * Enable the eQEP with basic position counting turned on -+ * PHEN - Quadrature position counter enable bit -+ * UTE - unit timer enable -+ * QCLM - latch QPOSLAT to QPOSCNT upon unit timer overflow -+ * IEL0 - Latch QPOSILAT on index signal. Rising or falling, IEL[1:0] = 0 is reserved -+ * SWI - Software initialization of position count register, i.e. set QPOSCNT <= QPOSINIT, -+ * but this bit was not being reset by hardware as advertised in TRM, -+ * (so omit & clear QPOSCNT manually elsewhere?) -+ */ -+ status = PHEN | UTE | QCLM | IEL0 | SWI; -+ writew(status, eqep->mmio_base + QEPCTL); -+ dev_info(&pdev->dev, "QEPCTL:0x%04x write\n", status); -+ dev_info(&pdev->dev, "QEPCTL:0x%04x read\n", readw(eqep->mmio_base + QEPCTL)); -+ -+ /* We default to absolute mode */ -+ eqep->op_mode = TIEQEP_MODE_ABSOLUTE; -+ -+ /* Enable the power management runtime */ -+ pm_runtime_enable(&pdev->dev); -+ -+ /* Increment the device usage count and run pm_runtime_resume() */ -+ pm_runtime_get_sync(&pdev->dev); -+ -+ /* Initialize the notify work struture */ -+ INIT_WORK(&eqep->notify_work, notify_handler); -+ -+ /* Decrement the device usage count (twice) and run pm_runtime_idle() if zero */ -+ pm_runtime_put_sync(&pdev->dev); -+ -+ /* Set the platform driver data to the data object we've been creating for the eQEP unit */ -+ platform_set_drvdata(pdev, eqep); -+ -+ /* Success! */ -+ dev_info(&pdev->dev, "irq:%d, clk_rate:%u\n", eqep->irq, eqep->clk_rate); -+ return 0; -+} -+ -+/* Remove an instance of the eQEP driver */ -+static int eqep_remove(struct platform_device *pdev) -+{ -+ /* Get the eQEP driver data from the platform device structure */ -+ struct eqep_chip *eqep = platform_get_drvdata(pdev); -+ -+ /* Cancel work */ -+ cancel_work_sync(&eqep->notify_work); -+ -+ /* Unmap from sysfs */ -+ sysfs_remove_group(&pdev->dev.kobj, &eqep_device_attr_group); -+ -+ /* Release important assets */ -+ free_irq(eqep->irq, pdev); -+ -+ /* Increment the device usage count and run pm_runtime_resume() */ -+ pm_runtime_get_sync(&pdev->dev); -+ -+ /* Decrement the device usage count (twice) and run pm_runtime_idle() if zero */ -+ pm_runtime_put_sync(&pdev->dev); -+ pm_runtime_put_sync(&pdev->dev); -+ -+ /* Disable the runtime power management of this device */ -+ pm_runtime_disable(&pdev->dev); -+ -+ /* Return success */ -+ return 0; -+} -+ -+/* Power management suspend device */ -+static int eqep_suspend(struct device *dev) -+{ -+ /* Get the eqep driver information */ -+ struct eqep_chip *eqep = dev_get_drvdata(dev); -+ u16 tmp; -+ -+ /* Shut down interrupts */ -+ eqep->prior_qeint = readw(eqep->mmio_base + QEINT); -+ tmp = eqep->prior_qeint & ~UTOF; -+ writew(tmp, eqep->mmio_base + QEINT); -+ -+ /* Get the existing state of QEPCTL */ -+ eqep->prior_qepctl = readw(eqep->mmio_base + QEPCTL); -+ -+ /* Disable eQEP controller */ -+ writew(eqep->prior_qepctl & ~PHEN, eqep->mmio_base + QEPCTL); -+ -+ /* Decrement the device usage count and run pm_runtime_idle() if zero */ -+ pm_runtime_put_sync(dev); -+ -+ /* Return success */ -+ return 0; -+} -+ -+/* Power management wake device back up */ -+static int eqep_resume(struct device *dev) -+{ -+ /* Get the eqep driver information */ -+ struct eqep_chip *eqep = dev_get_drvdata(dev); -+ -+ /* Restore interrupt enabled register */ -+ writew(eqep->prior_qeint, eqep->mmio_base + QEINT); -+ -+ /* Restore prior qep control register */ -+ writew(eqep->prior_qepctl, eqep->mmio_base + QEPCTL); -+ -+ /* Increment the device usage count and run pm_runtime_resume() */ -+ pm_runtime_get_sync(dev); -+ -+ /* Success */ -+ return 0; -+} -+ -+/* create pm functions object */ -+static SIMPLE_DEV_PM_OPS(eqep_pm_ops, eqep_suspend, eqep_resume); -+ -+/* Platform driver information */ -+static struct platform_driver eqep_driver = { -+ .driver = { -+ .name = "eqep", -+ .owner = THIS_MODULE, -+ .pm = &eqep_pm_ops, -+ .of_match_table = eqep_of_match, -+ }, -+ .probe = eqep_probe, -+ .remove = eqep_remove, -+}; -+ -+/* Register this platform driver */ -+module_platform_driver(eqep_driver); -+ -+/* Module information */ -+MODULE_DESCRIPTION("TI eQEP driver"); -+MODULE_AUTHOR("Nathaniel R. Lewis"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c -index 87a1337..eb57610 100644 ---- a/drivers/misc/tsl2550.c -+++ b/drivers/misc/tsl2550.c -@@ -177,7 +177,7 @@ static int tsl2550_calculate_lux(u8 ch0, u8 ch1) - } else - lux = 0; - else -- return -EAGAIN; -+ return 0; - - /* LUX range check */ - return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux; -diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c -index 709a872..288cb38 100644 ---- a/drivers/mmc/card/block.c -+++ b/drivers/mmc/card/block.c -@@ -36,6 +36,7 @@ - #include <linux/compat.h> - #include <linux/pm_runtime.h> - #include <linux/idr.h> -+#include <linux/of.h> - - #include <linux/mmc/ioctl.h> - #include <linux/mmc/card.h> -@@ -2219,13 +2220,20 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, - { - struct mmc_blk_data *md; - int devidx, ret; -+ int mindynidx = max(0, of_alias_get_highest_id("mmc") + 1); -+ int reqidx = card->host->index; - - again: - if (!ida_pre_get(&mmc_blk_ida, GFP_KERNEL)) - return ERR_PTR(-ENOMEM); - - spin_lock(&mmc_blk_lock); -- ret = ida_get_new(&mmc_blk_ida, &devidx); -+ ret = ida_get_new_above(&mmc_blk_ida, reqidx, &devidx); -+ if (!ret && devidx < mindynidx && devidx != reqidx) { -+ // requested index in use, fall back to dynamic -+ ida_remove(&mmc_blk_ida, devidx); -+ ret = ida_get_new_above(&mmc_blk_ida, mindynidx, &devidx); -+ } - spin_unlock(&mmc_blk_lock); - - if (ret == -EAGAIN) -diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c -index 848b345..2ae45ee 100644 ---- a/drivers/mmc/core/host.c -+++ b/drivers/mmc/core/host.c -@@ -344,6 +344,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) - { - int err; - struct mmc_host *host; -+ int mindynidx = max(0, of_alias_get_highest_id("mmc") + 1); -+ int reqidx = dev->of_node ? of_alias_get_id(dev->of_node, "mmc") : -1; - - host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); - if (!host) -@@ -359,7 +361,16 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) - } - - spin_lock(&mmc_host_lock); -- err = ida_get_new(&mmc_host_ida, &host->index); -+ if (reqidx >= 0) { -+ err = ida_get_new_above(&mmc_host_ida, reqidx, &host->index); -+ if (!err && host->index != reqidx) { -+ // requested index in use, fall back to dynamic -+ ida_remove(&mmc_host_ida, host->index); -+ reqidx = -1; -+ } -+ } -+ if (reqidx < 0) -+ err = ida_get_new_above(&mmc_host_ida, mindynidx, &host->index); - spin_unlock(&mmc_host_lock); - - if (err == -EAGAIN) { -diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c -index 5f2f24a..c04d836 100644 ---- a/drivers/mmc/host/omap_hsmmc.c -+++ b/drivers/mmc/host/omap_hsmmc.c -@@ -2098,9 +2098,9 @@ static int omap_hsmmc_probe(struct platform_device *pdev) - host->dbclk = NULL; - } - -- /* Since we do only SG emulation, we can have as many segs -- * as we want. */ -- mmc->max_segs = 1024; -+ /* Set this to a value that allows allocating an entire descriptor -+ * list within a page (zero order allocation). */ -+ mmc->max_segs = 64; - - mmc->max_blk_size = 512; /* Block Length at max can be 1024 */ - mmc->max_blk_count = 0xFFFF; /* No. of Blocks is 16 bits */ -diff --git a/drivers/net/ethernet/allwinner/Kconfig b/drivers/net/ethernet/allwinner/Kconfig -index 47da7e7..060569c 100644 ---- a/drivers/net/ethernet/allwinner/Kconfig -+++ b/drivers/net/ethernet/allwinner/Kconfig -@@ -33,4 +33,17 @@ config SUN4I_EMAC - To compile this driver as a module, choose M here. The module - will be called sun4i-emac. - -+config SUN8I_EMAC -+ tristate "Allwinner sun8i EMAC support" -+ depends on ARCH_SUNXI || COMPILE_TEST -+ depends on OF -+ select MII -+ select PHYLIB -+ ---help--- -+ This driver support the sun8i EMAC ethernet driver present on -+ H3/A83T/A64 Allwinner SoCs. -+ -+ To compile this driver as a module, choose M here. The module -+ will be called sun8i-emac. -+ - endif # NET_VENDOR_ALLWINNER -diff --git a/drivers/net/ethernet/allwinner/Makefile b/drivers/net/ethernet/allwinner/Makefile -index 03129f7..8bd1693 100644 ---- a/drivers/net/ethernet/allwinner/Makefile -+++ b/drivers/net/ethernet/allwinner/Makefile -@@ -3,3 +3,4 @@ - # - - obj-$(CONFIG_SUN4I_EMAC) += sun4i-emac.o -+obj-$(CONFIG_SUN8I_EMAC) += sun8i-emac.o -diff --git b/drivers/net/ethernet/allwinner/sun8i-emac.c b/drivers/net/ethernet/allwinner/sun8i-emac.c -new file mode 100644 -index 0000000..fc0c1dd ---- /dev/null -+++ b/drivers/net/ethernet/allwinner/sun8i-emac.c -@@ -0,0 +1,2129 @@ -+/* -+ * sun8i-emac driver -+ * -+ * Copyright (C) 2015-2016 Corentin LABBE <clabbe.montjoie@gmail.com> -+ * -+ * This is the driver for Allwinner Ethernet MAC found in H3/A83T/A64 SoC -+ * -+ * TODO: -+ * - MAC filtering -+ * - Jumbo frame -+ * - features rx-all (NETIF_F_RXALL_BIT) -+ */ -+#include <linux/bitops.h> -+#include <linux/clk.h> -+#include <linux/dma-mapping.h> -+#include <linux/etherdevice.h> -+#include <linux/interrupt.h> -+#include <linux/iopoll.h> -+#include <linux/mii.h> -+#include <linux/module.h> -+#include <linux/netdevice.h> -+#include <linux/of_device.h> -+#include <linux/of_mdio.h> -+#include <linux/of_net.h> -+#include <linux/phy.h> -+#include <linux/pinctrl/consumer.h> -+#include <linux/pinctrl/pinctrl.h> -+#include <linux/platform_device.h> -+#include <linux/reset.h> -+#include <linux/scatterlist.h> -+#include <linux/skbuff.h> -+ -+#define SUN8I_EMAC_BASIC_CTL0 0x00 -+#define SUN8I_EMAC_BASIC_CTL1 0x04 -+#define SUN8I_EMAC_INT_STA 0x08 -+#define SUN8I_EMAC_INT_EN 0x0C -+#define SUN8I_EMAC_TX_CTL0 0x10 -+#define SUN8I_EMAC_TX_CTL1 0x14 -+#define SUN8I_EMAC_TX_FLOW_CTL 0x1C -+#define SUN8I_EMAC_RX_CTL0 0x24 -+#define SUN8I_EMAC_RX_CTL1 0x28 -+#define SUN8I_EMAC_RX_FRM_FLT 0x38 -+#define SUN8I_EMAC_MDIO_CMD 0x48 -+#define SUN8I_EMAC_MDIO_DATA 0x4C -+#define SUN8I_EMAC_TX_DMA_STA 0xB0 -+#define SUN8I_EMAC_TX_CUR_DESC 0xB4 -+#define SUN8I_EMAC_TX_CUR_BUF 0xB8 -+#define SUN8I_EMAC_RX_DMA_STA 0xC0 -+ -+#define MDIO_CMD_MII_BUSY BIT(0) -+#define MDIO_CMD_MII_WRITE BIT(1) -+#define MDIO_CMD_MII_PHY_REG_ADDR_MASK GENMASK(8, 4) -+#define MDIO_CMD_MII_PHY_REG_ADDR_SHIFT 4 -+#define MDIO_CMD_MII_PHY_ADDR_MASK GENMASK(16, 12) -+#define MDIO_CMD_MII_PHY_ADDR_SHIFT 12 -+ -+#define SUN8I_EMAC_MACADDR_HI 0x50 -+#define SUN8I_EMAC_MACADDR_LO 0x54 -+ -+#define SUN8I_EMAC_RX_DESC_LIST 0x34 -+#define SUN8I_EMAC_TX_DESC_LIST 0x20 -+ -+#define SUN8I_EMAC_RX_DO_CRC BIT(27) -+#define SUN8I_EMAC_RX_STRIP_FCS BIT(28) -+ -+#define SUN8I_COULD_BE_USED_BY_DMA BIT(31) -+ -+/* Used in RX_CTL1*/ -+#define RX_DMA_EN BIT(30) -+#define RX_DMA_START BIT(31) -+/* Used in TX_CTL1*/ -+#define TX_DMA_EN BIT(30) -+#define TX_DMA_START BIT(31) -+ -+/* Used in RX_CTL0 */ -+#define RX_RECEIVER_EN BIT(31) -+/* Used in TX_CTL0 */ -+#define TX_TRANSMITTER_EN BIT(31) -+ -+/* Basic CTL0 */ -+#define BCTL0_FD BIT(0) -+#define BCTL0_SPEED_10 2 -+#define BCTL0_SPEED_100 3 -+#define BCTL0_SPEED_MASK GENMASK(3, 2) -+#define BCTL0_SPEED_SHIFT 2 -+ -+#define FLOW_RX 1 -+#define FLOW_TX 2 -+ -+#define RX_INT BIT(8) -+#define TX_INT BIT(0) -+ -+/* Bits used in frame RX status */ -+#define DSC_RX_FIRST BIT(9) -+#define DSC_RX_LAST BIT(8) -+ -+/* Bits used in frame TX ctl */ -+#define SUN8I_EMAC_MAGIC_TX_BIT BIT(24) -+#define SUN8I_EMAC_TX_DO_CRC (BIT(27) | BIT(28)) -+#define DSC_TX_FIRST BIT(29) -+#define DSC_TX_LAST BIT(30) -+#define SUN8I_EMAC_WANT_INT BIT(31) -+ -+enum emac_variant { -+ NONE_EMAC,/* for be sure that variant is non-0 if set */ -+ A83T_EMAC, -+ H3_EMAC, -+ A64_EMAC, -+}; -+ -+static const char const estats_str[][ETH_GSTRING_LEN] = { -+ /* errors */ -+ "rx_payload_error", -+ "rx_CRC_error", -+ "rx_phy_error", -+ "rx_length_error", -+ "rx_col_error", -+ "rx_header_error", -+ "rx_overflow_error", -+ "rx_saf_error", -+ "rx_daf_error", -+ "rx_buf_error", -+ /* misc infos */ -+ "tx_stop_queue", -+ "rx_dma_ua", -+ "rx_dma_stop", -+ "tx_dma_ua", -+ "tx_dma_stop", -+ "rx_hw_csum", -+ "tx_hw_csum", -+ /* interrupts */ -+ "rx_int", -+ "tx_int", -+ "rx_early_int", -+ "tx_early_int", -+ "tx_underflow_int", -+ /* debug */ -+ "tx_used_desc", -+ "napi_schedule", -+ "napi_underflow", -+}; -+ -+struct sun8i_emac_stats { -+ u64 rx_payload_error; -+ u64 rx_crc_error; -+ u64 rx_phy_error; -+ u64 rx_length_error; -+ u64 rx_col_error; -+ u64 rx_header_error; -+ u64 rx_overflow_error; -+ u64 rx_saf_fail; -+ u64 rx_daf_fail; -+ u64 rx_buf_error; -+ -+ u64 tx_stop_queue; -+ u64 rx_dma_ua; -+ u64 rx_dma_stop; -+ u64 tx_dma_ua; -+ u64 tx_dma_stop; -+ u64 rx_hw_csum; -+ u64 tx_hw_csum; -+ -+ u64 rx_int; -+ u64 tx_int; -+ u64 rx_early_int; -+ u64 tx_early_int; -+ u64 tx_underflow_int; -+ -+ u64 tx_used_desc; -+ u64 napi_schedule; -+ u64 napi_underflow; -+}; -+ -+/* The datasheet said that each descriptor can transfers up to 4096bytes -+ * But latter, a register documentation reduce that value to 2048 -+ * Anyway using 2048 cause strange behaviours and even BSP driver use 2047 -+ */ -+#define DESC_BUF_MAX 2044 -+#if (DESC_BUF_MAX < (ETH_FRAME_LEN + 4)) -+#error "DESC_BUF_MAX must be set at minimum to ETH_FRAME_LEN + 4" -+#endif -+ -+/* MAGIC value for knowing if a descriptor is available or not */ -+#define DCLEAN (BIT(16) | BIT(14) | BIT(12) | BIT(10) | BIT(9)) -+ -+/* struct dma_desc - Structure of DMA descriptor used by the hardware -+ * @status: Status of the frame written by HW, so RO for the -+ * driver (except for BIT(31) which is R/W) -+ * @ctl: Information on the frame written by the driver (INT, len,...) -+ * @buf_addr: physical address of the frame data -+ * @next: physical address of next dma_desc -+ */ -+struct dma_desc { -+ u32 status; -+ u32 ctl; -+ u32 buf_addr; -+ u32 next; -+}; -+ -+/* Describe how data from skb are DMA mapped (used in txinfo map member) */ -+#define MAP_SINGLE 1 -+#define MAP_PAGE 2 -+ -+/* Structure for storing information about data in TX ring buffer */ -+struct txinfo { -+ struct sk_buff *skb; -+ int map; -+}; -+ -+struct sun8i_emac_priv { -+ void __iomem *base; -+ void __iomem *syscon; -+ int irq; -+ struct device *dev; -+ struct net_device *ndev; -+ struct mii_bus *mdio; -+ struct napi_struct napi; -+ spinlock_t tx_lock;/* control the access of transmit descriptors */ -+ int duplex; -+ int speed; -+ int link; -+ int phy_interface; -+ enum emac_variant variant; -+ struct device_node *phy_node; -+ struct clk *ahb_clk; -+ struct clk *ephy_clk; -+ bool use_internal_phy; -+ -+ struct reset_control *rst; -+ struct reset_control *rst_ephy; -+ -+ struct dma_desc *dd_rx; -+ dma_addr_t dd_rx_phy; -+ struct dma_desc *dd_tx; -+ dma_addr_t dd_tx_phy; -+ struct sk_buff **rx_skb; -+ struct txinfo *txl; -+ -+ int nbdesc_tx; -+ int nbdesc_rx; -+ int tx_slot; -+ int tx_dirty; -+ int rx_dirty; -+ struct sun8i_emac_stats estats; -+ u32 msg_enable; -+ int flow_ctrl; -+ int pause; -+}; -+ -+static irqreturn_t sun8i_emac_dma_interrupt(int irq, void *dev_id); -+ -+static void rb_inc(int *p, const int max) -+{ -+ (*p)++; -+ (*p) %= max; -+} -+ -+/* Return the number of contiguous free descriptors -+ * starting from tx_slot -+ */ -+static int rb_tx_numfreedesc(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ -+ if (priv->tx_slot < priv->tx_dirty) -+ return priv->tx_dirty - priv->tx_slot; -+ -+ return (priv->nbdesc_tx - priv->tx_slot) + priv->tx_dirty; -+} -+ -+/* Allocate a skb in a DMA descriptor -+ * -+ * @i index of slot to fill -+*/ -+static int sun8i_emac_rx_skb(struct net_device *ndev, int i) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ struct dma_desc *ddesc; -+ struct sk_buff *skb; -+ -+ ddesc = priv->dd_rx + i; -+ -+ ddesc->ctl = 0; -+ -+ skb = netdev_alloc_skb_ip_align(ndev, DESC_BUF_MAX); -+ if (!skb) -+ return -ENOMEM; -+ -+ /* should not happen */ -+ if (unlikely(priv->rx_skb[i])) -+ dev_warn(priv->dev, "BUG: Leaking a skbuff\n"); -+ -+ priv->rx_skb[i] = skb; -+ -+ ddesc->buf_addr = dma_map_single(priv->dev, skb->data, -+ DESC_BUF_MAX, DMA_FROM_DEVICE); -+ if (dma_mapping_error(priv->dev, ddesc->buf_addr)) { -+ dev_err(priv->dev, "ERROR: Cannot map RX buffer for DMA\n"); -+ dev_kfree_skb(skb); -+ return -EFAULT; -+ } -+ ddesc->ctl |= DESC_BUF_MAX; -+ wmb();/* SUN8I_COULD_BE_USED_BY_DMA must be the last value written */ -+ ddesc->status = SUN8I_COULD_BE_USED_BY_DMA; -+ -+ return 0; -+} -+ -+static void sun8i_emac_stop_tx(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ u32 v; -+ -+ netif_stop_queue(ndev); -+ -+ v = readl(priv->base + SUN8I_EMAC_TX_CTL0); -+ v &= ~TX_TRANSMITTER_EN;/*Disable transmitter after current reception*/ -+ writel(v, priv->base + SUN8I_EMAC_TX_CTL0); -+ v = readl(priv->base + SUN8I_EMAC_TX_CTL1); -+ v &= ~TX_DMA_EN; /* Stop TX DMA */ -+ writel(v, priv->base + SUN8I_EMAC_TX_CTL1); -+} -+ -+static void sun8i_emac_stop_rx(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ u32 v; -+ -+ v = readl(priv->base + SUN8I_EMAC_RX_CTL0); -+ v &= ~RX_RECEIVER_EN; /* Disable receiver after current reception */ -+ writel(v, priv->base + SUN8I_EMAC_RX_CTL0); -+ v = readl(priv->base + SUN8I_EMAC_RX_CTL1); -+ v &= ~RX_DMA_EN; /* Stop RX DMA */ -+ writel(v, priv->base + SUN8I_EMAC_RX_CTL1); -+} -+ -+static void sun8i_emac_start_rx(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ u32 v; -+ -+ v = readl(priv->base + SUN8I_EMAC_RX_CTL0); -+ v |= RX_RECEIVER_EN;/* Enable receiver */ -+ writel(v, priv->base + SUN8I_EMAC_RX_CTL0); -+ -+ v = readl(priv->base + SUN8I_EMAC_RX_CTL1); -+ v |= RX_DMA_START; -+ v |= RX_DMA_EN; -+ writel(v, priv->base + SUN8I_EMAC_RX_CTL1); -+} -+ -+static void sun8i_emac_start_tx(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ u32 v; -+ -+ v = readl(priv->base + SUN8I_EMAC_TX_CTL0); -+ v |= TX_TRANSMITTER_EN; -+ writel(v, priv->base + SUN8I_EMAC_TX_CTL0); -+ -+ v = readl(priv->base + SUN8I_EMAC_TX_CTL1); -+ v |= TX_DMA_START; -+ v |= TX_DMA_EN; -+ writel(v, priv->base + SUN8I_EMAC_TX_CTL1); -+} -+ -+/* Set MAC address for slot index -+ * @addr: the MAC address to set -+ * @index: The index of slot where to set address. -+ * The slot 0 is the main MACaddr -+ */ -+static void sun8i_emac_set_macaddr(struct sun8i_emac_priv *priv, -+ const u8 *addr, int index) -+{ -+ u32 v; -+ -+ dev_info(priv->dev, "device MAC address slot %d %02x:%02x:%02x:%02x:%02x:%02x\n", -+ index, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); -+ -+ v = (addr[5] << 8) | addr[4]; -+ writel(v, priv->base + SUN8I_EMAC_MACADDR_HI + index * 8); -+ v = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0]; -+ writel(v, priv->base + SUN8I_EMAC_MACADDR_LO + index * 8); -+} -+ -+static void sun8i_emac_set_link_mode(struct sun8i_emac_priv *priv) -+{ -+ u32 v; -+ -+ v = readl(priv->base + SUN8I_EMAC_BASIC_CTL0); -+ -+ if (priv->duplex) -+ v |= BCTL0_FD; -+ else -+ v &= ~BCTL0_FD; -+ -+ v &= ~BCTL0_SPEED_MASK; -+ switch (priv->speed) { -+ case 1000: -+ break; -+ case 100: -+ v |= BCTL0_SPEED_100 << BCTL0_SPEED_SHIFT; -+ break; -+ case 10: -+ v |= BCTL0_SPEED_10 << BCTL0_SPEED_SHIFT; -+ break; -+ } -+ -+ writel(v, priv->base + SUN8I_EMAC_BASIC_CTL0); -+} -+ -+static void sun8i_emac_flow_ctrl(struct sun8i_emac_priv *priv, int duplex, -+ int fc) -+{ -+ u32 flow = 0; -+ -+ netif_dbg(priv, link, priv->ndev, "%s %d %d\n", __func__, -+ duplex, fc); -+ -+ flow = readl(priv->base + SUN8I_EMAC_RX_CTL0); -+ if (fc & FLOW_RX) -+ flow |= BIT(16); -+ else -+ flow &= ~BIT(16); -+ writel(flow, priv->base + SUN8I_EMAC_RX_CTL0); -+ -+ flow = readl(priv->base + SUN8I_EMAC_TX_FLOW_CTL); -+ if (fc & FLOW_TX) -+ flow |= BIT(0); -+ else -+ flow &= ~BIT(0); -+ writel(flow, priv->base + SUN8I_EMAC_TX_FLOW_CTL); -+} -+ -+/* Grab a frame into a skb from descriptor number i */ -+static int sun8i_emac_rx_from_ddesc(struct net_device *ndev, int i) -+{ -+ struct sk_buff *skb; -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ struct dma_desc *ddesc = priv->dd_rx + i; -+ int frame_len; -+ int rxcsum_done = 0; -+ -+ if (ndev->features & NETIF_F_RXCSUM) -+ rxcsum_done = 1; -+ -+ /* bit0/bit7 work only on IPv4/IPv6 TCP traffic, -+ * (not on ARP for example) so we dont raise rx_errors/discard frame -+ */ -+ /* the checksum or length of received frame's payload is wrong*/ -+ if (ddesc->status & BIT(0)) { -+ priv->estats.rx_payload_error++; -+ rxcsum_done = 0; -+ } -+ /* RX_CRC_ERR */ -+ if (ddesc->status & BIT(1)) { -+ priv->ndev->stats.rx_errors++; -+ priv->ndev->stats.rx_crc_errors++; -+ priv->estats.rx_crc_error++; -+ goto discard_frame; -+ } -+ /* RX_PHY_ERR */ -+ if ((ddesc->status & BIT(3))) { -+ priv->ndev->stats.rx_errors++; -+ priv->estats.rx_phy_error++; -+ goto discard_frame; -+ } -+ /* RX_LENGTH_ERR */ -+ if ((ddesc->status & BIT(4))) { -+ priv->ndev->stats.rx_errors++; -+ priv->ndev->stats.rx_length_errors++; -+ priv->estats.rx_length_error++; -+ goto discard_frame; -+ } -+ /* RX_COL_ERR */ -+ if ((ddesc->status & BIT(6))) { -+ priv->ndev->stats.rx_errors++; -+ priv->estats.rx_col_error++; -+ goto discard_frame; -+ } -+ /* RX_HEADER_ERR */ -+ if ((ddesc->status & BIT(7))) { -+ priv->estats.rx_header_error++; -+ rxcsum_done = 0; -+ } -+ /* RX_OVERFLOW_ERR */ -+ if ((ddesc->status & BIT(11))) { -+ priv->ndev->stats.rx_over_errors++; -+ priv->estats.rx_overflow_error++; -+ goto discard_frame; -+ } -+ /* RX_NO_ENOUGTH_BUF_ERR */ -+ if ((ddesc->status & BIT(14))) { -+ priv->ndev->stats.rx_errors++; -+ priv->estats.rx_buf_error++; -+ goto discard_frame; -+ } -+ -+ /* BIT(9) is for the first frame, not having it is bad since we do not -+ * handle Jumbo frame -+ */ -+ if ((ddesc->status & DSC_RX_FIRST) == 0) { -+ dev_warn_ratelimited(priv->dev, "BUG: Non-first frame received. This should not happen\n"); -+ goto discard_frame; -+ } -+ frame_len = (ddesc->status >> 16) & 0x3FFF; -+ if (!(ndev->features & NETIF_F_RXFCS)) -+ frame_len -= ETH_FCS_LEN; -+ -+ skb = priv->rx_skb[i]; -+ -+ netif_dbg(priv, rx_status, priv->ndev, -+ "%s from %02d %pad len=%d status=%x st=%x\n", -+ __func__, i, &ddesc, frame_len, ddesc->status, ddesc->ctl); -+ -+ skb_put(skb, frame_len); -+ -+ dma_unmap_single(priv->dev, ddesc->buf_addr, DESC_BUF_MAX, -+ DMA_FROM_DEVICE); -+ skb->protocol = eth_type_trans(skb, priv->ndev); -+ if (rxcsum_done) { -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ priv->estats.rx_hw_csum++; -+ } else { -+ skb->ip_summed = CHECKSUM_PARTIAL; -+ } -+ -+ priv->ndev->stats.rx_packets++; -+ priv->ndev->stats.rx_bytes += frame_len; -+ priv->rx_skb[i] = NULL; -+ -+ /* this frame is not the last */ -+ if ((ddesc->status & DSC_RX_LAST) == 0) { -+ dev_warn(priv->dev, "Multi frame not implemented currlen=%d\n", -+ frame_len); -+ } -+ -+ sun8i_emac_rx_skb(ndev, i); -+ napi_gro_receive(&priv->napi, skb); -+ -+ return 0; -+ /* If the frame need to be dropped, we simply reuse the buffer */ -+discard_frame: -+ ddesc->ctl = DESC_BUF_MAX; -+ wmb();/* SUN8I_COULD_BE_USED_BY_DMA must be the last value written */ -+ ddesc->status = SUN8I_COULD_BE_USED_BY_DMA; -+ return 0; -+} -+ -+/* iterate over dma_desc for finding completed xmit. -+ * Called from interrupt context, so no need to spinlock tx -+ * -+ * The problem is: how to know that a descriptor is sent and not just in -+ * preparation. -+ * Need to have status=0 and st set but this is the state of first frame just -+ * before setting the own-by-DMA bit. -+ * The solution is to used the artificial value DCLEAN. -+ */ -+static int sun8i_emac_complete_xmit(struct net_device *ndev, int budget) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ struct dma_desc *ddesc; -+ int frame_len; -+ int work = 0; -+ -+ spin_lock(&priv->tx_lock); -+ do { -+ ddesc = priv->dd_tx + priv->tx_dirty; -+ -+ if (ddesc->status & SUN8I_COULD_BE_USED_BY_DMA) -+ goto xmit_end; -+ -+ if (ddesc->status == DCLEAN) -+ goto xmit_end; -+ -+ if (ddesc->status == 0 && !ddesc->ctl) { -+ dev_err(priv->dev, "BUG: reached the void %d %d\n", -+ priv->tx_dirty, priv->tx_slot); -+ goto xmit_end; -+ } -+ -+ /* TX_UNDERFLOW_ERR */ -+ if (ddesc->status & BIT(1)) -+ priv->ndev->stats.tx_errors++; -+ /* TX_DEFER_ERR */ -+ if (ddesc->status & BIT(2)) -+ priv->ndev->stats.tx_errors++; -+ /* BIT 6:3 numbers of collisions */ -+ if (ddesc->status & 0x78) -+ priv->ndev->stats.collisions += -+ (ddesc->status & 0x78) >> 3; -+ /* TX_COL_ERR_1 */ -+ if (ddesc->status & BIT(8)) -+ priv->ndev->stats.tx_errors++; -+ /* TX_COL_ERR_0 */ -+ if (ddesc->status & BIT(9)) -+ priv->ndev->stats.tx_errors++; -+ /* TX_CRS_ERR */ -+ if (ddesc->status & BIT(10)) -+ priv->ndev->stats.tx_carrier_errors++; -+ /* TX_PAYLOAD_ERR */ -+ if (ddesc->status & BIT(12)) -+ priv->ndev->stats.tx_errors++; -+ /* TX_LENGTH_ERR */ -+ if (ddesc->status & BIT(14)) -+ priv->ndev->stats.tx_errors++; -+ /* TX_HEADER_ERR */ -+ if (ddesc->status & BIT(16)) -+ priv->ndev->stats.tx_errors++; -+ frame_len = ddesc->ctl & 0x3FFF; -+ if (priv->txl[priv->tx_dirty].map == MAP_SINGLE) -+ dma_unmap_single(priv->dev, ddesc->buf_addr, -+ frame_len, DMA_TO_DEVICE); -+ else -+ dma_unmap_page(priv->dev, ddesc->buf_addr, -+ frame_len, DMA_TO_DEVICE); -+ /* we can free skb only on last frame */ -+ if (priv->txl[priv->tx_dirty].skb && (ddesc->ctl & DSC_TX_LAST)) -+ dev_kfree_skb_irq(priv->txl[priv->tx_dirty].skb); -+ -+ priv->txl[priv->tx_dirty].skb = NULL; -+ priv->txl[priv->tx_dirty].map = 0; -+ ddesc->ctl = 0; -+ wmb(); /* setting to DCLEAN is the last value to be set */ -+ ddesc->status = DCLEAN; -+ work++; -+ -+ rb_inc(&priv->tx_dirty, priv->nbdesc_tx); -+ ddesc = priv->dd_tx + priv->tx_dirty; -+ } while (ddesc->ctl && !(ddesc->status & SUN8I_COULD_BE_USED_BY_DMA)); -+ -+ if (netif_queue_stopped(ndev) && -+ rb_tx_numfreedesc(ndev) > MAX_SKB_FRAGS + 1) -+ netif_wake_queue(ndev); -+xmit_end: -+ spin_unlock(&priv->tx_lock); -+ return work; -+} -+ -+static int sun8i_emac_poll(struct napi_struct *napi, int budget) -+{ -+ struct sun8i_emac_priv *priv = -+ container_of(napi, struct sun8i_emac_priv, napi); -+ struct net_device *ndev = priv->ndev; -+ int worked; -+ struct dma_desc *ddesc; -+ -+ priv->estats.napi_schedule++; -+ worked = sun8i_emac_complete_xmit(ndev, budget); -+ -+ ddesc = priv->dd_rx + priv->rx_dirty; -+ while (!(ddesc->status & SUN8I_COULD_BE_USED_BY_DMA) && -+ worked < budget) { -+ sun8i_emac_rx_from_ddesc(ndev, priv->rx_dirty); -+ worked++; -+ rb_inc(&priv->rx_dirty, priv->nbdesc_rx); -+ ddesc = priv->dd_rx + priv->rx_dirty; -+ }; -+ if (worked < budget) { -+ priv->estats.napi_underflow++; -+ napi_complete(&priv->napi); -+ writel(RX_INT | TX_INT, priv->base + SUN8I_EMAC_INT_EN); -+ } -+ return worked; -+} -+ -+static int sun8i_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg) -+{ -+ struct net_device *ndev = bus->priv; -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ int err; -+ u32 reg; -+ -+ err = readl_poll_timeout(priv->base + SUN8I_EMAC_MDIO_CMD, reg, -+ !(reg & MDIO_CMD_MII_BUSY), 100, 10000); -+ if (err) { -+ dev_err(priv->dev, "%s timeout %x\n", __func__, reg); -+ return err; -+ } -+ -+ reg &= ~MDIO_CMD_MII_WRITE; -+ reg &= ~MDIO_CMD_MII_PHY_REG_ADDR_MASK; -+ reg |= (phy_reg << MDIO_CMD_MII_PHY_REG_ADDR_SHIFT) & -+ MDIO_CMD_MII_PHY_REG_ADDR_MASK; -+ -+ reg &= ~MDIO_CMD_MII_PHY_ADDR_MASK; -+ -+ reg |= (phy_addr << MDIO_CMD_MII_PHY_ADDR_SHIFT) & -+ MDIO_CMD_MII_PHY_ADDR_MASK; -+ -+ reg |= MDIO_CMD_MII_BUSY; -+ -+ writel(reg, priv->base + SUN8I_EMAC_MDIO_CMD); -+ -+ err = readl_poll_timeout(priv->base + SUN8I_EMAC_MDIO_CMD, reg, -+ !(reg & MDIO_CMD_MII_BUSY), 100, 10000); -+ -+ if (err) { -+ dev_err(priv->dev, "%s timeout %x\n", __func__, reg); -+ return err; -+ } -+ -+ return readl(priv->base + SUN8I_EMAC_MDIO_DATA); -+} -+ -+static int sun8i_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, -+ u16 data) -+{ -+ struct net_device *ndev = bus->priv; -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ u32 reg; -+ int err; -+ -+ err = readl_poll_timeout(priv->base + SUN8I_EMAC_MDIO_CMD, reg, -+ !(reg & MDIO_CMD_MII_BUSY), 100, 10000); -+ if (err) { -+ dev_err(priv->dev, "%s timeout %x\n", __func__, reg); -+ return err; -+ } -+ -+ reg &= ~MDIO_CMD_MII_PHY_REG_ADDR_MASK; -+ reg |= (phy_reg << MDIO_CMD_MII_PHY_REG_ADDR_SHIFT) & -+ MDIO_CMD_MII_PHY_REG_ADDR_MASK; -+ -+ reg &= ~MDIO_CMD_MII_PHY_ADDR_MASK; -+ reg |= (phy_addr << MDIO_CMD_MII_PHY_ADDR_SHIFT) & -+ MDIO_CMD_MII_PHY_ADDR_MASK; -+ -+ reg |= MDIO_CMD_MII_WRITE; -+ reg |= MDIO_CMD_MII_BUSY; -+ -+ writel(reg, priv->base + SUN8I_EMAC_MDIO_CMD); -+ writel(data, priv->base + SUN8I_EMAC_MDIO_DATA); -+ dev_dbg(priv->dev, "%s %d %d %x %x\n", __func__, phy_addr, phy_reg, -+ reg, data); -+ -+ err = readl_poll_timeout(priv->base + SUN8I_EMAC_MDIO_CMD, reg, -+ !(reg & MDIO_CMD_MII_BUSY), 100, 10000); -+ if (err) { -+ dev_err(priv->dev, "%s timeout %x\n", __func__, reg); -+ return err; -+ } -+ -+ return 0; -+} -+ -+static int sun8i_emac_mdio_register(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ struct mii_bus *bus; -+ int ret; -+ -+ bus = mdiobus_alloc(); -+ if (!bus) { -+ netdev_err(ndev, "Failed to allocate a new mdio bus\n"); -+ return -ENOMEM; -+ } -+ -+ bus->name = dev_name(priv->dev); -+ bus->read = &sun8i_mdio_read; -+ bus->write = &sun8i_mdio_write; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%x", bus->name, priv->dev->id); -+ -+ bus->parent = priv->dev; -+ bus->priv = ndev; -+ -+ ret = of_mdiobus_register(bus, priv->dev->of_node); -+ if (ret) { -+ netdev_err(ndev, "Could not register a MDIO bus: %d\n", ret); -+ mdiobus_free(bus); -+ return ret; -+ } -+ -+ priv->mdio = bus; -+ -+ return 0; -+} -+ -+static void sun8i_emac_mdio_unregister(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ -+ mdiobus_unregister(priv->mdio); -+ mdiobus_free(priv->mdio); -+} -+ -+/* Run within phydev->lock */ -+static void sun8i_emac_adjust_link(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ struct phy_device *phydev = ndev->phydev; -+ int new_state = 0; -+ -+ netif_dbg(priv, link, priv->ndev, -+ "%s link=%x duplex=%x speed=%x\n", __func__, -+ phydev->link, phydev->duplex, phydev->speed); -+ if (!phydev) -+ return; -+ -+ if (phydev->link) { -+ if (phydev->duplex != priv->duplex) { -+ new_state = 1; -+ priv->duplex = phydev->duplex; -+ } -+ if (phydev->pause) -+ sun8i_emac_flow_ctrl(priv, phydev->duplex, -+ priv->flow_ctrl); -+ -+ if (phydev->speed != priv->speed) { -+ new_state = 1; -+ priv->speed = phydev->speed; -+ } -+ -+ if (priv->link == 0) { -+ new_state = 1; -+ priv->link = phydev->link; -+ } -+ -+ netif_dbg(priv, link, priv->ndev, -+ "%s new=%d link=%d pause=%d\n", -+ __func__, new_state, priv->link, phydev->pause); -+ if (new_state) -+ sun8i_emac_set_link_mode(priv); -+ } else if (priv->link != phydev->link) { -+ new_state = 1; -+ priv->link = 0; -+ priv->speed = 0; -+ priv->duplex = -1; -+ } -+ -+ if (new_state) -+ phy_print_status(phydev); -+} -+ -+/* H3 specific bits for EPHY */ -+#define H3_EPHY_ADDR_SHIFT 20 -+#define H3_EPHY_LED_POL BIT(17) /* 1: active low, 0: active high */ -+#define H3_EPHY_SHUTDOWN BIT(16) /* 1: shutdown, 0: power up */ -+#define H3_EPHY_SELECT BIT(15) /* 1: internal PHY, 0: external PHY */ -+#define H3_EPHY_DEFAULT_VALUE 0x58000 -+#define H3_EPHY_DEFAULT_MASK GENMASK(31, 15) -+ -+/* H3/A64 specific bits */ -+#define SC_RMII_EN BIT(13) /* 1: enable RMII (overrides EPIT) */ -+ -+/* Generic system control EMAC_CLK bits */ -+#define SC_ETXDC_MASK GENMASK(2, 0) -+#define SC_ETXDC_SHIFT 10 -+#define SC_ERXDC_MASK GENMASK(4, 0) -+#define SC_ERXDC_SHIFT 5 -+#define SC_EPIT BIT(2) /* 1: RGMII, 0: MII */ -+#define SC_ETCS_MASK GENMASK(1, 0) -+#define SC_ETCS_MII 0x0 -+#define SC_ETCS_EXT_GMII 0x1 -+#define SC_ETCS_INT_GMII 0x2 -+ -+static int sun8i_emac_set_syscon_ephy(struct net_device *ndev, u32 *reg) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ struct device_node *node = priv->dev->of_node; -+ int ret; -+ -+ *reg &= ~H3_EPHY_DEFAULT_MASK; -+ *reg |= H3_EPHY_DEFAULT_VALUE; -+ -+ if (!priv->use_internal_phy) { -+ /* switch to external PHY interface */ -+ *reg &= ~H3_EPHY_SELECT; -+ return 0; -+ } -+ -+ if (priv->phy_interface != PHY_INTERFACE_MODE_MII) { -+ netdev_warn(ndev, -+ "Internal PHY requested, forcing MII mode.\n"); -+ priv->phy_interface = PHY_INTERFACE_MODE_MII; -+ } -+ -+ *reg |= H3_EPHY_SELECT; -+ *reg &= ~H3_EPHY_SHUTDOWN; -+ -+ if (of_property_read_bool(node, "allwinner,leds-active-low")) -+ *reg |= H3_EPHY_LED_POL; -+ -+ ret = of_mdio_parse_addr(priv->dev, priv->phy_node); -+ if (ret < 0) { -+ netdev_err(ndev, "Could not parse MDIO addr\n"); -+ return ret; -+ } -+ -+ /* of_mdio_parse_addr returns a valid (0 ~ 31) PHY -+ * address. No need to mask it again. -+ */ -+ *reg |= ret << H3_EPHY_ADDR_SHIFT; -+ -+ return 0; -+} -+ -+static int sun8i_emac_set_syscon(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ struct device_node *node = priv->dev->of_node; -+ int ret; -+ u32 reg, val; -+ -+ reg = readl(priv->syscon); -+ -+ if (priv->variant == H3_EMAC) { -+ ret = sun8i_emac_set_syscon_ephy(ndev, ®); -+ if (ret) -+ return ret; -+ } -+ -+ if (!of_property_read_u32(node, "allwinner,tx-delay", &val)) { -+ if (val <= SC_ETXDC_MASK) { -+ reg &= ~(SC_ETXDC_MASK << SC_ETXDC_SHIFT); -+ reg |= (val << SC_ETXDC_SHIFT); -+ } else { -+ netdev_warn(ndev, "Invalid TX clock delay: %d\n", val); -+ } -+ } -+ -+ if (!of_property_read_u32(node, "allwinner,rx-delay", &val)) { -+ if (val <= SC_ERXDC_MASK) { -+ reg &= ~(SC_ERXDC_MASK << SC_ERXDC_SHIFT); -+ reg |= (val << SC_ERXDC_SHIFT); -+ } else { -+ netdev_warn(ndev, "Invalid RX clock delay: %d\n", val); -+ } -+ } -+ -+ /* Clear interface mode bits */ -+ reg &= ~(SC_ETCS_MASK | SC_EPIT); -+ if (priv->variant == H3_EMAC || priv->variant == A64_EMAC) -+ reg &= ~SC_RMII_EN; -+ -+ switch (priv->phy_interface) { -+ case PHY_INTERFACE_MODE_MII: -+ /* default */ -+ break; -+ case PHY_INTERFACE_MODE_RGMII: -+ reg |= SC_EPIT | SC_ETCS_INT_GMII; -+ break; -+ case PHY_INTERFACE_MODE_RMII: -+ if (priv->variant == H3_EMAC || priv->variant == A64_EMAC) { -+ reg |= SC_RMII_EN | SC_ETCS_EXT_GMII; -+ break; -+ } -+ /* RMII not supported on A83T */ -+ default: -+ netdev_err(ndev, "Unsupported interface mode: %s", -+ phy_modes(priv->phy_interface)); -+ return -EINVAL; -+ } -+ -+ writel(reg, priv->syscon); -+ -+ return 0; -+} -+ -+static void sun8i_emac_unset_syscon(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ u32 reg = 0; -+ -+ if (priv->variant == H3_EMAC) -+ reg = H3_EPHY_DEFAULT_VALUE; -+ -+ writel(reg, priv->syscon); -+} -+ -+/* Set Management Data Clock, must be call after device reset */ -+static void sun8i_emac_set_mdc(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ unsigned long rate; -+ u32 reg; -+ -+ rate = clk_get_rate(priv->ahb_clk); -+ if (rate > 160000000) -+ reg = 0x3 << 20; /* AHB / 128 */ -+ else if (rate > 80000000) -+ reg = 0x2 << 20; /* AHB / 64 */ -+ else if (rate > 40000000) -+ reg = 0x1 << 20; /* AHB / 32 */ -+ else -+ reg = 0x0 << 20; /* AHB / 16 */ -+ netif_dbg(priv, link, ndev, "MDC auto : %x\n", reg); -+ writel(reg, priv->base + SUN8I_EMAC_MDIO_CMD); -+} -+ -+/* "power" the device, by enabling clk/reset/regulators */ -+static int sun8i_emac_power(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ int ret; -+ -+ ret = clk_prepare_enable(priv->ahb_clk); -+ if (ret) { -+ netdev_err(ndev, "Could not enable AHB clock\n"); -+ return ret; -+ } -+ -+ if (priv->rst) { -+ ret = reset_control_deassert(priv->rst); -+ if (ret) { -+ netdev_err(ndev, "Could not deassert reset\n"); -+ goto err_reset; -+ } -+ } -+ -+ if (priv->ephy_clk) { -+ ret = clk_prepare_enable(priv->ephy_clk); -+ if (ret) { -+ netdev_err(ndev, "Could not enable EPHY clock\n"); -+ goto err_ephy_clk; -+ } -+ } -+ -+ if (priv->rst_ephy) { -+ ret = reset_control_deassert(priv->rst_ephy); -+ if (ret) { -+ netdev_err(ndev, "Could not deassert EPHY reset\n"); -+ goto err_ephy_reset; -+ } -+ } -+ -+ return 0; -+ -+err_ephy_reset: -+ if (priv->ephy_clk) -+ clk_disable_unprepare(priv->ephy_clk); -+err_ephy_clk: -+ if (priv->rst) -+ reset_control_assert(priv->rst); -+err_reset: -+ clk_disable_unprepare(priv->ahb_clk); -+ return ret; -+} -+ -+/* "Unpower" the device, disabling clocks and regulators, asserting reset */ -+static void sun8i_emac_unpower(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ -+ if (priv->rst_ephy) -+ reset_control_assert(priv->rst_ephy); -+ -+ if (priv->ephy_clk) -+ clk_disable_unprepare(priv->ephy_clk); -+ -+ if (priv->rst) -+ reset_control_assert(priv->rst); -+ -+ clk_disable_unprepare(priv->ahb_clk); -+} -+ -+static int sun8i_emac_init(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ struct device_node *node = priv->dev->of_node; -+ const u8 *addr; -+ -+ /* Try to get MAC address from DT, or assign a random one */ -+ addr = of_get_mac_address(node); -+ if (addr) -+ ether_addr_copy(ndev->dev_addr, addr); -+ else -+ eth_hw_addr_random(ndev); -+ -+ priv->phy_interface = of_get_phy_mode(node); -+ if (priv->phy_interface < 0) { -+ netdev_err(ndev, "PHY interface mode node unspecified\n"); -+ return priv->phy_interface; -+ } -+ -+ return sun8i_emac_power(ndev); -+} -+ -+static void sun8i_emac_uninit(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ -+ mdiobus_unregister(priv->mdio); -+ -+ sun8i_emac_unpower(ndev); -+} -+ -+static int sun8i_emac_mdio_probe(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ struct phy_device *phydev = NULL; -+ -+ phydev = of_phy_connect(ndev, priv->phy_node, &sun8i_emac_adjust_link, -+ 0, priv->phy_interface); -+ -+ if (!phydev) { -+ netdev_err(ndev, "Could not attach to PHY\n"); -+ return -ENODEV; -+ } -+ -+ phy_attached_info(phydev); -+ -+ /* mask with MAC supported features */ -+ phydev->supported &= PHY_GBIT_FEATURES; -+ phydev->advertising = phydev->supported; -+ -+ priv->link = 0; -+ priv->speed = 0; -+ priv->duplex = -1; -+ -+ return 0; -+} -+ -+/* Allocate both RX and TX ring buffer and init them -+ * This function also write the startbase of thoses ring in the device. -+ * All structures that help managing thoses rings are also handled -+ * by this functions (rx_skb/txl) -+ */ -+static int sun8i_emac_alloc_rings(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ struct dma_desc *ddesc; -+ int err, i; -+ -+ priv->rx_skb = kcalloc(priv->nbdesc_rx, sizeof(struct sk_buff *), -+ GFP_KERNEL); -+ if (!priv->rx_skb) { -+ err = -ENOMEM; -+ goto rx_skb_error; -+ } -+ priv->txl = kcalloc(priv->nbdesc_tx, sizeof(struct txinfo), GFP_KERNEL); -+ if (!priv->txl) { -+ err = -ENOMEM; -+ goto tx_error; -+ } -+ -+ /* allocate/init RX ring */ -+ priv->dd_rx = dma_zalloc_coherent(priv->dev, -+ priv->nbdesc_rx * sizeof(struct dma_desc), -+ &priv->dd_rx_phy, GFP_KERNEL); -+ if (!priv->dd_rx) { -+ dev_err(priv->dev, "ERROR: cannot allocate DMA RX buffer"); -+ err = -ENOMEM; -+ goto dma_rx_error; -+ } -+ ddesc = priv->dd_rx; -+ for (i = 0; i < priv->nbdesc_rx; i++) { -+ sun8i_emac_rx_skb(ndev, i); -+ ddesc->next = (u32)priv->dd_rx_phy + (i + 1) -+ * sizeof(struct dma_desc); -+ ddesc++; -+ } -+ /* last descriptor point back to first one */ -+ ddesc--; -+ ddesc->next = (u32)priv->dd_rx_phy; -+ -+ /* allocate/init TX ring */ -+ priv->dd_tx = dma_zalloc_coherent(priv->dev, -+ priv->nbdesc_tx * sizeof(struct dma_desc), -+ &priv->dd_tx_phy, GFP_KERNEL); -+ if (!priv->dd_tx) { -+ dev_err(priv->dev, "ERROR: cannot allocate DMA TX buffer"); -+ err = -ENOMEM; -+ goto dma_tx_error; -+ } -+ ddesc = priv->dd_tx; -+ for (i = 0; i < priv->nbdesc_tx; i++) { -+ ddesc->status = DCLEAN; -+ ddesc->ctl = 0; -+ ddesc->next = (u32)(priv->dd_tx_phy + (i + 1) -+ * sizeof(struct dma_desc)); -+ ddesc++; -+ } -+ /* last descriptor point back to first one */ -+ ddesc--; -+ ddesc->next = (u32)priv->dd_tx_phy; -+ i--; -+ -+ priv->tx_slot = 0; -+ priv->tx_dirty = 0; -+ priv->rx_dirty = 0; -+ -+ /* write start of RX ring descriptor */ -+ writel(priv->dd_rx_phy, priv->base + SUN8I_EMAC_RX_DESC_LIST); -+ /* write start of TX ring descriptor */ -+ writel(priv->dd_tx_phy, priv->base + SUN8I_EMAC_TX_DESC_LIST); -+ -+ return 0; -+dma_tx_error: -+ dma_free_coherent(priv->dev, priv->nbdesc_rx * sizeof(struct dma_desc), -+ priv->dd_rx, priv->dd_rx_phy); -+dma_rx_error: -+ kfree(priv->txl); -+tx_error: -+ kfree(priv->rx_skb); -+rx_skb_error: -+ return err; -+} -+ -+static int sun8i_emac_open(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ int err; -+ u32 v; -+ -+ err = request_irq(priv->irq, sun8i_emac_dma_interrupt, 0, -+ dev_name(priv->dev), ndev); -+ if (err) { -+ dev_err(priv->dev, "Cannot request IRQ: %d\n", err); -+ return err; -+ } -+ -+ /* Set interface mode (and configure internal PHY on H3) */ -+ err = sun8i_emac_set_syscon(ndev); -+ if (err) -+ goto err_irq; -+ -+ /* Do SOFT RST */ -+ v = readl(priv->base + SUN8I_EMAC_BASIC_CTL1); -+ writel(v | 0x01, priv->base + SUN8I_EMAC_BASIC_CTL1); -+ -+ err = readl_poll_timeout(priv->base + SUN8I_EMAC_BASIC_CTL1, v, -+ !(v & 0x01), 100, 10000); -+ if (err) { -+ dev_err(priv->dev, "EMAC reset timeout\n"); -+ err = -EFAULT; -+ goto err_syscon; -+ } -+ -+ sun8i_emac_set_mdc(ndev); -+ -+ err = sun8i_emac_mdio_register(ndev); -+ if (err) -+ goto err_syscon; -+ -+ err = sun8i_emac_mdio_probe(ndev); -+ if (err) -+ goto err_syscon; -+ -+ /* DMA */ -+ v = (8 << 24);/* burst len */ -+ writel(v, priv->base + SUN8I_EMAC_BASIC_CTL1); -+ -+ writel(RX_INT | TX_INT, priv->base + SUN8I_EMAC_INT_EN); -+ -+ v = readl(priv->base + SUN8I_EMAC_RX_CTL0); -+ /* CHECK_CRC */ -+ if (ndev->features & NETIF_F_RXCSUM) -+ v |= SUN8I_EMAC_RX_DO_CRC; -+ else -+ v &= ~SUN8I_EMAC_RX_DO_CRC; -+ /* STRIP_FCS */ -+ if (ndev->features & NETIF_F_RXFCS) -+ v &= ~SUN8I_EMAC_RX_STRIP_FCS; -+ else -+ v |= SUN8I_EMAC_RX_STRIP_FCS; -+ writel(v, priv->base + SUN8I_EMAC_RX_CTL0); -+ -+ v = readl(priv->base + SUN8I_EMAC_TX_CTL1); -+ /* TX_MD Transmission starts after a full frame located in TX DMA FIFO*/ -+ v |= BIT(1); -+ /* Undocumented bit (called TX_NEXT_FRM in BSP), the original comment is -+ * "Operating on second frame increase the performance -+ * especially when transmit store-and-forward is used." -+ */ -+ v |= BIT(2); -+ writel(v, priv->base + SUN8I_EMAC_TX_CTL1); -+ -+ v = readl(priv->base + SUN8I_EMAC_RX_CTL1); -+ /* RX_MD RX DMA reads data from RX DMA FIFO to host memory after a -+ * complete frame has been written to RX DMA FIFO -+ */ -+ v |= BIT(1); -+ writel(v, priv->base + SUN8I_EMAC_RX_CTL1); -+ -+ sun8i_emac_set_macaddr(priv, ndev->dev_addr, 0); -+ -+ err = sun8i_emac_alloc_rings(ndev); -+ if (err) { -+ netdev_err(ndev, "Fail to allocate rings\n"); -+ goto err_mdio; -+ } -+ -+ phy_start(ndev->phydev); -+ -+ sun8i_emac_start_rx(ndev); -+ sun8i_emac_start_tx(ndev); -+ -+ netif_napi_add(ndev, &priv->napi, sun8i_emac_poll, 64); -+ napi_enable(&priv->napi); -+ netif_start_queue(ndev); -+ -+ return 0; -+err_mdio: -+ phy_disconnect(ndev->phydev); -+err_syscon: -+ sun8i_emac_unset_syscon(ndev); -+err_irq: -+ free_irq(priv->irq, ndev); -+ return err; -+} -+ -+/* Clean the TX ring of any accepted skb for xmit */ -+static void sun8i_emac_tx_clean(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ int i; -+ struct dma_desc *ddesc; -+ int frame_len; -+ -+ spin_lock(&priv->tx_lock); -+ -+ for (i = 0; i < priv->nbdesc_tx; i++) { -+ if (priv->txl[i].skb) { -+ ddesc = priv->dd_tx + i; -+ frame_len = ddesc->ctl & 0x3FFF; -+ switch (priv->txl[i].map) { -+ case MAP_SINGLE: -+ dma_unmap_single(priv->dev, ddesc->buf_addr, -+ frame_len, DMA_TO_DEVICE); -+ break; -+ case MAP_PAGE: -+ dma_unmap_page(priv->dev, ddesc->buf_addr, -+ frame_len, DMA_TO_DEVICE); -+ break; -+ default: -+ dev_err(priv->dev, "Trying to free an empty slot\n"); -+ continue; -+ } -+ dev_kfree_skb_any(priv->txl[i].skb); -+ priv->txl[i].skb = NULL; -+ ddesc->ctl = 0; -+ ddesc->status = DCLEAN; -+ } -+ } -+ priv->tx_slot = 0; -+ priv->tx_dirty = 0; -+ -+ spin_unlock(&priv->tx_lock); -+} -+ -+/* Clean the RX ring */ -+static void sun8i_emac_rx_clean(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ int i; -+ struct dma_desc *ddesc; -+ -+ /* clean RX ring */ -+ for (i = 0; i < priv->nbdesc_rx; i++) -+ if (priv->rx_skb[i]) { -+ ddesc = priv->dd_rx + i; -+ dma_unmap_single(priv->dev, ddesc->buf_addr, -+ DESC_BUF_MAX, DMA_FROM_DEVICE); -+ dev_kfree_skb_any(priv->rx_skb[i]); -+ priv->rx_skb[i] = NULL; -+ } -+} -+ -+static int sun8i_emac_stop(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ -+ napi_disable(&priv->napi); -+ -+ sun8i_emac_stop_tx(ndev); -+ sun8i_emac_stop_rx(ndev); -+ -+ phy_stop(ndev->phydev); -+ phy_disconnect(ndev->phydev); -+ -+ sun8i_emac_mdio_unregister(ndev); -+ -+ sun8i_emac_unset_syscon(ndev); -+ -+ free_irq(priv->irq, ndev); -+ -+ sun8i_emac_rx_clean(ndev); -+ sun8i_emac_tx_clean(ndev); -+ -+ kfree(priv->rx_skb); -+ kfree(priv->txl); -+ -+ dma_free_coherent(priv->dev, priv->nbdesc_rx * sizeof(struct dma_desc), -+ priv->dd_rx, priv->dd_rx_phy); -+ dma_free_coherent(priv->dev, priv->nbdesc_tx * sizeof(struct dma_desc), -+ priv->dd_tx, priv->dd_tx_phy); -+ -+ return 0; -+} -+ -+static netdev_tx_t sun8i_emac_xmit(struct sk_buff *skb, struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ struct dma_desc *ddesc; -+ struct dma_desc *first; -+ int i = 0, rbd_first; -+ unsigned int len, fraglen, tlen; -+ u32 v; -+ int n; -+ int nf; -+ const skb_frag_t *frag; -+ int do_csum = 0; -+ -+ if (skb_put_padto(skb, ETH_ZLEN)) -+ return NETDEV_TX_OK; -+ len = skb_headlen(skb); -+ -+ n = skb_shinfo(skb)->nr_frags; -+ -+ if (skb->ip_summed == CHECKSUM_PARTIAL) { -+ do_csum = 1; -+ priv->estats.tx_hw_csum++; -+ } -+ netif_dbg(priv, tx_queued, ndev, "%s len=%u skblen=%u %x\n", __func__, -+ len, skb->len, -+ (skb->ip_summed == CHECKSUM_PARTIAL)); -+ -+ spin_lock(&priv->tx_lock); -+ -+ /* check for contigous space -+ * We need at least 1(skb->data) + n(numfrags) + 1(one clean slot) -+ */ -+ if (rb_tx_numfreedesc(ndev) < n + 2) { -+ dev_err_ratelimited(priv->dev, "BUG!: TX is full %d %d\n", -+ priv->tx_dirty, priv->tx_slot); -+ netif_stop_queue(ndev); -+ spin_unlock(&priv->tx_lock); -+ return NETDEV_TX_BUSY; -+ } -+ i = priv->tx_slot; -+ -+ ddesc = priv->dd_tx + i; -+ first = priv->dd_tx + i; -+ rbd_first = i; -+ -+ priv->tx_slot = (i + 1 + n) % priv->nbdesc_tx; -+ -+ ddesc->buf_addr = dma_map_single(priv->dev, skb->data, len, -+ DMA_TO_DEVICE); -+ if (dma_mapping_error(priv->dev, ddesc->buf_addr)) { -+ dev_err(priv->dev, "ERROR: Cannot map buffer for DMA\n"); -+ goto xmit_error; -+ } -+ priv->txl[i].map = MAP_SINGLE; -+ priv->txl[i].skb = skb; -+ -+ tlen = len; -+ ddesc->ctl = len; -+ /* Undocumented bit that make it works -+ * Without it, packets never be sent on H3 SoC -+ */ -+ ddesc->ctl |= SUN8I_EMAC_MAGIC_TX_BIT; -+ if (do_csum) -+ ddesc->ctl |= SUN8I_EMAC_TX_DO_CRC; -+ -+ /* handle fragmented skb, one descriptor per fragment */ -+ for (nf = 0; nf < n; nf++) { -+ frag = &skb_shinfo(skb)->frags[nf]; -+ rb_inc(&i, priv->nbdesc_tx); -+ priv->txl[i].skb = skb; -+ ddesc = priv->dd_tx + i; -+ fraglen = skb_frag_size(frag); -+ ddesc->ctl = fraglen; -+ tlen += fraglen, -+ ddesc->ctl |= SUN8I_EMAC_MAGIC_TX_BIT; -+ if (do_csum) -+ ddesc->ctl |= SUN8I_EMAC_TX_DO_CRC; -+ -+ ddesc->buf_addr = skb_frag_dma_map(priv->dev, frag, 0, -+ fraglen, DMA_TO_DEVICE); -+ if (dma_mapping_error(priv->dev, ddesc->buf_addr)) { -+ dev_err(priv->dev, "Cannot map buffer for DMA\n"); -+ goto xmit_error; -+ } -+ priv->txl[i].map = MAP_PAGE; -+ ddesc->status = SUN8I_COULD_BE_USED_BY_DMA; -+ } -+ -+ /* frame end */ -+ ddesc->ctl |= DSC_TX_LAST; -+ /* We want an interrupt after transmission */ -+ ddesc->ctl |= SUN8I_EMAC_WANT_INT; -+ -+ rb_inc(&i, priv->nbdesc_tx); -+ -+ /* frame begin */ -+ first->ctl |= DSC_TX_FIRST; -+ wmb();/* SUN8I_COULD_BE_USED_BY_DMA must be the last value written */ -+ first->status = SUN8I_COULD_BE_USED_BY_DMA; -+ priv->tx_slot = i; -+ -+ /* Trying to optimize this (recording DMA start/stop) seems -+ * to lead to errors. So we always start DMA. -+ */ -+ v = readl(priv->base + SUN8I_EMAC_TX_CTL1); -+ v |= TX_DMA_START; -+ v |= TX_DMA_EN; -+ writel(v, priv->base + SUN8I_EMAC_TX_CTL1); -+ -+ if (rb_tx_numfreedesc(ndev) < MAX_SKB_FRAGS + 1) { -+ netif_stop_queue(ndev); -+ priv->estats.tx_stop_queue++; -+ } -+ priv->estats.tx_used_desc = rb_tx_numfreedesc(ndev); -+ priv->ndev->stats.tx_packets++; -+ priv->ndev->stats.tx_bytes += tlen; -+ -+ spin_unlock(&priv->tx_lock); -+ -+ return NETDEV_TX_OK; -+ -+xmit_error: -+ /* destroy skb and return TX OK Documentation/DMA-API-HOWTO.txt */ -+ /* clean descritors from rbd_first to i */ -+ ddesc->ctl = 0; -+ wmb(); /* setting to DCLEAN is the last value to be set */ -+ ddesc->status = DCLEAN; -+ do { -+ ddesc = priv->dd_tx + rbd_first; -+ ddesc->ctl = 0; -+ wmb(); /* setting to DCLEAN is the last value to be set */ -+ ddesc->status = DCLEAN; -+ rb_inc(&rbd_first, priv->nbdesc_tx); -+ } while (rbd_first != i); -+ spin_unlock(&priv->tx_lock); -+ dev_kfree_skb_any(skb); -+ return NETDEV_TX_OK; -+} -+ -+static int sun8i_emac_change_mtu(struct net_device *ndev, int new_mtu) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ int max_mtu; -+ -+ dev_info(priv->dev, "%s set MTU to %d\n", __func__, new_mtu); -+ -+ if (netif_running(ndev)) { -+ dev_err(priv->dev, "%s: must be stopped to change its MTU\n", -+ ndev->name); -+ return -EBUSY; -+ } -+ -+ max_mtu = SKB_MAX_HEAD(NET_SKB_PAD + NET_IP_ALIGN); -+ -+ if ((new_mtu < 68) || (new_mtu > max_mtu)) { -+ dev_err(priv->dev, "%s: invalid MTU, max MTU is: %d\n", -+ ndev->name, max_mtu); -+ return -EINVAL; -+ } -+ -+ ndev->mtu = new_mtu; -+ netdev_update_features(ndev); -+ return 0; -+} -+ -+static netdev_features_t sun8i_emac_fix_features(struct net_device *ndev, -+ netdev_features_t features) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ -+ netif_dbg(priv, drv, ndev, "%s %llx\n", __func__, features); -+ return features; -+} -+ -+static int sun8i_emac_set_features(struct net_device *ndev, -+ netdev_features_t features) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ u32 v; -+ -+ v = readl(priv->base + SUN8I_EMAC_BASIC_CTL0); -+ if (features & NETIF_F_LOOPBACK && netif_running(ndev)) { -+ netif_info(priv, hw, ndev, "Set loopback features"); -+ v |= BIT(1); -+ } else { -+ netif_info(priv, hw, ndev, "Unset loopback features"); -+ v &= ~BIT(1); -+ } -+ writel(v, priv->base + SUN8I_EMAC_BASIC_CTL0); -+ -+ v = readl(priv->base + SUN8I_EMAC_RX_CTL0); -+ if (features & NETIF_F_RXCSUM) { -+ v |= SUN8I_EMAC_RX_DO_CRC; -+ netif_info(priv, hw, ndev, "Doing RX CRC check by hardware"); -+ } else { -+ v &= ~SUN8I_EMAC_RX_DO_CRC; -+ netif_info(priv, hw, ndev, "No RX CRC check by hardware"); -+ } -+ if (features & NETIF_F_RXFCS) { -+ v &= ~SUN8I_EMAC_RX_STRIP_FCS; -+ netif_info(priv, hw, ndev, "Keep FCS"); -+ } else { -+ v |= SUN8I_EMAC_RX_STRIP_FCS; -+ netif_info(priv, hw, ndev, "Strip FCS"); -+ } -+ writel(v, priv->base + SUN8I_EMAC_RX_CTL0); -+ -+ netif_dbg(priv, drv, ndev, "%s %llx %x\n", __func__, features, v); -+ -+ return 0; -+} -+ -+static void sun8i_emac_set_rx_mode(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ u32 v = 0; -+ int i = 0; -+ struct netdev_hw_addr *ha; -+ -+ /* Receive all multicast frames */ -+ v |= BIT(16); -+ /* Receive all control frames */ -+ v |= BIT(13); -+ if (ndev->flags & IFF_PROMISC) -+ v |= BIT(1); -+ if (netdev_uc_count(ndev) > 7) { -+ v |= BIT(1); -+ } else { -+ netdev_for_each_uc_addr(ha, ndev) { -+ i++; -+ sun8i_emac_set_macaddr(priv, ha->addr, i); -+ } -+ } -+ writel(v, priv->base + SUN8I_EMAC_RX_FRM_FLT); -+} -+ -+static void sun8i_emac_tx_timeout(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ -+ netdev_err(ndev, "%s\n", __func__); -+ -+ sun8i_emac_stop_tx(ndev); -+ -+ sun8i_emac_tx_clean(ndev); -+ -+ /* write start of tx ring descriptor */ -+ writel(priv->dd_tx_phy, priv->base + SUN8I_EMAC_TX_DESC_LIST); -+ -+ sun8i_emac_start_tx(ndev); -+ -+ netdev_reset_queue(ndev); -+ -+ ndev->stats.tx_errors++; -+ netif_wake_queue(ndev); -+} -+ -+static int sun8i_emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) -+{ -+ struct phy_device *phydev = ndev->phydev; -+ -+ if (!netif_running(ndev)) -+ return -EINVAL; -+ -+ if (!phydev) -+ return -ENODEV; -+ -+ return phy_mii_ioctl(phydev, rq, cmd); -+} -+ -+static int sun8i_emac_check_if_running(struct net_device *ndev) -+{ -+ if (!netif_running(ndev)) -+ return -EINVAL; -+ return 0; -+} -+ -+static int sun8i_emac_get_sset_count(struct net_device *ndev, int sset) -+{ -+ switch (sset) { -+ case ETH_SS_STATS: -+ return ARRAY_SIZE(estats_str); -+ } -+ return -EOPNOTSUPP; -+} -+ -+static int sun8i_emac_ethtool_get_settings(struct net_device *ndev, -+ struct ethtool_cmd *cmd) -+{ -+ struct phy_device *phy = ndev->phydev; -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ -+ if (!phy) { -+ netdev_err(ndev, "%s: %s: PHY is not registered\n", -+ __func__, ndev->name); -+ return -ENODEV; -+ } -+ -+ if (!netif_running(ndev)) { -+ dev_err(priv->dev, "interface disabled: we cannot track link speed / duplex setting\n"); -+ return -EBUSY; -+ } -+ -+ return phy_ethtool_gset(phy, cmd); -+} -+ -+static int sun8i_emac_ethtool_set_settings(struct net_device *ndev, -+ struct ethtool_cmd *cmd) -+{ -+ struct phy_device *phy = ndev->phydev; -+ -+ return phy_ethtool_sset(phy, cmd); -+} -+ -+static void sun8i_emac_ethtool_getdrvinfo(struct net_device *ndev, -+ struct ethtool_drvinfo *info) -+{ -+ strlcpy(info->driver, "sun8i_emac", sizeof(info->driver)); -+ strcpy(info->version, "00"); -+ info->fw_version[0] = '\0'; -+} -+ -+static void sun8i_emac_ethtool_stats(struct net_device *ndev, -+ struct ethtool_stats *dummy, u64 *data) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ -+ memcpy(data, &priv->estats, -+ sun8i_emac_get_sset_count(ndev, ETH_SS_STATS) * sizeof(u64)); -+} -+ -+static void sun8i_emac_ethtool_strings(struct net_device *dev, u32 stringset, -+ u8 *buffer) -+{ -+ switch (stringset) { -+ case ETH_SS_STATS: -+ memcpy(buffer, &estats_str, sizeof(estats_str)); -+ break; -+ } -+} -+ -+static u32 sun8i_emac_ethtool_getmsglevel(struct net_device *ndev) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ -+ return priv->msg_enable; -+} -+ -+static void sun8i_emac_ethtool_setmsglevel(struct net_device *ndev, u32 level) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ -+ priv->msg_enable = level; -+} -+ -+static void sun8i_emac_get_pauseparam(struct net_device *ndev, -+ struct ethtool_pauseparam *pause) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ -+ pause->rx_pause = 0; -+ pause->tx_pause = 0; -+ pause->autoneg = ndev->phydev->autoneg; -+ -+ if (priv->flow_ctrl & FLOW_RX) -+ pause->rx_pause = 1; -+ if (priv->flow_ctrl & FLOW_TX) -+ pause->tx_pause = 1; -+} -+ -+static int sun8i_emac_set_pauseparam(struct net_device *ndev, -+ struct ethtool_pauseparam *pause) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ struct phy_device *phy = ndev->phydev; -+ int new_pause = 0; -+ int ret = 0; -+ -+ if (pause->rx_pause) -+ new_pause |= FLOW_RX; -+ if (pause->tx_pause) -+ new_pause |= FLOW_TX; -+ -+ priv->flow_ctrl = new_pause; -+ phy->autoneg = pause->autoneg; -+ -+ if (phy->autoneg) { -+ if (netif_running(ndev)) -+ ret = phy_start_aneg(phy); -+ } else { -+ sun8i_emac_flow_ctrl(priv, phy->duplex, priv->flow_ctrl); -+ } -+ return ret; -+} -+ -+static void sun8i_emac_ethtool_get_ringparam(struct net_device *ndev, -+ struct ethtool_ringparam *ring) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ -+ ring->rx_pending = priv->nbdesc_rx; -+ ring->tx_pending = priv->nbdesc_tx; -+} -+ -+static int sun8i_emac_ethtool_set_ringparam(struct net_device *ndev, -+ struct ethtool_ringparam *ring) -+{ -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ int err; -+ -+ if (ring->rx_max_pending || ring->rx_mini_max_pending || -+ ring->rx_jumbo_max_pending || ring->rx_mini_pending || -+ ring->rx_jumbo_pending || ring->tx_max_pending) -+ return -EINVAL; -+ -+ if (ring->tx_pending < MAX_SKB_FRAGS + 1) { -+ netdev_err(ndev, "The number of TX descriptors is too low"); -+ return -EINVAL; -+ } -+ -+ sun8i_emac_stop_tx(ndev); -+ sun8i_emac_stop_rx(ndev); -+ -+ sun8i_emac_rx_clean(ndev); -+ sun8i_emac_tx_clean(ndev); -+ -+ kfree(priv->rx_skb); -+ kfree(priv->txl); -+ -+ dma_free_coherent(priv->dev, priv->nbdesc_rx * sizeof(struct dma_desc), -+ priv->dd_rx, priv->dd_rx_phy); -+ dma_free_coherent(priv->dev, priv->nbdesc_tx * sizeof(struct dma_desc), -+ priv->dd_tx, priv->dd_tx_phy); -+ -+ priv->nbdesc_rx = ring->rx_pending; -+ priv->nbdesc_tx = ring->tx_pending; -+ err = sun8i_emac_alloc_rings(ndev); -+ if (err) { -+ /* Fatal error, we cannot re start */ -+ netdev_err(ndev, "Fail to allocate rings\n"); -+ return -EFAULT; -+ } -+ -+ sun8i_emac_start_rx(ndev); -+ sun8i_emac_start_tx(ndev); -+ -+ netif_start_queue(ndev); -+ -+ netdev_info(ndev, "Ring Param settings: rx: %d, tx %d\n", -+ ring->rx_pending, ring->tx_pending); -+ return 0; -+} -+ -+static const struct ethtool_ops sun8i_emac_ethtool_ops = { -+ .begin = sun8i_emac_check_if_running, -+ .get_settings = sun8i_emac_ethtool_get_settings, -+ .set_settings = sun8i_emac_ethtool_set_settings, -+ .get_link = ethtool_op_get_link, -+ .get_pauseparam = sun8i_emac_get_pauseparam, -+ .set_pauseparam = sun8i_emac_set_pauseparam, -+ .get_ethtool_stats = sun8i_emac_ethtool_stats, -+ .get_strings = sun8i_emac_ethtool_strings, -+ .get_sset_count = sun8i_emac_get_sset_count, -+ .get_drvinfo = sun8i_emac_ethtool_getdrvinfo, -+ .get_msglevel = sun8i_emac_ethtool_getmsglevel, -+ .set_msglevel = sun8i_emac_ethtool_setmsglevel, -+ .get_ringparam = sun8i_emac_ethtool_get_ringparam, -+ .set_ringparam = sun8i_emac_ethtool_set_ringparam, -+}; -+ -+static const struct net_device_ops sun8i_emac_netdev_ops = { -+ .ndo_init = sun8i_emac_init, -+ .ndo_uninit = sun8i_emac_uninit, -+ .ndo_open = sun8i_emac_open, -+ .ndo_start_xmit = sun8i_emac_xmit, -+ .ndo_stop = sun8i_emac_stop, -+ .ndo_change_mtu = sun8i_emac_change_mtu, -+ .ndo_fix_features = sun8i_emac_fix_features, -+ .ndo_set_features = sun8i_emac_set_features, -+ .ndo_set_rx_mode = sun8i_emac_set_rx_mode, -+ .ndo_tx_timeout = sun8i_emac_tx_timeout, -+ .ndo_do_ioctl = sun8i_emac_ioctl, -+ .ndo_set_mac_address = eth_mac_addr, -+}; -+ -+static irqreturn_t sun8i_emac_dma_interrupt(int irq, void *dev_id) -+{ -+ struct net_device *ndev = dev_id; -+ struct sun8i_emac_priv *priv = netdev_priv(ndev); -+ u32 v, u; -+ -+ v = readl(priv->base + SUN8I_EMAC_INT_STA); -+ -+ /* When this bit is asserted, a frame transmission is completed. */ -+ if (v & BIT(0)) { -+ priv->estats.tx_int++; -+ writel(0, priv->base + SUN8I_EMAC_INT_EN); -+ napi_schedule(&priv->napi); -+ } -+ -+ /* When this bit is asserted, the TX DMA FSM is stopped. */ -+ if (v & BIT(1)) -+ priv->estats.tx_dma_stop++; -+ -+ /* When this asserted, the TX DMA can not acquire next TX descriptor -+ * and TX DMA FSM is suspended. -+ */ -+ if (v & BIT(2)) -+ priv->estats.tx_dma_ua++; -+ -+ if (v & BIT(3)) -+ netif_dbg(priv, intr, ndev, "Unhandled interrupt TX TIMEOUT\n"); -+ -+ if (v & BIT(4)) { -+ netif_dbg(priv, intr, ndev, "Unhandled interrupt TX underflow\n"); -+ priv->estats.tx_underflow_int++; -+ } -+ -+ /* When this bit asserted , the frame is transmitted to FIFO totally. */ -+ if (v & BIT(5)) { -+ netif_dbg(priv, intr, ndev, "Unhandled interrupt TX_EARLY_INT\n"); -+ priv->estats.tx_early_int++; -+ } -+ -+ /* When this bit is asserted, a frame reception is completed */ -+ if (v & BIT(8)) { -+ priv->estats.rx_int++; -+ writel(0, priv->base + SUN8I_EMAC_INT_EN); -+ napi_schedule(&priv->napi); -+ } -+ -+ /* When this asserted, the RX DMA can not acquire next TX descriptor -+ * and RX DMA FSM is suspended. -+ */ -+ if (v & BIT(9)) { -+ u = readl(priv->base + SUN8I_EMAC_RX_CTL1); -+ netif_info(priv, intr, ndev, "Re-run RX DMA %x\n", u); -+ writel(u | RX_DMA_START, priv->base + SUN8I_EMAC_RX_CTL1); -+ priv->estats.rx_dma_ua++; -+ } -+ -+ if (v & BIT(10)) { -+ netif_dbg(priv, intr, ndev, "Unhandled interrupt RX_DMA_STOPPED_INT\n"); -+ priv->estats.rx_dma_stop++; -+ } -+ if (v & BIT(11)) -+ netif_dbg(priv, intr, ndev, "Unhandled interrupt RX_TIMEOUT\n"); -+ if (v & BIT(12)) -+ netif_dbg(priv, intr, ndev, "Unhandled interrupt RX OVERFLOW\n"); -+ if (v & BIT(13)) { -+ netif_dbg(priv, intr, ndev, "Unhandled interrupt RX EARLY\n"); -+ priv->estats.rx_early_int++; -+ } -+ if (v & BIT(16)) -+ netif_dbg(priv, intr, ndev, "Unhandled interrupt RGMII\n"); -+ -+ /* the datasheet state those register as read-only -+ * but nothing work(freeze) without writing to it -+ */ -+ writel(v & 0x3FFF, priv->base + SUN8I_EMAC_INT_STA); -+ -+ return IRQ_HANDLED; -+} -+ -+static int sun8i_emac_probe(struct platform_device *pdev) -+{ -+ struct device_node *node = pdev->dev.of_node; -+ struct sun8i_emac_priv *priv; -+ struct net_device *ndev; -+ struct resource *res; -+ int ret; -+ -+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); -+ if (ret) { -+ dev_err(&pdev->dev, "No suitable DMA available\n"); -+ return ret; -+ } -+ -+ ndev = alloc_etherdev(sizeof(*priv)); -+ if (!ndev) -+ return -ENOMEM; -+ -+ SET_NETDEV_DEV(ndev, &pdev->dev); -+ priv = netdev_priv(ndev); -+ platform_set_drvdata(pdev, ndev); -+ -+ priv->variant = (enum emac_variant)of_device_get_match_data(&pdev->dev); -+ if (!priv->variant) { -+ dev_err(&pdev->dev, "Missing sun8i-emac variant\n"); -+ return -EINVAL; -+ } -+ -+ priv->phy_node = of_parse_phandle(node, "phy", 0); -+ if (!priv->phy_node) { -+ netdev_err(ndev, "No associated PHY\n"); -+ return -ENODEV; -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ priv->base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(priv->base)) { -+ ret = PTR_ERR(priv->base); -+ dev_err(&pdev->dev, "Cannot request MMIO: %d\n", ret); -+ return ret; -+ } -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "syscon"); -+ priv->syscon = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(priv->syscon)) { -+ ret = PTR_ERR(priv->syscon); -+ dev_err(&pdev->dev, -+ "Cannot map system control registers: %d\n", ret); -+ return ret; -+ } -+ -+ priv->ahb_clk = devm_clk_get(&pdev->dev, "ahb"); -+ if (IS_ERR(priv->ahb_clk)) { -+ ret = PTR_ERR(priv->ahb_clk); -+ dev_err(&pdev->dev, "Cannot get AHB clock err=%d\n", ret); -+ goto probe_err; -+ } -+ -+ priv->rst = devm_reset_control_get_optional(&pdev->dev, "ahb"); -+ if (IS_ERR(priv->rst)) { -+ ret = PTR_ERR(priv->rst); -+ if (ret == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ dev_info(&pdev->dev, "No MAC reset control found %d\n", ret); -+ priv->rst = NULL; -+ } -+ -+ if (priv->variant == H3_EMAC) -+ priv->use_internal_phy = of_property_read_bool(node, -+ "allwinner,use-internal-phy"); -+ -+ if (priv->use_internal_phy) { -+ priv->ephy_clk = devm_clk_get(&pdev->dev, "ephy"); -+ if (IS_ERR(priv->ephy_clk)) { -+ ret = PTR_ERR(priv->ephy_clk); -+ dev_err(&pdev->dev, "Cannot get EPHY clock err=%d\n", -+ ret); -+ goto probe_err; -+ } -+ -+ priv->rst_ephy = devm_reset_control_get_optional(&pdev->dev, -+ "ephy"); -+ if (IS_ERR(priv->rst_ephy)) { -+ ret = PTR_ERR(priv->rst_ephy); -+ if (ret == -EPROBE_DEFER) -+ goto probe_err; -+ dev_info(&pdev->dev, -+ "No EPHY reset control found %d\n", ret); -+ priv->rst_ephy = NULL; -+ } -+ } -+ -+ priv->irq = platform_get_irq(pdev, 0); -+ if (priv->irq < 0) { -+ ret = priv->irq; -+ dev_err(&pdev->dev, "Cannot claim IRQ: %d\n", ret); -+ goto probe_err; -+ } -+ -+ spin_lock_init(&priv->tx_lock); -+ -+ ndev->netdev_ops = &sun8i_emac_netdev_ops; -+ ndev->ethtool_ops = &sun8i_emac_ethtool_ops; -+ -+ priv->ndev = ndev; -+ priv->dev = &pdev->dev; -+ -+ ndev->hw_features = NETIF_F_SG | NETIF_F_HIGHDMA; -+ ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | -+ NETIF_F_RXCSUM; -+ ndev->features |= ndev->hw_features; -+ ndev->hw_features |= NETIF_F_RXFCS; -+ ndev->hw_features |= NETIF_F_RXALL; -+ ndev->hw_features |= NETIF_F_LOOPBACK; -+ ndev->priv_flags |= IFF_UNICAST_FLT; -+ -+ ndev->watchdog_timeo = msecs_to_jiffies(5000); -+ netif_carrier_off(ndev); -+ -+ /* Benched on OPIPC with 100M, setting more than 256 does not give any -+ * perf boost -+ */ -+ priv->nbdesc_rx = 128; -+ priv->nbdesc_tx = 256; -+ -+ ret = register_netdev(ndev); -+ if (ret) { -+ dev_err(&pdev->dev, "ERROR: Register %s failed\n", ndev->name); -+ goto probe_err; -+ } -+ -+ return 0; -+ -+probe_err: -+ free_netdev(ndev); -+ return ret; -+} -+ -+static int sun8i_emac_remove(struct platform_device *pdev) -+{ -+ struct net_device *ndev = platform_get_drvdata(pdev); -+ -+ unregister_netdev(ndev); -+ platform_set_drvdata(pdev, NULL); -+ free_netdev(ndev); -+ -+ return 0; -+} -+ -+static const struct of_device_id sun8i_emac_of_match_table[] = { -+ { .compatible = "allwinner,sun8i-a83t-emac", -+ .data = (void *)A83T_EMAC }, -+ { .compatible = "allwinner,sun8i-h3-emac", -+ .data = (void *)H3_EMAC }, -+ { .compatible = "allwinner,sun50i-a64-emac", -+ .data = (void *)A64_EMAC }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, sun8i_emac_of_match_table); -+ -+static struct platform_driver sun8i_emac_driver = { -+ .probe = sun8i_emac_probe, -+ .remove = sun8i_emac_remove, -+ .driver = { -+ .name = "sun8i-emac", -+ .of_match_table = sun8i_emac_of_match_table, -+ }, -+}; -+ -+module_platform_driver(sun8i_emac_driver); -+ -+MODULE_DESCRIPTION("sun8i Ethernet driver"); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("LABBE Corentin <clabbe.montjoie@gmail.com"); -diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c -index 33df340..425856f 100644 ---- a/drivers/net/ethernet/ti/davinci_mdio.c -+++ b/drivers/net/ethernet/ti/davinci_mdio.c -@@ -106,6 +106,10 @@ struct davinci_mdio_data { - u32 clk_div; - }; - -+#if IS_ENABLED(CONFIG_OF) -+static void davinci_mdio_update_dt_from_phymask(u32 phy_mask); -+#endif -+ - static void davinci_mdio_init_clk(struct davinci_mdio_data *data) - { - u32 mdio_in, div, mdio_out_khz, access_time; -@@ -171,6 +175,12 @@ static int davinci_mdio_reset(struct mii_bus *bus) - /* restrict mdio bus to live phys only */ - dev_info(data->dev, "detected phy mask %x\n", ~phy_mask); - phy_mask = ~phy_mask; -+ -+ #if IS_ENABLED(CONFIG_OF) -+ if (of_machine_is_compatible("ti,am335x-bone")) -+ davinci_mdio_update_dt_from_phymask(phy_mask); -+ #endif -+ - } else { - /* desperately scan all phys */ - dev_warn(data->dev, "no live phy, scanning all\n"); -@@ -334,6 +344,93 @@ static int davinci_mdio_probe_dt(struct mdio_platform_data *data, - - return 0; - } -+static void davinci_mdio_update_dt_from_phymask(u32 phy_mask) -+{ -+ int i, len, skip; -+ u32 addr; -+ __be32 *old_phy_p, *phy_id_p; -+ struct property *phy_id_property = NULL; -+ struct device_node *node_p, *slave_p; -+ -+ addr = 0; -+ -+ for (i = 0; i < PHY_MAX_ADDR; i++) { -+ if ((phy_mask & (1 << i)) == 0) { -+ addr = (u32) i; -+ break; -+ } -+ } -+ -+ for_each_compatible_node(node_p, NULL, "ti,cpsw") { -+ for_each_node_by_name(slave_p, "slave") { -+ -+#if IS_ENABLED(CONFIG_OF_OVERLAY) -+ skip = 1; -+ // Hack, the overlay fixup "slave" doesn't have phy-mode... -+ old_phy_p = (__be32 *) of_get_property(slave_p, "phy-mode", &len); -+ -+ if (len != (sizeof(__be32 *) * 1)) -+ { -+ skip = 0; -+ } -+ -+ if (skip) { -+#endif -+ -+ old_phy_p = (__be32 *) of_get_property(slave_p, "phy_id", &len); -+ -+ if (len != (sizeof(__be32 *) * 2)) -+ goto err_out; -+ -+ if (old_phy_p) { -+ -+ phy_id_property = kzalloc(sizeof(*phy_id_property), GFP_KERNEL); -+ -+ if (! phy_id_property) -+ goto err_out; -+ -+ phy_id_property->length = len; -+ phy_id_property->name = kstrdup("phy_id", GFP_KERNEL); -+ phy_id_property->value = kzalloc(len, GFP_KERNEL); -+ -+ if (! phy_id_property->name) -+ goto err_out; -+ -+ if (! phy_id_property->value) -+ goto err_out; -+ -+ memcpy(phy_id_property->value, old_phy_p, len); -+ -+ phy_id_p = (__be32 *) phy_id_property->value + 1; -+ -+ *phy_id_p = cpu_to_be32(addr); -+ -+ of_update_property(slave_p, phy_id_property); -+ pr_info("davinci_mdio: dt: updated phy_id[%d] from phy_mask[%x]\n", addr, phy_mask); -+ -+ ++addr; -+ } -+#if IS_ENABLED(CONFIG_OF_OVERLAY) -+ } -+#endif -+ } -+ } -+ -+ return; -+ -+err_out: -+ -+ if (phy_id_property) { -+ if (phy_id_property->name) -+ kfree(phy_id_property->name); -+ -+ if (phy_id_property->value) -+ kfree(phy_id_property->value); -+ -+ if (phy_id_property) -+ kfree(phy_id_property); -+ } -+} - #endif - - #if IS_ENABLED(CONFIG_OF) -diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig -index ba7b034..7d4169e 100644 ---- a/drivers/of/Kconfig -+++ b/drivers/of/Kconfig -@@ -112,4 +112,11 @@ config OF_OVERLAY - config OF_NUMA - bool - -+config OF_CONFIGFS -+ bool "Device Tree Overlay ConfigFS interface" -+ select CONFIGFS_FS -+ depends on OF_OVERLAY -+ help -+ Enable a simple user-space driven DT overlay interface. -+ - endif # OF -diff --git a/drivers/of/Makefile b/drivers/of/Makefile -index d7efd9d..aa5ef9d 100644 ---- a/drivers/of/Makefile -+++ b/drivers/of/Makefile -@@ -1,4 +1,5 @@ - obj-y = base.o device.o platform.o -+obj-$(CONFIG_OF_CONFIGFS) += configfs.o - obj-$(CONFIG_OF_DYNAMIC) += dynamic.o - obj-$(CONFIG_OF_FLATTREE) += fdt.o - obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o -diff --git a/drivers/of/base.c b/drivers/of/base.c -index a0bccb5..4e9df30 100644 ---- a/drivers/of/base.c -+++ b/drivers/of/base.c -@@ -30,6 +30,7 @@ - #include <linux/slab.h> - #include <linux/string.h> - #include <linux/proc_fs.h> -+#include <linux/rhashtable.h> - - #include "of_private.h" - -@@ -44,6 +45,18 @@ static const char *of_stdout_options; - - struct kset *of_kset; - -+const struct rhashtable_params of_phandle_ht_params = { -+ .key_offset = offsetof(struct device_node, phandle), /* base offset */ -+ .key_len = sizeof(phandle), -+ .head_offset = offsetof(struct device_node, ht_node), -+ .automatic_shrinking = true, -+}; -+ -+struct rhashtable *of_phandle_ht; -+ -+/* default is false */ -+bool of_phandle_ht_is_disabled; -+ - /* - * Used to protect the of_aliases, to hold off addition of nodes to sysfs. - * This mutex must be held whenever modifications are being made to the -@@ -163,13 +176,19 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp) - return rc; - } - --int __of_attach_node_sysfs(struct device_node *np) -+int __of_attach_node_post(struct device_node *np) - { - const char *name; - struct kobject *parent; - struct property *pp; - int rc; - -+ if (of_phandle_ht_available()) { -+ rc = of_phandle_ht_insert(np); -+ WARN(rc, "insert to phandle hash fail @%s\n", -+ of_node_full_name(np)); -+ } -+ - if (!IS_ENABLED(CONFIG_SYSFS)) - return 0; - -@@ -201,6 +220,18 @@ int __of_attach_node_sysfs(struct device_node *np) - void __init of_core_init(void) - { - struct device_node *np; -+ int ret; -+ -+ of_phandle_ht = kzalloc(sizeof(*of_phandle_ht), GFP_KERNEL); -+ if (!of_phandle_ht) { -+ pr_warn("devicetree: Failed to allocate hashtable\n"); -+ return; -+ } -+ ret = rhashtable_init(of_phandle_ht, &of_phandle_ht_params); -+ if (ret) { -+ pr_warn("devicetree: Failed to initialize hashtable\n"); -+ return; -+ } - - /* Create the kset, and register existing nodes */ - mutex_lock(&of_mutex); -@@ -211,12 +242,16 @@ void __init of_core_init(void) - return; - } - for_each_of_allnodes(np) -- __of_attach_node_sysfs(np); -+ __of_attach_node_post(np); - mutex_unlock(&of_mutex); - - /* Symlink in /proc as required by userspace ABI */ - if (of_root) - proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base"); -+ -+ ret = of_overlay_init(); -+ if (ret != 0) -+ pr_warn("of_init: of_overlay_init failed!\n"); - } - - static struct property *__of_find_property(const struct device_node *np, -@@ -1100,9 +1135,14 @@ struct device_node *of_find_node_by_phandle(phandle handle) - return NULL; - - raw_spin_lock_irqsave(&devtree_lock, flags); -- for_each_of_allnodes(np) -- if (np->phandle == handle) -- break; -+ /* when we're ready use the hash table (and not disabled) */ -+ if (of_phandle_ht_available() && !of_phandle_ht_is_disabled) -+ np = of_phandle_ht_lookup(handle); -+ else { /* fallback */ -+ for_each_of_allnodes(np) -+ if (np->phandle == handle) -+ break; -+ } - of_node_get(np); - raw_spin_unlock_irqrestore(&devtree_lock, flags); - return np; -diff --git b/drivers/of/configfs.c b/drivers/of/configfs.c -new file mode 100644 -index 0000000..c7e999c ---- /dev/null -+++ b/drivers/of/configfs.c -@@ -0,0 +1,307 @@ -+/* -+ * Configfs entries for device-tree -+ * -+ * Copyright (C) 2013 - Pantelis Antoniou <panto@antoniou-consulting.com> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+#include <linux/ctype.h> -+#include <linux/cpu.h> -+#include <linux/module.h> -+#include <linux/of.h> -+#include <linux/of_fdt.h> -+#include <linux/spinlock.h> -+#include <linux/sizes.h> -+#include <linux/slab.h> -+#include <linux/proc_fs.h> -+#include <linux/configfs.h> -+#include <linux/types.h> -+#include <linux/stat.h> -+#include <linux/limits.h> -+#include <linux/file.h> -+#include <linux/vmalloc.h> -+#include <linux/firmware.h> -+ -+#include "of_private.h" -+ -+struct cfs_overlay_item { -+ struct config_item item; -+ -+ char path[PATH_MAX]; -+ -+ const struct firmware *fw; -+ struct device_node *overlay; -+ int ov_id; -+ -+ void *dtbo; -+ int dtbo_size; -+}; -+ -+static int create_overlay(struct cfs_overlay_item *overlay, void *blob) -+{ -+ int err; -+ -+ /* unflatten the tree */ -+ of_fdt_unflatten_tree(blob, NULL, &overlay->overlay); -+ if (overlay->overlay == NULL) { -+ pr_err("%s: failed to unflatten tree\n", __func__); -+ err = -EINVAL; -+ goto out_err; -+ } -+ pr_debug("%s: unflattened OK\n", __func__); -+ -+ /* mark it as detached */ -+ of_node_set_flag(overlay->overlay, OF_DETACHED); -+ -+ /* perform resolution */ -+ err = of_resolve_phandles(overlay->overlay); -+ if (err != 0) { -+ pr_err("%s: Failed to resolve tree\n", __func__); -+ goto out_err; -+ } -+ pr_debug("%s: resolved OK\n", __func__); -+ -+ err = of_overlay_create(overlay->overlay); -+ if (err < 0) { -+ pr_err("%s: Failed to create overlay (err=%d)\n", -+ __func__, err); -+ goto out_err; -+ } -+ overlay->ov_id = err; -+ -+out_err: -+ return err; -+} -+ -+static inline struct cfs_overlay_item *to_cfs_overlay_item( -+ struct config_item *item) -+{ -+ return item ? container_of(item, struct cfs_overlay_item, item) : NULL; -+} -+ -+static ssize_t cfs_overlay_item_path_show(struct config_item *item, char *page) -+{ -+ return sprintf(page, "%s\n", to_cfs_overlay_item(item)->path); -+} -+ -+static ssize_t cfs_overlay_item_path_store(struct config_item *item, -+ const char *page, size_t count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ const char *p = page; -+ char *s; -+ int err; -+ -+ /* if it's set do not allow changes */ -+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) -+ return -EPERM; -+ -+ /* copy to path buffer (and make sure it's always zero terminated */ -+ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p); -+ overlay->path[sizeof(overlay->path) - 1] = '\0'; -+ -+ /* strip trailing newlines */ -+ s = overlay->path + strlen(overlay->path); -+ while (s > overlay->path && *--s == '\n') -+ *s = '\0'; -+ -+ pr_debug("%s: path is '%s'\n", __func__, overlay->path); -+ -+ err = request_firmware(&overlay->fw, overlay->path, NULL); -+ if (err != 0) -+ goto out_err; -+ -+ err = create_overlay(overlay, (void *)overlay->fw->data); -+ if (err < 0) -+ goto out_err; -+ -+ return count; -+ -+out_err: -+ -+ release_firmware(overlay->fw); -+ overlay->fw = NULL; -+ -+ overlay->path[0] = '\0'; -+ return err; -+} -+ -+static ssize_t cfs_overlay_item_status_show(struct config_item *item, -+ char *page) -+{ -+ return sprintf(page, "%s\n", to_cfs_overlay_item(item)->ov_id >= 0 ? -+ "applied" : "unapplied"); -+} -+ -+CONFIGFS_ATTR(cfs_overlay_item_, path); -+CONFIGFS_ATTR_RO(cfs_overlay_item_, status); -+ -+static struct configfs_attribute *cfs_overlay_attrs[] = { -+ &cfs_overlay_item_attr_path, -+ &cfs_overlay_item_attr_status, -+ NULL, -+}; -+ -+ssize_t cfs_overlay_item_dtbo_read(struct config_item *item, void *buf, -+ size_t max_count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ pr_debug("%s: buf=%p max_count=%u\n", __func__, -+ buf, max_count); -+ -+ if (overlay->dtbo == NULL) -+ return 0; -+ -+ /* copy if buffer provided */ -+ if (buf != NULL) { -+ /* the buffer must be large enough */ -+ if (overlay->dtbo_size > max_count) -+ return -ENOSPC; -+ -+ memcpy(buf, overlay->dtbo, overlay->dtbo_size); -+ } -+ -+ return overlay->dtbo_size; -+} -+ -+ssize_t cfs_overlay_item_dtbo_write(struct config_item *item, const void *buf, -+ size_t count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ int err; -+ -+ /* if it's set do not allow changes */ -+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) -+ return -EPERM; -+ -+ /* copy the contents */ -+ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL); -+ if (overlay->dtbo == NULL) -+ return -ENOMEM; -+ -+ overlay->dtbo_size = count; -+ -+ err = create_overlay(overlay, overlay->dtbo); -+ if (err < 0) -+ goto out_err; -+ -+ return count; -+ -+out_err: -+ kfree(overlay->dtbo); -+ overlay->dtbo = NULL; -+ overlay->dtbo_size = 0; -+ -+ return err; -+} -+ -+CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M); -+ -+static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = { -+ &cfs_overlay_item_attr_dtbo, -+ NULL, -+}; -+ -+static void cfs_overlay_release(struct config_item *item) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ if (overlay->ov_id >= 0) -+ of_overlay_destroy(overlay->ov_id); -+ if (overlay->fw) -+ release_firmware(overlay->fw); -+ /* kfree with NULL is safe */ -+ kfree(overlay->dtbo); -+ kfree(overlay); -+} -+ -+static struct configfs_item_operations cfs_overlay_item_ops = { -+ .release = cfs_overlay_release, -+}; -+ -+static struct config_item_type cfs_overlay_type = { -+ .ct_item_ops = &cfs_overlay_item_ops, -+ .ct_attrs = cfs_overlay_attrs, -+ .ct_bin_attrs = cfs_overlay_bin_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct config_item *cfs_overlay_group_make_item( -+ struct config_group *group, const char *name) -+{ -+ struct cfs_overlay_item *overlay; -+ -+ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); -+ if (!overlay) -+ return ERR_PTR(-ENOMEM); -+ overlay->ov_id = -1; -+ -+ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type); -+ return &overlay->item; -+} -+ -+static void cfs_overlay_group_drop_item(struct config_group *group, -+ struct config_item *item) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ config_item_put(&overlay->item); -+} -+ -+static struct configfs_group_operations overlays_ops = { -+ .make_item = cfs_overlay_group_make_item, -+ .drop_item = cfs_overlay_group_drop_item, -+}; -+ -+static struct config_item_type overlays_type = { -+ .ct_group_ops = &overlays_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct configfs_group_operations of_cfs_ops = { -+ /* empty - we don't allow anything to be created */ -+}; -+ -+static struct config_item_type of_cfs_type = { -+ .ct_group_ops = &of_cfs_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+struct config_group of_cfs_overlay_group; -+ -+static struct configfs_subsystem of_cfs_subsys = { -+ .su_group = { -+ .cg_item = { -+ .ci_namebuf = "device-tree", -+ .ci_type = &of_cfs_type, -+ }, -+ }, -+ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex), -+}; -+ -+static int __init of_cfs_init(void) -+{ -+ int ret; -+ -+ pr_info("%s\n", __func__); -+ -+ config_group_init(&of_cfs_subsys.su_group); -+ config_group_init_type_name(&of_cfs_overlay_group, "overlays", -+ &overlays_type); -+ configfs_add_default_group(&of_cfs_overlay_group, -+ &of_cfs_subsys.su_group); -+ -+ ret = configfs_register_subsystem(&of_cfs_subsys); -+ if (ret != 0) { -+ pr_err("%s: failed to register subsys\n", __func__); -+ goto out; -+ } -+ pr_info("%s: OK\n", __func__); -+out: -+ return ret; -+} -+late_initcall(of_cfs_init); -diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c -index 888fdbc..2a89b17 100644 ---- a/drivers/of/dynamic.c -+++ b/drivers/of/dynamic.c -@@ -13,6 +13,7 @@ - #include <linux/slab.h> - #include <linux/string.h> - #include <linux/proc_fs.h> -+#include <linux/rhashtable.h> - - #include "of_private.h" - -@@ -43,9 +44,16 @@ void of_node_put(struct device_node *node) - } - EXPORT_SYMBOL(of_node_put); - --void __of_detach_node_sysfs(struct device_node *np) -+void __of_detach_node_post(struct device_node *np) - { - struct property *pp; -+ int rc; -+ -+ if (of_phandle_ht_available()) { -+ rc = of_phandle_ht_remove(np); -+ WARN(rc, "remove from phandle hash fail @%s\n", -+ of_node_full_name(np)); -+ } - - if (!IS_ENABLED(CONFIG_SYSFS)) - return; -@@ -253,7 +261,7 @@ int of_attach_node(struct device_node *np) - __of_attach_node(np); - raw_spin_unlock_irqrestore(&devtree_lock, flags); - -- __of_attach_node_sysfs(np); -+ __of_attach_node_post(np); - mutex_unlock(&of_mutex); - - of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, &rd); -@@ -306,7 +314,7 @@ int of_detach_node(struct device_node *np) - __of_detach_node(np); - raw_spin_unlock_irqrestore(&devtree_lock, flags); - -- __of_detach_node_sysfs(np); -+ __of_detach_node_post(np); - mutex_unlock(&of_mutex); - - of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd); -@@ -397,8 +405,9 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags) - } - - /** -- * __of_node_dup() - Duplicate or create an empty device node dynamically. -- * @fmt: Format string (plus vargs) for new full name of the device node -+ * __of_node_dupv() - Duplicate or create an empty device node dynamically. -+ * @fmt: Format string for new full name of the device node -+ * @vargs: va_list containing the arugments for the node full name - * - * Create an device tree node, either by duplicating an empty node or by allocating - * an empty one suitable for further modification. The node data are -@@ -406,17 +415,15 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags) - * OF_DETACHED bits set. Returns the newly allocated node or NULL on out of - * memory error. - */ --struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, ...) -+struct device_node *__of_node_dupv(const struct device_node *np, -+ const char *fmt, va_list vargs) - { -- va_list vargs; - struct device_node *node; - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return NULL; -- va_start(vargs, fmt); - node->full_name = kvasprintf(GFP_KERNEL, fmt, vargs); -- va_end(vargs); - if (!node->full_name) { - kfree(node); - return NULL; -@@ -448,6 +455,24 @@ struct device_node *__of_node_dup(const struct device_node *np, const char *fmt, - return NULL; - } - -+/** -+ * __of_node_dup() - Duplicate or create an empty device node dynamically. -+ * @fmt: Format string (plus vargs) for new full name of the device node -+ * -+ * See: __of_node_dupv() -+ */ -+struct device_node *__of_node_dup(const struct device_node *np, -+ const char *fmt, ...) -+{ -+ va_list vargs; -+ struct device_node *node; -+ -+ va_start(vargs, fmt); -+ node = __of_node_dupv(np, fmt, vargs); -+ va_end(vargs); -+ return node; -+} -+ - static void __of_changeset_entry_destroy(struct of_changeset_entry *ce) - { - of_node_put(ce->np); -@@ -614,10 +639,10 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) - - switch (ce->action) { - case OF_RECONFIG_ATTACH_NODE: -- __of_attach_node_sysfs(ce->np); -+ __of_attach_node_post(ce->np); - break; - case OF_RECONFIG_DETACH_NODE: -- __of_detach_node_sysfs(ce->np); -+ __of_detach_node_post(ce->np); - break; - case OF_RECONFIG_ADD_PROPERTY: - /* ignore duplicate names */ -@@ -813,3 +838,295 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action, - return 0; - } - EXPORT_SYMBOL_GPL(of_changeset_action); -+ -+/* changeset helpers */ -+ -+/** -+ * of_changeset_create_device_node - Create an empty device node -+ * -+ * @ocs: changeset pointer -+ * @parent: parent device node -+ * @fmt: format string for the node's full_name -+ * @args: argument list for the format string -+ * -+ * Create an empty device node, marking it as detached and allocated. -+ * -+ * Returns a device node on success, an error encoded pointer otherwise -+ */ -+struct device_node *of_changeset_create_device_nodev( -+ struct of_changeset *ocs, struct device_node *parent, -+ const char *fmt, va_list vargs) -+{ -+ struct device_node *node; -+ -+ node = __of_node_dupv(NULL, fmt, vargs); -+ if (!node) -+ return ERR_PTR(-ENOMEM); -+ -+ node->parent = parent; -+ return node; -+} -+EXPORT_SYMBOL_GPL(of_changeset_create_device_nodev); -+ -+/** -+ * of_changeset_create_device_node - Create an empty device node -+ * -+ * @ocs: changeset pointer -+ * @parent: parent device node -+ * @fmt: Format string for the node's full_name -+ * ... Arguments -+ * -+ * Create an empty device node, marking it as detached and allocated. -+ * -+ * Returns a device node on success, an error encoded pointer otherwise -+ */ -+__printf(3, 4) struct device_node * -+of_changeset_create_device_node(struct of_changeset *ocs, -+ struct device_node *parent, const char *fmt, ...) -+{ -+ va_list vargs; -+ struct device_node *node; -+ -+ va_start(vargs, fmt); -+ node = of_changeset_create_device_nodev(ocs, parent, fmt, vargs); -+ va_end(vargs); -+ return node; -+} -+EXPORT_SYMBOL_GPL(of_changeset_create_device_node); -+ -+/** -+ * __of_changeset_add_property_copy - Create/update a new property copying -+ * name & value -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @value: pointer to the value data -+ * @length: length of the value in bytes -+ * @update: True on update operation -+ * -+ * Adds/updates a property to the changeset by making copies of the name & value -+ * entries. The @update parameter controls whether an add or update takes place. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+int __of_changeset_add_update_property_copy(struct of_changeset *ocs, -+ struct device_node *np, const char *name, const void *value, -+ int length, bool update) -+{ -+ struct property *prop; -+ char *new_name; -+ void *new_value; -+ int ret = -ENOMEM; -+ -+ prop = kzalloc(sizeof(*prop), GFP_KERNEL); -+ if (!prop) -+ return -ENOMEM; -+ -+ new_name = kstrdup(name, GFP_KERNEL); -+ if (!new_name) -+ goto out_err; -+ -+ /* -+ * NOTE: There is no check for zero length value. -+ * In case of a boolean property, this will allocate a value -+ * of zero bytes. We do this to work around the use -+ * of of_get_property() calls on boolean values. -+ */ -+ new_value = kmemdup(value, length, GFP_KERNEL); -+ if (!new_value) -+ goto out_err; -+ -+ of_property_set_flag(prop, OF_DYNAMIC); -+ -+ prop->name = new_name; -+ prop->value = new_value; -+ prop->length = length; -+ -+ if (!update) -+ ret = of_changeset_add_property(ocs, np, prop); -+ else -+ ret = of_changeset_update_property(ocs, np, prop); -+ -+ if (!ret) -+ return 0; -+ -+out_err: -+ kfree(prop->value); -+ kfree(prop->name); -+ kfree(prop); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(__of_changeset_add_update_property_copy); -+ -+/** -+ * of_changeset_add_property_stringf - Create a new formatted string property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @fmt: format of string property -+ * ... arguments of the format string -+ * -+ * Adds a string property to the changeset by making copies of the name -+ * and the formatted value. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+__printf(4, 5) int of_changeset_add_property_stringf( -+ struct of_changeset *ocs, struct device_node *np, -+ const char *name, const char *fmt, ...) -+{ -+ va_list vargs; -+ int ret; -+ -+ va_start(vargs, fmt); -+ ret = __of_changeset_add_update_property_stringv(ocs, np, name, fmt, -+ vargs, false); -+ va_end(vargs); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(of_changeset_add_property_stringf); -+ -+/** -+ * of_changeset_update_property_stringf - Update formatted string property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @fmt: format of string property -+ * ... arguments of the format string -+ * -+ * Updates a string property to the changeset by making copies of the name -+ * and the formatted value. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+int of_changeset_update_property_stringf( -+ struct of_changeset *ocs, struct device_node *np, -+ const char *name, const char *fmt, ...) -+{ -+ va_list vargs; -+ int ret; -+ -+ va_start(vargs, fmt); -+ ret = __of_changeset_add_update_property_stringv(ocs, np, name, fmt, -+ vargs, true); -+ va_end(vargs); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(of_changeset_update_property_stringf); -+ -+/** -+ * __of_changeset_add_update_property_string_list - Create/update a string -+ * list property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @strs: pointer to the string list -+ * @count: string count -+ * @update: True on update operation -+ * -+ * Adds a string list property to the changeset. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+int __of_changeset_add_update_property_string_list( -+ struct of_changeset *ocs, struct device_node *np, -+ const char *name, const char **strs, int count, bool update) -+{ -+ int total = 0, i, ret; -+ char *value, *s; -+ -+ for (i = 0; i < count; i++) { -+ /* check if it's NULL */ -+ if (!strs[i]) -+ return -EINVAL; -+ total += strlen(strs[i]) + 1; -+ } -+ -+ value = kmalloc(total, GFP_KERNEL); -+ if (!value) -+ return -ENOMEM; -+ -+ for (i = 0, s = value; i < count; i++) { -+ /* no need to check for NULL, check above */ -+ strcpy(s, strs[i]); -+ s += strlen(strs[i]) + 1; -+ } -+ -+ ret = __of_changeset_add_update_property_copy(ocs, np, name, value, -+ total, update); -+ -+ kfree(value); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(__of_changeset_add_update_property_string_list); -+ -+static struct device_node * -+__of_changeset_node_move_one(struct of_changeset *ocs, -+ struct device_node *np, struct device_node *new_parent) -+{ -+ struct device_node *np2; -+ const char *unitname; -+ int err; -+ -+ err = of_changeset_detach_node(ocs, np); -+ if (err) -+ return ERR_PTR(err); -+ -+ unitname = strrchr(np->full_name, '/'); -+ if (!unitname) -+ unitname = np->full_name; -+ -+ np2 = __of_node_dup(np, "%s/%s", -+ new_parent->full_name, unitname); -+ if (!np2) -+ return ERR_PTR(-ENOMEM); -+ np2->parent = new_parent; -+ -+ err = of_changeset_attach_node(ocs, np2); -+ if (err) -+ return ERR_PTR(err); -+ -+ return np2; -+} -+ -+/** -+ * of_changeset_node_move_to - Moves a subtree to a new place in -+ * the tree -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer to be moved -+ * @to: device node of the new parent -+ * -+ * Moves a subtree to a new place in the tree. -+ * Note that a move is a safe operation because the phandles -+ * remain valid. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+int of_changeset_node_move(struct of_changeset *ocs, -+ struct device_node *np, struct device_node *new_parent) -+{ -+ struct device_node *npc, *nppc; -+ -+ /* move the root first */ -+ nppc = __of_changeset_node_move_one(ocs, np, new_parent); -+ if (IS_ERR(nppc)) -+ return PTR_ERR(nppc); -+ -+ /* move the subtrees next */ -+ for_each_child_of_node(np, npc) { -+ nppc = __of_changeset_node_move_one(ocs, npc, nppc); -+ if (IS_ERR(nppc)) { -+ of_node_put(npc); -+ return PTR_ERR(nppc); -+ } -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(of_changeset_node_move); -diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h -index 18bbb45..2f906dd 100644 ---- a/drivers/of/of_private.h -+++ b/drivers/of/of_private.h -@@ -79,9 +79,9 @@ extern void __of_update_property_sysfs(struct device_node *np, - struct property *newprop, struct property *oldprop); - - extern void __of_attach_node(struct device_node *np); --extern int __of_attach_node_sysfs(struct device_node *np); -+extern int __of_attach_node_post(struct device_node *np); - extern void __of_detach_node(struct device_node *np); --extern void __of_detach_node_sysfs(struct device_node *np); -+extern void __of_detach_node_post(struct device_node *np); - - extern void __of_sysfs_remove_bin_file(struct device_node *np, - struct property *prop); -@@ -95,4 +95,46 @@ extern void __of_sysfs_remove_bin_file(struct device_node *np, - #define for_each_transaction_entry_reverse(_oft, _te) \ - list_for_each_entry_reverse(_te, &(_oft)->te_list, node) - -+#if defined(CONFIG_OF_OVERLAY) -+extern int of_overlay_init(void); -+#else -+static inline int of_overlay_init(void) -+{ -+ return 0; -+} -+#endif -+ -+extern const struct rhashtable_params of_phandle_ht_params; -+extern struct rhashtable *of_phandle_ht; -+ -+/* for unittest use */ -+extern bool of_phandle_ht_is_disabled; -+ -+static inline bool of_phandle_ht_available(void) -+{ -+ return of_phandle_ht != NULL; -+} -+ -+static inline int of_phandle_ht_insert(struct device_node *np) -+{ -+ if (!np || !np->phandle) -+ return 0; -+ return rhashtable_insert_fast(of_phandle_ht, -+ &np->ht_node, of_phandle_ht_params); -+} -+ -+static inline int of_phandle_ht_remove(struct device_node *np) -+{ -+ if (!np || !np->phandle) -+ return 0; -+ return rhashtable_remove_fast(of_phandle_ht, -+ &np->ht_node, of_phandle_ht_params); -+} -+ -+static inline struct device_node *of_phandle_ht_lookup(phandle handle) -+{ -+ return rhashtable_lookup_fast(of_phandle_ht, -+ &handle, of_phandle_ht_params); -+} -+ - #endif /* _LINUX_OF_PRIVATE_H */ -diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c -index 318dbb5..27e5c21 100644 ---- a/drivers/of/overlay.c -+++ b/drivers/of/overlay.c -@@ -22,11 +22,28 @@ - #include <linux/slab.h> - #include <linux/err.h> - #include <linux/idr.h> -+#include <linux/sysfs.h> -+#include <linux/atomic.h> - - #include "of_private.h" - -+/* fwd. decl */ -+struct of_overlay; -+struct of_overlay_info; -+ -+/* an attribute for each fragment */ -+struct fragment_attribute { -+ struct attribute attr; -+ ssize_t (*show)(struct kobject *kobj, struct fragment_attribute *fattr, -+ char *buf); -+ ssize_t (*store)(struct kobject *kobj, struct fragment_attribute *fattr, -+ const char *buf, size_t count); -+ struct of_overlay_info *ovinfo; -+}; -+ - /** - * struct of_overlay_info - Holds a single overlay info -+ * @info: info node that contains the target and overlay - * @target: target of the overlay operation - * @overlay: pointer to the overlay contents node - * -@@ -34,8 +51,13 @@ - * records. - */ - struct of_overlay_info { -+ struct of_overlay *ov; -+ struct device_node *info; - struct device_node *target; - struct device_node *overlay; -+ struct attribute_group attr_group; -+ struct attribute *attrs[2]; -+ struct fragment_attribute target_attr; - }; - - /** -@@ -52,11 +74,26 @@ struct of_overlay { - struct list_head node; - int count; - struct of_overlay_info *ovinfo_tab; -+ const struct attribute_group **attr_groups; - struct of_changeset cset; -+ struct kobject kobj; -+ int target_index; -+ struct device_node *target_root; - }; - -+/* master enable switch; once set to 0 can't be re-enabled */ -+static atomic_t ov_enable = ATOMIC_INIT(1); -+ -+static int __init of_overlay_disable_setup(char *str __always_unused) -+{ -+ atomic_set(&ov_enable, 0); -+ return 1; -+} -+__setup("of_overlay_disable", of_overlay_disable_setup); -+ - static int of_overlay_apply_one(struct of_overlay *ov, - struct device_node *target, const struct device_node *overlay); -+static int overlay_removal_is_ok(struct of_overlay *ov); - - static int of_overlay_apply_single_property(struct of_overlay *ov, - struct device_node *target, struct property *prop) -@@ -187,30 +224,92 @@ static int of_overlay_apply(struct of_overlay *ov) - - /* - * Find the target node using a number of different strategies -- * in order of preference -+ * in order of preference. Respects the target index if available. - * - * "target" property containing the phandle of the target - * "target-path" property containing the path of the target - */ --static struct device_node *find_target_node(struct device_node *info_node) -+static struct device_node *find_target_node(struct of_overlay *ov, -+ struct device_node *info_node, int index) - { -+ struct device_node *target = NULL, *np; - const char *path; -+ char *newpath; - u32 val; - int ret; - - /* first try to go by using the target as a phandle */ -- ret = of_property_read_u32(info_node, "target", &val); -- if (ret == 0) -- return of_find_node_by_phandle(val); -+ ret = of_property_read_u32_index(info_node, "target", index, &val); -+ if (ret == 0) { -+ target = of_find_node_by_phandle(val); -+ if (!target) { -+ pr_err("%s: Could not find target phandle 0x%x\n", -+ __func__, val); -+ return NULL; -+ } -+ goto check_root; -+ } - -- /* now try to locate by path */ -- ret = of_property_read_string(info_node, "target-path", &path); -- if (ret == 0) -- return of_find_node_by_path(path); -+ /* failed, try to locate by path */ -+ ret = of_property_read_string_index(info_node, "target-path", index, -+ &path); -+ if (ret == 0) { -+ -+ if (!ov->target_root) { -+ target = of_find_node_by_path(path); -+ if (!target) -+ pr_err("%s: Could not find target path \"%s\"\n", -+ __func__, path); -+ return target; -+ } -+ -+ /* remove preceding '/' from path; relative path */ -+ if (*path == '/') { -+ while (*path == '/') -+ path++; -+ -+ newpath = kasprintf(GFP_KERNEL, "%s%s%s", -+ of_node_full_name(ov->target_root), -+ *path ? "/" : "", path); -+ if (!newpath) { -+ pr_err("%s: Could not allocate \"%s%s%s\"\n", -+ __func__, -+ of_node_full_name(ov->target_root), -+ *path ? "/" : "", path); -+ return NULL; -+ } -+ target = of_find_node_by_path(newpath); -+ kfree(newpath); - -- pr_err("Failed to find target for node %p (%s)\n", -- info_node, info_node->name); -+ return target; - -+ } -+ /* target is an alias, need to check */ -+ target = of_find_node_by_path(path); -+ if (!target) { -+ pr_err("%s: Could not find alias \"%s\"\n", -+ __func__, path); -+ return NULL; -+ } -+ goto check_root; -+ } -+ -+ return NULL; -+ -+check_root: -+ if (!ov->target_root) -+ return target; -+ -+ /* got a target, but we have to check it's under target root */ -+ for (np = target; np; np = np->parent) { -+ if (np == ov->target_root) -+ return target; -+ } -+ pr_err("%s: target \"%s\" not under target_root \"%s\"\n", -+ __func__, of_node_full_name(target), -+ of_node_full_name(ov->target_root)); -+ /* target is not under target_root */ -+ of_node_put(target); - return NULL; - } - -@@ -235,10 +334,12 @@ static int of_fill_overlay_info(struct of_overlay *ov, - if (ovinfo->overlay == NULL) - goto err_fail; - -- ovinfo->target = find_target_node(info_node); -+ ovinfo->target = find_target_node(ov, info_node, ov->target_index); - if (ovinfo->target == NULL) - goto err_fail; - -+ ovinfo->info = of_node_get(info_node); -+ - return 0; - - err_fail: -@@ -249,6 +350,17 @@ static int of_fill_overlay_info(struct of_overlay *ov, - return -EINVAL; - } - -+static ssize_t target_show(struct kobject *kobj, -+ struct fragment_attribute *fattr, char *buf) -+{ -+ struct of_overlay_info *ovinfo = fattr->ovinfo; -+ -+ return snprintf(buf, PAGE_SIZE, "%s\n", -+ of_node_full_name(ovinfo->target)); -+} -+ -+static const struct fragment_attribute target_template_attr = __ATTR_RO(target); -+ - /** - * of_build_overlay_info() - Build an overlay info array - * @ov Overlay to build -@@ -266,7 +378,7 @@ static int of_build_overlay_info(struct of_overlay *ov, - { - struct device_node *node; - struct of_overlay_info *ovinfo; -- int cnt, err; -+ int i, cnt, err; - - /* worst case; every child is a node */ - cnt = 0; -@@ -287,14 +399,45 @@ static int of_build_overlay_info(struct of_overlay *ov, - - /* if nothing filled, return error */ - if (cnt == 0) { -- kfree(ovinfo); -- return -ENODEV; -+ err = -ENODEV; -+ goto err_free_ovinfo; - } - - ov->count = cnt; - ov->ovinfo_tab = ovinfo; - -+ ov->attr_groups = kcalloc(cnt + 1, -+ sizeof(struct attribute_group *), GFP_KERNEL); -+ if (ov->attr_groups == NULL) { -+ err = -ENOMEM; -+ goto err_free_ovinfo; -+ } -+ -+ for (i = 0; i < cnt; i++) { -+ ovinfo = &ov->ovinfo_tab[i]; -+ -+ ov->attr_groups[i] = &ovinfo->attr_group; -+ -+ ovinfo->target_attr = target_template_attr; -+ /* make lockdep happy */ -+ sysfs_attr_init(&ovinfo->target_attr.attr); -+ ovinfo->target_attr.ovinfo = ovinfo; -+ -+ ovinfo->attrs[0] = &ovinfo->target_attr.attr; -+ ovinfo->attrs[1] = NULL; -+ -+ /* NOTE: direct reference to the full_name */ -+ ovinfo->attr_group.name = kbasename(ovinfo->info->full_name); -+ ovinfo->attr_group.attrs = ovinfo->attrs; -+ -+ } -+ ov->attr_groups[i] = NULL; -+ - return 0; -+ -+err_free_ovinfo: -+ kfree(ovinfo); -+ return err; - } - - /** -@@ -311,46 +454,201 @@ static int of_free_overlay_info(struct of_overlay *ov) - struct of_overlay_info *ovinfo; - int i; - -+ /* free attribute groups space */ -+ kfree(ov->attr_groups); -+ - /* do it in reverse */ - for (i = ov->count - 1; i >= 0; i--) { - ovinfo = &ov->ovinfo_tab[i]; - - of_node_put(ovinfo->target); - of_node_put(ovinfo->overlay); -+ of_node_put(ovinfo->info); - } - kfree(ov->ovinfo_tab); - - return 0; - } - -+static int of_overlay_add_symbols( -+ struct device_node *tree, -+ struct of_overlay *ov) -+{ -+ struct of_overlay_info *ovinfo; -+ struct device_node *root_sym = NULL; -+ struct device_node *child = NULL; -+ struct property *prop; -+ const char *path, *s; -+ char *new_path; -+ int i, len, err; -+ -+ /* both may fail (if no fixups are required) */ -+ root_sym = of_find_node_by_path("/__symbols__"); -+ child = of_get_child_by_name(tree, "__symbols__"); -+ -+ err = 0; -+ /* do nothing if either is NULL */ -+ if (!root_sym || !child) -+ goto out; -+ -+ for_each_property_of_node(child, prop) { -+ -+ /* skip properties added automatically */ -+ if (of_prop_cmp(prop->name, "name") == 0) -+ continue; -+ -+ err = of_property_read_string(child, -+ prop->name, &path); -+ if (err != 0) { -+ pr_err("Could not find symbol '%s'\n", prop->name); -+ continue; -+ } -+ -+ /* now find fragment index */ -+ s = path; -+ -+ /* compare paths to find fragment index */ -+ for (i = 0, ovinfo = NULL, len = -1; i < ov->count; i++) { -+ ovinfo = &ov->ovinfo_tab[i]; -+ -+ pr_debug("#%d: overlay->name=%s target->name=%s\n", -+ i, ovinfo->overlay->full_name, -+ ovinfo->target->full_name); -+ -+ len = strlen(ovinfo->overlay->full_name); -+ if (strncasecmp(path, ovinfo->overlay->full_name, -+ len) == 0 && path[len] == '/') -+ break; -+ } -+ -+ if (i >= ov->count) -+ continue; -+ -+ pr_debug("found target at #%d\n", i); -+ new_path = kasprintf(GFP_KERNEL, "%s%s", -+ ovinfo->target->full_name, -+ path + len); -+ if (!new_path) { -+ pr_err("Failed to allocate propname for \"%s\"\n", -+ prop->name); -+ err = -ENOMEM; -+ break; -+ } -+ -+ err = of_changeset_add_property_string(&ov->cset, root_sym, -+ prop->name, new_path); -+ -+ /* free always */ -+ kfree(new_path); -+ -+ if (err) { -+ pr_err("Failed to add property for \"%s\"\n", -+ prop->name); -+ break; -+ } -+ } -+ -+out: -+ of_node_put(child); -+ of_node_put(root_sym); -+ -+ return err; -+} -+ - static LIST_HEAD(ov_list); - static DEFINE_IDR(ov_idr); - --/** -- * of_overlay_create() - Create and apply an overlay -- * @tree: Device node containing all the overlays -- * -- * Creates and applies an overlay while also keeping track -- * of the overlay in a list. This list can be used to prevent -- * illegal overlay removals. -- * -- * Returns the id of the created overlay, or a negative error number -- */ --int of_overlay_create(struct device_node *tree) -+static inline struct of_overlay *kobj_to_overlay(struct kobject *kobj) -+{ -+ return container_of(kobj, struct of_overlay, kobj); -+} -+ -+void of_overlay_release(struct kobject *kobj) -+{ -+ struct of_overlay *ov = kobj_to_overlay(kobj); -+ -+ of_node_put(ov->target_root); -+ kfree(ov); -+} -+ -+static ssize_t enable_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&ov_enable)); -+} -+ -+static ssize_t enable_store(struct kobject *kobj, -+ struct kobj_attribute *attr, const char *buf, size_t count) -+{ -+ int ret; -+ bool new_enable; -+ -+ ret = strtobool(buf, &new_enable); -+ if (ret != 0) -+ return ret; -+ /* if we've disabled it, no going back */ -+ if (atomic_read(&ov_enable) == 0) -+ return -EPERM; -+ atomic_set(&ov_enable, (int)new_enable); -+ return count; -+} -+ -+static struct kobj_attribute enable_attr = __ATTR_RW(enable); -+ -+static const struct attribute *overlay_global_attrs[] = { -+ &enable_attr.attr, -+ NULL -+}; -+ -+static ssize_t can_remove_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) -+{ -+ struct of_overlay *ov = kobj_to_overlay(kobj); -+ -+ return snprintf(buf, PAGE_SIZE, "%d\n", overlay_removal_is_ok(ov)); -+} -+ -+static struct kobj_attribute can_remove_attr = __ATTR_RO(can_remove); -+ -+static struct attribute *overlay_attrs[] = { -+ &can_remove_attr.attr, -+ NULL -+}; -+ -+static struct kobj_type of_overlay_ktype = { -+ .release = of_overlay_release, -+ .sysfs_ops = &kobj_sysfs_ops, /* default kobj sysfs ops */ -+ .default_attrs = overlay_attrs, -+}; -+ -+static struct kset *ov_kset; -+ -+static int __of_overlay_create(struct device_node *tree, -+ int target_index, struct device_node *target_root) - { - struct of_overlay *ov; - int err, id; - -+ /* administratively disabled */ -+ if (!atomic_read(&ov_enable)) -+ return -EPERM; -+ - /* allocate the overlay structure */ - ov = kzalloc(sizeof(*ov), GFP_KERNEL); - if (ov == NULL) - return -ENOMEM; - ov->id = -1; - -+ ov->target_index = target_index; -+ ov->target_root = of_node_get(target_root); -+ - INIT_LIST_HEAD(&ov->node); - - of_changeset_init(&ov->cset); - -+ /* initialize kobject */ -+ kobject_init(&ov->kobj, &of_overlay_ktype); -+ - mutex_lock(&of_mutex); - - id = idr_alloc(&ov_idr, ov, 0, 0, GFP_KERNEL); -@@ -373,19 +671,44 @@ int of_overlay_create(struct device_node *tree) - if (err) - goto err_abort_trans; - -+ err = of_overlay_add_symbols(tree, ov); -+ if (err) { -+ pr_err("%s: of_overlay_add_symbols() failed for tree@%s\n", -+ __func__, tree->full_name); -+ goto err_abort_trans; -+ } -+ - /* apply the changeset */ - err = __of_changeset_apply(&ov->cset); - if (err) - goto err_revert_overlay; - - -+ ov->kobj.kset = ov_kset; -+ err = kobject_add(&ov->kobj, NULL, "%d", id); -+ if (err != 0) { -+ pr_err("%s: kobject_add() failed for tree@%s\n", -+ __func__, tree->full_name); -+ goto err_cancel_overlay; -+ } -+ -+ err = sysfs_create_groups(&ov->kobj, ov->attr_groups); -+ if (err != 0) { -+ pr_err("%s: sysfs_create_groups() failed for tree@%s\n", -+ __func__, tree->full_name); -+ goto err_remove_kobj; -+ } -+ - /* add to the tail of the overlay list */ - list_add_tail(&ov->node, &ov_list); - - mutex_unlock(&of_mutex); - - return id; -- -+err_remove_kobj: -+ kobject_put(&ov->kobj); -+err_cancel_overlay: -+ of_changeset_revert(&ov->cset); - err_revert_overlay: - err_abort_trans: - of_free_overlay_info(ov); -@@ -393,13 +716,66 @@ int of_overlay_create(struct device_node *tree) - idr_remove(&ov_idr, ov->id); - err_destroy_trans: - of_changeset_destroy(&ov->cset); -+ of_node_put(ov->target_root); - kfree(ov); - mutex_unlock(&of_mutex); - - return err; - } -+ -+/** -+ * of_overlay_create() - Create and apply an overlay -+ * @tree: Device node containing all the overlays -+ * -+ * Creates and applies an overlay while also keeping track -+ * of the overlay in a list. This list can be used to prevent -+ * illegal overlay removals. -+ * -+ * Returns the id of the created overlay, or a negative error number -+ */ -+int of_overlay_create(struct device_node *tree) -+{ -+ return __of_overlay_create(tree, 0, NULL); -+} - EXPORT_SYMBOL_GPL(of_overlay_create); - -+/** -+ * of_overlay_create_target_index() - Create and apply an overlay -+ * @tree: Device node containing all the overlays -+ * @index: Index to use in the target properties -+ * -+ * Creates and applies an overlay while also keeping track -+ * of the overlay in a list. This list can be used to prevent -+ * illegal overlay removals. -+ * -+ * Returns the id of the created overlay, or a negative error number -+ */ -+int of_overlay_create_target_index(struct device_node *tree, int index) -+{ -+ return __of_overlay_create(tree, index, NULL); -+} -+EXPORT_SYMBOL_GPL(of_overlay_create_target_index); -+ -+/** -+ * of_overlay_create_target_root() - Create and apply an overlay -+ * under which will be limited to target_root -+ * @tree: Device node containing all the overlays -+ * @target_root: Target root for the overlay. -+ * -+ * Creates and applies an overlay while also keeping track -+ * of the overlay in a list. This list can be used to prevent -+ * illegal overlay removals. The overlay is only allowed to -+ * target nodes under the target_root node. -+ * -+ * Returns the id of the created overlay, or an negative error number -+ */ -+int of_overlay_create_target_root(struct device_node *tree, -+ struct device_node *target_root) -+{ -+ return __of_overlay_create(tree, 0, target_root); -+} -+EXPORT_SYMBOL_GPL(of_overlay_create_target_root); -+ - /* check whether the given node, lies under the given tree */ - static int overlay_subtree_check(struct device_node *tree, - struct device_node *dn) -@@ -500,11 +876,13 @@ int of_overlay_destroy(int id) - - - list_del(&ov->node); -+ sysfs_remove_groups(&ov->kobj, ov->attr_groups); - __of_changeset_revert(&ov->cset); - of_free_overlay_info(ov); - idr_remove(&ov_idr, id); - of_changeset_destroy(&ov->cset); -- kfree(ov); -+ -+ kobject_put(&ov->kobj); - - err = 0; - -@@ -534,7 +912,7 @@ int of_overlay_destroy_all(void) - __of_changeset_revert(&ov->cset); - of_free_overlay_info(ov); - idr_remove(&ov_idr, ov->id); -- kfree(ov); -+ kobject_put(&ov->kobj); - } - - mutex_unlock(&of_mutex); -@@ -542,3 +920,18 @@ int of_overlay_destroy_all(void) - return 0; - } - EXPORT_SYMBOL_GPL(of_overlay_destroy_all); -+ -+/* called from of_init() */ -+int of_overlay_init(void) -+{ -+ int rc; -+ -+ ov_kset = kset_create_and_add("overlays", NULL, &of_kset->kobj); -+ if (!ov_kset) -+ return -ENOMEM; -+ -+ rc = sysfs_create_files(&ov_kset->kobj, overlay_global_attrs); -+ WARN(rc, "%s: error adding global attributes\n", __func__); -+ -+ return rc; -+} -diff --git a/drivers/of/unittest-data/testcases.dts b/drivers/of/unittest-data/testcases.dts -index 12f7c3d..a6ded1b 100644 ---- a/drivers/of/unittest-data/testcases.dts -+++ b/drivers/of/unittest-data/testcases.dts -@@ -75,5 +75,15 @@ - target = <0x00000000>; - }; - }; -+ overlay16 { -+ fragment@0 { -+ target = <0x00000000 0x00000004>; -+ }; -+ }; -+ overlay18 { -+ fragment@0 { -+ target = <0x00000000>; -+ }; -+ }; - }; - }; }; -diff --git a/drivers/of/unittest-data/tests-overlay.dtsi b/drivers/of/unittest-data/tests-overlay.dtsi -index 02ba56c..170b04d 100644 ---- a/drivers/of/unittest-data/tests-overlay.dtsi -+++ b/drivers/of/unittest-data/tests-overlay.dtsi -@@ -110,6 +110,30 @@ - }; - }; - }; -+ -+ unittest16: test-unittest16 { -+ compatible = "unittest"; -+ status = "disabled"; -+ reg = <16>; -+ }; -+ -+ unittest17: test-unittest17 { -+ compatible = "unittest"; -+ status = "disabled"; -+ reg = <17>; -+ }; -+ -+ unittest18: test-unittest18 { -+ compatible = "unittest"; -+ status = "disabled"; -+ reg = <18>; -+ }; -+ -+ unittest19: test-unittest19 { -+ compatible = "unittest"; -+ status = "disabled"; -+ reg = <19>; -+ }; - }; - }; - -@@ -325,5 +349,44 @@ - }; - }; - -+ /* test enable using indirect functionality */ -+ overlay16 { -+ fragment@0 { -+ target = <&unittest17>, <&unittest16>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ /* test enable using target root (relative path) */ -+ overlay17 { -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ /* test enable using target phandle */ -+ overlay18 { -+ fragment@0 { -+ target = <&unittest18>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ /* test trying to enable out of root (should fail) */ -+ overlay19 { -+ fragment@0 { -+ target = <&unittest19>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ }; - }; - }; -diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c -index 53c83d6..b560ae7 100644 ---- a/drivers/of/unittest.c -+++ b/drivers/of/unittest.c -@@ -24,6 +24,9 @@ - - #include <linux/bitops.h> - -+#include <linux/timekeeping.h> -+#include <linux/random.h> -+ - #include "of_private.h" - - static struct unittest_results { -@@ -542,6 +545,59 @@ static void __init of_unittest_changeset(void) - #endif - } - -+static void __init of_unittest_changeset_helper(void) -+{ -+#ifdef CONFIG_OF_DYNAMIC -+ struct device_node *n1, *n2, *n21, *parent, *np; -+ struct of_changeset chgset; -+ -+ of_changeset_init(&chgset); -+ -+ parent = of_find_node_by_path("/testcase-data/changeset"); -+ -+ unittest(parent, "testcase setup failure\n"); -+ n1 = of_changeset_create_device_node(&chgset, -+ parent, "/testcase-data/changeset/n1"); -+ unittest(n1, "testcase setup failure\n"); -+ n2 = of_changeset_create_device_node(&chgset, -+ parent, "/testcase-data/changeset/n2"); -+ unittest(n2, "testcase setup failure\n"); -+ n21 = of_changeset_create_device_node(&chgset, n2, "%s/%s", -+ "/testcase-data/changeset/n2", "n21"); -+ unittest(n21, "testcase setup failure\n"); -+ -+ unittest(!of_changeset_add_property_string(&chgset, parent, -+ "prop-add", "foo"), "fail add prop\n"); -+ -+ unittest(!of_changeset_attach_node(&chgset, n1), "fail n1 attach\n"); -+ unittest(!of_changeset_attach_node(&chgset, n2), "fail n2 attach\n"); -+ unittest(!of_changeset_attach_node(&chgset, n21), "fail n21 attach\n"); -+ -+ unittest(!of_changeset_apply(&chgset), "apply failed\n"); -+ -+ /* Make sure node names are constructed correctly */ -+ np = of_find_node_by_path("/testcase-data/changeset/n1"); -+ unittest(np, "'%s' not added\n", n1->full_name); -+ of_node_put(np); -+ -+ /* Make sure node names are constructed correctly */ -+ np = of_find_node_by_path("/testcase-data/changeset/n2"); -+ unittest(np, "'%s' not added\n", n2->full_name); -+ of_node_put(np); -+ -+ np = of_find_node_by_path("/testcase-data/changeset/n2/n21"); -+ unittest(np, "'%s' not added\n", n21->full_name); -+ of_node_put(np); -+ -+ unittest(!of_changeset_revert(&chgset), "revert failed\n"); -+ -+ of_changeset_destroy(&chgset); -+ -+ of_node_put(parent); -+#endif -+} -+ -+ - static void __init of_unittest_parse_interrupts(void) - { - struct device_node *np; -@@ -877,7 +933,7 @@ static int attach_node_and_children(struct device_node *np) - of_node_clear_flag(np, OF_DETACHED); - raw_spin_unlock_irqrestore(&devtree_lock, flags); - -- __of_attach_node_sysfs(np); -+ __of_attach_node_post(np); - mutex_unlock(&of_mutex); - - while (child) { -@@ -935,7 +991,7 @@ static int __init unittest_data_add(void) - if (!of_root) { - of_root = unittest_data_node; - for_each_of_allnodes(np) -- __of_attach_node_sysfs(np); -+ __of_attach_node_post(np); - of_aliases = of_find_node_by_path("/aliases"); - of_chosen = of_find_node_by_path("/chosen"); - return 0; -@@ -1854,6 +1910,273 @@ static inline void of_unittest_overlay_i2c_15(void) { } - - #endif - -+static void of_unittest_overlay_16(void) -+{ -+ int ret; -+ int overlay_nr = 16; -+ int unittest_nr = 16; -+ enum overlay_type ovtype = PDEV_OVERLAY; -+ int before = 0; -+ int after = 1; -+ struct device_node *np = NULL; -+ int id = -1; -+ -+ /* unittest device must not be in before state */ -+ if (of_unittest_device_exists(unittest_nr, ovtype) != before) { -+ unittest(0, "overlay @\"%s\" with device @\"%s\" %s\n", -+ overlay_path(overlay_nr), -+ unittest_path(unittest_nr, ovtype), -+ !before ? "enabled" : "disabled"); -+ return; -+ } -+ -+ np = of_find_node_by_path(overlay_path(overlay_nr)); -+ if (np == NULL) { -+ unittest(0, "could not find overlay node @\"%s\"\n", -+ overlay_path(overlay_nr)); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ /* unittest16 is at index #1 */ -+ ret = of_overlay_create_target_index(np, 1); -+ if (ret < 0) { -+ unittest(0, "could not create overlay from \"%s\"\n", -+ overlay_path(overlay_nr)); -+ goto out; -+ } -+ id = ret; -+ of_unittest_track_overlay(id); -+ -+ ret = 0; -+ -+out: -+ of_node_put(np); -+ -+ if (ret) -+ return; -+ -+ /* unittest device must be to set to after state */ -+ if (of_unittest_device_exists(unittest_nr, ovtype) != after) { -+ unittest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n", -+ overlay_path(overlay_nr), -+ unittest_path(unittest_nr, ovtype), -+ !after ? "enabled" : "disabled"); -+ return; -+ } -+ -+ unittest(1, "overlay test %d passed\n", 16); -+} -+ -+static void of_unittest_overlay_17(void) -+{ -+ int ret; -+ int overlay_nr = 17; -+ int unittest_nr = 17; -+ enum overlay_type ovtype = PDEV_OVERLAY; -+ int before = 0; -+ int after = 1; -+ const char *root_path; -+ struct device_node *np = NULL, *target_root = NULL; -+ int id = -1; -+ -+ /* unittest device must not be in before state */ -+ if (of_unittest_device_exists(unittest_nr, ovtype) != before) { -+ unittest(0, "overlay @\"%s\" with device @\"%s\" %s\n", -+ overlay_path(overlay_nr), -+ unittest_path(unittest_nr, ovtype), -+ !before ? "enabled" : "disabled"); -+ return; -+ } -+ -+ np = of_find_node_by_path(overlay_path(overlay_nr)); -+ if (np == NULL) { -+ unittest(0, "could not find overlay node @\"%s\"\n", -+ overlay_path(overlay_nr)); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ root_path = "/testcase-data/overlay-node/test-bus/test-unittest17"; -+ target_root = of_find_node_by_path(root_path); -+ if (!target_root) { -+ unittest(0, "could not find target_root node @\"%s\"\n", -+ root_path); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ ret = of_overlay_create_target_root(np, target_root); -+ of_node_put(target_root); -+ -+ if (ret < 0) { -+ unittest(0, "could not create overlay from \"%s\"\n", -+ overlay_path(overlay_nr)); -+ goto out; -+ } -+ id = ret; -+ of_unittest_track_overlay(id); -+ -+ ret = 0; -+ -+out: -+ of_node_put(np); -+ -+ if (ret) -+ return; -+ -+ /* unittest device must be to set to after state */ -+ if (of_unittest_device_exists(unittest_nr, ovtype) != after) { -+ unittest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n", -+ overlay_path(overlay_nr), -+ unittest_path(unittest_nr, ovtype), -+ !after ? "enabled" : "disabled"); -+ return; -+ } -+ -+ unittest(1, "overlay test %d passed\n", 17); -+} -+ -+static void of_unittest_overlay_18(void) -+{ -+ int ret; -+ int overlay_nr = 18; -+ int unittest_nr = 18; -+ enum overlay_type ovtype = PDEV_OVERLAY; -+ int before = 0; -+ int after = 1; -+ const char *root_path; -+ struct device_node *np = NULL, *target_root = NULL; -+ int id = -1; -+ -+ /* unittest device must not be in before state */ -+ if (of_unittest_device_exists(unittest_nr, ovtype) != before) { -+ unittest(0, "overlay @\"%s\" with device @\"%s\" %s\n", -+ overlay_path(overlay_nr), -+ unittest_path(unittest_nr, ovtype), -+ !before ? "enabled" : "disabled"); -+ return; -+ } -+ -+ np = of_find_node_by_path(overlay_path(overlay_nr)); -+ if (np == NULL) { -+ unittest(0, "could not find overlay node @\"%s\"\n", -+ overlay_path(overlay_nr)); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ root_path = "/testcase-data/overlay-node/test-bus/test-unittest18"; -+ target_root = of_find_node_by_path(root_path); -+ if (!target_root) { -+ unittest(0, "could not find target_root node @\"%s\"\n", -+ root_path); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ ret = of_overlay_create_target_root(np, target_root); -+ of_node_put(target_root); -+ -+ if (ret < 0) { -+ unittest(0, "could not create overlay from \"%s\"\n", -+ overlay_path(overlay_nr)); -+ goto out; -+ } -+ id = ret; -+ of_unittest_track_overlay(id); -+ -+ ret = 0; -+ -+out: -+ of_node_put(np); -+ -+ if (ret) -+ return; -+ -+ /* unittest device must be to set to after state */ -+ if (of_unittest_device_exists(unittest_nr, ovtype) != after) { -+ unittest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n", -+ overlay_path(overlay_nr), -+ unittest_path(unittest_nr, ovtype), -+ !after ? "enabled" : "disabled"); -+ return; -+ } -+ -+ unittest(1, "overlay test %d passed\n", 18); -+} -+ -+static void of_unittest_overlay_19(void) -+{ -+ int ret; -+ int overlay_nr = 19; -+ int unittest_nr = 19; -+ enum overlay_type ovtype = PDEV_OVERLAY; -+ int before = 0; -+ int after = 0; -+ const char *root_path; -+ struct device_node *np = NULL, *target_root = NULL; -+ int id = -1; -+ -+ /* unittest device must not be in before state */ -+ if (of_unittest_device_exists(unittest_nr, ovtype) != before) { -+ unittest(0, "overlay @\"%s\" with device @\"%s\" %s\n", -+ overlay_path(overlay_nr), -+ unittest_path(unittest_nr, ovtype), -+ !before ? "enabled" : "disabled"); -+ return; -+ } -+ -+ np = of_find_node_by_path(overlay_path(overlay_nr)); -+ if (np == NULL) { -+ unittest(0, "could not find overlay node @\"%s\"\n", -+ overlay_path(overlay_nr)); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ root_path = "/testcase-data/overlay-node/test-bus/test-unittest19"; -+ target_root = of_find_node_by_path(root_path); -+ if (!target_root) { -+ unittest(0, "could not find target_root node @\"%s\"\n", -+ root_path); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ ret = of_overlay_create_target_root(np, target_root); -+ of_node_put(target_root); -+ -+ if (ret >= 0) { -+ unittest(0, "created overlay from \"%s\" while we shouldn't\n", -+ overlay_path(overlay_nr)); -+ id = ret; -+ of_unittest_track_overlay(id); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ ret = 0; -+ -+out: -+ of_node_put(np); -+ -+ if (ret) -+ return; -+ -+ /* unittest device must be to set to after state */ -+ if (of_unittest_device_exists(unittest_nr, ovtype) != after) { -+ unittest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n", -+ overlay_path(overlay_nr), -+ unittest_path(unittest_nr, ovtype), -+ !after ? "enabled" : "disabled"); -+ return; -+ } -+ -+ unittest(1, "overlay test %d passed\n", 16); -+} -+ -+ - static void __init of_unittest_overlay(void) - { - struct device_node *bus_np = NULL; -@@ -1904,6 +2227,12 @@ static void __init of_unittest_overlay(void) - of_unittest_overlay_10(); - of_unittest_overlay_11(); - -+ of_unittest_overlay_16(); -+ -+ of_unittest_overlay_17(); -+ of_unittest_overlay_18(); -+ of_unittest_overlay_19(); -+ - #if IS_BUILTIN(CONFIG_I2C) - if (unittest(of_unittest_overlay_i2c_init() == 0, "i2c init failed\n")) - goto out; -@@ -1926,6 +2255,70 @@ static void __init of_unittest_overlay(void) - static inline void __init of_unittest_overlay(void) { } - #endif - -+#define PHANDLE_LOOKUPS 1000 -+ -+static void __init of_unittest_phandle_hash(void) -+{ -+ struct device_node *node; -+ phandle max_phandle; -+ u32 ph; -+ unsigned long flags; -+ int i, j, total; -+ ktime_t start, end; -+ s64 dur[2]; -+ int dec, frac; -+ -+ /* test only available when hashing is available */ -+ if (!of_phandle_ht_available()) { -+ pr_warn("phandle hash test requires hash to be initialized\n"); -+ return; -+ } -+ -+ /* find the maximum phandle of the tree */ -+ raw_spin_lock_irqsave(&devtree_lock, flags); -+ max_phandle = 0; -+ total = 0; -+ for_each_of_allnodes(node) { -+ if (node->phandle != (phandle)-1U && -+ node->phandle > max_phandle) -+ max_phandle = node->phandle; -+ total++; -+ } -+ raw_spin_unlock_irqrestore(&devtree_lock, flags); -+ max_phandle++; -+ -+ pr_debug("phandle: max-phandle #%u, #%d total nodes\n", -+ (u32)max_phandle, total); -+ -+ /* perform random lookups using the hash */ -+ for (j = 0; j < 2; j++) { -+ -+ /* disabled for pass #0, enabled for pass #1 */ -+ of_phandle_ht_is_disabled = j == 0; -+ -+ start = ktime_get_raw(); -+ for (i = 0; i < PHANDLE_LOOKUPS; i++) { -+ ph = prandom_u32() % max_phandle; -+ node = of_find_node_by_phandle(ph); -+ of_node_put(node); -+ } -+ end = ktime_get_raw(); -+ -+ dur[j] = ktime_to_us(end) - ktime_to_us(start); -+ pr_debug("#%d lookups in %lld us (%s)\n", -+ PHANDLE_LOOKUPS, dur[j], -+ j == 0 ? "original" : "hashed"); -+ } -+ -+ unittest(dur[0] > dur[1], "Non hashing phandles are faster!?"); -+ -+ dec = (int)div64_s64(dur[0] * 10 + 5, dur[1]); -+ frac = dec % 10; -+ dec /= 10; -+ pr_info("the hash method is %d.%d times faster than the original\n", -+ dec, frac); -+} -+ - static int __init of_unittest(void) - { - struct device_node *np; -@@ -1954,11 +2347,13 @@ static int __init of_unittest(void) - of_unittest_property_string(); - of_unittest_property_copy(); - of_unittest_changeset(); -+ of_unittest_changeset_helper(); - of_unittest_parse_interrupts(); - of_unittest_parse_interrupts_extended(); - of_unittest_match_node(); - of_unittest_platform_populate(); - of_unittest_overlay(); -+ of_unittest_phandle_hash(); - - /* Double check linkage after removing testcase data */ - of_unittest_check_tree_linkage(); -diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig -index 671610c..f90bed9 100644 ---- a/drivers/pinctrl/Kconfig -+++ b/drivers/pinctrl/Kconfig -@@ -180,6 +180,18 @@ config PINCTRL_ST - select PINCONF - select GPIOLIB_IRQCHIP - -+config PINCTRL_TI_IODELAY -+ bool "TI IODelay Module pinconf driver" -+ depends on OF -+ select PINCONF -+ select GENERIC_PINCONF -+ select REGMAP_MMIO -+ help -+ Say Y here to support Texas Instruments' IODelay pinconf driver. -+ IODelay module is used for the DRA7 SoC family. This driver is in -+ addition to PINCTRL_SINGLE which controls the mux. -+ -+ - config PINCTRL_TZ1090 - bool "Toumaz Xenif TZ1090 pin control driver" - depends on SOC_TZ1090 -diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile -index 11bad37..23e118e 100644 ---- a/drivers/pinctrl/Makefile -+++ b/drivers/pinctrl/Makefile -@@ -26,6 +26,7 @@ obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o - obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o - obj-$(CONFIG_PINCTRL_SIRF) += sirf/ - obj-$(CONFIG_ARCH_TEGRA) += tegra/ -+obj-$(CONFIG_PINCTRL_TI_IODELAY)+= pinctrl-ti-iodelay.o - obj-$(CONFIG_PINCTRL_TZ1090) += pinctrl-tz1090.o - obj-$(CONFIG_PINCTRL_TZ1090_PDC) += pinctrl-tz1090-pdc.o - obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o -diff --git b/drivers/pinctrl/pinctrl-ti-iodelay.c b/drivers/pinctrl/pinctrl-ti-iodelay.c -new file mode 100644 -index 0000000..8d33414 ---- /dev/null -+++ b/drivers/pinctrl/pinctrl-ti-iodelay.c -@@ -0,0 +1,968 @@ -+/* -+ * Support for configuration of IO Delay module found on Texas Instruments SoCs -+ * such as DRA7 -+ * -+ * Copyright (C) 2015 Texas Instruments, Inc. -+ * -+ * This file is licensed under the terms of the GNU General Public -+ * License version 2. This program is licensed "as is" without any -+ * warranty of any kind, whether express or implied. -+ */ -+#include <linux/err.h> -+#include <linux/init.h> -+#include <linux/io.h> -+#include <linux/list.h> -+#include <linux/module.h> -+#include <linux/of_device.h> -+#include <linux/of.h> -+#include <linux/pinctrl/pinconf-generic.h> -+#include <linux/pinctrl/pinconf.h> -+#include <linux/pinctrl/pinctrl.h> -+#include <linux/regmap.h> -+#include <linux/slab.h> -+ -+#define IODELAY_REG_NAME_LEN ((sizeof(u32) * 2) + 3) -+#define DRIVER_NAME "ti-io-delay" -+/* Should I change this? Abuse? */ -+#define IODELAY_MUX_PINS_NAME "pinctrl-single,pins" -+ -+/* Device tree match, populated later */ -+static const struct of_device_id ti_iodelay_of_match[]; -+ -+/** -+ * struct ti_iodelay_conf_vals - Description of each configuration parameters. -+ * @offset: Configuration register offset -+ * @a_delay: Agnostic Delay (in ps) -+ * @g_delay: Gnostic Delay (in ps) -+ */ -+struct ti_iodelay_conf_vals { -+ u16 offset; -+ u16 a_delay; -+ u16 g_delay; -+}; -+ -+/** -+ * struct ti_iodelay_reg_data - Describes the registers for the IOdelay instance -+ * @signature_mask: Conf reg- mask for the signature bits -+ * @signature_value: Conf reg- signature value to be written (see TRM) -+ * @lock_mask: Conf reg- mask for the lock bits -+ * @lock_val: Conf reg- lock value for the lock bits (see TRM) -+ * @unlock_val: Conf reg- unlock value for the lock bits (see TRM) -+ * @binary_data_coarse_mask: Conf reg- coarse mask (see TRM) -+ * @binary_data_fine_mask: Conf reg- fine mask (see TRM) -+ * @reg_refclk_offset: Refclk register offset -+ * @refclk_period_mask: Refclk mask -+ * @reg_coarse_offset: Coarse register configuration offset -+ * @coarse_delay_count_mask: Coarse delay count mask -+ * @coarse_ref_count_mask: Coarse ref count mask -+ * @reg_fine_offset: Fine register configuration offset -+ * @fine_delay_count_mask: Fine delay count mask -+ * @fine_ref_count_mask: Fine ref count mask -+ * @reg_global_lock_offset: Global(for the IOdelay module) lock register offset -+ * @global_lock_mask: Lock mask -+ * @global_unlock_val: unlock value -+ * @global_lock_val: lock value -+ * @reg_start_offset: Where does the configuration registers start? -+ * @regmap_config: Regmap configuration for the IODelay region -+ */ -+struct ti_iodelay_reg_data { -+ u32 signature_mask; -+ u32 signature_value; -+ u32 lock_mask; -+ u32 lock_val; -+ u32 unlock_val; -+ u32 binary_data_coarse_mask; -+ u32 binary_data_fine_mask; -+ -+ u32 reg_refclk_offset; -+ u32 refclk_period_mask; -+ -+ u32 reg_coarse_offset; -+ u32 coarse_delay_count_mask; -+ u32 coarse_ref_count_mask; -+ -+ u32 reg_fine_offset; -+ u32 fine_delay_count_mask; -+ u32 fine_ref_count_mask; -+ -+ u32 reg_global_lock_offset; -+ u32 global_lock_mask; -+ u32 global_unlock_val; -+ u32 global_lock_val; -+ -+ u32 reg_start_offset; -+ -+ struct regmap_config *regmap_config; -+}; -+ -+/** -+ * struct ti_iodelay_reg_values - Computed io_reg configuration values (see TRM) -+ * @coarse_ref_count: Coarse reference count -+ * @coarse_delay_count: Coarse delay count -+ * @fine_ref_count: Fine reference count -+ * @fine_delay_count: Fine Delay count -+ * @ref_clk_period: Reference Clock period -+ * @cdpe: Coarse delay parameter -+ * @fdpe: Fine delay parameter -+ */ -+struct ti_iodelay_reg_values { -+ u16 coarse_ref_count; -+ u16 coarse_delay_count; -+ -+ u16 fine_ref_count; -+ u16 fine_delay_count; -+ -+ u16 ref_clk_period; -+ -+ u32 cdpe; -+ u32 fdpe; -+}; -+ -+/** -+ * struct ti_iodelay_pin_name - name of the pins -+ * @name: name -+ */ -+struct ti_iodelay_pin_name { -+ char name[IODELAY_REG_NAME_LEN]; -+}; -+ -+/** -+ * struct ti_iodelay_pingroup - Structure that describes one group -+ * @np: Node pointer (device tree) -+ * @name: Name of the group -+ * @map: pinctrl map allocated for the group -+ * @vals: configuration values allocated for the group (from dt) -+ * @nvals: number of configuration values allocated -+ * @config: pinconf "Config" - currently a dummy value -+ * @node: list node to next group -+ */ -+struct ti_iodelay_pingroup { -+ struct device_node *np; -+ const char *name; -+ struct pinctrl_map *map; -+ struct ti_iodelay_conf_vals *vals; -+ int nvals; -+ unsigned long config; -+ struct list_head node; -+}; -+ -+/** -+ * struct ti_iodelay_device - Represents information for a IOdelay instance -+ * @dev: device pointer -+ * @reg_base: Remapped virtual address -+ * @regmap: Regmap for this IOdelay instance -+ * @pctl: Pinctrl device -+ * @desc: pinctrl descriptor for pctl -+ * @pa: pinctrl pin wise description -+ * @names: names of the pins -+ * @groups: list of pinconf groups for iodelay instance -+ * @ngroups: number of groups in the list -+ * @mutex: mutex to protect group list modification -+ * @reg_data: Register definition data for the IODelay instance -+ * @reg_init_conf_values: Initial configuration values. -+ */ -+struct ti_iodelay_device { -+ struct device *dev; -+ void __iomem *reg_base; -+ struct regmap *regmap; -+ -+ struct pinctrl_dev *pctl; -+ struct pinctrl_desc desc; -+ struct pinctrl_pin_desc *pa; -+ struct ti_iodelay_pin_name *names; -+ -+ struct list_head groups; -+ int ngroups; -+ struct mutex mutex; /* list protection */ -+ -+ const struct ti_iodelay_reg_data *reg_data; -+ struct ti_iodelay_reg_values reg_init_conf_values; -+}; -+ -+/*--- IOdelay configuration stuff ----*/ -+ -+/** -+ * ti_iodelay_extract() - extract bits for a field -+ * @val: register value -+ * @mask: Mask -+ * -+ * Return: extracted value which is appropriately shifted -+ */ -+static inline u32 ti_iodelay_extract(u32 val, u32 mask) -+{ -+ return (val & mask) >> __ffs(mask); -+} -+ -+/** -+ * ti_iodelay_compute_dpe() - Compute equation for delay parameter -+ * @period: Period to use -+ * @ref: Reference Count -+ * @delay: Delay count -+ * @delay_m: Delay multiplier -+ * -+ * Return: Computed delay parameter -+ */ -+static inline u32 ti_iodelay_compute_dpe(u16 period, u16 ref, u16 delay, -+ u16 delay_m) -+{ -+ u64 m, d; -+ -+ /* Handle overflow conditions */ -+ m = 10 * (u64)period * (u64)ref; -+ d = 2 * (u64)delay * (u64)delay_m; -+ -+ /* Truncate result back to 32 bits */ -+ return div64_u64(m, d); -+} -+ -+/** -+ * ti_iodelay_pinconf_set() - Configure the pin configuration -+ * @iod: IODelay device -+ * @val: Configuration value -+ * -+ * Update the configuration register as per TRM and lockup once done. -+ * *IMPORTANT NOTE* SoC TRM does recommend doing iodelay programmation only -+ * while in Isolation. But, then, isolation also implies that every pin -+ * on the SoC(including DDR) will be isolated out. The only benefit being -+ * a glitchless configuration, However, the intent of this driver is purely -+ * to support a "glitchy" configuration where applicable. -+ * -+ * Return: 0 in case of success, else appropriate error value -+ */ -+static int ti_iodelay_pinconf_set(struct ti_iodelay_device *iod, -+ struct ti_iodelay_conf_vals *val) -+{ -+ const struct ti_iodelay_reg_data *reg = iod->reg_data; -+ struct ti_iodelay_reg_values *ival = &iod->reg_init_conf_values; -+ struct device *dev = iod->dev; -+ u32 g_delay_coarse, g_delay_fine; -+ u32 a_delay_coarse, a_delay_fine; -+ u32 c_elements, f_elements; -+ u32 total_delay; -+ u32 reg_mask, reg_val, tmp_val; -+ int r; -+ -+ /* NOTE: Truncation is expected in all division below */ -+ g_delay_coarse = val->g_delay / 920; -+ g_delay_fine = ((val->g_delay % 920) * 10) / 60; -+ -+ a_delay_coarse = val->a_delay / ival->cdpe; -+ a_delay_fine = ((val->a_delay % ival->cdpe) * 10) / ival->fdpe; -+ -+ c_elements = g_delay_coarse + a_delay_coarse; -+ f_elements = (g_delay_fine + a_delay_fine) / 10; -+ -+ if (f_elements > 22) { -+ total_delay = c_elements * ival->cdpe + f_elements * ival->fdpe; -+ c_elements = total_delay / ival->cdpe; -+ f_elements = (total_delay % ival->cdpe) / ival->fdpe; -+ } -+ -+ reg_mask = reg->signature_mask; -+ reg_val = reg->signature_value << __ffs(reg->signature_mask); -+ -+ reg_mask |= reg->binary_data_coarse_mask; -+ tmp_val = c_elements << __ffs(reg->binary_data_coarse_mask); -+ if (tmp_val & ~reg->binary_data_coarse_mask) { -+ dev_err(dev, "Masking overflow of coarse elements %08x\n", -+ tmp_val); -+ tmp_val &= reg->binary_data_coarse_mask; -+ } -+ reg_val |= tmp_val; -+ -+ reg_mask |= reg->binary_data_fine_mask; -+ tmp_val = f_elements << __ffs(reg->binary_data_fine_mask); -+ if (tmp_val & ~reg->binary_data_fine_mask) { -+ dev_err(dev, "Masking overflow of fine elements %08x\n", -+ tmp_val); -+ tmp_val &= reg->binary_data_fine_mask; -+ } -+ reg_val |= tmp_val; -+ -+ /* -+ * NOTE: we leave the iodelay values unlocked - this is to work around -+ * situations such as those found with mmc mode change. -+ * However, this leaves open any unwarranted changes to padconf register -+ * impacting iodelay configuration. Use with care! -+ */ -+ reg_mask |= reg->lock_mask; -+ reg_val |= reg->unlock_val << __ffs(reg->lock_mask); -+ r = regmap_update_bits(iod->regmap, val->offset, reg_mask, reg_val); -+ -+ dev_dbg(dev, "Set reg 0x%x Delay(a=%d g=%d), Elements(C=%d F=%d)0x%x\n", -+ val->offset, val->a_delay, val->g_delay, c_elements, -+ f_elements, reg_val); -+ -+ return r; -+} -+ -+/** -+ * ti_iodelay_pinconf_init_dev() - Initialize IODelay device -+ * @iod: IODelay device -+ * -+ * Unlocks the IODelay region, computes the common parameters -+ * -+ * Return: 0 in case of success, else appropriate error value -+ */ -+static int ti_iodelay_pinconf_init_dev(struct ti_iodelay_device *iod) -+{ -+ const struct ti_iodelay_reg_data *reg = iod->reg_data; -+ struct device *dev = iod->dev; -+ struct ti_iodelay_reg_values *ival = &iod->reg_init_conf_values; -+ u32 val; -+ int r; -+ -+ /* unlock the IOdelay region */ -+ r = regmap_update_bits(iod->regmap, reg->reg_global_lock_offset, -+ reg->global_lock_mask, reg->global_unlock_val); -+ if (r) -+ return r; -+ -+ /* Read up Recalibration sequence done by bootloader */ -+ r = regmap_read(iod->regmap, reg->reg_refclk_offset, &val); -+ if (r) -+ return r; -+ ival->ref_clk_period = ti_iodelay_extract(val, reg->refclk_period_mask); -+ dev_dbg(dev, "refclk_period=0x%04x\n", ival->ref_clk_period); -+ -+ r = regmap_read(iod->regmap, reg->reg_coarse_offset, &val); -+ if (r) -+ return r; -+ ival->coarse_ref_count = -+ ti_iodelay_extract(val, reg->coarse_ref_count_mask); -+ ival->coarse_delay_count = -+ ti_iodelay_extract(val, reg->coarse_delay_count_mask); -+ if (!ival->coarse_delay_count) { -+ dev_err(dev, "Invalid Coarse delay count (0) (reg=0x%08x)\n", -+ val); -+ return -EINVAL; -+ } -+ ival->cdpe = ti_iodelay_compute_dpe(ival->ref_clk_period, -+ ival->coarse_ref_count, -+ ival->coarse_delay_count, 88); -+ if (!ival->cdpe) { -+ dev_err(dev, "Invalid cdpe computed params = %d %d %d\n", -+ ival->ref_clk_period, ival->coarse_ref_count, -+ ival->coarse_delay_count); -+ return -EINVAL; -+ } -+ dev_dbg(iod->dev, "coarse: ref=0x%04x delay=0x%04x cdpe=0x%08x\n", -+ ival->coarse_ref_count, ival->coarse_delay_count, ival->cdpe); -+ -+ r = regmap_read(iod->regmap, reg->reg_fine_offset, &val); -+ if (r) -+ return r; -+ ival->fine_ref_count = -+ ti_iodelay_extract(val, reg->fine_ref_count_mask); -+ ival->fine_delay_count = -+ ti_iodelay_extract(val, reg->fine_delay_count_mask); -+ if (!ival->fine_delay_count) { -+ dev_err(dev, "Invalid Fine delay count (0) (reg=0x%08x)\n", -+ val); -+ return -EINVAL; -+ } -+ ival->fdpe = ti_iodelay_compute_dpe(ival->ref_clk_period, -+ ival->fine_ref_count, -+ ival->fine_delay_count, 264); -+ if (!ival->fdpe) { -+ dev_err(dev, "Invalid fdpe(0) computed params = %d %d %d\n", -+ ival->ref_clk_period, ival->fine_ref_count, -+ ival->fine_delay_count); -+ return -EINVAL; -+ } -+ dev_dbg(iod->dev, "fine: ref=0x%04x delay=0x%04x fdpe=0x%08x\n", -+ ival->fine_ref_count, ival->fine_delay_count, ival->fdpe); -+ -+ return 0; -+} -+ -+/** -+ * ti_iodelay_pinconf_deinit_dev() - deinit the IOdelay device -+ * @iod: IODelay device -+ * -+ * Deinitialize the IODelay device (basically just lock the region back up. -+ */ -+static void ti_iodelay_pinconf_deinit_dev(struct ti_iodelay_device *iod) -+{ -+ const struct ti_iodelay_reg_data *reg = iod->reg_data; -+ -+ /* lock the IOdelay region back again */ -+ regmap_update_bits(iod->regmap, reg->reg_global_lock_offset, -+ reg->global_lock_mask, reg->global_lock_val); -+} -+ -+/*--- Pinctrl/pinconf framework stuff ----*/ -+ -+/** -+ * ti_iodelay_get_group() - Find the group mapped by a group selector -+ * @iod: IODelay device -+ * @gselector: Group Selector -+ * -+ * Return: Corresponding group representing group selector in list of groups -+ * managed in IOdelay device OR NULL if not found. -+ */ -+static struct ti_iodelay_pingroup *ti_iodelay_get_group(struct ti_iodelay_device -+ *iod, -+ unsigned gselector) -+{ -+ struct ti_iodelay_pingroup *group; -+ int gid = 0; -+ -+ list_for_each_entry(group, &iod->groups, node) { -+ if (gid == gselector) -+ return group; -+ gid++; -+ } -+ -+ dev_err(iod->dev, "%s could not find pingroup %i\n", __func__, -+ gselector); -+ return NULL; -+} -+ -+/** -+ * ti_iodelay_dt_node_to_map() - Map a device tree node to appropriate group -+ * @pctldev: pinctrl device representing IODelay device -+ * @np: Node Pointer (device tree) -+ * @map: Pinctrl Map returned back to pinctrl framework -+ * @num_maps: Number of maps (1) -+ * -+ * Maps the device tree description into a group of configuration parameters -+ * for IOdelay block entry. -+ * -+ * Return: 0 in case of success, else appropriate error value -+ */ -+static int ti_iodelay_dt_node_to_map(struct pinctrl_dev *pctldev, -+ struct device_node *np, -+ struct pinctrl_map **map, -+ unsigned *num_maps) -+{ -+ struct ti_iodelay_device *iod; -+ struct device *dev; -+ /* const char **pgnames; */ -+ int ret = 0; -+ const __be32 *mux; -+ struct ti_iodelay_conf_vals *vals; -+ struct ti_iodelay_pingroup *group; -+ int size, index, idx, rows; -+ u32 offset, val; -+ -+ iod = pinctrl_dev_get_drvdata(pctldev); -+ if (!iod) -+ return -EINVAL; -+ dev = iod->dev; -+ -+ *map = devm_kzalloc(dev, sizeof(**map), GFP_KERNEL); -+ if (!*map) -+ return -ENOMEM; -+ *num_maps = 0; -+ -+ group = devm_kzalloc(dev, sizeof(*group), GFP_KERNEL); -+ if (!group) { -+ ret = -ENOMEM; -+ goto free_map; -+ } -+ -+ mux = of_get_property(np, IODELAY_MUX_PINS_NAME, &size); -+ if ((!mux) || (size < sizeof(*mux) * 2)) { -+ dev_err(dev, "bad data for mux %s\n", np->name); -+ ret = -EINVAL; -+ goto free_group; -+ } -+ -+ size /= sizeof(*mux); /* Number of elements in array */ -+ rows = size / 2; -+ -+ vals = devm_kzalloc(dev, sizeof(*vals) * rows, GFP_KERNEL); -+ if (!vals) { -+ ret = -ENOMEM; -+ goto free_group; -+ } -+ -+ index = 0; -+ idx = 0; -+ while (index < size) { -+ offset = be32_to_cpup(mux + index++); -+ val = be32_to_cpup(mux + index++); -+ vals[idx].offset = offset; -+ vals[idx].a_delay = val & 0xFFFF; -+ vals[idx].g_delay = (val & 0xFFFF0000) >> 16; -+ if (offset > iod->reg_data->regmap_config->max_register) { -+ dev_err(dev, "Invalid offset for %s 0x%x\n", -+ np->name, offset); -+ break; -+ } -+ dev_dbg(dev, "%s offset=%x a_delay = %d g_delay = %d\n", -+ np->name, vals[idx].offset, vals[idx].a_delay, -+ vals[idx].g_delay); -+ idx++; -+ } -+ -+ group->name = np->name; -+ group->np = np; -+ group->vals = vals; -+ group->nvals = idx; -+ group->config = PIN_CONFIG_END; -+ group->map = *map; -+ -+ /* Add to group list */ -+ mutex_lock(&iod->mutex); -+ list_add_tail(&group->node, &iod->groups); -+ iod->ngroups++; -+ mutex_unlock(&iod->mutex); -+ -+ (*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP; -+ (*map)->data.configs.group_or_pin = np->name; -+ (*map)->data.configs.configs = &group->config; -+ (*map)->data.configs.num_configs = 1; -+ *num_maps = 1; -+ -+ return 0; -+ -+free_group: -+ devm_kfree(dev, group); -+free_map: -+ devm_kfree(dev, *map); -+ return ret; -+} -+ -+/** -+ * ti_iodelay_dt_free_map() - Free map and resource alloted as per the map -+ * @pctldev: pinctrl device representing IODelay device -+ * @map: Map allocated by ti_iodelay_dt_node_to_map -+ * @num_maps: Num maps (1) -+ * -+ * Removes the group associated with the map and frees all resources allocated -+ * for the group. -+ */ -+static void ti_iodelay_dt_free_map(struct pinctrl_dev *pctldev, -+ struct pinctrl_map *map, unsigned num_maps) -+{ -+ struct ti_iodelay_device *iod; -+ struct device *dev; -+ struct ti_iodelay_pingroup *group; -+ bool found = false; -+ -+ if (!map) -+ return; -+ -+ iod = pinctrl_dev_get_drvdata(pctldev); -+ if (!iod) -+ return; -+ dev = iod->dev; -+ -+ mutex_lock(&iod->mutex); -+ list_for_each_entry(group, &iod->groups, node) { -+ if (group->map == map) { -+ found = true; -+ list_del(&group->node); -+ iod->ngroups--; -+ break; -+ } -+ } -+ mutex_unlock(&iod->mutex); -+ -+ /* If some freaky pinconf framework bug... */ -+ if (!found) -+ return; -+ -+ devm_kfree(dev, group->vals); -+ devm_kfree(dev, group); -+ devm_kfree(dev, map); -+} -+ -+/** -+ * ti_iodelay_pinctrl_get_groups_count() - Get number of groups registered -+ * @pctldev: pinctrl device representing IODelay device -+ * -+ * Return: number of groups mapped on the IODelay -+ */ -+static int ti_iodelay_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) -+{ -+ struct ti_iodelay_device *iod; -+ struct device *dev; -+ -+ iod = pinctrl_dev_get_drvdata(pctldev); -+ dev = iod->dev; -+ -+ return iod->ngroups; -+} -+ -+/** -+ * ti_iodelay_pinctrl_get_group_name() - Get the group name -+ * @pctldev: pinctrl device representing IODelay device -+ * @gselector: group selector -+ * -+ * Return: name of the Group given a valid gselector, else NULL. -+ */ -+static const char *ti_iodelay_pinctrl_get_group_name(struct pinctrl_dev -+ *pctldev, -+ unsigned gselector) -+{ -+ struct ti_iodelay_device *iod; -+ struct device *dev; -+ struct ti_iodelay_pingroup *group; -+ -+ iod = pinctrl_dev_get_drvdata(pctldev); -+ dev = iod->dev; -+ -+ group = ti_iodelay_get_group(iod, gselector); -+ if (!group) -+ return NULL; -+ -+ return group->name; -+} -+ -+/** -+ * ti_iodelay_pinctrl_get_group_pins() - get group pins -+ * @pctldev: pinctrl device representing IODelay device -+ * @gselector: Group selector -+ * @pins: pointer to the pins -+ * @npins: number of pins -+ * -+ * Dummy implementation since we do not track pins, we track configurations -+ * Forced by pinctrl's pinctrl_check_ops() -+ * -+ * Return: -EINVAL -+ */ -+static int ti_iodelay_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, -+ unsigned gselector, -+ const unsigned **pins, -+ unsigned *npins) -+{ -+ /* Dummy implementation - we dont do pin mux */ -+ return -EINVAL; -+} -+ -+/** -+ * ti_iodelay_pinconf_group_get() - Get the group configuration -+ * @pctldev: pinctrl device representing IODelay device -+ * @gselector: Group selector -+ * @config: configuration returned -+ * -+ * Return: The configuration if the group is valid, else returns -EINVAL -+ */ -+static int ti_iodelay_pinconf_group_get(struct pinctrl_dev *pctldev, -+ unsigned gselector, -+ unsigned long *config) -+{ -+ struct ti_iodelay_device *iod; -+ struct device *dev; -+ struct ti_iodelay_pingroup *group; -+ -+ iod = pinctrl_dev_get_drvdata(pctldev); -+ dev = iod->dev; -+ group = ti_iodelay_get_group(iod, gselector); -+ -+ if (!group) -+ return -EINVAL; -+ -+ *config = group->config; -+ return 0; -+} -+ -+/** -+ * ti_iodelay_pinconf_group_set() - Configure the groups of pins -+ * @pctldev: pinctrl device representing IODelay device -+ * @gselector: Group selector -+ * @configs: Configurations -+ * @num_configs: Number of configurations -+ * -+ * Return: 0 if all went fine, else appropriate error value. -+ */ -+static int ti_iodelay_pinconf_group_set(struct pinctrl_dev *pctldev, -+ unsigned gselector, -+ unsigned long *configs, -+ unsigned num_configs) -+{ -+ struct ti_iodelay_device *iod; -+ struct device *dev; -+ struct ti_iodelay_pingroup *group; -+ int i; -+ -+ iod = pinctrl_dev_get_drvdata(pctldev); -+ dev = iod->dev; -+ group = ti_iodelay_get_group(iod, gselector); -+ -+ if (num_configs != 1) { -+ dev_err(dev, "Unsupported number of configurations %d\n", -+ num_configs); -+ return -EINVAL; -+ } -+ -+ if (*configs != PIN_CONFIG_END) { -+ dev_err(dev, "Unsupported configuration\n"); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < group->nvals; i++) { -+ if (ti_iodelay_pinconf_set(iod, &group->vals[i])) -+ return -ENOTSUPP; -+ } -+ -+ return 0; -+} -+ -+#ifdef CONFIG_DEBUG_FS -+/** -+ * ti_iodelay_pinconf_group_dbg_show() - show the group information -+ * @pctldev: Show the group information -+ * @s: Sequence file -+ * @gselector: group selector -+ * -+ * Provide the configuration information of the selected group -+ */ -+static void ti_iodelay_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, -+ struct seq_file *s, -+ unsigned gselector) -+{ -+ struct ti_iodelay_device *iod; -+ struct device *dev; -+ struct ti_iodelay_pingroup *group; -+ int i; -+ -+ iod = pinctrl_dev_get_drvdata(pctldev); -+ dev = iod->dev; -+ group = ti_iodelay_get_group(iod, gselector); -+ if (!group) -+ return; -+ -+ for (i = 0; i < group->nvals; i++) { -+ struct ti_iodelay_conf_vals *val; -+ u32 reg = 0; -+ -+ val = &group->vals[i]; -+ regmap_read(iod->regmap, val->offset, ®), -+ seq_printf(s, "\n\t0x%08x = 0x%08x (%3d, %3d)", -+ val->offset, reg, val->a_delay, val->g_delay); -+ } -+} -+#endif -+ -+static struct pinctrl_ops ti_iodelay_pinctrl_ops = { -+ .dt_node_to_map = ti_iodelay_dt_node_to_map, -+ .dt_free_map = ti_iodelay_dt_free_map, -+ .get_groups_count = ti_iodelay_pinctrl_get_groups_count, -+ .get_group_name = ti_iodelay_pinctrl_get_group_name, -+ .get_group_pins = ti_iodelay_pinctrl_get_group_pins, -+}; -+ -+static struct pinconf_ops ti_iodelay_pinctrl_pinconf_ops = { -+ .pin_config_group_get = ti_iodelay_pinconf_group_get, -+ .pin_config_group_set = ti_iodelay_pinconf_group_set, -+#ifdef CONFIG_DEBUG_FS -+ .pin_config_group_dbg_show = ti_iodelay_pinconf_group_dbg_show, -+#endif -+}; -+ -+/** -+ * ti_iodelay_alloc_pins() - Allocate structures needed for pins for IOdelay -+ * @dev: device pointer -+ * @iod: IODelay device -+ * @base_phy: Base Physical Address -+ * -+ * Return: 0 if all went fine, else appropriate error value. -+ */ -+static int ti_iodelay_alloc_pins(struct device *dev, -+ struct ti_iodelay_device *iod, u32 base_phy) -+{ -+ const struct ti_iodelay_reg_data *r = iod->reg_data; -+ struct pinctrl_pin_desc *pin; -+ struct ti_iodelay_pin_name *pn; -+ u32 phy_reg; -+ int nr_pins, i; -+ -+ nr_pins = (r->regmap_config->max_register - r->reg_start_offset) / 4; -+ -+ dev_dbg(dev, "Allocating %i pins\n", nr_pins); -+ -+ iod->pa = devm_kzalloc(dev, sizeof(*iod->pa) * nr_pins, GFP_KERNEL); -+ if (!iod->pa) -+ return -ENOMEM; -+ -+ iod->names = -+ devm_kzalloc(dev, sizeof(struct ti_iodelay_pin_name) * nr_pins, -+ GFP_KERNEL); -+ if (!iod->names) -+ return -ENOMEM; -+ -+ iod->desc.pins = iod->pa; -+ iod->desc.npins = nr_pins; -+ -+ phy_reg = r->reg_start_offset + base_phy; -+ pn = iod->names; -+ for (i = 0; i < nr_pins; i++, pn++, phy_reg += 4) { -+ pin = &iod->pa[i]; -+ sprintf(pn->name, "%x.%d", phy_reg, i); -+ pin->number = i; -+ pin->name = pn->name; -+ } -+ -+ return 0; -+} -+ -+/** -+ * ti_iodelay_probe() - Standard probe -+ * @pdev: platform device -+ * -+ * Return: 0 if all went fine, else appropriate error value. -+ */ -+static int ti_iodelay_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = of_node_get(dev->of_node); -+ const struct of_device_id *match; -+ struct resource *res; -+ struct ti_iodelay_device *iod; -+ int ret = 0; -+ -+ if (!np) { -+ ret = -EINVAL; -+ dev_err(dev, "No OF node\n"); -+ goto exit_out; -+ } -+ -+ match = of_match_device(ti_iodelay_of_match, dev); -+ if (!match) { -+ ret = -EINVAL; -+ dev_err(dev, "No DATA match\n"); -+ goto exit_out; -+ } -+ -+ iod = devm_kzalloc(dev, sizeof(*iod), GFP_KERNEL); -+ if (!iod) { -+ ret = -ENOMEM; -+ goto exit_out; -+ } -+ iod->dev = dev; -+ iod->reg_data = match->data; -+ -+ /* So far We can assume there is only 1 bank of registers */ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(dev, "Missing MEM resource\n"); -+ ret = -ENODEV; -+ goto exit_out; -+ } -+ -+ iod->reg_base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(iod->reg_base)) { -+ ret = PTR_ERR(iod->reg_base); -+ goto exit_out; -+ } -+ -+ iod->regmap = devm_regmap_init_mmio(dev, iod->reg_base, -+ iod->reg_data->regmap_config); -+ if (IS_ERR(iod->regmap)) { -+ dev_err(dev, "Regmap MMIO init failed.\n"); -+ ret = PTR_ERR(iod->regmap); -+ goto exit_out; -+ } -+ -+ if (ti_iodelay_pinconf_init_dev(iod)) -+ goto exit_out; -+ -+ ret = ti_iodelay_alloc_pins(dev, iod, res->start); -+ if (ret) -+ goto exit_out; -+ -+ INIT_LIST_HEAD(&iod->groups); -+ mutex_init(&iod->mutex); -+ -+ iod->desc.pctlops = &ti_iodelay_pinctrl_ops; -+ /* no pinmux ops - we are pinconf */ -+ iod->desc.confops = &ti_iodelay_pinctrl_pinconf_ops; -+ iod->desc.name = dev_name(dev); -+ iod->desc.owner = THIS_MODULE; -+ -+ iod->pctl = pinctrl_register(&iod->desc, dev, iod); -+ if (!iod->pctl) { -+ dev_err(dev, "Failed to register pinctrl\n"); -+ ret = -ENODEV; -+ goto exit_out; -+ } -+ -+ platform_set_drvdata(pdev, iod); -+ -+exit_out: -+ of_node_put(np); -+ return ret; -+} -+ -+/** -+ * ti_iodelay_remove() - standard remove -+ * @pdev: platform device -+ * -+ * Return: 0 if all went fine, else appropriate error value. -+ */ -+static int ti_iodelay_remove(struct platform_device *pdev) -+{ -+ struct ti_iodelay_device *iod = platform_get_drvdata(pdev); -+ -+ if (!iod) -+ return 0; -+ if (iod->pctl) -+ pinctrl_unregister(iod->pctl); -+ -+ ti_iodelay_pinconf_deinit_dev(iod); -+ -+ /* Expect other allocations to be freed by devm */ -+ -+ return 0; -+} -+ -+static struct regmap_config dra7_iodelay_regmap_config = { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .max_register = 0xD1C, -+}; -+ -+static struct ti_iodelay_reg_data dra7_iodelay_data = { -+ .signature_mask = 0x0003F000, -+ .signature_value = 0x29, -+ .lock_mask = 0x00000400, -+ .lock_val = 1, -+ .unlock_val = 0, -+ .binary_data_coarse_mask = 0x000003E0, -+ .binary_data_fine_mask = 0x0000001F, -+ -+ .reg_refclk_offset = 0x14, -+ .refclk_period_mask = 0xFFFF, -+ -+ .reg_coarse_offset = 0x18, -+ .coarse_delay_count_mask = 0xFFFF0000, -+ .coarse_ref_count_mask = 0x0000FFFF, -+ -+ .reg_fine_offset = 0x1C, -+ .fine_delay_count_mask = 0xFFFF0000, -+ .fine_ref_count_mask = 0x0000FFFF, -+ -+ .reg_global_lock_offset = 0x2C, -+ .global_lock_mask = 0x0000FFFF, -+ .global_unlock_val = 0x0000AAAA, -+ .global_lock_val = 0x0000AAAB, -+ -+ .reg_start_offset = 0x30, -+ .regmap_config = &dra7_iodelay_regmap_config, -+}; -+ -+static const struct of_device_id ti_iodelay_of_match[] = { -+ {.compatible = "ti,dra7-iodelay", .data = &dra7_iodelay_data}, -+ { /* Hopefully no more.. */ }, -+}; -+MODULE_DEVICE_TABLE(of, ti_iodelay_of_match); -+ -+static struct platform_driver ti_iodelay_driver = { -+ .probe = ti_iodelay_probe, -+ .remove = ti_iodelay_remove, -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = DRIVER_NAME, -+ .of_match_table = ti_iodelay_of_match, -+ }, -+}; -+module_platform_driver(ti_iodelay_driver); -+ -+MODULE_AUTHOR("Texas Instruments, Inc."); -+MODULE_DESCRIPTION("Pinconf driver for TI's IO Delay module"); -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig -index 63454b5..c1bb046 100644 ---- a/drivers/power/Kconfig -+++ b/drivers/power/Kconfig -@@ -1,3 +1,4 @@ - source "drivers/power/avs/Kconfig" - source "drivers/power/reset/Kconfig" - source "drivers/power/supply/Kconfig" -+source "drivers/power/pwrseq/Kconfig" -diff --git a/drivers/power/Makefile b/drivers/power/Makefile -index ff35c71..7db8035 100644 ---- a/drivers/power/Makefile -+++ b/drivers/power/Makefile -@@ -1,3 +1,4 @@ - obj-$(CONFIG_POWER_AVS) += avs/ - obj-$(CONFIG_POWER_RESET) += reset/ - obj-$(CONFIG_POWER_SUPPLY) += supply/ -+obj-$(CONFIG_POWER_SEQUENCE) += pwrseq/ -diff --git b/drivers/power/pwrseq/Kconfig b/drivers/power/pwrseq/Kconfig -new file mode 100644 -index 0000000..3859a67 ---- /dev/null -+++ b/drivers/power/pwrseq/Kconfig -@@ -0,0 +1,19 @@ -+# -+# Power Sequence library -+# -+ -+config POWER_SEQUENCE -+ bool -+ -+menu "Power Sequence Support" -+ -+config PWRSEQ_GENERIC -+ bool "Generic power sequence control" -+ depends on OF -+ select POWER_SEQUENCE -+ help -+ It is used for drivers which needs to do power sequence -+ (eg, turn on clock, toggle reset gpio) before the related -+ devices can be found by hardware. This generic one can be -+ used for common power sequence control. -+endmenu -diff --git b/drivers/power/pwrseq/Makefile b/drivers/power/pwrseq/Makefile -new file mode 100644 -index 0000000..ad82389 ---- /dev/null -+++ b/drivers/power/pwrseq/Makefile -@@ -0,0 +1,2 @@ -+obj-$(CONFIG_POWER_SEQUENCE) += core.o -+obj-$(CONFIG_PWRSEQ_GENERIC) += pwrseq_generic.o -diff --git b/drivers/power/pwrseq/core.c b/drivers/power/pwrseq/core.c -new file mode 100644 -index 0000000..9cb1223 ---- /dev/null -+++ b/drivers/power/pwrseq/core.c -@@ -0,0 +1,191 @@ -+/* -+ * core.c power sequence core file -+ * -+ * Copyright (C) 2016 Freescale Semiconductor, Inc. -+ * Author: Peter Chen <peter.chen@nxp.com> -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 of -+ * the License as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#include <linux/list.h> -+#include <linux/mutex.h> -+#include <linux/of.h> -+#include <linux/slab.h> -+#include <linux/power/pwrseq.h> -+ -+static DEFINE_MUTEX(pwrseq_list_mutex); -+static LIST_HEAD(pwrseq_list); -+ -+int pwrseq_get(struct device_node *np, struct pwrseq *p) -+{ -+ if (p && p->get) -+ return p->get(np, p); -+ -+ return -ENOTSUPP; -+} -+EXPORT_SYMBOL_GPL(pwrseq_get); -+ -+int pwrseq_on(struct pwrseq *p) -+{ -+ if (p && p->on) -+ return p->on(p); -+ -+ return -ENOTSUPP; -+} -+EXPORT_SYMBOL_GPL(pwrseq_on); -+ -+void pwrseq_off(struct pwrseq *p) -+{ -+ if (p && p->off) -+ p->off(p); -+} -+EXPORT_SYMBOL_GPL(pwrseq_off); -+ -+void pwrseq_put(struct pwrseq *p) -+{ -+ if (p && p->put) -+ p->put(p); -+} -+EXPORT_SYMBOL_GPL(pwrseq_put); -+ -+int pwrseq_suspend(struct pwrseq *p) -+{ -+ if (p && p->suspend) -+ return p->suspend(p); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(pwrseq_suspend); -+ -+int pwrseq_resume(struct pwrseq *p) -+{ -+ if (p && p->resume) -+ return p->resume(p); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(pwrseq_resume); -+ -+void pwrseq_register(struct pwrseq *pwrseq) -+{ -+ mutex_lock(&pwrseq_list_mutex); -+ list_add(&pwrseq->node, &pwrseq_list); -+ mutex_unlock(&pwrseq_list_mutex); -+} -+EXPORT_SYMBOL_GPL(pwrseq_register); -+ -+void pwrseq_unregister(struct pwrseq *pwrseq) -+{ -+ mutex_lock(&pwrseq_list_mutex); -+ list_del(&pwrseq->node); -+ mutex_unlock(&pwrseq_list_mutex); -+} -+EXPORT_SYMBOL_GPL(pwrseq_unregister); -+ -+static struct pwrseq *pwrseq_find_available_instance(struct device_node *np) -+{ -+ struct pwrseq *pwrseq; -+ -+ list_for_each_entry(pwrseq, &pwrseq_list, node) { -+ if (pwrseq->used) -+ continue; -+ -+ /* compare compatible string for pwrseq node */ -+ if (of_match_node(pwrseq->pwrseq_of_match_table, np)) { -+ pwrseq->used = true; -+ return pwrseq; -+ } -+ -+ /* return generic pwrseq instance */ -+ if (!strcmp(pwrseq->pwrseq_of_match_table->compatible, -+ "generic")) { -+ pr_debug("using generic pwrseq instance for %s\n", -+ np->full_name); -+ pwrseq->used = true; -+ return pwrseq; -+ } -+ } -+ pr_warn("Can't find any pwrseq instances for %s\n", np->full_name); -+ -+ return NULL; -+} -+ -+struct pwrseq *of_pwrseq_on(struct device_node *np) -+{ -+ struct pwrseq *pwrseq; -+ int ret; -+ -+ pwrseq = pwrseq_find_available_instance(np); -+ if (!pwrseq) -+ return ERR_PTR(-ENONET); -+ -+ ret = pwrseq_get(np, pwrseq); -+ if (ret) { -+ /* Mark current pwrseq as unused */ -+ pwrseq->used = false; -+ return ERR_PTR(ret); -+ } -+ -+ ret = pwrseq_on(pwrseq); -+ if (ret) -+ goto pwr_put; -+ -+ return pwrseq; -+ -+pwr_put: -+ pwrseq_put(pwrseq); -+ return ERR_PTR(ret); -+} -+EXPORT_SYMBOL_GPL(of_pwrseq_on); -+ -+void of_pwrseq_off(struct pwrseq *pwrseq) -+{ -+ pwrseq_off(pwrseq); -+ pwrseq_put(pwrseq); -+} -+EXPORT_SYMBOL_GPL(of_pwrseq_off); -+ -+int of_pwrseq_on_list(struct device_node *np, struct list_head *head) -+{ -+ struct pwrseq *pwrseq; -+ struct pwrseq_list_per_dev *pwrseq_list_node; -+ -+ pwrseq = of_pwrseq_on(np); -+ if (IS_ERR(pwrseq)) -+ return PTR_ERR(pwrseq); -+ -+ pwrseq_list_node = kzalloc(sizeof(*pwrseq_list_node), GFP_KERNEL); -+ if (!pwrseq_list_node) { -+ of_pwrseq_off(pwrseq); -+ return -ENOMEM; -+ } -+ pwrseq_list_node->pwrseq = pwrseq; -+ list_add(&pwrseq_list_node->list, head); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(of_pwrseq_on_list); -+ -+void of_pwrseq_off_list(struct list_head *head) -+{ -+ struct pwrseq *pwrseq; -+ struct pwrseq_list_per_dev *pwrseq_list_node, *tmp_node; -+ -+ list_for_each_entry_safe(pwrseq_list_node, tmp_node, head, list) { -+ pwrseq = pwrseq_list_node->pwrseq; -+ of_pwrseq_off(pwrseq); -+ list_del(&pwrseq_list_node->list); -+ kfree(pwrseq_list_node); -+ } -+} -+EXPORT_SYMBOL_GPL(of_pwrseq_off_list); -diff --git b/drivers/power/pwrseq/pwrseq_generic.c b/drivers/power/pwrseq/pwrseq_generic.c -new file mode 100644 -index 0000000..d7a77f2 ---- /dev/null -+++ b/drivers/power/pwrseq/pwrseq_generic.c -@@ -0,0 +1,183 @@ -+/* -+ * pwrseq_generic.c Generic power sequence handling -+ * -+ * Copyright (C) 2016 Freescale Semiconductor, Inc. -+ * Author: Peter Chen <peter.chen@nxp.com> -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 of -+ * the License as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#include <linux/clk.h> -+#include <linux/delay.h> -+#include <linux/gpio.h> -+#include <linux/gpio/consumer.h> -+#include <linux/of.h> -+#include <linux/of_gpio.h> -+#include <linux/slab.h> -+ -+#include <linux/power/pwrseq.h> -+ -+struct pwrseq_generic { -+ struct pwrseq pwrseq; -+ struct gpio_desc *gpiod_reset; -+ struct clk *clks[PWRSEQ_MAX_CLKS]; -+ u32 duration_us; -+}; -+ -+#define to_generic_pwrseq(p) container_of(p, struct pwrseq_generic, pwrseq) -+ -+static int pwrseq_generic_alloc_instance(void); -+static const struct of_device_id generic_id_table[] = { -+ { .compatible = "generic",}, -+ { /* sentinel */ } -+}; -+ -+static void pwrseq_generic_put(struct pwrseq *pwrseq) -+{ -+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq); -+ int clk; -+ -+ if (pwrseq_gen->gpiod_reset) -+ gpiod_put(pwrseq_gen->gpiod_reset); -+ -+ for (clk = 0; clk < PWRSEQ_MAX_CLKS; clk++) -+ clk_put(pwrseq_gen->clks[clk]); -+ -+ pwrseq_unregister(&pwrseq_gen->pwrseq); -+ kfree(pwrseq_gen); -+} -+ -+static void pwrseq_generic_off(struct pwrseq *pwrseq) -+{ -+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq); -+ int clk; -+ -+ for (clk = PWRSEQ_MAX_CLKS - 1; clk >= 0; clk--) -+ clk_disable_unprepare(pwrseq_gen->clks[clk]); -+} -+ -+static int pwrseq_generic_on(struct pwrseq *pwrseq) -+{ -+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq); -+ int clk, ret = 0; -+ struct gpio_desc *gpiod_reset = pwrseq_gen->gpiod_reset; -+ -+ for (clk = 0; clk < PWRSEQ_MAX_CLKS && pwrseq_gen->clks[clk]; clk++) { -+ ret = clk_prepare_enable(pwrseq_gen->clks[clk]); -+ if (ret) { -+ pr_err("Can't enable clock, ret=%d\n", ret); -+ goto err_disable_clks; -+ } -+ } -+ -+ if (gpiod_reset) { -+ u32 duration_us = pwrseq_gen->duration_us; -+ -+ if (duration_us <= 10) -+ udelay(10); -+ else -+ usleep_range(duration_us, duration_us + 100); -+ gpiod_set_value(gpiod_reset, 0); -+ } -+ -+ return ret; -+ -+err_disable_clks: -+ while (--clk >= 0) -+ clk_disable_unprepare(pwrseq_gen->clks[clk]); -+ -+ return ret; -+} -+ -+static int pwrseq_generic_get(struct device_node *np, struct pwrseq *pwrseq) -+{ -+ struct pwrseq_generic *pwrseq_gen = to_generic_pwrseq(pwrseq); -+ enum of_gpio_flags flags; -+ int reset_gpio, clk, ret = 0; -+ -+ for (clk = 0; clk < PWRSEQ_MAX_CLKS; clk++) { -+ pwrseq_gen->clks[clk] = of_clk_get(np, clk); -+ if (IS_ERR(pwrseq_gen->clks[clk])) { -+ ret = PTR_ERR(pwrseq_gen->clks[clk]); -+ if (ret != -ENOENT) -+ goto err_put_clks; -+ pwrseq_gen->clks[clk] = NULL; -+ break; -+ } -+ } -+ -+ reset_gpio = of_get_named_gpio_flags(np, "reset-gpios", 0, &flags); -+ if (gpio_is_valid(reset_gpio)) { -+ unsigned long gpio_flags; -+ -+ if (flags & OF_GPIO_ACTIVE_LOW) -+ gpio_flags = GPIOF_ACTIVE_LOW | GPIOF_OUT_INIT_LOW; -+ else -+ gpio_flags = GPIOF_OUT_INIT_HIGH; -+ -+ ret = gpio_request_one(reset_gpio, gpio_flags, -+ "pwrseq-reset-gpios"); -+ if (ret) -+ goto err_put_clks; -+ -+ pwrseq_gen->gpiod_reset = gpio_to_desc(reset_gpio); -+ of_property_read_u32(np, "reset-duration-us", -+ &pwrseq_gen->duration_us); -+ } else if (reset_gpio == -ENOENT) { -+ ; /* no such gpio */ -+ } else { -+ ret = reset_gpio; -+ pr_err("Failed to get reset gpio on %s, err = %d\n", -+ np->full_name, reset_gpio); -+ goto err_put_clks; -+ } -+ -+ /* allocate new one for later pwrseq instance request */ -+ ret = pwrseq_generic_alloc_instance(); -+ if (ret) -+ goto err_put_gpio; -+ -+ return 0; -+ -+err_put_gpio: -+ if (pwrseq_gen->gpiod_reset) -+ gpiod_put(pwrseq_gen->gpiod_reset); -+err_put_clks: -+ while (--clk >= 0) -+ clk_put(pwrseq_gen->clks[clk]); -+ return ret; -+} -+ -+static int pwrseq_generic_alloc_instance(void) -+{ -+ struct pwrseq_generic *pwrseq_gen; -+ -+ pwrseq_gen = kzalloc(sizeof(*pwrseq_gen), GFP_KERNEL); -+ if (!pwrseq_gen) -+ return -ENOMEM; -+ -+ pwrseq_gen->pwrseq.pwrseq_of_match_table = generic_id_table; -+ pwrseq_gen->pwrseq.get = pwrseq_generic_get; -+ pwrseq_gen->pwrseq.on = pwrseq_generic_on; -+ pwrseq_gen->pwrseq.off = pwrseq_generic_off; -+ pwrseq_gen->pwrseq.put = pwrseq_generic_put; -+ -+ pwrseq_register(&pwrseq_gen->pwrseq); -+ return 0; -+} -+ -+static int __init pwrseq_generic_register(void) -+{ -+ return pwrseq_generic_alloc_instance(); -+} -+postcore_initcall(pwrseq_generic_register) -diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c -index 2e05046..3c6dfad 100644 ---- a/drivers/spi/spidev.c -+++ b/drivers/spi/spidev.c -@@ -751,11 +751,11 @@ static int spidev_probe(struct spi_device *spi) - * compatible string, it is a Linux implementation thing - * rather than a description of the hardware. - */ -- if (spi->dev.of_node && !of_match_device(spidev_dt_ids, &spi->dev)) { -- dev_err(&spi->dev, "buggy DT: spidev listed directly in DT\n"); -- WARN_ON(spi->dev.of_node && -- !of_match_device(spidev_dt_ids, &spi->dev)); -- } -+// if (spi->dev.of_node && !of_match_device(spidev_dt_ids, &spi->dev)) { -+// dev_err(&spi->dev, "buggy DT: spidev listed directly in DT\n"); -+// WARN_ON(spi->dev.of_node && -+// !of_match_device(spidev_dt_ids, &spi->dev)); -+// } - - spidev_probe_acpi(spi); - -diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c -index da31159..2c2d09c 100644 ---- a/drivers/tty/serial/8250/8250_omap.c -+++ b/drivers/tty/serial/8250/8250_omap.c -@@ -1437,10 +1437,10 @@ static int __init omap8250_console_fixup(void) - } - - add_preferred_console("ttyS", idx, options); -- pr_err("WARNING: Your 'console=ttyO%d' has been replaced by 'ttyS%d'\n", -+ pr_info("WARNING: Your 'console=ttyO%d' has been replaced by 'ttyS%d'\n", - idx, idx); -- pr_err("This ensures that you still see kernel messages. Please\n"); -- pr_err("update your kernel commandline.\n"); -+ pr_info("This ensures that you still see kernel messages. Please\n"); -+ pr_info("update your kernel commandline.\n"); - return 0; - } - console_initcall(omap8250_console_fixup); -diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c -index 44e5b5b..2914903 100644 ---- a/drivers/tty/serial/omap-serial.c -+++ b/drivers/tty/serial/omap-serial.c -@@ -1595,6 +1595,31 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up, - return 0; - } - -+static int serial_omap_of_get_port_line(struct device_node *np) -+{ -+ unsigned long val; -+ const char *hwmod; -+ int ret; -+ -+ /* first try the serial alias */ -+ ret = of_alias_get_id(np, "serial"); -+ if (ret >= 0) -+ return ret; -+ -+ /* no? calculate it from hwmods */ -+ ret = of_property_read_string(np, "ti,hwmods", &hwmod); -+ if (ret != 0 || strncmp(hwmod, "uart", 4) || -+ kstrtoul(hwmod + 4, 10, &val)) -+ return -ENODEV; -+ -+ /* numbering of hwmods is +1 */ -+ ret = (int)val - 1; -+ if (ret < 0) -+ return -ENODEV; -+ -+ return ret; -+} -+ - static int serial_omap_probe(struct platform_device *pdev) - { - struct omap_uart_port_info *omap_up_info = dev_get_platdata(&pdev->dev); -@@ -1612,7 +1637,10 @@ static int serial_omap_probe(struct platform_device *pdev) - return -EPROBE_DEFER; - wakeirq = irq_of_parse_and_map(pdev->dev.of_node, 1); - omap_up_info = of_get_uart_port_info(&pdev->dev); -- pdev->dev.platform_data = omap_up_info; -+ ret = platform_device_add_data(pdev, omap_up_info, -+ sizeof(*omap_up_info)); -+ if (ret != 0) -+ return ret; - } else { - uartirq = platform_get_irq(pdev, 0); - if (uartirq < 0) -@@ -1638,7 +1666,7 @@ static int serial_omap_probe(struct platform_device *pdev) - up->port.ops = &serial_omap_pops; - - if (pdev->dev.of_node) -- ret = of_alias_get_id(pdev->dev.of_node, "serial"); -+ ret = serial_omap_of_get_port_line(pdev->dev.of_node); - else - ret = pdev->id; - -diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig -index 52c98ce..05400bc 100644 ---- a/drivers/uio/Kconfig -+++ b/drivers/uio/Kconfig -@@ -129,7 +129,7 @@ config UIO_PRUSS - select GENERIC_ALLOCATOR - depends on HAS_IOMEM && HAS_DMA - help -- PRUSS driver for OMAPL138/DA850/AM18XX devices -+ PRUSS driver for OMAPL138/DA850/AM18XX and AM33XX devices - PRUSS driver requires user space components, examples and user space - driver is available from below SVN repo - you may use anonymous login - -diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c -index ca9e2fa..6559752 100644 ---- a/drivers/uio/uio_pruss.c -+++ b/drivers/uio/uio_pruss.c -@@ -19,6 +19,7 @@ - #include <linux/module.h> - #include <linux/moduleparam.h> - #include <linux/platform_device.h> -+#include <linux/of_gpio.h> - #include <linux/uio_driver.h> - #include <linux/platform_data/uio_pruss.h> - #include <linux/io.h> -@@ -27,6 +28,11 @@ - #include <linux/sizes.h> - #include <linux/slab.h> - #include <linux/genalloc.h> -+#include <linux/of_address.h> -+#include <linux/of_device.h> -+#include <linux/pinctrl/consumer.h> -+#include <linux/err.h> -+#include <linux/pm_runtime.h> - - #define DRV_NAME "pruss_uio" - #define DRV_VERSION "1.0" -@@ -106,10 +112,12 @@ static void pruss_cleanup(struct device *dev, struct uio_pruss_dev *gdev) - dma_free_coherent(dev, extram_pool_sz, gdev->ddr_vaddr, - gdev->ddr_paddr); - } -+#ifdef CONFIG_ARCH_DAVINCI_DA850 - if (gdev->sram_vaddr) - gen_pool_free(gdev->sram_pool, - gdev->sram_vaddr, - sram_pool_sz); -+#endif - kfree(gdev->info); - clk_put(gdev->pruss_clk); - kfree(gdev); -@@ -120,9 +128,15 @@ static int pruss_probe(struct platform_device *pdev) - struct uio_info *p; - struct uio_pruss_dev *gdev; - struct resource *regs_prussio; -+ struct resource res; - struct device *dev = &pdev->dev; - int ret = -ENODEV, cnt = 0, len; - struct uio_pruss_pdata *pdata = dev_get_platdata(dev); -+ struct pinctrl *pinctrl; -+ -+ int count; -+ struct device_node *child; -+ const char *pin_name; - - gdev = kzalloc(sizeof(struct uio_pruss_dev), GFP_KERNEL); - if (!gdev) -@@ -133,7 +147,7 @@ static int pruss_probe(struct platform_device *pdev) - kfree(gdev); - return -ENOMEM; - } -- -+#ifdef CONFIG_ARCH_DAVINCI_DA850 - /* Power on PRU in case its not done as part of boot-loader */ - gdev->pruss_clk = clk_get(dev, "pruss"); - if (IS_ERR(gdev->pruss_clk)) { -@@ -145,8 +159,25 @@ static int pruss_probe(struct platform_device *pdev) - } else { - clk_enable(gdev->pruss_clk); - } -+#endif -+ -+ if (pdev->dev.of_node) { -+ pm_runtime_enable(&pdev->dev); -+ ret = pm_runtime_get_sync(&pdev->dev); -+ if (IS_ERR_VALUE(ret)) { -+ dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); -+ return ret; -+ } - -- regs_prussio = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ ret = of_address_to_resource(pdev->dev.of_node, 0, &res); -+ if (IS_ERR_VALUE(ret)) { -+ dev_err(&pdev->dev, "failed to parse DT reg\n"); -+ return ret; -+ } -+ regs_prussio = &res; -+ } -+ else -+ regs_prussio = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs_prussio) { - dev_err(dev, "No PRUSS I/O resource specified\n"); - goto out_free; -@@ -157,7 +188,50 @@ static int pruss_probe(struct platform_device *pdev) - goto out_free; - } - -- if (pdata->sram_pool) { -+ -+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev); -+ if (IS_ERR(pinctrl)) -+ dev_warn(&pdev->dev, -+ "pins are not configured from the driver\n"); -+ else{ -+ count = of_get_child_count(pdev->dev.of_node); -+ if (!count){ -+ dev_info(&pdev->dev, "No children\n"); -+ return -ENODEV; -+ } -+ // Run through all children. They have lables for easy reference. -+ for_each_child_of_node(pdev->dev.of_node, child){ -+ enum of_gpio_flags flags; -+ unsigned gpio; -+ -+ count = of_gpio_count(child); -+ -+ ret = of_property_count_strings(child, "pin-names"); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "Failed to get pin-names\n"); -+ continue; -+ } -+ if(count != ret){ -+ dev_err(&pdev->dev, "The number of gpios (%d) does not match"\ -+ " the number of pin names (%d)\n", count, ret); -+ continue; -+ } -+ -+ for(cnt=0; cnt<count; cnt++){ -+ ret = of_property_read_string_index(child, -+ "pin-names", cnt, &pin_name); -+ if (ret != 0) -+ dev_err(&pdev->dev, "Error on pin-name #%d\n", cnt); -+ gpio = of_get_gpio_flags(child, cnt, &flags); -+ ret = devm_gpio_request_one(&pdev->dev, gpio, flags, pin_name); -+ if (ret < 0) { -+ dev_err(dev, "Failed to request GPIO %d (%s) flags: '%d', error %d\n", -+ gpio, pin_name, flags, ret); -+ } -+ } -+ } -+ } -+ if (pdata && pdata->sram_pool) { - gdev->sram_pool = pdata->sram_pool; - gdev->sram_vaddr = - (unsigned long)gen_pool_dma_alloc(gdev->sram_pool, -@@ -182,7 +256,17 @@ static int pruss_probe(struct platform_device *pdev) - goto out_free; - } - -- gdev->pintc_base = pdata->pintc_base; -+ if (pdev->dev.of_node) { -+ ret = of_property_read_u32(pdev->dev.of_node, -+ "ti,pintc-offset", -+ &gdev->pintc_base); -+ if (ret < 0) { -+ dev_err(&pdev->dev, -+ "Can't parse ti,pintc-offset property\n"); -+ goto out_free; -+ } -+ } else -+ gdev->pintc_base = pdata->pintc_base; - gdev->hostirq_start = platform_get_irq(pdev, 0); - - for (cnt = 0, p = gdev->info; cnt < MAX_PRUSS_EVT; cnt++, p++) { -@@ -190,6 +274,7 @@ static int pruss_probe(struct platform_device *pdev) - p->mem[0].size = resource_size(regs_prussio); - p->mem[0].memtype = UIO_MEM_PHYS; - -+#ifdef CONFIG_ARCH_DAVINCI_DA850 - p->mem[1].addr = gdev->sram_paddr; - p->mem[1].size = sram_pool_sz; - p->mem[1].memtype = UIO_MEM_PHYS; -@@ -197,7 +282,11 @@ static int pruss_probe(struct platform_device *pdev) - p->mem[2].addr = gdev->ddr_paddr; - p->mem[2].size = extram_pool_sz; - p->mem[2].memtype = UIO_MEM_PHYS; -- -+#else -+ p->mem[1].addr = gdev->ddr_paddr; -+ p->mem[1].size = extram_pool_sz; -+ p->mem[1].memtype = UIO_MEM_PHYS; -+#endif - p->name = kasprintf(GFP_KERNEL, "pruss_evt%d", cnt); - p->version = DRV_VERSION; - -@@ -227,11 +316,20 @@ static int pruss_remove(struct platform_device *dev) - return 0; - } - -+static const struct of_device_id pruss_dt_ids[] = { -+ { .compatible = "ti,pruss-v1", .data = NULL, }, -+ { .compatible = "ti,pruss-v2", .data = NULL, }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, pruss_dt_ids); -+ -+ - static struct platform_driver pruss_driver = { - .probe = pruss_probe, - .remove = pruss_remove, - .driver = { - .name = DRV_NAME, -+ .of_match_table = pruss_dt_ids, - }, - }; - -diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c -index 6e0d614..17e69cb 100644 ---- a/drivers/usb/chipidea/core.c -+++ b/drivers/usb/chipidea/core.c -@@ -896,6 +896,16 @@ static int ci_hdrc_probe(struct platform_device *pdev) - return -ENODEV; - } - -+ /* -+ * At device tree, we have no device node for chipidea core, -+ * the glue layer's node is the parent node for host and udc -+ * device. But in related driver, the parent device is chipidea -+ * core. So, in order to let the common driver get parent's node, -+ * we let the core's device node equals glue layer's node. -+ */ -+ if (dev->parent && dev->parent->of_node) -+ dev->of_node = dev->parent->of_node; -+ - if (ci->platdata->phy) { - ci->phy = ci->platdata->phy; - } else if (ci->platdata->usb_phy) { -@@ -906,11 +916,15 @@ static int ci_hdrc_probe(struct platform_device *pdev) - - /* if both generic PHY and USB PHY layers aren't enabled */ - if (PTR_ERR(ci->phy) == -ENOSYS && -- PTR_ERR(ci->usb_phy) == -ENXIO) -- return -ENXIO; -+ PTR_ERR(ci->usb_phy) == -ENXIO) { -+ ret = -ENXIO; -+ goto clear_of_node; -+ } - -- if (IS_ERR(ci->phy) && IS_ERR(ci->usb_phy)) -- return -EPROBE_DEFER; -+ if (IS_ERR(ci->phy) && IS_ERR(ci->usb_phy)) { -+ ret = -EPROBE_DEFER; -+ goto clear_of_node; -+ } - - if (IS_ERR(ci->phy)) - ci->phy = NULL; -@@ -921,7 +935,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) - ret = ci_usb_phy_init(ci); - if (ret) { - dev_err(dev, "unable to init phy: %d\n", ret); -- return ret; -+ goto clear_of_node; - } - - ci->hw_bank.phys = res->start; -@@ -1027,6 +1041,8 @@ static int ci_hdrc_probe(struct platform_device *pdev) - ci_role_destroy(ci); - deinit_phy: - ci_usb_phy_exit(ci); -+clear_of_node: -+ dev->of_node = NULL; - - return ret; - } -@@ -1045,6 +1061,7 @@ static int ci_hdrc_remove(struct platform_device *pdev) - ci_extcon_unregister(ci); - ci_role_destroy(ci); - ci_hdrc_enter_lpm(ci, true); -+ ci->dev->of_node = NULL; - ci_usb_phy_exit(ci); - - return 0; -diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index 706b3d6..6fe5665 100644 ---- a/drivers/usb/core/hub.c -+++ b/drivers/usb/core/hub.c -@@ -26,6 +26,7 @@ - #include <linux/mutex.h> - #include <linux/random.h> - #include <linux/pm_qos.h> -+#include <linux/power/pwrseq.h> - - #include <asm/uaccess.h> - #include <asm/byteorder.h> -@@ -1632,6 +1633,7 @@ static void hub_disconnect(struct usb_interface *intf) - hub->error = 0; - hub_quiesce(hub, HUB_DISCONNECT); - -+ of_pwrseq_off_list(&hub->pwrseq_on_list); - mutex_lock(&usb_port_peer_mutex); - - /* Avoid races with recursively_mark_NOTATTACHED() */ -@@ -1659,12 +1661,41 @@ static void hub_disconnect(struct usb_interface *intf) - kref_put(&hub->kref, hub_release); - } - -+#ifdef CONFIG_OF -+static int hub_of_pwrseq_on(struct usb_hub *hub) -+{ -+ struct device *parent; -+ struct usb_device *hdev = hub->hdev; -+ struct device_node *np; -+ int ret; -+ -+ if (hdev->parent) -+ parent = &hdev->dev; -+ else -+ parent = bus_to_hcd(hdev->bus)->self.controller; -+ -+ for_each_child_of_node(parent->of_node, np) { -+ ret = of_pwrseq_on_list(np, &hub->pwrseq_on_list); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+#else -+static int hub_of_pwrseq_on(struct usb_hub *hub) -+{ -+ return 0; -+} -+#endif -+ - static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) - { - struct usb_host_interface *desc; - struct usb_endpoint_descriptor *endpoint; - struct usb_device *hdev; - struct usb_hub *hub; -+ int ret = -ENODEV; - - desc = intf->cur_altsetting; - hdev = interface_to_usbdev(intf); -@@ -1769,6 +1800,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) - INIT_DELAYED_WORK(&hub->leds, led_work); - INIT_DELAYED_WORK(&hub->init_work, NULL); - INIT_WORK(&hub->events, hub_event); -+ INIT_LIST_HEAD(&hub->pwrseq_on_list); - usb_get_intf(intf); - usb_get_dev(hdev); - -@@ -1782,11 +1814,14 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) - if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND) - hub->quirk_check_port_auto_suspend = 1; - -- if (hub_configure(hub, endpoint) >= 0) -- return 0; -+ if (hub_configure(hub, endpoint) >= 0) { -+ ret = hub_of_pwrseq_on(hub); -+ if (!ret) -+ return 0; -+ } - - hub_disconnect(intf); -- return -ENODEV; -+ return ret; - } - - static int -diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h -index 34c1a7e..cd86f91 100644 ---- a/drivers/usb/core/hub.h -+++ b/drivers/usb/core/hub.h -@@ -78,6 +78,7 @@ struct usb_hub { - struct delayed_work init_work; - struct work_struct events; - struct usb_port **ports; -+ struct list_head pwrseq_on_list; /* powered pwrseq node list */ - }; - - /** -diff --git a/firmware/am335x-bone-scale-data.bin b/firmware/am335x-bone-scale-data.bin -new file mode 100644 -index 0000000000000000000000000000000000000000..1ce3c1c596d7a7f400b0cc89bda5a41eed2780c5 -GIT binary patch -literal 73 -pcmd-HXHZUIU{c}EWl|AfLZWk+R0P|Ad@#)bSHb~R0-{lr003gr3L5|b - -literal 0 -HcmV?d00001 - -diff --git a/firmware/am335x-evm-scale-data.bin b/firmware/am335x-evm-scale-data.bin -new file mode 100644 -index 0000000000000000000000000000000000000000..a222389d233fa8f1c76ef35470b57284999c8df5 -GIT binary patch -literal 17 -Ucmd-HXJAiZVA55UX8=>$024d{B>(^b - -literal 0 -HcmV?d00001 - -diff --git a/firmware/am43x-evm-scale-data.bin b/firmware/am43x-evm-scale-data.bin -new file mode 100644 -index 0000000000000000000000000000000000000000..2d71341089816be7989e6dc11b265d9194ac909e -GIT binary patch -literal 41 -hcmd-HXAn+dU{VptW>OLB0@CSBDpG9>aG{wnApnMi2I2q! - -literal 0 -HcmV?d00001 - -diff --git b/include/dt-bindings/board/am335x-bbw-bbb-base.h b/include/dt-bindings/board/am335x-bbw-bbb-base.h -new file mode 100644 -index 0000000..35f6d57 ---- /dev/null -+++ b/include/dt-bindings/board/am335x-bbw-bbb-base.h -@@ -0,0 +1,103 @@ -+/* -+ * This header provides constants for bbw/bbb pinctrl bindings. -+ * -+ * Copyright (C) 2014 Robert Nelson <robertcnelson@gmail.com> -+ * -+ * Numbers Based on: https://github.com/derekmolloy/boneDeviceTree/tree/master/docs -+ */ -+ -+#ifndef _DT_BINDINGS_BOARD_AM335X_BBW_BBB_BASE_H -+#define _DT_BINDINGS_BOARD_AM335X_BBW_BBB_BASE_H -+ -+#define BONE_P8_03 0x018 -+#define BONE_P8_04 0x01C -+ -+#define BONE_P8_05 0x008 -+#define BONE_P8_06 0x00C -+#define BONE_P8_07 0x090 -+#define BONE_P8_08 0x094 -+ -+#define BONE_P8_09 0x09C -+#define BONE_P8_10 0x098 -+#define BONE_P8_11 0x034 -+#define BONE_P8_12 0x030 -+ -+#define BONE_P8_13 0x024 -+#define BONE_P8_14 0x028 -+#define BONE_P8_15 0x03C -+#define BONE_P8_16 0x038 -+ -+#define BONE_P8_17 0x02C -+#define BONE_P8_18 0x08C -+#define BONE_P8_19 0x020 -+#define BONE_P8_20 0x084 -+ -+#define BONE_P8_21 0x080 -+#define BONE_P8_22 0x014 -+#define BONE_P8_23 0x010 -+#define BONE_P8_24 0x004 -+ -+#define BONE_P8_25 0x000 -+#define BONE_P8_26 0x07C -+#define BONE_P8_27 0x0E0 -+#define BONE_P8_28 0x0E8 -+ -+#define BONE_P8_29 0x0E4 -+#define BONE_P8_30 0x0EC -+#define BONE_P8_31 0x0D8 -+#define BONE_P8_32 0x0DC -+ -+#define BONE_P8_33 0x0D4 -+#define BONE_P8_34 0x0CC -+#define BONE_P8_35 0x0D0 -+#define BONE_P8_36 0x0C8 -+ -+#define BONE_P8_37 0x0C0 -+#define BONE_P8_38 0x0C4 -+#define BONE_P8_39 0x0B8 -+#define BONE_P8_40 0x0BC -+ -+#define BONE_P8_41 0x0B0 -+#define BONE_P8_42 0x0B4 -+#define BONE_P8_43 0x0A8 -+#define BONE_P8_44 0x0AC -+ -+#define BONE_P8_45 0x0A0 -+#define BONE_P8_46 0x0A4 -+ -+#define BONE_P9_11 0x070 -+#define BONE_P9_12 0x078 -+ -+#define BONE_P9_13 0x074 -+#define BONE_P9_14 0x048 -+#define BONE_P9_15 0x040 -+#define BONE_P9_16 0x04C -+ -+#define BONE_P9_17 0x15C -+#define BONE_P9_18 0x158 -+#define BONE_P9_19 0x17C -+#define BONE_P9_20 0x178 -+ -+#define BONE_P9_21 0x154 -+#define BONE_P9_22 0x150 -+#define BONE_P9_23 0x044 -+#define BONE_P9_24 0x184 -+ -+#define BONE_P9_25 0x1AC -+#define BONE_P9_26 0x180 -+#define BONE_P9_27 0x1A4 -+#define BONE_P9_28 0x19C -+ -+#define BONE_P9_29 0x194 -+#define BONE_P9_30 0x198 -+#define BONE_P9_31 0x190 -+ -+/* Shared P21 of P11 */ -+#define BONE_P9_41A 0x1B4 -+#define BONE_P9_41B 0x1A8 -+ -+/* Shared P22 of P11 */ -+#define BONE_P9_42A 0x164 -+#define BONE_P9_42B 0x1A0 -+ -+#endif -diff --git b/include/dt-bindings/mfd/tps65217.h b/include/dt-bindings/mfd/tps65217.h -new file mode 100644 -index 0000000..cafb9e6 ---- /dev/null -+++ b/include/dt-bindings/mfd/tps65217.h -@@ -0,0 +1,26 @@ -+/* -+ * This header provides macros for TI TPS65217 DT bindings. -+ * -+ * Copyright (C) 2016 Texas Instruments -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef __DT_BINDINGS_TPS65217_H__ -+#define __DT_BINDINGS_TPS65217_H__ -+ -+#define TPS65217_IRQ_USB 0 -+#define TPS65217_IRQ_AC 1 -+#define TPS65217_IRQ_PB 2 -+ -+#endif -diff --git a/include/dt-bindings/pinctrl/dra.h b/include/dt-bindings/pinctrl/dra.h -index 5c75e80..5a60e3b 100644 ---- a/include/dt-bindings/pinctrl/dra.h -+++ b/include/dt-bindings/pinctrl/dra.h -@@ -50,6 +50,8 @@ - - #define MODE_SELECT (1 << 8) - -+#define MANUAL_MODE MODE_SELECT -+ - #define PULL_ENA (0 << 16) - #define PULL_DIS (1 << 16) - #define PULL_UP (1 << 17) -@@ -73,5 +75,9 @@ - */ - #define DRA7XX_CORE_IOPAD(pa, val) (((pa) & 0xffff) - 0x3400) (val) - -+/* DRA7 IODELAY configuration parameters */ -+#define A_DELAY(val) ((val) & 0xFFFF) -+#define G_DELAY(val) (((val) & 0xFFFF) << 16) -+ - #endif - -diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h -index 4ccda89..3cbec4b 100644 ---- a/include/linux/mfd/tps65217.h -+++ b/include/linux/mfd/tps65217.h -@@ -234,12 +234,11 @@ struct tps65217_bl_pdata { - int dft_brightness; - }; - --enum tps65217_irq_type { -- TPS65217_IRQ_PB, -- TPS65217_IRQ_AC, -- TPS65217_IRQ_USB, -- TPS65217_NUM_IRQ --}; -+/* Interrupt numbers */ -+#define TPS65217_IRQ_USB 0 -+#define TPS65217_IRQ_AC 1 -+#define TPS65217_IRQ_PB 2 -+#define TPS65217_NUM_IRQ 3 - - /** - * struct tps65217_board - packages regulator init data -diff --git a/include/linux/of.h b/include/linux/of.h -index 299aeb1..725bd28 100644 ---- a/include/linux/of.h -+++ b/include/linux/of.h -@@ -23,8 +23,10 @@ - #include <linux/spinlock.h> - #include <linux/topology.h> - #include <linux/notifier.h> -+#include <linux/slab.h> - #include <linux/property.h> - #include <linux/list.h> -+#include <linux/rhashtable.h> - - #include <asm/byteorder.h> - #include <asm/errno.h> -@@ -52,6 +54,7 @@ struct device_node { - phandle phandle; - const char *full_name; - struct fwnode_handle fwnode; -+ struct rhash_head ht_node; - - struct property *properties; - struct property *deadprops; /* removed properties */ -@@ -1184,6 +1187,8 @@ enum of_reconfig_change { - }; - - #ifdef CONFIG_OF_DYNAMIC -+#include <linux/slab.h> -+ - extern int of_reconfig_notifier_register(struct notifier_block *); - extern int of_reconfig_notifier_unregister(struct notifier_block *); - extern int of_reconfig_notify(unsigned long, struct of_reconfig_data *rd); -@@ -1227,6 +1232,26 @@ static inline int of_changeset_update_property(struct of_changeset *ocs, - { - return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop); - } -+ -+struct device_node *of_changeset_create_device_nodev( -+ struct of_changeset *ocs, struct device_node *parent, -+ const char *fmt, va_list vargs); -+ -+__printf(3, 4) struct device_node * -+of_changeset_create_device_node(struct of_changeset *ocs, -+ struct device_node *parent, const char *fmt, ...); -+ -+int __of_changeset_add_update_property_copy(struct of_changeset *ocs, -+ struct device_node *np, const char *name, const void *value, -+ int length, bool update); -+ -+int __of_changeset_add_update_property_string_list( -+ struct of_changeset *ocs, struct device_node *np, -+ const char *name, const char **strs, int count, bool update); -+ -+int of_changeset_node_move(struct of_changeset *ocs, -+ struct device_node *np, struct device_node *new_parent); -+ - #else /* CONFIG_OF_DYNAMIC */ - static inline int of_reconfig_notifier_register(struct notifier_block *nb) - { -@@ -1246,8 +1271,323 @@ static inline int of_reconfig_get_state_change(unsigned long action, - { - return -EINVAL; - } -+ -+static inline struct device_node *of_changeset_create_device_nodev( -+ struct of_changeset *ocs, struct device_node *parent, -+ const char *fmt, va_list vargs) -+{ -+ return ERR_PTR(-EINVAL); -+} -+ -+static inline __printf(3, 4) struct device_node * -+of_changeset_create_device_node(struct of_changeset *ocs, -+ struct device_node *parent, const char *fmt, ...) -+{ -+ return ERR_PTR(-EINVAL); -+} -+ -+static inline int __of_changeset_add_update_property_copy( -+ struct of_changeset *ocs, struct device_node *np, -+ const char *name, const void *value, int length, bool update) -+{ -+ return -EINVAL; -+} -+ -+static inline __printf(4, 5) int of_changeset_add_property_stringf( -+ struct of_changeset *ocs, struct device_node *np, -+ const char *name, const char *fmt, ...) -+{ -+ return -EINVAL; -+} -+ -+static inline int of_changeset_update_property_stringf( -+ struct of_changeset *ocs, struct device_node *np, -+ const char *name, const char *fmt, ...) -+{ -+ return -EINVAL; -+} -+ -+static inline int __of_changeset_add_update_property_string_list( -+ struct of_changeset *ocs, struct device_node *np, -+ const char *name, const char **strs, int count, bool update) -+{ -+ return -EINVAL; -+} -+ -+static inline int of_changeset_node_move(struct of_changeset *ocs, -+ struct device_node *np, struct device_node *new_parent) -+{ -+ return -EINVAL; -+} -+ - #endif /* CONFIG_OF_DYNAMIC */ - -+/** -+ * of_changeset_add_property_copy - Create a new property copying name & value -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @value: pointer to the value data -+ * @length: length of the value in bytes -+ * -+ * Adds a property to the changeset by making copies of the name & value -+ * entries. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+static inline int of_changeset_add_property_copy(struct of_changeset *ocs, -+ struct device_node *np, const char *name, -+ const void *value, int length) -+{ -+ return __of_changeset_add_update_property_copy(ocs, np, name, value, -+ length, false); -+} -+ -+/** -+ * of_changeset_update_property_copy - Update a property copying name & value -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @value: pointer to the value data -+ * @length: length of the value in bytes -+ * -+ * Update a property to the changeset by making copies of the name & value -+ * entries. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+static inline int of_changeset_update_property_copy(struct of_changeset *ocs, -+ struct device_node *np, const char *name, -+ const void *value, int length) -+{ -+ return __of_changeset_add_update_property_copy(ocs, np, name, value, -+ length, true); -+} -+ -+/** -+ * __of_changeset_add_update_property_string - Create/update a string property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @str: string property value -+ * @update: True on update operation -+ * -+ * Adds/updates a string property to the changeset by making copies of the name -+ * and the given value. The @update parameter controls whether an add or -+ * update takes place. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+static inline int __of_changeset_add_update_property_string( -+ struct of_changeset *ocs, struct device_node *np, const char *name, -+ const char *str, bool update) -+{ -+ return __of_changeset_add_update_property_copy(ocs, np, name, str, -+ strlen(str) + 1, update); -+} -+ -+/** -+ * __of_changeset_add_update_property_stringv - Create/update a formatted -+ * string property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @fmt: format of string property -+ * @vargs: arguments of the format string -+ * @update: True on update operation -+ * -+ * Adds/updates a string property to the changeset by making copies of the name -+ * and the formatted value. The @update parameter controls whether an add or -+ * update takes place. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+static inline int __of_changeset_add_update_property_stringv( -+ struct of_changeset *ocs, struct device_node *np, const char *name, -+ const char *fmt, va_list vargs, bool update) -+{ -+ char *str; -+ int ret; -+ -+ str = kvasprintf(GFP_KERNEL, fmt, vargs); -+ if (!str) -+ return -ENOMEM; -+ ret = __of_changeset_add_update_property_string(ocs, np, name, str, -+ update); -+ kfree(str); -+ -+ return ret; -+} -+ -+/** -+ * of_changeset_add_property_string_list - Create a new string list property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @strs: pointer to the string list -+ * @count: string count -+ * -+ * Adds a string list property to the changeset. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+static inline int of_changeset_add_property_string_list( -+ struct of_changeset *ocs, struct device_node *np, const char *name, -+ const char **strs, int count) -+{ -+ return __of_changeset_add_update_property_string_list(ocs, np, name, -+ strs, count, false); -+} -+ -+/** -+ * of_changeset_update_property_string_list - Update string list property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @strs: pointer to the string list -+ * @count: string count -+ * -+ * Updates a string list property to the changeset. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+static inline int of_changeset_update_property_string_list( -+ struct of_changeset *ocs, struct device_node *np, -+ const char *name, const char **strs, int count) -+{ -+ return __of_changeset_add_update_property_string_list(ocs, np, name, -+ strs, count, true); -+} -+ -+/** -+ * of_changeset_add_property_string - Adds a string property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @str: string property -+ * -+ * Adds a string property to the changeset by making copies of the name -+ * and the string value. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+static inline int of_changeset_add_property_string( -+ struct of_changeset *ocs, struct device_node *np, -+ const char *name, const char *str) -+{ -+ return __of_changeset_add_update_property_string(ocs, np, name, str, -+ false); -+} -+ -+/** -+ * of_changeset_update_property_string - Update a string property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @str: string property -+ * -+ * Updates a string property to the changeset by making copies of the name -+ * and the string value. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+static inline int of_changeset_update_property_string( -+ struct of_changeset *ocs, struct device_node *np, -+ const char *name, const char *str) -+{ -+ return __of_changeset_add_update_property_string(ocs, np, name, str, -+ true); -+} -+ -+/** -+ * of_changeset_add_property_u32 - Create a new u32 property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @val: value in host endian format -+ * -+ * Adds a u32 property to the changeset. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+static inline int of_changeset_add_property_u32(struct of_changeset *ocs, -+ struct device_node *np, const char *name, u32 val) -+{ -+ val = cpu_to_be32(val); -+ return __of_changeset_add_update_property_copy(ocs, np, name, &val, -+ sizeof(val), false); -+} -+ -+/** -+ * of_changeset_update_property_u32 - Update u32 property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * @val: value in host endian format -+ * -+ * Updates a u32 property to the changeset. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+static inline int of_changeset_update_property_u32( -+ struct of_changeset *ocs, struct device_node *np, -+ const char *name, u32 val) -+{ -+ val = cpu_to_be32(val); -+ return __of_changeset_add_update_property_copy(ocs, np, name, &val, -+ sizeof(val), true); -+} -+ -+/** -+ * of_changeset_add_property_bool - Create a new u32 property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * -+ * Adds a bool property to the changeset. Note that there is -+ * no option to set the value to false, since the property -+ * existing sets it to true. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+static inline int of_changeset_add_property_bool( -+ struct of_changeset *ocs, struct device_node *np, const char *name) -+{ -+ return __of_changeset_add_update_property_copy(ocs, np, name, "", 0, -+ false); -+} -+ -+/** -+ * of_changeset_update_property_bool - Update a bool property -+ * -+ * @ocs: changeset pointer -+ * @np: device node pointer -+ * @name: name of the property -+ * -+ * Updates a property to the changeset. Note that there is -+ * no option to set the value to false, since the property -+ * existing sets it to true. -+ * -+ * Returns zero on success, a negative error value otherwise. -+ */ -+static inline int of_changeset_update_property_bool(struct of_changeset *ocs, -+ struct device_node *np, const char *name) -+{ -+ return __of_changeset_add_update_property_copy(ocs, np, name, "", 0, -+ true); -+} -+ - /* CONFIG_OF_RESOLVE api */ - extern int of_resolve_phandles(struct device_node *tree); - -@@ -1273,6 +1613,10 @@ int of_overlay_create(struct device_node *tree); - int of_overlay_destroy(int id); - int of_overlay_destroy_all(void); - -+int of_overlay_create_target_index(struct device_node *tree, int index); -+int of_overlay_create_target_root(struct device_node *tree, -+ struct device_node *target_root); -+ - #else - - static inline int of_overlay_create(struct device_node *tree) -@@ -1290,6 +1634,18 @@ static inline int of_overlay_destroy_all(void) - return -ENOTSUPP; - } - -+static inline int of_overlay_create_target_index(struct device_node *tree, -+ int index) -+{ -+ return -ENOTSUPP; -+} -+ -+static inline int of_overlay_create_target_root(struct device_node *tree, -+ struct device_node *target_root) -+{ -+ return -ENOTSUPP; -+} -+ - #endif - - #endif /* _LINUX_OF_H */ -diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h -index f6bc765..e9be0ec 100644 ---- a/include/linux/pm_opp.h -+++ b/include/linux/pm_opp.h -@@ -17,14 +17,64 @@ - #include <linux/err.h> - #include <linux/notifier.h> - -+struct clk; -+struct regulator; - struct dev_pm_opp; - struct device; --struct opp_table; - - enum dev_pm_opp_event { - OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE, - }; - -+/** -+ * struct dev_pm_opp_supply - Power supply voltage/current values -+ * @u_volt: Target voltage in microvolts corresponding to this OPP -+ * @u_volt_min: Minimum voltage in microvolts corresponding to this OPP -+ * @u_volt_max: Maximum voltage in microvolts corresponding to this OPP -+ * @u_amp: Maximum current drawn by the device in microamperes -+ * -+ * This structure stores the voltage/current values for a single power supply. -+ */ -+struct dev_pm_opp_supply { -+ unsigned long u_volt; -+ unsigned long u_volt_min; -+ unsigned long u_volt_max; -+ unsigned long u_amp; -+}; -+ -+/** -+ * struct dev_pm_opp_info - OPP freq/voltage/current values -+ * @rate: Target clk rate in hz -+ * @supplies: Array of voltage/current values for all power supplies -+ * -+ * This structure stores the freq/voltage/current values for a single OPP. -+ */ -+struct dev_pm_opp_info { -+ unsigned long rate; -+ struct dev_pm_opp_supply *supplies; -+}; -+ -+/** -+ * struct dev_pm_set_opp_data - Set OPP data -+ * @old_opp: Old OPP info -+ * @new_opp: New OPP info -+ * @regulators: Array of regulator pointers -+ * @regulator_count: Number of regulators -+ * @clk: Pointer to clk -+ * @dev: Pointer to the struct device -+ * -+ * This structure contains all information required for setting an OPP. -+ */ -+struct dev_pm_set_opp_data { -+ struct dev_pm_opp_info old_opp; -+ struct dev_pm_opp_info new_opp; -+ -+ struct regulator **regulators; -+ unsigned int regulator_count; -+ struct clk *clk; -+ struct device *dev; -+}; -+ - #if defined(CONFIG_PM_OPP) - - unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp); -@@ -63,8 +113,10 @@ int dev_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, - void dev_pm_opp_put_supported_hw(struct device *dev); - int dev_pm_opp_set_prop_name(struct device *dev, const char *name); - void dev_pm_opp_put_prop_name(struct device *dev); --struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name); --void dev_pm_opp_put_regulator(struct opp_table *opp_table); -+int dev_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count); -+void dev_pm_opp_put_regulators(struct device *dev); -+int dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data)); -+void dev_pm_opp_register_put_opp_helper(struct device *dev); - int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); - int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask); - int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); -@@ -164,6 +216,14 @@ static inline int dev_pm_opp_set_supported_hw(struct device *dev, - - static inline void dev_pm_opp_put_supported_hw(struct device *dev) {} - -+static inline int dev_pm_opp_register_set_opp_helper(struct device *dev, -+ int (*set_opp)(struct dev_pm_set_opp_data *data)) -+{ -+ return -ENOTSUPP; -+} -+ -+static inline void dev_pm_opp_register_put_opp_helper(struct device *dev) {} -+ - static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name) - { - return -ENOTSUPP; -@@ -171,12 +231,12 @@ static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name) - - static inline void dev_pm_opp_put_prop_name(struct device *dev) {} - --static inline struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name) -+static inline int dev_pm_opp_set_regulators(struct device *dev, const char *names[], unsigned int count) - { -- return ERR_PTR(-ENOTSUPP); -+ return -ENOTSUPP; - } - --static inline void dev_pm_opp_put_regulator(struct opp_table *opp_table) {} -+static inline void dev_pm_opp_put_regulators(struct device *dev) {} - - static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) - { -@@ -209,6 +269,7 @@ void dev_pm_opp_of_remove_table(struct device *dev); - int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask); - void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask); - int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); -+struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev); - #else - static inline int dev_pm_opp_of_add_table(struct device *dev) - { -@@ -232,6 +293,11 @@ static inline int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct - { - return -ENOTSUPP; - } -+ -+static inline struct device_node *dev_pm_opp_of_get_opp_desc_node(struct device *dev) -+{ -+ return NULL; -+} - #endif - - #endif /* __LINUX_OPP_H__ */ -diff --git b/include/linux/power/pwrseq.h b/include/linux/power/pwrseq.h -new file mode 100644 -index 0000000..4f37275 ---- /dev/null -+++ b/include/linux/power/pwrseq.h -@@ -0,0 +1,72 @@ -+#ifndef __LINUX_PWRSEQ_H -+#define __LINUX_PWRSEQ_H -+ -+#include <linux/of.h> -+ -+#define PWRSEQ_MAX_CLKS 3 -+ -+struct pwrseq { -+ const struct of_device_id *pwrseq_of_match_table; -+ struct list_head node; -+ int (*get)(struct device_node *np, struct pwrseq *p); -+ int (*on)(struct pwrseq *p); -+ void (*off)(struct pwrseq *p); -+ void (*put)(struct pwrseq *p); -+ int (*suspend)(struct pwrseq *p); -+ int (*resume)(struct pwrseq *p); -+ bool used; -+}; -+ -+/* used for power sequence instance list in one driver */ -+struct pwrseq_list_per_dev { -+ struct pwrseq *pwrseq; -+ struct list_head list; -+}; -+ -+#if IS_ENABLED(CONFIG_POWER_SEQUENCE) -+int pwrseq_get(struct device_node *np, struct pwrseq *p); -+int pwrseq_on(struct pwrseq *p); -+void pwrseq_off(struct pwrseq *p); -+void pwrseq_put(struct pwrseq *p); -+int pwrseq_suspend(struct pwrseq *p); -+int pwrseq_resume(struct pwrseq *p); -+void pwrseq_register(struct pwrseq *pwrseq); -+void pwrseq_unregister(struct pwrseq *pwrseq); -+struct pwrseq *of_pwrseq_on(struct device_node *np); -+void of_pwrseq_off(struct pwrseq *pwrseq); -+int of_pwrseq_on_list(struct device_node *np, struct list_head *head); -+void of_pwrseq_off_list(struct list_head *head); -+#else -+static inline int pwrseq_get(struct device_node *np, struct pwrseq *p) -+{ -+ return 0; -+} -+static inline int pwrseq_on(struct pwrseq *p) -+{ -+ return 0; -+} -+static inline void pwrseq_off(struct pwrseq *p) {} -+static inline void pwrseq_put(struct pwrseq *p) {} -+static inline int pwrseq_suspend(struct pwrseq *p) -+{ -+ return 0; -+} -+static inline int pwrseq_resume(struct pwrseq *p) -+{ -+ return 0; -+} -+static inline void pwrseq_register(struct pwrseq *pwrseq) {} -+static inline void pwrseq_unregister(struct pwrseq *pwrseq) {} -+static inline struct pwrseq *of_pwrseq_on(struct device_node *np) -+{ -+ return NULL; -+} -+void of_pwrseq_off(struct pwrseq *pwrseq) {} -+int of_pwrseq_on_list(struct device_node *np, struct list_head *head) -+{ -+ return 0; -+} -+void of_pwrseq_off_list(struct list_head *head) {} -+#endif /* CONFIG_POWER_SEQUENCE */ -+ -+#endif /* __LINUX_PWRSEQ_H */ -diff --git a/lib/vsprintf.c b/lib/vsprintf.c -index 0967771..319e09d 100644 ---- a/lib/vsprintf.c -+++ b/lib/vsprintf.c -@@ -35,6 +35,7 @@ - #ifdef CONFIG_BLOCK - #include <linux/blkdev.h> - #endif -+#include <linux/of.h> - - #include "../mm/internal.h" /* For the trace_print_flags arrays */ - -@@ -1470,6 +1471,141 @@ char *flags_string(char *buf, char *end, void *flags_ptr, const char *fmt) - return format_flags(buf, end, flags, names); - } - -+/* helper method for calculating extends on first pass and filling in later */ -+static noinline_for_stack -+void append_str(const char *str, int pass, int *lenp, char **bufp, char *end) -+{ -+ int len; -+ -+ len = strlen(str); -+ if (pass == 1) -+ *lenp += len; -+ else { -+ if (len > (end - *bufp)) -+ len = end - *bufp; -+ memcpy(*bufp, str, len); -+ *bufp += len; -+ } -+} -+ -+static noinline_for_stack -+char *device_node_string(char *buf, char *end, struct device_node *dn, -+ struct printf_spec spec, const char *fmt) -+{ -+ char tbuf[sizeof("xxxxxxxxxx") + 1]; -+ const char *fmtp, *p; -+ int len, ret, i, j, pass; -+ char c; -+ -+ if (!IS_ENABLED(CONFIG_OF)) { -+ /* if OF is not enabled just print the pointer */ -+ spec.flags |= SMALL; -+ if (spec.field_width == -1) { -+ spec.field_width = 2 * sizeof(void *); -+ spec.flags |= ZEROPAD; -+ } -+ spec.base = 16; -+ return number(buf, end, (unsigned long) dn, spec); -+ } -+ -+ if ((unsigned long)dn < PAGE_SIZE) -+ return string(buf, end, "(null)", spec); -+ -+ /* simple case without anything any more format specifiers */ -+ if (fmt[1] == '\0' || isspace(fmt[1])) -+ fmt = "Of"; -+ -+ len = 0; -+ -+ /* two passes; the first calculates length, the second fills in */ -+ for (pass = 1; pass <= 2; pass++) { -+ if (pass == 2 && !(spec.flags & LEFT)) { -+ /* padding */ -+ while (len < spec.field_width--) { -+ if (buf < end) -+ *buf = ' '; -+ ++buf; -+ } -+ } -+ -+ for (fmtp = fmt + 1, j = 0; (c = *fmtp++) != '\0'; ) { -+ -+ /* validate option */ -+ if (c != 'f' && c != 'n' && c != 'p' && c != 'P' && -+ c != 'F' && c != 'c' && c != 'C' && c != 'r') -+ continue; -+ -+ /* handle separator */ -+ if (j++ > 0) -+ append_str("|", pass, &len, &buf, end); -+ -+ switch (c) { -+ case 'f': /* full_name */ -+ append_str(of_node_full_name(dn), pass, &len, -+ &buf, end); -+ break; -+ case 'n': /* name */ -+ append_str(dn->name, pass, &len, &buf, end); -+ break; -+ case 'p': /* phandle */ -+ snprintf(tbuf, sizeof(tbuf), "%u", -+ (unsigned int)dn->phandle); -+ append_str(tbuf, pass, &len, &buf, end); -+ break; -+ case 'P': /* path-spec */ -+ append_str(dn->name, pass, &len, &buf, end); -+ /* need to tack on the @ postfix */ -+ p = strchr(of_node_full_name(dn), '@'); -+ if (p) -+ append_str(p, pass, &len, &buf, end); -+ break; -+ case 'F': /* flags */ -+ snprintf(tbuf, sizeof(tbuf), "%c%c%c%c", -+ of_node_check_flag(dn, OF_DYNAMIC) ? -+ 'D' : '-', -+ of_node_check_flag(dn, OF_DETACHED) ? -+ 'd' : '-', -+ of_node_check_flag(dn, OF_POPULATED) ? -+ 'P' : '-', -+ of_node_check_flag(dn, -+ OF_POPULATED_BUS) ? 'B' : '-'); -+ append_str(tbuf, pass, &len, &buf, end); -+ break; -+ case 'c': /* major compatible string */ -+ ret = of_property_read_string(dn, "compatible", -+ &p); -+ if (ret == 0) -+ append_str(p, pass, &len, &buf, end); -+ break; -+ case 'C': /* full compatible string */ -+ i = 0; -+ while (of_property_read_string_index(dn, -+ "compatible", i, &p) == 0) { -+ append_str(i == 0 ? "\"" : "\",\"", -+ pass, &len, &buf, end); -+ append_str(p, pass, &len, &buf, end); -+ i++; -+ } -+ if (i > 0) -+ append_str("\"", pass, &len, &buf, end); -+ break; -+ case 'r': /* node reference count */ -+ snprintf(tbuf, sizeof(tbuf), "%u", -+ atomic_read(&dn->kobj.kref.refcount)); -+ append_str(tbuf, pass, &len, &buf, end); -+ break; -+ default: -+ break; -+ } -+ } -+ } -+ /* finish up */ -+ while (buf < end && len < spec.field_width--) -+ *buf++ = ' '; -+ -+ return buf; -+} -+ - int kptr_restrict __read_mostly; - - /* -@@ -1563,6 +1699,16 @@ int kptr_restrict __read_mostly; - * p page flags (see struct page) given as pointer to unsigned long - * g gfp flags (GFP_* and __GFP_*) given as pointer to gfp_t - * v vma flags (VM_*) given as pointer to unsigned long -+ * - 'O[fnpPcCFr]' For an DT device node -+ * Without any optional arguments prints the full_name -+ * f device node full_name -+ * n device node name -+ * p device node phandle -+ * P device node path spec (name + @unit) -+ * F device node flags -+ * c major compatible string -+ * C full compatible string -+ * r node reference count - * - * ** Please update also Documentation/printk-formats.txt when making changes ** - * -@@ -1718,6 +1864,10 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, - - case 'G': - return flags_string(buf, end, ptr, fmt); -+ -+ case 'O': -+ return device_node_string(buf, end, ptr, spec, fmt); -+ - } - spec.flags |= SMALL; - if (spec.field_width == -1) { -diff --git a/samples/seccomp/Makefile b/samples/seccomp/Makefile -index ae7ff6f..7659beb 100644 ---- a/samples/seccomp/Makefile -+++ b/samples/seccomp/Makefile -@@ -20,6 +20,7 @@ bpf-direct-objs := bpf-direct.o - # Try to match the kernel target. - ifndef CROSS_COMPILE - ifndef CONFIG_64BIT -+ifndef CONFIG_ARM - - # s390 has -m31 flag to build 31 bit binaries - ifndef CONFIG_S390 -@@ -46,3 +47,4 @@ ifndef CONFIG_MIPS - always := $(hostprogs-y) - endif - endif -+endif -diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c -index 386f956..38f548e 100644 ---- a/scripts/dtc/checks.c -+++ b/scripts/dtc/checks.c -@@ -40,16 +40,11 @@ enum checkstatus { - - struct check; - --typedef void (*tree_check_fn)(struct check *c, struct node *dt); --typedef void (*node_check_fn)(struct check *c, struct node *dt, struct node *node); --typedef void (*prop_check_fn)(struct check *c, struct node *dt, -- struct node *node, struct property *prop); -+typedef void (*check_fn)(struct check *c, struct dt_info *dti, struct node *node); - - struct check { - const char *name; -- tree_check_fn tree_fn; -- node_check_fn node_fn; -- prop_check_fn prop_fn; -+ check_fn fn; - void *data; - bool warn, error; - enum checkstatus status; -@@ -58,57 +53,35 @@ struct check { - struct check **prereq; - }; - --#define CHECK_ENTRY(nm, tfn, nfn, pfn, d, w, e, ...) \ -- static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \ -- static struct check nm = { \ -- .name = #nm, \ -- .tree_fn = (tfn), \ -- .node_fn = (nfn), \ -- .prop_fn = (pfn), \ -- .data = (d), \ -- .warn = (w), \ -- .error = (e), \ -+#define CHECK_ENTRY(_nm, _fn, _d, _w, _e, ...) \ -+ static struct check *_nm##_prereqs[] = { __VA_ARGS__ }; \ -+ static struct check _nm = { \ -+ .name = #_nm, \ -+ .fn = (_fn), \ -+ .data = (_d), \ -+ .warn = (_w), \ -+ .error = (_e), \ - .status = UNCHECKED, \ -- .num_prereqs = ARRAY_SIZE(nm##_prereqs), \ -- .prereq = nm##_prereqs, \ -+ .num_prereqs = ARRAY_SIZE(_nm##_prereqs), \ -+ .prereq = _nm##_prereqs, \ - }; --#define WARNING(nm, tfn, nfn, pfn, d, ...) \ -- CHECK_ENTRY(nm, tfn, nfn, pfn, d, true, false, __VA_ARGS__) --#define ERROR(nm, tfn, nfn, pfn, d, ...) \ -- CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, true, __VA_ARGS__) --#define CHECK(nm, tfn, nfn, pfn, d, ...) \ -- CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, false, __VA_ARGS__) -- --#define TREE_WARNING(nm, d, ...) \ -- WARNING(nm, check_##nm, NULL, NULL, d, __VA_ARGS__) --#define TREE_ERROR(nm, d, ...) \ -- ERROR(nm, check_##nm, NULL, NULL, d, __VA_ARGS__) --#define TREE_CHECK(nm, d, ...) \ -- CHECK(nm, check_##nm, NULL, NULL, d, __VA_ARGS__) --#define NODE_WARNING(nm, d, ...) \ -- WARNING(nm, NULL, check_##nm, NULL, d, __VA_ARGS__) --#define NODE_ERROR(nm, d, ...) \ -- ERROR(nm, NULL, check_##nm, NULL, d, __VA_ARGS__) --#define NODE_CHECK(nm, d, ...) \ -- CHECK(nm, NULL, check_##nm, NULL, d, __VA_ARGS__) --#define PROP_WARNING(nm, d, ...) \ -- WARNING(nm, NULL, NULL, check_##nm, d, __VA_ARGS__) --#define PROP_ERROR(nm, d, ...) \ -- ERROR(nm, NULL, NULL, check_##nm, d, __VA_ARGS__) --#define PROP_CHECK(nm, d, ...) \ -- CHECK(nm, NULL, NULL, check_##nm, d, __VA_ARGS__) -- --#ifdef __GNUC__ --static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3))); --#endif --static inline void check_msg(struct check *c, const char *fmt, ...) -+#define WARNING(_nm, _fn, _d, ...) \ -+ CHECK_ENTRY(_nm, _fn, _d, true, false, __VA_ARGS__) -+#define ERROR(_nm, _fn, _d, ...) \ -+ CHECK_ENTRY(_nm, _fn, _d, false, true, __VA_ARGS__) -+#define CHECK(_nm, _fn, _d, ...) \ -+ CHECK_ENTRY(_nm, _fn, _d, false, false, __VA_ARGS__) -+ -+static inline void PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti, -+ const char *fmt, ...) - { - va_list ap; - va_start(ap, fmt); - - if ((c->warn && (quiet < 1)) - || (c->error && (quiet < 2))) { -- fprintf(stderr, "%s (%s): ", -+ fprintf(stderr, "%s: %s (%s): ", -+ strcmp(dti->outname, "-") ? dti->outname : "<stdout>", - (c->error) ? "ERROR" : "Warning", c->name); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); -@@ -116,34 +89,28 @@ static inline void check_msg(struct check *c, const char *fmt, ...) - va_end(ap); - } - --#define FAIL(c, ...) \ -- do { \ -- TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ -- (c)->status = FAILED; \ -- check_msg((c), __VA_ARGS__); \ -+#define FAIL(c, dti, ...) \ -+ do { \ -+ TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ -+ (c)->status = FAILED; \ -+ check_msg((c), dti, __VA_ARGS__); \ - } while (0) - --static void check_nodes_props(struct check *c, struct node *dt, struct node *node) -+static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node) - { - struct node *child; -- struct property *prop; - - TRACE(c, "%s", node->fullpath); -- if (c->node_fn) -- c->node_fn(c, dt, node); -- -- if (c->prop_fn) -- for_each_property(node, prop) { -- TRACE(c, "%s\t'%s'", node->fullpath, prop->name); -- c->prop_fn(c, dt, node, prop); -- } -+ if (c->fn) -+ c->fn(c, dti, node); - - for_each_child(node, child) -- check_nodes_props(c, dt, child); -+ check_nodes_props(c, dti, child); - } - --static bool run_check(struct check *c, struct node *dt) -+static bool run_check(struct check *c, struct dt_info *dti) - { -+ struct node *dt = dti->dt; - bool error = false; - int i; - -@@ -156,10 +123,10 @@ static bool run_check(struct check *c, struct node *dt) - - for (i = 0; i < c->num_prereqs; i++) { - struct check *prq = c->prereq[i]; -- error = error || run_check(prq, dt); -+ error = error || run_check(prq, dti); - if (prq->status != PASSED) { - c->status = PREREQ; -- check_msg(c, "Failed prerequisite '%s'", -+ check_msg(c, dti, "Failed prerequisite '%s'", - c->prereq[i]->name); - } - } -@@ -167,11 +134,8 @@ static bool run_check(struct check *c, struct node *dt) - if (c->status != UNCHECKED) - goto out; - -- if (c->node_fn || c->prop_fn) -- check_nodes_props(c, dt, dt); -+ check_nodes_props(c, dti, dt); - -- if (c->tree_fn) -- c->tree_fn(c, dt); - if (c->status == UNCHECKED) - c->status = PASSED; - -@@ -189,13 +153,14 @@ static bool run_check(struct check *c, struct node *dt) - */ - - /* A check which always fails, for testing purposes only */ --static inline void check_always_fail(struct check *c, struct node *dt) -+static inline void check_always_fail(struct check *c, struct dt_info *dti, -+ struct node *node) - { -- FAIL(c, "always_fail check"); -+ FAIL(c, dti, "always_fail check"); - } --TREE_CHECK(always_fail, NULL); -+CHECK(always_fail, check_always_fail, NULL); - --static void check_is_string(struct check *c, struct node *root, -+static void check_is_string(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *prop; -@@ -206,15 +171,15 @@ static void check_is_string(struct check *c, struct node *root, - return; /* Not present, assumed ok */ - - if (!data_is_one_string(prop->val)) -- FAIL(c, "\"%s\" property in %s is not a string", -+ FAIL(c, dti, "\"%s\" property in %s is not a string", - propname, node->fullpath); - } - #define WARNING_IF_NOT_STRING(nm, propname) \ -- WARNING(nm, NULL, check_is_string, NULL, (propname)) -+ WARNING(nm, check_is_string, (propname)) - #define ERROR_IF_NOT_STRING(nm, propname) \ -- ERROR(nm, NULL, check_is_string, NULL, (propname)) -+ ERROR(nm, check_is_string, (propname)) - --static void check_is_cell(struct check *c, struct node *root, -+static void check_is_cell(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *prop; -@@ -225,19 +190,19 @@ static void check_is_cell(struct check *c, struct node *root, - return; /* Not present, assumed ok */ - - if (prop->val.len != sizeof(cell_t)) -- FAIL(c, "\"%s\" property in %s is not a single cell", -+ FAIL(c, dti, "\"%s\" property in %s is not a single cell", - propname, node->fullpath); - } - #define WARNING_IF_NOT_CELL(nm, propname) \ -- WARNING(nm, NULL, check_is_cell, NULL, (propname)) -+ WARNING(nm, check_is_cell, (propname)) - #define ERROR_IF_NOT_CELL(nm, propname) \ -- ERROR(nm, NULL, check_is_cell, NULL, (propname)) -+ ERROR(nm, check_is_cell, (propname)) - - /* - * Structural check functions - */ - --static void check_duplicate_node_names(struct check *c, struct node *dt, -+static void check_duplicate_node_names(struct check *c, struct dt_info *dti, - struct node *node) - { - struct node *child, *child2; -@@ -247,12 +212,12 @@ static void check_duplicate_node_names(struct check *c, struct node *dt, - child2; - child2 = child2->next_sibling) - if (streq(child->name, child2->name)) -- FAIL(c, "Duplicate node name %s", -+ FAIL(c, dti, "Duplicate node name %s", - child->fullpath); - } --NODE_ERROR(duplicate_node_names, NULL); -+ERROR(duplicate_node_names, check_duplicate_node_names, NULL); - --static void check_duplicate_property_names(struct check *c, struct node *dt, -+static void check_duplicate_property_names(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *prop, *prop2; -@@ -262,40 +227,52 @@ static void check_duplicate_property_names(struct check *c, struct node *dt, - if (prop2->deleted) - continue; - if (streq(prop->name, prop2->name)) -- FAIL(c, "Duplicate property name %s in %s", -+ FAIL(c, dti, "Duplicate property name %s in %s", - prop->name, node->fullpath); - } - } - } --NODE_ERROR(duplicate_property_names, NULL); -+ERROR(duplicate_property_names, check_duplicate_property_names, NULL); - - #define LOWERCASE "abcdefghijklmnopqrstuvwxyz" - #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - #define DIGITS "0123456789" - #define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" -+#define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-" - --static void check_node_name_chars(struct check *c, struct node *dt, -+static void check_node_name_chars(struct check *c, struct dt_info *dti, - struct node *node) - { - int n = strspn(node->name, c->data); - - if (n < strlen(node->name)) -- FAIL(c, "Bad character '%c' in node %s", -+ FAIL(c, dti, "Bad character '%c' in node %s", - node->name[n], node->fullpath); - } --NODE_ERROR(node_name_chars, PROPNODECHARS "@"); -+ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@"); - --static void check_node_name_format(struct check *c, struct node *dt, -+static void check_node_name_chars_strict(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ int n = strspn(node->name, c->data); -+ -+ if (n < node->basenamelen) -+ FAIL(c, dti, "Character '%c' not recommended in node %s", -+ node->name[n], node->fullpath); -+} -+CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT); -+ -+static void check_node_name_format(struct check *c, struct dt_info *dti, - struct node *node) - { - if (strchr(get_unitname(node), '@')) -- FAIL(c, "Node %s has multiple '@' characters in name", -+ FAIL(c, dti, "Node %s has multiple '@' characters in name", - node->fullpath); - } --NODE_ERROR(node_name_format, NULL, &node_name_chars); -+ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars); - --static void check_unit_address_vs_reg(struct check *c, struct node *dt, -- struct node *node) -+static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti, -+ struct node *node) - { - const char *unitname = get_unitname(node); - struct property *prop = get_property(node, "reg"); -@@ -308,26 +285,62 @@ static void check_unit_address_vs_reg(struct check *c, struct node *dt, - - if (prop) { - if (!unitname[0]) -- FAIL(c, "Node %s has a reg or ranges property, but no unit name", -+ FAIL(c, dti, "Node %s has a reg or ranges property, but no unit name", - node->fullpath); - } else { - if (unitname[0]) -- FAIL(c, "Node %s has a unit name, but no reg property", -+ FAIL(c, dti, "Node %s has a unit name, but no reg property", - node->fullpath); - } - } --NODE_WARNING(unit_address_vs_reg, NULL); -+WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL); -+ -+static void check_property_name_chars(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ struct property *prop; -+ -+ for_each_property(node, prop) { -+ int n = strspn(prop->name, c->data); -+ -+ if (n < strlen(prop->name)) -+ FAIL(c, dti, "Bad character '%c' in property name \"%s\", node %s", -+ prop->name[n], prop->name, node->fullpath); -+ } -+} -+ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS); - --static void check_property_name_chars(struct check *c, struct node *dt, -- struct node *node, struct property *prop) -+static void check_property_name_chars_strict(struct check *c, -+ struct dt_info *dti, -+ struct node *node) - { -- int n = strspn(prop->name, c->data); -+ struct property *prop; -+ -+ for_each_property(node, prop) { -+ const char *name = prop->name; -+ int n = strspn(name, c->data); -+ -+ if (n == strlen(prop->name)) -+ continue; -+ -+ /* Certain names are whitelisted */ -+ if (streq(name, "device_type")) -+ continue; - -- if (n < strlen(prop->name)) -- FAIL(c, "Bad character '%c' in property name \"%s\", node %s", -- prop->name[n], prop->name, node->fullpath); -+ /* -+ * # is only allowed at the beginning of property names not counting -+ * the vendor prefix. -+ */ -+ if (name[n] == '#' && ((n == 0) || (name[n-1] == ','))) { -+ name += n + 1; -+ n = strspn(name, c->data); -+ } -+ if (n < strlen(name)) -+ FAIL(c, dti, "Character '%c' not recommended in property name \"%s\", node %s", -+ name[n], prop->name, node->fullpath); -+ } - } --PROP_ERROR(property_name_chars, PROPNODECHARS); -+CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT); - - #define DESCLABEL_FMT "%s%s%s%s%s" - #define DESCLABEL_ARGS(node,prop,mark) \ -@@ -336,10 +349,11 @@ PROP_ERROR(property_name_chars, PROPNODECHARS); - ((prop) ? (prop)->name : ""), \ - ((prop) ? "' in " : ""), (node)->fullpath - --static void check_duplicate_label(struct check *c, struct node *dt, -+static void check_duplicate_label(struct check *c, struct dt_info *dti, - const char *label, struct node *node, - struct property *prop, struct marker *mark) - { -+ struct node *dt = dti->dt; - struct node *othernode = NULL; - struct property *otherprop = NULL; - struct marker *othermark = NULL; -@@ -356,50 +370,49 @@ static void check_duplicate_label(struct check *c, struct node *dt, - return; - - if ((othernode != node) || (otherprop != prop) || (othermark != mark)) -- FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT -+ FAIL(c, dti, "Duplicate label '%s' on " DESCLABEL_FMT - " and " DESCLABEL_FMT, - label, DESCLABEL_ARGS(node, prop, mark), - DESCLABEL_ARGS(othernode, otherprop, othermark)); - } - --static void check_duplicate_label_node(struct check *c, struct node *dt, -+static void check_duplicate_label_node(struct check *c, struct dt_info *dti, - struct node *node) - { - struct label *l; -+ struct property *prop; - - for_each_label(node->labels, l) -- check_duplicate_label(c, dt, l->label, node, NULL, NULL); --} --static void check_duplicate_label_prop(struct check *c, struct node *dt, -- struct node *node, struct property *prop) --{ -- struct marker *m = prop->val.markers; -- struct label *l; -+ check_duplicate_label(c, dti, l->label, node, NULL, NULL); - -- for_each_label(prop->labels, l) -- check_duplicate_label(c, dt, l->label, node, prop, NULL); -+ for_each_property(node, prop) { -+ struct marker *m = prop->val.markers; - -- for_each_marker_of_type(m, LABEL) -- check_duplicate_label(c, dt, m->ref, node, prop, m); -+ for_each_label(prop->labels, l) -+ check_duplicate_label(c, dti, l->label, node, prop, NULL); -+ -+ for_each_marker_of_type(m, LABEL) -+ check_duplicate_label(c, dti, m->ref, node, prop, m); -+ } - } --ERROR(duplicate_label, NULL, check_duplicate_label_node, -- check_duplicate_label_prop, NULL); -+ERROR(duplicate_label, check_duplicate_label_node, NULL); - --static void check_explicit_phandles(struct check *c, struct node *root, -- struct node *node, struct property *prop) -+static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, -+ struct node *node, const char *propname) - { -+ struct node *root = dti->dt; -+ struct property *prop; - struct marker *m; -- struct node *other; - cell_t phandle; - -- if (!streq(prop->name, "phandle") -- && !streq(prop->name, "linux,phandle")) -- return; -+ prop = get_property(node, propname); -+ if (!prop) -+ return 0; - - if (prop->val.len != sizeof(cell_t)) { -- FAIL(c, "%s has bad length (%d) %s property", -+ FAIL(c, dti, "%s has bad length (%d) %s property", - node->fullpath, prop->val.len, prop->name); -- return; -+ return 0; - } - - m = prop->val.markers; -@@ -409,42 +422,65 @@ static void check_explicit_phandles(struct check *c, struct node *root, - /* "Set this node's phandle equal to some - * other node's phandle". That's nonsensical - * by construction. */ { -- FAIL(c, "%s in %s is a reference to another node", -+ FAIL(c, dti, "%s in %s is a reference to another node", - prop->name, node->fullpath); -- return; - } - /* But setting this node's phandle equal to its own - * phandle is allowed - that means allocate a unique - * phandle for this node, even if it's not otherwise - * referenced. The value will be filled in later, so -- * no further checking for now. */ -- return; -+ * we treat it as having no phandle data for now. */ -+ return 0; - } - - phandle = propval_cell(prop); - - if ((phandle == 0) || (phandle == -1)) { -- FAIL(c, "%s has bad value (0x%x) in %s property", -+ FAIL(c, dti, "%s has bad value (0x%x) in %s property", - node->fullpath, phandle, prop->name); -- return; -+ return 0; - } - -- if (node->phandle && (node->phandle != phandle)) -- FAIL(c, "%s has %s property which replaces existing phandle information", -- node->fullpath, prop->name); -+ return phandle; -+} -+ -+static void check_explicit_phandles(struct check *c, struct dt_info *dti, -+ struct node *node) -+{ -+ struct node *root = dti->dt; -+ struct node *other; -+ cell_t phandle, linux_phandle; -+ -+ /* Nothing should have assigned phandles yet */ -+ assert(!node->phandle); -+ -+ phandle = check_phandle_prop(c, dti, node, "phandle"); -+ -+ linux_phandle = check_phandle_prop(c, dti, node, "linux,phandle"); -+ -+ if (!phandle && !linux_phandle) -+ /* No valid phandles; nothing further to check */ -+ return; -+ -+ if (linux_phandle && phandle && (phandle != linux_phandle)) -+ FAIL(c, dti, "%s has mismatching 'phandle' and 'linux,phandle'" -+ " properties", node->fullpath); -+ -+ if (linux_phandle && !phandle) -+ phandle = linux_phandle; - - other = get_node_by_phandle(root, phandle); - if (other && (other != node)) { -- FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)", -+ FAIL(c, dti, "%s has duplicated phandle 0x%x (seen before at %s)", - node->fullpath, phandle, other->fullpath); - return; - } - - node->phandle = phandle; - } --PROP_ERROR(explicit_phandles, NULL); -+ERROR(explicit_phandles, check_explicit_phandles, NULL); - --static void check_name_properties(struct check *c, struct node *root, -+static void check_name_properties(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property **pp, *prop = NULL; -@@ -460,7 +496,7 @@ static void check_name_properties(struct check *c, struct node *root, - - if ((prop->val.len != node->basenamelen+1) - || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { -- FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead" -+ FAIL(c, dti, "\"name\" property in %s is incorrect (\"%s\" instead" - " of base node name)", node->fullpath, prop->val.val); - } else { - /* The name property is correct, and therefore redundant. -@@ -472,60 +508,73 @@ static void check_name_properties(struct check *c, struct node *root, - } - } - ERROR_IF_NOT_STRING(name_is_string, "name"); --NODE_ERROR(name_properties, NULL, &name_is_string); -+ERROR(name_properties, check_name_properties, NULL, &name_is_string); - - /* - * Reference fixup functions - */ - --static void fixup_phandle_references(struct check *c, struct node *dt, -- struct node *node, struct property *prop) -+static void fixup_phandle_references(struct check *c, struct dt_info *dti, -+ struct node *node) - { -- struct marker *m = prop->val.markers; -- struct node *refnode; -- cell_t phandle; -+ struct node *dt = dti->dt; -+ struct property *prop; - -- for_each_marker_of_type(m, REF_PHANDLE) { -- assert(m->offset + sizeof(cell_t) <= prop->val.len); -+ for_each_property(node, prop) { -+ struct marker *m = prop->val.markers; -+ struct node *refnode; -+ cell_t phandle; -+ -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ assert(m->offset + sizeof(cell_t) <= prop->val.len); -+ -+ refnode = get_node_by_ref(dt, m->ref); -+ if (! refnode) { -+ if (!(dti->dtsflags & DTSF_PLUGIN)) -+ FAIL(c, dti, "Reference to non-existent node or " -+ "label \"%s\"\n", m->ref); -+ else /* mark the entry as unresolved */ -+ *((fdt32_t *)(prop->val.val + m->offset)) = -+ cpu_to_fdt32(0xffffffff); -+ continue; -+ } - -- refnode = get_node_by_ref(dt, m->ref); -- if (! refnode) { -- FAIL(c, "Reference to non-existent node or label \"%s\"\n", -- m->ref); -- continue; -+ phandle = get_node_phandle(dt, refnode); -+ *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); - } -- -- phandle = get_node_phandle(dt, refnode); -- *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); - } - } --ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL, -+ERROR(phandle_references, fixup_phandle_references, NULL, - &duplicate_node_names, &explicit_phandles); - --static void fixup_path_references(struct check *c, struct node *dt, -- struct node *node, struct property *prop) -+static void fixup_path_references(struct check *c, struct dt_info *dti, -+ struct node *node) - { -- struct marker *m = prop->val.markers; -- struct node *refnode; -- char *path; -+ struct node *dt = dti->dt; -+ struct property *prop; -+ -+ for_each_property(node, prop) { -+ struct marker *m = prop->val.markers; -+ struct node *refnode; -+ char *path; - -- for_each_marker_of_type(m, REF_PATH) { -- assert(m->offset <= prop->val.len); -+ for_each_marker_of_type(m, REF_PATH) { -+ assert(m->offset <= prop->val.len); - -- refnode = get_node_by_ref(dt, m->ref); -- if (!refnode) { -- FAIL(c, "Reference to non-existent node or label \"%s\"\n", -- m->ref); -- continue; -- } -+ refnode = get_node_by_ref(dt, m->ref); -+ if (!refnode) { -+ FAIL(c, dti, "Reference to non-existent node or label \"%s\"\n", -+ m->ref); -+ continue; -+ } - -- path = refnode->fullpath; -- prop->val = data_insert_at_marker(prop->val, m, path, -- strlen(path) + 1); -+ path = refnode->fullpath; -+ prop->val = data_insert_at_marker(prop->val, m, path, -+ strlen(path) + 1); -+ } - } - } --ERROR(path_references, NULL, NULL, fixup_path_references, NULL, -- &duplicate_node_names); -+ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names); - - /* - * Semantic checks -@@ -538,7 +587,7 @@ WARNING_IF_NOT_STRING(device_type_is_string, "device_type"); - WARNING_IF_NOT_STRING(model_is_string, "model"); - WARNING_IF_NOT_STRING(status_is_string, "status"); - --static void fixup_addr_size_cells(struct check *c, struct node *dt, -+static void fixup_addr_size_cells(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *prop; -@@ -554,7 +603,7 @@ static void fixup_addr_size_cells(struct check *c, struct node *dt, - if (prop) - node->size_cells = propval_cell(prop); - } --WARNING(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, -+WARNING(addr_size_cells, fixup_addr_size_cells, NULL, - &address_cells_is_cell, &size_cells_is_cell); - - #define node_addr_cells(n) \ -@@ -562,7 +611,7 @@ WARNING(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, - #define node_size_cells(n) \ - (((n)->size_cells == -1) ? 1 : (n)->size_cells) - --static void check_reg_format(struct check *c, struct node *dt, -+static void check_reg_format(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *prop; -@@ -573,25 +622,25 @@ static void check_reg_format(struct check *c, struct node *dt, - return; /* No "reg", that's fine */ - - if (!node->parent) { -- FAIL(c, "Root node has a \"reg\" property"); -+ FAIL(c, dti, "Root node has a \"reg\" property"); - return; - } - - if (prop->val.len == 0) -- FAIL(c, "\"reg\" property in %s is empty", node->fullpath); -+ FAIL(c, dti, "\"reg\" property in %s is empty", node->fullpath); - - addr_cells = node_addr_cells(node->parent); - size_cells = node_size_cells(node->parent); - entrylen = (addr_cells + size_cells) * sizeof(cell_t); - - if (!entrylen || (prop->val.len % entrylen) != 0) -- FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) " -+ FAIL(c, dti, "\"reg\" property in %s has invalid length (%d bytes) " - "(#address-cells == %d, #size-cells == %d)", - node->fullpath, prop->val.len, addr_cells, size_cells); - } --NODE_WARNING(reg_format, NULL, &addr_size_cells); -+WARNING(reg_format, check_reg_format, NULL, &addr_size_cells); - --static void check_ranges_format(struct check *c, struct node *dt, -+static void check_ranges_format(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *prop; -@@ -602,7 +651,7 @@ static void check_ranges_format(struct check *c, struct node *dt, - return; - - if (!node->parent) { -- FAIL(c, "Root node has a \"ranges\" property"); -+ FAIL(c, dti, "Root node has a \"ranges\" property"); - return; - } - -@@ -614,28 +663,28 @@ static void check_ranges_format(struct check *c, struct node *dt, - - if (prop->val.len == 0) { - if (p_addr_cells != c_addr_cells) -- FAIL(c, "%s has empty \"ranges\" property but its " -+ FAIL(c, dti, "%s has empty \"ranges\" property but its " - "#address-cells (%d) differs from %s (%d)", - node->fullpath, c_addr_cells, node->parent->fullpath, - p_addr_cells); - if (p_size_cells != c_size_cells) -- FAIL(c, "%s has empty \"ranges\" property but its " -+ FAIL(c, dti, "%s has empty \"ranges\" property but its " - "#size-cells (%d) differs from %s (%d)", - node->fullpath, c_size_cells, node->parent->fullpath, - p_size_cells); - } else if ((prop->val.len % entrylen) != 0) { -- FAIL(c, "\"ranges\" property in %s has invalid length (%d bytes) " -+ FAIL(c, dti, "\"ranges\" property in %s has invalid length (%d bytes) " - "(parent #address-cells == %d, child #address-cells == %d, " - "#size-cells == %d)", node->fullpath, prop->val.len, - p_addr_cells, c_addr_cells, c_size_cells); - } - } --NODE_WARNING(ranges_format, NULL, &addr_size_cells); -+WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells); - - /* - * Style checks - */ --static void check_avoid_default_addr_size(struct check *c, struct node *dt, -+static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti, - struct node *node) - { - struct property *reg, *ranges; -@@ -650,31 +699,39 @@ static void check_avoid_default_addr_size(struct check *c, struct node *dt, - return; - - if (node->parent->addr_cells == -1) -- FAIL(c, "Relying on default #address-cells value for %s", -+ FAIL(c, dti, "Relying on default #address-cells value for %s", - node->fullpath); - - if (node->parent->size_cells == -1) -- FAIL(c, "Relying on default #size-cells value for %s", -+ FAIL(c, dti, "Relying on default #size-cells value for %s", - node->fullpath); - } --NODE_WARNING(avoid_default_addr_size, NULL, &addr_size_cells); -+WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL, -+ &addr_size_cells); - - static void check_obsolete_chosen_interrupt_controller(struct check *c, -- struct node *dt) -+ struct dt_info *dti, -+ struct node *node) - { -+ struct node *dt = dti->dt; - struct node *chosen; - struct property *prop; - -+ if (node != dt) -+ return; -+ -+ - chosen = get_node_by_path(dt, "/chosen"); - if (!chosen) - return; - - prop = get_property(chosen, "interrupt-controller"); - if (prop) -- FAIL(c, "/chosen has obsolete \"interrupt-controller\" " -+ FAIL(c, dti, "/chosen has obsolete \"interrupt-controller\" " - "property"); - } --TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); -+WARNING(obsolete_chosen_interrupt_controller, -+ check_obsolete_chosen_interrupt_controller, NULL); - - static struct check *check_table[] = { - &duplicate_node_names, &duplicate_property_names, -@@ -689,6 +746,9 @@ static struct check *check_table[] = { - &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, - &device_type_is_string, &model_is_string, &status_is_string, - -+ &property_name_chars_strict, -+ &node_name_chars_strict, -+ - &addr_size_cells, ®_format, &ranges_format, - - &unit_address_vs_reg, -@@ -760,9 +820,8 @@ void parse_checks_option(bool warn, bool error, const char *arg) - die("Unrecognized check name \"%s\"\n", name); - } - --void process_checks(bool force, struct boot_info *bi) -+void process_checks(bool force, struct dt_info *dti) - { -- struct node *dt = bi->dt; - int i; - int error = 0; - -@@ -770,7 +829,7 @@ void process_checks(bool force, struct boot_info *bi) - struct check *c = check_table[i]; - - if (c->warn || c->error) -- error = error || run_check(c, dt); -+ error = error || run_check(c, dti); - } - - if (error) { -diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c -index 8cae237..aa37a16 100644 ---- a/scripts/dtc/data.c -+++ b/scripts/dtc/data.c -@@ -171,9 +171,9 @@ struct data data_merge(struct data d1, struct data d2) - struct data data_append_integer(struct data d, uint64_t value, int bits) - { - uint8_t value_8; -- uint16_t value_16; -- uint32_t value_32; -- uint64_t value_64; -+ fdt16_t value_16; -+ fdt32_t value_32; -+ fdt64_t value_64; - - switch (bits) { - case 8: -@@ -197,14 +197,14 @@ struct data data_append_integer(struct data d, uint64_t value, int bits) - } - } - --struct data data_append_re(struct data d, const struct fdt_reserve_entry *re) -+struct data data_append_re(struct data d, uint64_t address, uint64_t size) - { -- struct fdt_reserve_entry bere; -+ struct fdt_reserve_entry re; - -- bere.address = cpu_to_fdt64(re->address); -- bere.size = cpu_to_fdt64(re->size); -+ re.address = cpu_to_fdt64(address); -+ re.size = cpu_to_fdt64(size); - -- return data_append_data(d, &bere, sizeof(bere)); -+ return data_append_data(d, &re, sizeof(re)); - } - - struct data data_append_cell(struct data d, cell_t word) -diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l -index 790fbf6..fd825eb 100644 ---- a/scripts/dtc/dtc-lexer.l -+++ b/scripts/dtc/dtc-lexer.l -@@ -62,7 +62,8 @@ static int dts_version = 1; - - static void push_input_file(const char *filename); - static bool pop_input_file(void); --static void lexical_error(const char *fmt, ...); -+static void PRINTF(1, 2) lexical_error(const char *fmt, ...); -+ - %} - - %% -@@ -121,6 +122,11 @@ static void lexical_error(const char *fmt, ...); - return DT_V1; - } - -+<*>"/plugin/" { -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ - <*>"/memreserve/" { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); -@@ -184,16 +190,16 @@ static void lexical_error(const char *fmt, ...); - if (d.len == 1) { - lexical_error("Empty character literal"); - yylval.integer = 0; -- return DT_CHAR_LITERAL; -- } -- -- yylval.integer = (unsigned char)d.val[0]; -+ } else { -+ yylval.integer = (unsigned char)d.val[0]; - -- if (d.len > 2) -- lexical_error("Character literal has %d" -- " characters instead of 1", -- d.len - 1); -+ if (d.len > 2) -+ lexical_error("Character literal has %d" -+ " characters instead of 1", -+ d.len - 1); -+ } - -+ data_free(d); - return DT_CHAR_LITERAL; - } - -diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped -index ba525c2..c37d7ff 100644 ---- a/scripts/dtc/dtc-lexer.lex.c_shipped -+++ b/scripts/dtc/dtc-lexer.lex.c_shipped -@@ -8,8 +8,8 @@ - - #define FLEX_SCANNER - #define YY_FLEX_MAJOR_VERSION 2 --#define YY_FLEX_MINOR_VERSION 5 --#define YY_FLEX_SUBMINOR_VERSION 39 -+#define YY_FLEX_MINOR_VERSION 6 -+#define YY_FLEX_SUBMINOR_VERSION 1 - #if YY_FLEX_SUBMINOR_VERSION > 0 - #define FLEX_BETA - #endif -@@ -88,25 +88,13 @@ typedef unsigned int flex_uint32_t; - - #endif /* ! FLEXINT_H */ - --#ifdef __cplusplus -- --/* The "const" storage-class-modifier is valid. */ --#define YY_USE_CONST -- --#else /* ! __cplusplus */ -- --/* C99 requires __STDC__ to be defined as 1. */ --#if defined (__STDC__) -- --#define YY_USE_CONST -- --#endif /* defined (__STDC__) */ --#endif /* ! __cplusplus */ -- --#ifdef YY_USE_CONST -+/* TODO: this is always defined, so inline it */ - #define yyconst const -+ -+#if defined(__GNUC__) && __GNUC__ >= 3 -+#define yynoreturn __attribute__((__noreturn__)) - #else --#define yyconst -+#define yynoreturn - #endif - - /* Returned upon end-of-file. */ -@@ -167,7 +155,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; - typedef size_t yy_size_t; - #endif - --extern yy_size_t yyleng; -+extern int yyleng; - - extern FILE *yyin, *yyout; - -@@ -206,12 +194,12 @@ struct yy_buffer_state - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ -- yy_size_t yy_buf_size; -+ int yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ -- yy_size_t yy_n_chars; -+ int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to -@@ -234,7 +222,7 @@ struct yy_buffer_state - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ -- -+ - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ -@@ -262,7 +250,7 @@ struct yy_buffer_state - /* Stack of input buffers. */ - static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ - static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ --static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ -+static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ - - /* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general -@@ -281,11 +269,11 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - - /* yy_hold_char holds the character lost when yytext is formed. */ - static char yy_hold_char; --static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ --yy_size_t yyleng; -+static int yy_n_chars; /* number of characters read into yy_ch_buf */ -+int yyleng; - - /* Points to current character in buffer. */ --static char *yy_c_buf_p = (char *) 0; -+static char *yy_c_buf_p = NULL; - static int yy_init = 0; /* whether we need to initialize */ - static int yy_start = 0; /* start state number */ - -@@ -310,7 +298,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); - - YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); - YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); --YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); -+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); - - void *yyalloc (yy_size_t ); - void *yyrealloc (void *,yy_size_t ); -@@ -342,12 +330,12 @@ void yyfree (void * ); - - /* Begin user sect3 */ - --#define yywrap() 1 -+#define yywrap() (/*CONSTCOND*/1) - #define YY_SKIP_YYWRAP - - typedef unsigned char YY_CHAR; - --FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; -+FILE *yyin = NULL, *yyout = NULL; - - typedef int yy_state_type; - -@@ -356,25 +344,28 @@ extern int yylineno; - int yylineno = 1; - - extern char *yytext; -+#ifdef yytext_ptr -+#undef yytext_ptr -+#endif - #define yytext_ptr yytext - - static yy_state_type yy_get_previous_state (void ); - static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); - static int yy_get_next_buffer (void ); --static void yy_fatal_error (yyconst char msg[] ); -+static void yynoreturn yy_fatal_error (yyconst char* msg ); - - /* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ - #define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ -- yyleng = (size_t) (yy_cp - yy_bp); \ -+ yyleng = (int) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - --#define YY_NUM_RULES 30 --#define YY_END_OF_BUFFER 31 -+#define YY_NUM_RULES 31 -+#define YY_END_OF_BUFFER 32 - /* This struct is not used in this scanner, - but its presence is necessary. */ - struct yy_trans_info -@@ -382,28 +373,29 @@ struct yy_trans_info - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; --static yyconst flex_int16_t yy_accept[159] = -+static yyconst flex_int16_t yy_accept[166] = - { 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, -- 18, 18, 29, 29, 29, 29, 29, 29, 29, 29, -- 29, 29, 29, 29, 29, 29, 15, 16, 16, 29, -- 16, 10, 10, 18, 26, 0, 3, 0, 27, 12, -- 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, -- 21, 23, 25, 24, 22, 0, 9, 28, 0, 0, -- 0, 14, 14, 16, 16, 16, 10, 10, 10, 0, -- 12, 0, 11, 0, 0, 0, 20, 0, 0, 0, -- 0, 0, 0, 0, 0, 16, 10, 10, 10, 0, -- 13, 19, 0, 0, 0, 0, 0, 0, 0, 0, -- -- 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 16, 6, 0, 0, 0, 0, 0, 0, 2, -- 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, -- 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -- 5, 8, 0, 0, 0, 0, 7, 0 -+ 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, -+ 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, -+ 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, -+ 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, -+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, -+ 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, -+ 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, -+ 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, -+ 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, -+ -+ 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, -+ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, -+ 0, 0, 0, 8, 0 - } ; - --static yyconst flex_int32_t yy_ec[256] = -+static yyconst YY_CHAR yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, -@@ -416,9 +408,9 @@ static yyconst flex_int32_t yy_ec[256] = - 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, - 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, - -- 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, -- 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, -- 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, -+ 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, -+ 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, -+ 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -@@ -435,163 +427,165 @@ static yyconst flex_int32_t yy_ec[256] = - 1, 1, 1, 1, 1 - } ; - --static yyconst flex_int32_t yy_meta[47] = -+static yyconst YY_CHAR yy_meta[48] = - { 0, - 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, - 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, - 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, - 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, -- 8, 8, 8, 3, 1, 4 -+ 8, 8, 8, 8, 3, 1, 4 - } ; - --static yyconst flex_int16_t yy_base[173] = -+static yyconst flex_uint16_t yy_base[180] = - { 0, -- 0, 383, 34, 382, 65, 381, 37, 105, 387, 391, -- 54, 111, 367, 110, 109, 109, 112, 41, 366, 104, -- 367, 338, 124, 117, 0, 144, 391, 0, 121, 0, -- 135, 155, 140, 179, 391, 160, 391, 379, 391, 0, -- 368, 141, 391, 167, 370, 376, 346, 103, 342, 345, -- 391, 391, 391, 391, 391, 358, 391, 391, 175, 342, -- 338, 391, 355, 0, 185, 339, 184, 347, 346, 0, -- 0, 322, 175, 357, 175, 363, 352, 324, 330, 323, -- 332, 326, 201, 324, 329, 322, 391, 333, 181, 309, -- 391, 341, 340, 313, 320, 338, 178, 311, 146, 317, -- -- 314, 315, 335, 331, 303, 300, 309, 299, 308, 188, -- 336, 335, 391, 305, 320, 281, 283, 271, 203, 288, -- 281, 271, 266, 264, 245, 242, 208, 104, 391, 391, -- 244, 218, 204, 219, 206, 224, 201, 212, 204, 229, -- 215, 208, 207, 200, 219, 391, 233, 221, 200, 181, -- 391, 391, 149, 122, 86, 41, 391, 391, 245, 251, -- 259, 263, 267, 273, 280, 284, 292, 300, 304, 310, -- 318, 326 -+ 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, -+ 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, -+ 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, -+ 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, -+ 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, -+ 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, -+ 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, -+ 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, -+ 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, -+ 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, -+ -+ 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, -+ 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, -+ 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, -+ 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, -+ 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, -+ 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, -+ 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, -+ 281, 288, 292, 300, 308, 312, 318, 326, 334 - } ; - --static yyconst flex_int16_t yy_def[173] = -+static yyconst flex_int16_t yy_def[180] = - { 0, -- 158, 1, 1, 3, 158, 5, 1, 1, 158, 158, -- 158, 158, 158, 159, 160, 161, 158, 158, 158, 158, -- 162, 158, 158, 158, 163, 162, 158, 164, 165, 164, -- 164, 158, 158, 158, 158, 159, 158, 159, 158, 166, -- 158, 161, 158, 161, 167, 168, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 162, 158, 158, 158, 158, -- 158, 158, 162, 164, 165, 164, 158, 158, 158, 169, -- 166, 170, 161, 167, 167, 168, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 164, 158, 158, 169, 170, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- -- 158, 164, 158, 158, 158, 158, 158, 158, 158, 171, -- 158, 164, 158, 158, 158, 158, 158, 158, 171, 158, -- 171, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 172, 158, 158, 158, 172, 158, 172, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 0, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158 -+ 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, -+ 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, -+ 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, -+ 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, -+ 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, -+ 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, -+ 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, -+ 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, -+ -+ 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, -+ 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, -+ 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_nxt[438] = -+static yyconst flex_uint16_t yy_nxt[449] = - { 0, - 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, - 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, - 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -- 21, 21, 21, 10, 22, 10, 24, 25, 25, 25, -- 32, 33, 33, 157, 26, 34, 34, 34, 51, 52, -- 27, 26, 26, 26, 26, 10, 11, 12, 11, 13, -- 14, 28, 15, 16, 28, 28, 28, 24, 28, 28, -- 28, 10, 18, 19, 20, 29, 29, 29, 29, 29, -- 30, 10, 29, 29, 29, 29, 29, 29, 29, 29, -- -- 29, 29, 29, 29, 29, 29, 29, 29, 10, 22, -- 10, 23, 34, 34, 34, 37, 39, 43, 32, 33, -- 33, 45, 54, 55, 46, 59, 45, 64, 156, 46, -- 64, 64, 64, 79, 44, 38, 59, 57, 134, 47, -- 135, 48, 80, 49, 47, 50, 48, 99, 61, 43, -- 50, 110, 41, 67, 67, 67, 60, 63, 63, 63, -- 57, 155, 68, 69, 63, 37, 44, 66, 67, 67, -- 67, 63, 63, 63, 63, 73, 59, 68, 69, 70, -- 34, 34, 34, 43, 75, 38, 154, 92, 83, 83, -- 83, 64, 44, 120, 64, 64, 64, 67, 67, 67, -- -- 44, 57, 99, 68, 69, 107, 68, 69, 120, 127, -- 108, 153, 152, 121, 83, 83, 83, 133, 133, 133, -- 146, 133, 133, 133, 146, 140, 140, 140, 121, 141, -- 140, 140, 140, 151, 141, 158, 150, 149, 148, 144, -- 147, 143, 142, 139, 147, 36, 36, 36, 36, 36, -- 36, 36, 36, 40, 138, 137, 136, 40, 40, 42, -- 42, 42, 42, 42, 42, 42, 42, 56, 56, 56, -- 56, 62, 132, 62, 64, 131, 130, 64, 129, 64, -- 64, 65, 128, 158, 65, 65, 65, 65, 71, 127, -- 71, 71, 74, 74, 74, 74, 74, 74, 74, 74, -- -- 76, 76, 76, 76, 76, 76, 76, 76, 89, 126, -- 89, 90, 125, 90, 90, 124, 90, 90, 119, 119, -- 119, 119, 119, 119, 119, 119, 145, 145, 145, 145, -- 145, 145, 145, 145, 123, 122, 59, 59, 118, 117, -- 116, 115, 114, 113, 45, 112, 108, 111, 109, 106, -- 105, 104, 46, 103, 91, 87, 102, 101, 100, 98, -- 97, 96, 95, 94, 93, 77, 75, 91, 88, 87, -- 86, 57, 85, 84, 57, 82, 81, 78, 77, 75, -- 72, 158, 58, 57, 53, 35, 158, 31, 23, 23, -- 9, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158 -+ 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, -+ 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, -+ 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, -+ 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, -+ 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, -+ 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, -+ -+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -+ 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, -+ 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, -+ 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, -+ 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, -+ 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, -+ 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, -+ 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, -+ 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, -+ 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, -+ -+ 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, -+ 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, -+ 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, -+ 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, -+ 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, -+ 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, -+ 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, -+ 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, -+ 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, -+ 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, -+ -+ 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, -+ 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, -+ 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, -+ 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, -+ 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, -+ 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, -+ 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, -+ 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, -+ 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, -+ 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, -+ -+ 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - --static yyconst flex_int16_t yy_chk[438] = -+static yyconst flex_int16_t yy_chk[449] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -- 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, -- 7, 7, 7, 156, 3, 11, 11, 11, 18, 18, -- 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, -+ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, -+ 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, -+ 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -- 5, 8, 12, 12, 12, 14, 15, 16, 8, 8, -- 8, 17, 20, 20, 17, 23, 24, 29, 155, 24, -- 29, 29, 29, 48, 16, 14, 31, 29, 128, 17, -- 128, 17, 48, 17, 24, 17, 24, 99, 24, 42, -- 24, 99, 15, 33, 33, 33, 23, 26, 26, 26, -- 26, 154, 33, 33, 26, 36, 42, 31, 32, 32, -- 32, 26, 26, 26, 26, 44, 59, 32, 32, 32, -- 34, 34, 34, 73, 75, 36, 153, 75, 59, 59, -- 59, 65, 44, 110, 65, 65, 65, 67, 67, 67, -- -- 73, 65, 83, 89, 89, 97, 67, 67, 119, 127, -- 97, 150, 149, 110, 83, 83, 83, 133, 133, 133, -- 141, 127, 127, 127, 145, 136, 136, 136, 119, 136, -- 140, 140, 140, 148, 140, 147, 144, 143, 142, 139, -- 141, 138, 137, 135, 145, 159, 159, 159, 159, 159, -- 159, 159, 159, 160, 134, 132, 131, 160, 160, 161, -- 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, -- 162, 163, 126, 163, 164, 125, 124, 164, 123, 164, -- 164, 165, 122, 121, 165, 165, 165, 165, 166, 120, -- 166, 166, 167, 167, 167, 167, 167, 167, 167, 167, -- -- 168, 168, 168, 168, 168, 168, 168, 168, 169, 118, -- 169, 170, 117, 170, 170, 116, 170, 170, 171, 171, -- 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, -- 172, 172, 172, 172, 115, 114, 112, 111, 109, 108, -- 107, 106, 105, 104, 103, 102, 101, 100, 98, 96, -- 95, 94, 93, 92, 90, 88, 86, 85, 84, 82, -- 81, 80, 79, 78, 77, 76, 74, 72, 69, 68, -- 66, 63, 61, 60, 56, 50, 49, 47, 46, 45, -+ 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, -+ 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, -+ 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, -+ 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, -+ 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, -+ 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, -+ 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, -+ 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, -+ 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, -+ -+ 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, -+ 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, -+ 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, -+ 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, -+ 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, -+ 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, -+ 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, -+ 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, -+ 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, -+ 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, -+ -+ 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, -+ 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, -+ 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, -+ 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, -+ 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, -+ 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, -+ 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, -+ 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, -+ 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, - 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, - -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, -- 158, 158, 158, 158, 158, 158, 158 -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, -+ 165, 165, 165, 165, 165, 165, 165, 165 - } ; - - static yy_state_type yy_last_accepting_state; -@@ -661,8 +655,9 @@ static int dts_version = 1; - - static void push_input_file(const char *filename); - static bool pop_input_file(void); --static void lexical_error(const char *fmt, ...); --#line 666 "dtc-lexer.lex.c" -+static void PRINTF(1, 2) lexical_error(const char *fmt, ...); -+ -+#line 661 "dtc-lexer.lex.c" - - #define INITIAL 0 - #define BYTESTRING 1 -@@ -698,19 +693,19 @@ void yyset_extra (YY_EXTRA_TYPE user_defined ); - - FILE *yyget_in (void ); - --void yyset_in (FILE * in_str ); -+void yyset_in (FILE * _in_str ); - - FILE *yyget_out (void ); - --void yyset_out (FILE * out_str ); -+void yyset_out (FILE * _out_str ); - --yy_size_t yyget_leng (void ); -+ int yyget_leng (void ); - - char *yyget_text (void ); - - int yyget_lineno (void ); - --void yyset_lineno (int line_number ); -+void yyset_lineno (int _line_number ); - - /* Macros after this point can all be overridden by user definitions in - * section 1. -@@ -724,6 +719,10 @@ extern int yywrap (void ); - #endif - #endif - -+#ifndef YY_NO_UNPUT -+ -+#endif -+ - #ifndef yytext_ptr - static void yy_flex_strncpy (char *,yyconst char *,int ); - #endif -@@ -757,7 +756,7 @@ static int input (void ); - /* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ --#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) -+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) - #endif - - /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, -@@ -781,7 +780,7 @@ static int input (void ); - else \ - { \ - errno=0; \ -- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ -+ while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ -@@ -836,7 +835,7 @@ extern int yylex (void); - - /* Code executed at the end of each rule. */ - #ifndef YY_BREAK --#define YY_BREAK break; -+#define YY_BREAK /*LINTED*/break; - #endif - - #define YY_RULE_SETUP \ -@@ -849,9 +848,9 @@ extern int yylex (void); - */ - YY_DECL - { -- register yy_state_type yy_current_state; -- register char *yy_cp, *yy_bp; -- register int yy_act; -+ yy_state_type yy_current_state; -+ char *yy_cp, *yy_bp; -+ int yy_act; - - if ( !(yy_init) ) - { -@@ -880,11 +879,11 @@ YY_DECL - } - - { --#line 68 "dtc-lexer.l" -+#line 69 "dtc-lexer.l" - --#line 886 "dtc-lexer.lex.c" -+#line 885 "dtc-lexer.lex.c" - -- while ( 1 ) /* loops until end-of-file is reached */ -+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - -@@ -901,7 +900,7 @@ YY_DECL - yy_match: - do - { -- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; -+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; -@@ -910,13 +909,13 @@ yy_match: - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } -- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; - ++yy_cp; - } -- while ( yy_current_state != 158 ); -+ while ( yy_current_state != 165 ); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - -@@ -939,7 +938,7 @@ do_action: /* This label is used only to access EOF actions. */ - case 1: - /* rule 1 can match eol */ - YY_RULE_SETUP --#line 69 "dtc-lexer.l" -+#line 70 "dtc-lexer.l" - { - char *name = strchr(yytext, '\"') + 1; - yytext[yyleng-1] = '\0'; -@@ -949,7 +948,7 @@ YY_RULE_SETUP - case 2: - /* rule 2 can match eol */ - YY_RULE_SETUP --#line 75 "dtc-lexer.l" -+#line 76 "dtc-lexer.l" - { - char *line, *fnstart, *fnend; - struct data fn; -@@ -983,7 +982,7 @@ case YY_STATE_EOF(INITIAL): - case YY_STATE_EOF(BYTESTRING): - case YY_STATE_EOF(PROPNODENAME): - case YY_STATE_EOF(V1): --#line 104 "dtc-lexer.l" -+#line 105 "dtc-lexer.l" - { - if (!pop_input_file()) { - yyterminate(); -@@ -993,7 +992,7 @@ case YY_STATE_EOF(V1): - case 3: - /* rule 3 can match eol */ - YY_RULE_SETUP --#line 110 "dtc-lexer.l" -+#line 111 "dtc-lexer.l" - { - DPRINT("String: %s\n", yytext); - yylval.data = data_copy_escape_string(yytext+1, -@@ -1003,7 +1002,7 @@ YY_RULE_SETUP - YY_BREAK - case 4: - YY_RULE_SETUP --#line 117 "dtc-lexer.l" -+#line 118 "dtc-lexer.l" - { - DPRINT("Keyword: /dts-v1/\n"); - dts_version = 1; -@@ -1013,25 +1012,33 @@ YY_RULE_SETUP - YY_BREAK - case 5: - YY_RULE_SETUP --#line 124 "dtc-lexer.l" -+#line 125 "dtc-lexer.l" -+{ -+ DPRINT("Keyword: /plugin/\n"); -+ return DT_PLUGIN; -+ } -+ YY_BREAK -+case 6: -+YY_RULE_SETUP -+#line 130 "dtc-lexer.l" - { - DPRINT("Keyword: /memreserve/\n"); - BEGIN_DEFAULT(); - return DT_MEMRESERVE; - } - YY_BREAK --case 6: -+case 7: - YY_RULE_SETUP --#line 130 "dtc-lexer.l" -+#line 136 "dtc-lexer.l" - { - DPRINT("Keyword: /bits/\n"); - BEGIN_DEFAULT(); - return DT_BITS; - } - YY_BREAK --case 7: -+case 8: - YY_RULE_SETUP --#line 136 "dtc-lexer.l" -+#line 142 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-property/\n"); - DPRINT("<PROPNODENAME>\n"); -@@ -1039,9 +1046,9 @@ YY_RULE_SETUP - return DT_DEL_PROP; - } - YY_BREAK --case 8: -+case 9: - YY_RULE_SETUP --#line 143 "dtc-lexer.l" -+#line 149 "dtc-lexer.l" - { - DPRINT("Keyword: /delete-node/\n"); - DPRINT("<PROPNODENAME>\n"); -@@ -1049,9 +1056,9 @@ YY_RULE_SETUP - return DT_DEL_NODE; - } - YY_BREAK --case 9: -+case 10: - YY_RULE_SETUP --#line 150 "dtc-lexer.l" -+#line 156 "dtc-lexer.l" - { - DPRINT("Label: %s\n", yytext); - yylval.labelref = xstrdup(yytext); -@@ -1059,9 +1066,9 @@ YY_RULE_SETUP - return DT_LABEL; - } - YY_BREAK --case 10: -+case 11: - YY_RULE_SETUP --#line 157 "dtc-lexer.l" -+#line 163 "dtc-lexer.l" - { - char *e; - DPRINT("Integer Literal: '%s'\n", yytext); -@@ -1084,10 +1091,10 @@ YY_RULE_SETUP - return DT_LITERAL; - } - YY_BREAK --case 11: --/* rule 11 can match eol */ -+case 12: -+/* rule 12 can match eol */ - YY_RULE_SETUP --#line 179 "dtc-lexer.l" -+#line 185 "dtc-lexer.l" - { - struct data d; - DPRINT("Character literal: %s\n", yytext); -@@ -1096,31 +1103,31 @@ YY_RULE_SETUP - if (d.len == 1) { - lexical_error("Empty character literal"); - yylval.integer = 0; -- return DT_CHAR_LITERAL; -- } -+ } else { -+ yylval.integer = (unsigned char)d.val[0]; - -- yylval.integer = (unsigned char)d.val[0]; -- -- if (d.len > 2) -- lexical_error("Character literal has %d" -- " characters instead of 1", -- d.len - 1); -+ if (d.len > 2) -+ lexical_error("Character literal has %d" -+ " characters instead of 1", -+ d.len - 1); -+ } - -+ data_free(d); - return DT_CHAR_LITERAL; - } - YY_BREAK --case 12: -+case 13: - YY_RULE_SETUP --#line 200 "dtc-lexer.l" -+#line 206 "dtc-lexer.l" - { /* label reference */ - DPRINT("Ref: %s\n", yytext+1); - yylval.labelref = xstrdup(yytext+1); - return DT_REF; - } - YY_BREAK --case 13: -+case 14: - YY_RULE_SETUP --#line 206 "dtc-lexer.l" -+#line 212 "dtc-lexer.l" - { /* new-style path reference */ - yytext[yyleng-1] = '\0'; - DPRINT("Ref: %s\n", yytext+2); -@@ -1128,27 +1135,27 @@ YY_RULE_SETUP - return DT_REF; - } - YY_BREAK --case 14: -+case 15: - YY_RULE_SETUP --#line 213 "dtc-lexer.l" -+#line 219 "dtc-lexer.l" - { - yylval.byte = strtol(yytext, NULL, 16); - DPRINT("Byte: %02x\n", (int)yylval.byte); - return DT_BYTE; - } - YY_BREAK --case 15: -+case 16: - YY_RULE_SETUP --#line 219 "dtc-lexer.l" -+#line 225 "dtc-lexer.l" - { - DPRINT("/BYTESTRING\n"); - BEGIN_DEFAULT(); - return ']'; - } - YY_BREAK --case 16: -+case 17: - YY_RULE_SETUP --#line 225 "dtc-lexer.l" -+#line 231 "dtc-lexer.l" - { - DPRINT("PropNodeName: %s\n", yytext); - yylval.propnodename = xstrdup((yytext[0] == '\\') ? -@@ -1157,75 +1164,75 @@ YY_RULE_SETUP - return DT_PROPNODENAME; - } - YY_BREAK --case 17: -+case 18: - YY_RULE_SETUP --#line 233 "dtc-lexer.l" -+#line 239 "dtc-lexer.l" - { - DPRINT("Binary Include\n"); - return DT_INCBIN; - } - YY_BREAK --case 18: --/* rule 18 can match eol */ --YY_RULE_SETUP --#line 238 "dtc-lexer.l" --/* eat whitespace */ -- YY_BREAK - case 19: - /* rule 19 can match eol */ - YY_RULE_SETUP --#line 239 "dtc-lexer.l" --/* eat C-style comments */ -+#line 244 "dtc-lexer.l" -+/* eat whitespace */ - YY_BREAK - case 20: - /* rule 20 can match eol */ - YY_RULE_SETUP --#line 240 "dtc-lexer.l" --/* eat C++-style comments */ -+#line 245 "dtc-lexer.l" -+/* eat C-style comments */ - YY_BREAK - case 21: -+/* rule 21 can match eol */ - YY_RULE_SETUP --#line 242 "dtc-lexer.l" --{ return DT_LSHIFT; }; -+#line 246 "dtc-lexer.l" -+/* eat C++-style comments */ - YY_BREAK - case 22: - YY_RULE_SETUP --#line 243 "dtc-lexer.l" --{ return DT_RSHIFT; }; -+#line 248 "dtc-lexer.l" -+{ return DT_LSHIFT; }; - YY_BREAK - case 23: - YY_RULE_SETUP --#line 244 "dtc-lexer.l" --{ return DT_LE; }; -+#line 249 "dtc-lexer.l" -+{ return DT_RSHIFT; }; - YY_BREAK - case 24: - YY_RULE_SETUP --#line 245 "dtc-lexer.l" --{ return DT_GE; }; -+#line 250 "dtc-lexer.l" -+{ return DT_LE; }; - YY_BREAK - case 25: - YY_RULE_SETUP --#line 246 "dtc-lexer.l" --{ return DT_EQ; }; -+#line 251 "dtc-lexer.l" -+{ return DT_GE; }; - YY_BREAK - case 26: - YY_RULE_SETUP --#line 247 "dtc-lexer.l" --{ return DT_NE; }; -+#line 252 "dtc-lexer.l" -+{ return DT_EQ; }; - YY_BREAK - case 27: - YY_RULE_SETUP --#line 248 "dtc-lexer.l" --{ return DT_AND; }; -+#line 253 "dtc-lexer.l" -+{ return DT_NE; }; - YY_BREAK - case 28: - YY_RULE_SETUP --#line 249 "dtc-lexer.l" --{ return DT_OR; }; -+#line 254 "dtc-lexer.l" -+{ return DT_AND; }; - YY_BREAK - case 29: - YY_RULE_SETUP --#line 251 "dtc-lexer.l" -+#line 255 "dtc-lexer.l" -+{ return DT_OR; }; -+ YY_BREAK -+case 30: -+YY_RULE_SETUP -+#line 257 "dtc-lexer.l" - { - DPRINT("Char: %c (\\x%02x)\n", yytext[0], - (unsigned)yytext[0]); -@@ -1241,12 +1248,12 @@ YY_RULE_SETUP - return yytext[0]; - } - YY_BREAK --case 30: -+case 31: - YY_RULE_SETUP --#line 266 "dtc-lexer.l" -+#line 272 "dtc-lexer.l" - ECHO; - YY_BREAK --#line 1250 "dtc-lexer.lex.c" -+#line 1257 "dtc-lexer.lex.c" - - case YY_END_OF_BUFFER: - { -@@ -1388,9 +1395,9 @@ ECHO; - */ - static int yy_get_next_buffer (void) - { -- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; -- register char *source = (yytext_ptr); -- register int number_to_move, i; -+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; -+ char *source = (yytext_ptr); -+ int number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) -@@ -1419,7 +1426,7 @@ static int yy_get_next_buffer (void) - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ -- number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; -+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); -@@ -1432,7 +1439,7 @@ static int yy_get_next_buffer (void) - - else - { -- yy_size_t num_to_read = -+ int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) -@@ -1446,7 +1453,7 @@ static int yy_get_next_buffer (void) - - if ( b->yy_is_our_buffer ) - { -- yy_size_t new_size = b->yy_buf_size * 2; -+ int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; -@@ -1459,7 +1466,7 @@ static int yy_get_next_buffer (void) - } - else - /* Can't grow it, we don't own it. */ -- b->yy_ch_buf = 0; -+ b->yy_ch_buf = NULL; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( -@@ -1501,9 +1508,9 @@ static int yy_get_next_buffer (void) - else - ret_val = EOB_ACT_CONTINUE_SCAN; - -- if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { -+ if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ -- yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); -+ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); -@@ -1522,15 +1529,15 @@ static int yy_get_next_buffer (void) - - static yy_state_type yy_get_previous_state (void) - { -- register yy_state_type yy_current_state; -- register char *yy_cp; -+ yy_state_type yy_current_state; -+ char *yy_cp; - - yy_current_state = (yy_start); - yy_current_state += YY_AT_BOL(); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { -- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); -+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; -@@ -1539,10 +1546,10 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } -- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; - } - - return yy_current_state; -@@ -1555,10 +1562,10 @@ static int yy_get_next_buffer (void) - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) - { -- register int yy_is_jam; -- register char *yy_cp = (yy_c_buf_p); -+ int yy_is_jam; -+ char *yy_cp = (yy_c_buf_p); - -- register YY_CHAR yy_c = 1; -+ YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; -@@ -1567,15 +1574,19 @@ static int yy_get_next_buffer (void) - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; -- if ( yy_current_state >= 159 ) -+ if ( yy_current_state >= 166 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } -- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -- yy_is_jam = (yy_current_state == 158); -+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; -+ yy_is_jam = (yy_current_state == 165); - - return yy_is_jam ? 0 : yy_current_state; - } - -+#ifndef YY_NO_UNPUT -+ -+#endif -+ - #ifndef YY_NO_INPUT - #ifdef __cplusplus - static int yyinput (void) -@@ -1600,7 +1611,7 @@ static int yy_get_next_buffer (void) - - else - { /* need more input */ -- yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); -+ int offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) -@@ -1624,7 +1635,7 @@ static int yy_get_next_buffer (void) - case EOB_ACT_END_OF_FILE: - { - if ( yywrap( ) ) -- return EOF; -+ return 0; - - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; -@@ -1727,7 +1738,7 @@ static void yy_load_buffer_state (void) - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - -- b->yy_buf_size = size; -+ b->yy_buf_size = (yy_size_t)size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. -@@ -1874,7 +1885,7 @@ void yypop_buffer_state (void) - */ - static void yyensure_buffer_stack (void) - { -- yy_size_t num_to_alloc; -+ int num_to_alloc; - - if (!(yy_buffer_stack)) { - -@@ -1882,15 +1893,15 @@ static void yyensure_buffer_stack (void) - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ -- num_to_alloc = 1; -+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ - (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); -- -+ - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); -- -+ - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; -@@ -1899,7 +1910,7 @@ static void yyensure_buffer_stack (void) - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ -- int grow_size = 8 /* arbitrary grow size */; -+ yy_size_t grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc -@@ -1919,7 +1930,7 @@ static void yyensure_buffer_stack (void) - * @param base the character buffer - * @param size the size in bytes of the character buffer - * -- * @return the newly allocated buffer state object. -+ * @return the newly allocated buffer state object. - */ - YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) - { -@@ -1929,7 +1940,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ -- return 0; -+ return NULL; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) -@@ -1938,7 +1949,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; -- b->yy_input_file = 0; -+ b->yy_input_file = NULL; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; -@@ -1961,7 +1972,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) - YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) - { - -- return yy_scan_bytes(yystr,strlen(yystr) ); -+ return yy_scan_bytes(yystr,(int) strlen(yystr) ); - } - - /** Setup the input buffer state to scan the given bytes. The next call to yylex() will -@@ -1971,15 +1982,15 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) - * - * @return the newly allocated buffer state object. - */ --YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) -+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; -- yy_size_t i; -+ int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ -- n = _yybytes_len + 2; -+ n = (yy_size_t) (_yybytes_len + 2); - buf = (char *) yyalloc(n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); -@@ -2005,9 +2016,9 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len - #define YY_EXIT_FAILURE 2 - #endif - --static void yy_fatal_error (yyconst char* msg ) -+static void yynoreturn yy_fatal_error (yyconst char* msg ) - { -- (void) fprintf( stderr, "%s\n", msg ); -+ (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } - -@@ -2035,7 +2046,7 @@ static void yy_fatal_error (yyconst char* msg ) - */ - int yyget_lineno (void) - { -- -+ - return yylineno; - } - -@@ -2058,7 +2069,7 @@ FILE *yyget_out (void) - /** Get the length of the current token. - * - */ --yy_size_t yyget_leng (void) -+int yyget_leng (void) - { - return yyleng; - } -@@ -2073,29 +2084,29 @@ char *yyget_text (void) - } - - /** Set the current line number. -- * @param line_number -+ * @param _line_number line number - * - */ --void yyset_lineno (int line_number ) -+void yyset_lineno (int _line_number ) - { - -- yylineno = line_number; -+ yylineno = _line_number; - } - - /** Set the input stream. This does not discard the current - * input buffer. -- * @param in_str A readable stream. -+ * @param _in_str A readable stream. - * - * @see yy_switch_to_buffer - */ --void yyset_in (FILE * in_str ) -+void yyset_in (FILE * _in_str ) - { -- yyin = in_str ; -+ yyin = _in_str ; - } - --void yyset_out (FILE * out_str ) -+void yyset_out (FILE * _out_str ) - { -- yyout = out_str ; -+ yyout = _out_str ; - } - - int yyget_debug (void) -@@ -2103,9 +2114,9 @@ int yyget_debug (void) - return yy_flex_debug; - } - --void yyset_debug (int bdebug ) -+void yyset_debug (int _bdebug ) - { -- yy_flex_debug = bdebug ; -+ yy_flex_debug = _bdebug ; - } - - static int yy_init_globals (void) -@@ -2114,10 +2125,10 @@ static int yy_init_globals (void) - * This function is called from yylex_destroy(), so don't allocate here. - */ - -- (yy_buffer_stack) = 0; -+ (yy_buffer_stack) = NULL; - (yy_buffer_stack_top) = 0; - (yy_buffer_stack_max) = 0; -- (yy_c_buf_p) = (char *) 0; -+ (yy_c_buf_p) = NULL; - (yy_init) = 0; - (yy_start) = 0; - -@@ -2126,8 +2137,8 @@ static int yy_init_globals (void) - yyin = stdin; - yyout = stdout; - #else -- yyin = (FILE *) 0; -- yyout = (FILE *) 0; -+ yyin = NULL; -+ yyout = NULL; - #endif - - /* For future reference: Set errno on error, since we are called by -@@ -2165,7 +2176,8 @@ int yylex_destroy (void) - #ifndef yytext_ptr - static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) - { -- register int i; -+ -+ int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } -@@ -2174,7 +2186,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) - #ifdef YY_NEED_STRLEN - static int yy_flex_strlen (yyconst char * s ) - { -- register int n; -+ int n; - for ( n = 0; s[n]; ++n ) - ; - -@@ -2184,11 +2196,12 @@ static int yy_flex_strlen (yyconst char * s ) - - void *yyalloc (yy_size_t size ) - { -- return (void *) malloc( size ); -+ return malloc(size); - } - - void *yyrealloc (void * ptr, yy_size_t size ) - { -+ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter -@@ -2196,17 +2209,17 @@ void *yyrealloc (void * ptr, yy_size_t size ) - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ -- return (void *) realloc( (char *) ptr, size ); -+ return realloc(ptr, size); - } - - void yyfree (void * ptr ) - { -- free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ - } - - #define YYTABLES_NAME "yytables" - --#line 265 "dtc-lexer.l" -+#line 272 "dtc-lexer.l" - - - -diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped -index 31cec50..0a7a5ed 100644 ---- a/scripts/dtc/dtc-parser.tab.c_shipped -+++ b/scripts/dtc/dtc-parser.tab.c_shipped -@@ -1,8 +1,8 @@ --/* A Bison parser, made by GNU Bison 3.0.2. */ -+/* A Bison parser, made by GNU Bison 3.0.4. */ - - /* Bison implementation for Yacc-like parsers in C - -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by -@@ -44,7 +44,7 @@ - #define YYBISON 1 - - /* Bison version. */ --#define YYBISON_VERSION "3.0.2" -+#define YYBISON_VERSION "3.0.4" - - /* Skeleton name. */ - #define YYSKELETON_NAME "yacc.c" -@@ -65,6 +65,7 @@ - #line 20 "dtc-parser.y" /* yacc.c:339 */ - - #include <stdio.h> -+#include <inttypes.h> - - #include "dtc.h" - #include "srcpos.h" -@@ -77,10 +78,10 @@ extern void yyerror(char const *s); - treesource_error = true; \ - } while (0) - --extern struct boot_info *the_boot_info; -+extern struct dt_info *parser_output; - extern bool treesource_error; - --#line 84 "dtc-parser.tab.c" /* yacc.c:339 */ -+#line 85 "dtc-parser.tab.c" /* yacc.c:339 */ - - # ifndef YY_NULLPTR - # if defined __cplusplus && 201103L <= __cplusplus -@@ -116,35 +117,36 @@ extern int yydebug; - enum yytokentype - { - DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BYTE = 274, -- DT_STRING = 275, -- DT_LABEL = 276, -- DT_REF = 277, -- DT_INCBIN = 278 -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 - }; - #endif - - /* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE YYSTYPE; -+ - union YYSTYPE - { --#line 38 "dtc-parser.y" /* yacc.c:355 */ -+#line 39 "dtc-parser.y" /* yacc.c:355 */ - - char *propnodename; - char *labelref; -@@ -162,9 +164,12 @@ union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ unsigned int flags; - --#line 167 "dtc-parser.tab.c" /* yacc.c:355 */ -+#line 170 "dtc-parser.tab.c" /* yacc.c:355 */ - }; -+ -+typedef union YYSTYPE YYSTYPE; - # define YYSTYPE_IS_TRIVIAL 1 - # define YYSTYPE_IS_DECLARED 1 - #endif -@@ -192,7 +197,7 @@ int yyparse (void); - - /* Copy the second part of user declarations. */ - --#line 196 "dtc-parser.tab.c" /* yacc.c:358 */ -+#line 201 "dtc-parser.tab.c" /* yacc.c:358 */ - - #ifdef short - # undef short -@@ -434,23 +439,23 @@ union yyalloc - #endif /* !YYCOPY_NEEDED */ - - /* YYFINAL -- State number of the termination state. */ --#define YYFINAL 4 -+#define YYFINAL 6 - /* YYLAST -- Last index in YYTABLE. */ --#define YYLAST 136 -+#define YYLAST 138 - - /* YYNTOKENS -- Number of terminals. */ --#define YYNTOKENS 47 -+#define YYNTOKENS 48 - /* YYNNTS -- Number of nonterminals. */ --#define YYNNTS 28 -+#define YYNNTS 30 - /* YYNRULES -- Number of rules. */ --#define YYNRULES 80 -+#define YYNRULES 84 - /* YYNSTATES -- Number of states. */ --#define YYNSTATES 144 -+#define YYNSTATES 149 - - /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ - #define YYUNDEFTOK 2 --#define YYMAXUTOK 278 -+#define YYMAXUTOK 279 - - #define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -@@ -462,16 +467,16 @@ static const yytype_uint8 yytranslate[] = - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 46, 2, 2, 2, 44, 40, 2, -- 32, 34, 43, 41, 33, 42, 2, 25, 2, 2, -- 2, 2, 2, 2, 2, 2, 2, 2, 37, 24, -- 35, 28, 29, 36, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 47, 2, 2, 2, 45, 41, 2, -+ 33, 35, 44, 42, 34, 43, 2, 26, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 38, 25, -+ 36, 29, 30, 37, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 30, 2, 31, 39, 2, 2, 2, 2, 2, -+ 2, 31, 2, 32, 40, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -- 2, 2, 2, 26, 38, 27, 45, 2, 2, 2, -+ 2, 2, 2, 27, 39, 28, 46, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -@@ -486,22 +491,22 @@ static const yytype_uint8 yytranslate[] = - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, -- 15, 16, 17, 18, 19, 20, 21, 22, 23 -+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 - }; - - #if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ - static const yytype_uint16 yyrline[] = - { -- 0, 104, 104, 113, 116, 123, 127, 135, 139, 144, -- 155, 165, 180, 188, 191, 198, 202, 206, 210, 218, -- 222, 226, 230, 234, 250, 260, 268, 271, 275, 282, -- 298, 303, 322, 336, 343, 344, 345, 352, 356, 357, -- 361, 362, 366, 367, 371, 372, 376, 377, 381, 382, -- 386, 387, 388, 392, 393, 394, 395, 396, 400, 401, -- 402, 406, 407, 408, 412, 413, 422, 431, 435, 436, -- 437, 438, 443, 446, 450, 458, 461, 465, 473, 477, -- 481 -+ 0, 109, 109, 117, 121, 128, 129, 139, 142, 149, -+ 153, 161, 165, 170, 181, 191, 206, 214, 217, 224, -+ 228, 232, 236, 244, 248, 252, 256, 260, 276, 286, -+ 294, 297, 301, 308, 324, 329, 348, 362, 369, 370, -+ 371, 378, 382, 383, 387, 388, 392, 393, 397, 398, -+ 402, 403, 407, 408, 412, 413, 414, 418, 419, 420, -+ 421, 422, 426, 427, 428, 432, 433, 434, 438, 439, -+ 448, 457, 461, 462, 463, 464, 469, 472, 476, 484, -+ 487, 491, 499, 503, 507 - }; - #endif - -@@ -510,19 +515,20 @@ static const yytype_uint16 yyrline[] = - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ - static const char *const yytname[] = - { -- "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", -- "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", -- "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", -- "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", -- "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", "']'", -- "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", "'+'", -- "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -- "memreserves", "memreserve", "devicetree", "nodedef", "proplist", -- "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", -- "integer_expr", "integer_trinary", "integer_or", "integer_and", -- "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", -- "integer_rela", "integer_shift", "integer_add", "integer_mul", -- "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR -+ "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", -+ "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", -+ "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", -+ "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", -+ "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", -+ "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", -+ "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", -+ "header", "headers", "memreserves", "memreserve", "devicetree", -+ "nodedef", "proplist", "propdef", "propdata", "propdataprefix", -+ "arrayprefix", "integer_prim", "integer_expr", "integer_trinary", -+ "integer_or", "integer_and", "integer_bitor", "integer_bitxor", -+ "integer_bitand", "integer_eq", "integer_rela", "integer_shift", -+ "integer_add", "integer_mul", "integer_unary", "bytestring", "subnodes", -+ "subnode", YY_NULLPTR - }; - #endif - -@@ -533,16 +539,16 @@ static const yytype_uint16 yytoknum[] = - { - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, -- 275, 276, 277, 278, 59, 47, 123, 125, 61, 62, -- 91, 93, 40, 44, 41, 60, 63, 58, 124, 94, -- 38, 43, 45, 42, 37, 126, 33 -+ 275, 276, 277, 278, 279, 59, 47, 123, 125, 61, -+ 62, 91, 93, 40, 44, 41, 60, 63, 58, 124, -+ 94, 38, 43, 45, 42, 37, 126, 33 - }; - # endif - --#define YYPACT_NINF -81 -+#define YYPACT_NINF -44 - - #define yypact_value_is_default(Yystate) \ -- (!!((Yystate) == (-81))) -+ (!!((Yystate) == (-44))) - - #define YYTABLE_NINF -1 - -@@ -553,21 +559,21 @@ static const yytype_uint16 yytoknum[] = - STATE-NUM. */ - static const yytype_int8 yypact[] = - { -- 16, -11, 21, 10, -81, 25, 10, 19, 10, -81, -- -81, -9, 25, -81, 2, 51, -81, -9, -9, -9, -- -81, 1, -81, -6, 50, 14, 28, 29, 36, 3, -- 58, 44, -3, -81, 47, -81, -81, 65, 68, 2, -- 2, -81, -81, -81, -81, -9, -9, -9, -9, -9, -- -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -- -9, -9, -9, -9, -81, 63, 69, 2, -81, -81, -- 50, 57, 14, 28, 29, 36, 3, 3, 58, 58, -- 58, 58, 44, 44, -3, -3, -81, -81, -81, 79, -- 80, -8, 63, -81, 72, 63, -81, -81, -9, 76, -- 77, -81, -81, -81, -81, -81, 78, -81, -81, -81, -- -81, -81, 35, 4, -81, -81, -81, -81, 86, -81, -- -81, -81, 73, -81, -81, 33, 71, 84, 39, -81, -- -81, -81, -81, -81, 41, -81, -81, -81, 25, -81, -- 74, 25, 75, -81 -+ 14, 27, 61, 14, 8, 18, -44, -44, 37, 8, -+ 40, 8, 64, -44, -44, -12, 37, -44, 50, 52, -+ -44, -44, -12, -12, -12, -44, 51, -44, -4, 78, -+ 53, 54, 55, 17, 2, 30, 38, -3, -44, 66, -+ -44, -44, 70, 72, 50, 50, -44, -44, -44, -44, -+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -+ -12, -12, -12, -12, -12, -12, -12, -12, -12, -44, -+ 3, 73, 50, -44, -44, 78, 59, 53, 54, 55, -+ 17, 2, 2, 30, 30, 30, 30, 38, 38, -3, -+ -3, -44, -44, -44, 82, 83, 44, 3, -44, 74, -+ 3, -44, -44, -12, 76, 79, -44, -44, -44, -44, -+ -44, 80, -44, -44, -44, -44, -44, -10, 36, -44, -+ -44, -44, -44, 85, -44, -44, -44, 75, -44, -44, -+ 21, 71, 88, -6, -44, -44, -44, -44, -44, 11, -+ -44, -44, -44, 37, -44, 77, 37, 81, -44 - }; - - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. -@@ -575,37 +581,37 @@ static const yytype_int8 yypact[] = - means the default is an error. */ - static const yytype_uint8 yydefact[] = - { -- 0, 0, 0, 3, 1, 0, 0, 0, 3, 34, -- 35, 0, 0, 6, 0, 2, 4, 0, 0, 0, -- 68, 0, 37, 38, 40, 42, 44, 46, 48, 50, -- 53, 60, 63, 67, 0, 13, 7, 0, 0, 0, -- 0, 69, 70, 71, 36, 0, 0, 0, 0, 0, -+ 0, 0, 0, 5, 7, 3, 1, 6, 0, 0, -+ 0, 7, 0, 38, 39, 0, 0, 10, 0, 2, -+ 8, 4, 0, 0, 0, 72, 0, 41, 42, 44, -+ 46, 48, 50, 52, 54, 57, 64, 67, 71, 0, -+ 17, 11, 0, 0, 0, 0, 73, 74, 75, 40, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 5, 75, 0, 0, 10, 8, -- 41, 0, 43, 45, 47, 49, 51, 52, 56, 57, -- 55, 54, 58, 59, 61, 62, 65, 64, 66, 0, -- 0, 0, 0, 14, 0, 75, 11, 9, 0, 0, -- 0, 16, 26, 78, 18, 80, 0, 77, 76, 39, -- 17, 79, 0, 0, 12, 25, 15, 27, 0, 19, -- 28, 22, 0, 72, 30, 0, 0, 0, 0, 33, -- 32, 20, 31, 29, 0, 73, 74, 21, 0, 24, -- 0, 0, 0, 23 -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, -+ 79, 0, 0, 14, 12, 45, 0, 47, 49, 51, -+ 53, 55, 56, 60, 61, 59, 58, 62, 63, 65, -+ 66, 69, 68, 70, 0, 0, 0, 0, 18, 0, -+ 79, 15, 13, 0, 0, 0, 20, 30, 82, 22, -+ 84, 0, 81, 80, 43, 21, 83, 0, 0, 16, -+ 29, 19, 31, 0, 23, 32, 26, 0, 76, 34, -+ 0, 0, 0, 0, 37, 36, 24, 35, 33, 0, -+ 77, 78, 25, 0, 28, 0, 0, 0, 27 - }; - - /* YYPGOTO[NTERM-NUM]. */ - static const yytype_int8 yypgoto[] = - { -- -81, -81, 100, 104, -81, -38, -81, -80, -81, -81, -- -81, -5, 66, 13, -81, 70, 67, 81, 64, 82, -- 37, 27, 34, 38, -14, -81, 22, 24 -+ -44, -44, -44, 103, 99, 104, -44, -43, -44, -21, -+ -44, -44, -44, -8, 63, 9, -44, 65, 67, 68, -+ 69, 62, 26, 4, 22, 23, -19, -44, 20, 28 - }; - - /* YYDEFGOTO[NTERM-NUM]. */ - static const yytype_int16 yydefgoto[] = - { -- -1, 2, 7, 8, 15, 36, 65, 93, 112, 113, -- 125, 20, 21, 22, 23, 24, 25, 26, 27, 28, -- 29, 30, 31, 32, 33, 128, 94, 95 -+ -1, 2, 3, 4, 10, 11, 19, 41, 70, 98, -+ 117, 118, 130, 25, 26, 27, 28, 29, 30, 31, -+ 32, 33, 34, 35, 36, 37, 38, 133, 99, 100 - }; - - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If -@@ -613,87 +619,87 @@ static const yytype_int16 yydefgoto[] = - number is the opposite. If YYTABLE_NINF, syntax error. */ - static const yytype_uint8 yytable[] = - { -- 12, 68, 69, 41, 42, 43, 45, 34, 9, 10, -- 53, 54, 104, 3, 5, 107, 101, 118, 35, 1, -- 102, 4, 61, 11, 119, 120, 121, 122, 35, 97, -- 46, 6, 55, 17, 123, 44, 18, 19, 56, 124, -- 62, 63, 9, 10, 14, 51, 52, 86, 87, 88, -- 9, 10, 48, 103, 129, 130, 115, 11, 135, 116, -- 136, 47, 131, 57, 58, 11, 37, 49, 117, 50, -- 137, 64, 38, 39, 138, 139, 40, 89, 90, 91, -- 78, 79, 80, 81, 92, 59, 60, 66, 76, 77, -- 67, 82, 83, 96, 98, 99, 100, 84, 85, 106, -- 110, 111, 114, 126, 134, 127, 133, 141, 16, 143, -- 13, 109, 71, 74, 72, 70, 105, 108, 0, 0, -- 132, 0, 0, 0, 0, 0, 0, 0, 0, 73, -- 0, 0, 75, 140, 0, 0, 142 -+ 16, 73, 74, 46, 47, 48, 13, 14, 39, 50, -+ 58, 59, 120, 8, 140, 121, 141, 1, 94, 95, -+ 96, 15, 12, 66, 122, 97, 142, 56, 57, 102, -+ 9, 22, 60, 51, 23, 24, 62, 63, 61, 13, -+ 14, 67, 68, 134, 135, 143, 144, 91, 92, 93, -+ 123, 136, 5, 108, 15, 13, 14, 124, 125, 126, -+ 127, 6, 83, 84, 85, 86, 18, 128, 42, 106, -+ 15, 40, 129, 107, 43, 44, 109, 40, 45, 112, -+ 64, 65, 81, 82, 87, 88, 49, 89, 90, 21, -+ 52, 69, 53, 71, 54, 72, 55, 103, 101, 104, -+ 105, 115, 111, 131, 116, 119, 7, 138, 132, 139, -+ 20, 146, 114, 17, 76, 75, 148, 80, 0, 77, -+ 113, 78, 137, 79, 0, 110, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 145, 0, 0, 147 - }; - - static const yytype_int16 yycheck[] = - { -- 5, 39, 40, 17, 18, 19, 12, 12, 17, 18, -- 7, 8, 92, 24, 4, 95, 24, 13, 26, 3, -- 28, 0, 25, 32, 20, 21, 22, 23, 26, 67, -- 36, 21, 29, 42, 30, 34, 45, 46, 35, 35, -- 43, 44, 17, 18, 25, 9, 10, 61, 62, 63, -- 17, 18, 38, 91, 21, 22, 21, 32, 19, 24, -- 21, 11, 29, 5, 6, 32, 15, 39, 33, 40, -- 31, 24, 21, 22, 33, 34, 25, 14, 15, 16, -- 53, 54, 55, 56, 21, 41, 42, 22, 51, 52, -- 22, 57, 58, 24, 37, 16, 16, 59, 60, 27, -- 24, 24, 24, 17, 20, 32, 35, 33, 8, 34, -- 6, 98, 46, 49, 47, 45, 92, 95, -1, -1, -- 125, -1, -1, -1, -1, -1, -1, -1, -1, 48, -- -1, -1, 50, 138, -1, -1, 141 -+ 8, 44, 45, 22, 23, 24, 18, 19, 16, 13, -+ 8, 9, 22, 5, 20, 25, 22, 3, 15, 16, -+ 17, 33, 4, 26, 34, 22, 32, 10, 11, 72, -+ 22, 43, 30, 37, 46, 47, 6, 7, 36, 18, -+ 19, 44, 45, 22, 23, 34, 35, 66, 67, 68, -+ 14, 30, 25, 96, 33, 18, 19, 21, 22, 23, -+ 24, 0, 58, 59, 60, 61, 26, 31, 16, 25, -+ 33, 27, 36, 29, 22, 23, 97, 27, 26, 100, -+ 42, 43, 56, 57, 62, 63, 35, 64, 65, 25, -+ 12, 25, 39, 23, 40, 23, 41, 38, 25, 17, -+ 17, 25, 28, 18, 25, 25, 3, 36, 33, 21, -+ 11, 34, 103, 9, 51, 50, 35, 55, -1, 52, -+ 100, 53, 130, 54, -1, 97, -1, -1, -1, -1, -+ -1, -1, -1, -1, -1, 143, -1, -1, 146 - }; - - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ - static const yytype_uint8 yystos[] = - { -- 0, 3, 48, 24, 0, 4, 21, 49, 50, 17, -- 18, 32, 58, 50, 25, 51, 49, 42, 45, 46, -- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, -- 68, 69, 70, 71, 58, 26, 52, 15, 21, 22, -- 25, 71, 71, 71, 34, 12, 36, 11, 38, 39, -- 40, 9, 10, 7, 8, 29, 35, 5, 6, 41, -- 42, 25, 43, 44, 24, 53, 22, 22, 52, 52, -- 62, 59, 63, 64, 65, 66, 67, 67, 68, 68, -- 68, 68, 69, 69, 70, 70, 71, 71, 71, 14, -- 15, 16, 21, 54, 73, 74, 24, 52, 37, 16, -- 16, 24, 28, 52, 54, 74, 27, 54, 73, 60, -- 24, 24, 55, 56, 24, 21, 24, 33, 13, 20, -- 21, 22, 23, 30, 35, 57, 17, 32, 72, 21, -- 22, 29, 58, 35, 20, 19, 21, 31, 33, 34, -- 58, 33, 58, 34 -+ 0, 3, 49, 50, 51, 25, 0, 51, 5, 22, -+ 52, 53, 4, 18, 19, 33, 61, 53, 26, 54, -+ 52, 25, 43, 46, 47, 61, 62, 63, 64, 65, -+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 61, -+ 27, 55, 16, 22, 23, 26, 74, 74, 74, 35, -+ 13, 37, 12, 39, 40, 41, 10, 11, 8, 9, -+ 30, 36, 6, 7, 42, 43, 26, 44, 45, 25, -+ 56, 23, 23, 55, 55, 65, 62, 66, 67, 68, -+ 69, 70, 70, 71, 71, 71, 71, 72, 72, 73, -+ 73, 74, 74, 74, 15, 16, 17, 22, 57, 76, -+ 77, 25, 55, 38, 17, 17, 25, 29, 55, 57, -+ 77, 28, 57, 76, 63, 25, 25, 58, 59, 25, -+ 22, 25, 34, 14, 21, 22, 23, 24, 31, 36, -+ 60, 18, 33, 75, 22, 23, 30, 61, 36, 21, -+ 20, 22, 32, 34, 35, 61, 34, 61, 35 - }; - - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ - static const yytype_uint8 yyr1[] = - { -- 0, 47, 48, 49, 49, 50, 50, 51, 51, 51, -- 51, 51, 52, 53, 53, 54, 54, 54, 54, 55, -- 55, 55, 55, 55, 55, 55, 56, 56, 56, 57, -- 57, 57, 57, 57, 58, 58, 58, 59, 60, 60, -- 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, -- 66, 66, 66, 67, 67, 67, 67, 67, 68, 68, -- 68, 69, 69, 69, 70, 70, 70, 70, 71, 71, -- 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, -- 74 -+ 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, -+ 53, 54, 54, 54, 54, 54, 55, 56, 56, 57, -+ 57, 57, 57, 58, 58, 58, 58, 58, 58, 58, -+ 59, 59, 59, 60, 60, 60, 60, 60, 61, 61, -+ 61, 62, 63, 63, 64, 64, 65, 65, 66, 66, -+ 67, 67, 68, 68, 69, 69, 69, 70, 70, 70, -+ 70, 70, 71, 71, 71, 72, 72, 72, 73, 73, -+ 73, 73, 74, 74, 74, 74, 75, 75, 75, 76, -+ 76, 76, 77, 77, 77 - }; - - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ - static const yytype_uint8 yyr2[] = - { -- 0, 2, 4, 0, 2, 4, 2, 2, 3, 4, -- 3, 4, 5, 0, 2, 4, 2, 3, 2, 2, -- 3, 4, 2, 9, 5, 2, 0, 2, 2, 3, -- 1, 2, 2, 2, 1, 1, 3, 1, 1, 5, -- 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, -- 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, -- 1, 3, 3, 1, 3, 3, 3, 1, 1, 2, -- 2, 2, 0, 2, 2, 0, 2, 2, 2, 3, -- 2 -+ 0, 2, 3, 2, 4, 1, 2, 0, 2, 4, -+ 2, 2, 3, 4, 3, 4, 5, 0, 2, 4, -+ 2, 3, 2, 2, 3, 4, 2, 9, 5, 2, -+ 0, 2, 2, 3, 1, 2, 2, 2, 1, 1, -+ 3, 1, 1, 5, 1, 3, 1, 3, 1, 3, -+ 1, 3, 1, 3, 1, 3, 3, 1, 3, 3, -+ 3, 3, 3, 3, 1, 3, 3, 1, 3, 3, -+ 3, 1, 1, 2, 2, 2, 0, 2, 2, 0, -+ 2, 2, 2, 3, 2 - }; - - -@@ -1463,80 +1469,106 @@ yyreduce: - switch (yyn) - { - case 2: --#line 105 "dtc-parser.y" /* yacc.c:1646 */ -+#line 110 "dtc-parser.y" /* yacc.c:1646 */ - { -- the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), -- guess_boot_cpuid((yyvsp[0].node))); -+ parser_output = build_dt_info((yyvsp[-2].flags), (yyvsp[-1].re), (yyvsp[0].node), -+ guess_boot_cpuid((yyvsp[0].node))); - } --#line 1472 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1478 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 3: --#line 113 "dtc-parser.y" /* yacc.c:1646 */ -+#line 118 "dtc-parser.y" /* yacc.c:1646 */ - { -- (yyval.re) = NULL; -+ (yyval.flags) = DTSF_V1; - } --#line 1480 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1486 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - case 4: --#line 117 "dtc-parser.y" /* yacc.c:1646 */ -+#line 122 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.flags) = DTSF_V1 | DTSF_PLUGIN; -+ } -+#line 1494 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ case 6: -+#line 130 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ if ((yyvsp[0].flags) != (yyvsp[-1].flags)) -+ ERROR(&(yylsp[0]), "Header flags don't match earlier ones"); -+ (yyval.flags) = (yyvsp[-1].flags); -+ } -+#line 1504 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ case 7: -+#line 139 "dtc-parser.y" /* yacc.c:1646 */ -+ { -+ (yyval.re) = NULL; -+ } -+#line 1512 "dtc-parser.tab.c" /* yacc.c:1646 */ -+ break; -+ -+ case 8: -+#line 143 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); - } --#line 1488 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1520 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 5: --#line 124 "dtc-parser.y" /* yacc.c:1646 */ -+ case 9: -+#line 150 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); - } --#line 1496 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1528 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 6: --#line 128 "dtc-parser.y" /* yacc.c:1646 */ -+ case 10: -+#line 154 "dtc-parser.y" /* yacc.c:1646 */ - { - add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); - (yyval.re) = (yyvsp[0].re); - } --#line 1505 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1537 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 7: --#line 136 "dtc-parser.y" /* yacc.c:1646 */ -+ case 11: -+#line 162 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = name_node((yyvsp[0].node), ""); - } --#line 1513 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1545 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 8: --#line 140 "dtc-parser.y" /* yacc.c:1646 */ -+ case 12: -+#line 166 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); - } --#line 1521 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1553 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 9: --#line 145 "dtc-parser.y" /* yacc.c:1646 */ -+ case 13: -+#line 171 "dtc-parser.y" /* yacc.c:1646 */ - { - struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); - -- add_label(&target->labels, (yyvsp[-2].labelref)); -- if (target) -+ if (target) { -+ add_label(&target->labels, (yyvsp[-2].labelref)); - merge_nodes(target, (yyvsp[0].node)); -- else -+ } else - ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); - (yyval.node) = (yyvsp[-3].node); - } --#line 1536 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1568 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 10: --#line 156 "dtc-parser.y" /* yacc.c:1646 */ -+ case 14: -+#line 182 "dtc-parser.y" /* yacc.c:1646 */ - { - struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); - -@@ -1546,11 +1578,11 @@ yyreduce: - ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); - (yyval.node) = (yyvsp[-2].node); - } --#line 1550 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 11: --#line 166 "dtc-parser.y" /* yacc.c:1646 */ -+ case 15: -+#line 192 "dtc-parser.y" /* yacc.c:1646 */ - { - struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); - -@@ -1562,100 +1594,100 @@ yyreduce: - - (yyval.node) = (yyvsp[-3].node); - } --#line 1566 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 12: --#line 181 "dtc-parser.y" /* yacc.c:1646 */ -+ case 16: -+#line 207 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); - } --#line 1574 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 13: --#line 188 "dtc-parser.y" /* yacc.c:1646 */ -+ case 17: -+#line 214 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.proplist) = NULL; - } --#line 1582 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 14: --#line 192 "dtc-parser.y" /* yacc.c:1646 */ -+ case 18: -+#line 218 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); - } --#line 1590 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1622 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 15: --#line 199 "dtc-parser.y" /* yacc.c:1646 */ -+ case 19: -+#line 225 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); - } --#line 1598 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1630 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 16: --#line 203 "dtc-parser.y" /* yacc.c:1646 */ -+ case 20: -+#line 229 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); - } --#line 1606 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1638 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 17: --#line 207 "dtc-parser.y" /* yacc.c:1646 */ -+ case 21: -+#line 233 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); - } --#line 1614 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1646 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 18: --#line 211 "dtc-parser.y" /* yacc.c:1646 */ -+ case 22: -+#line 237 "dtc-parser.y" /* yacc.c:1646 */ - { - add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); - (yyval.prop) = (yyvsp[0].prop); - } --#line 1623 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 19: --#line 219 "dtc-parser.y" /* yacc.c:1646 */ -+ case 23: -+#line 245 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); - } --#line 1631 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1663 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 20: --#line 223 "dtc-parser.y" /* yacc.c:1646 */ -+ case 24: -+#line 249 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); - } --#line 1639 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1671 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 21: --#line 227 "dtc-parser.y" /* yacc.c:1646 */ -+ case 25: -+#line 253 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); - } --#line 1647 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1679 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 22: --#line 231 "dtc-parser.y" /* yacc.c:1646 */ -+ case 26: -+#line 257 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); - } --#line 1655 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1687 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 23: --#line 235 "dtc-parser.y" /* yacc.c:1646 */ -+ case 27: -+#line 261 "dtc-parser.y" /* yacc.c:1646 */ - { - FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); - struct data d; -@@ -1671,11 +1703,11 @@ yyreduce: - (yyval.data) = data_merge((yyvsp[-8].data), d); - fclose(f); - } --#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1707 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 24: --#line 251 "dtc-parser.y" /* yacc.c:1646 */ -+ case 28: -+#line 277 "dtc-parser.y" /* yacc.c:1646 */ - { - FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); - struct data d = empty_data; -@@ -1685,43 +1717,43 @@ yyreduce: - (yyval.data) = data_merge((yyvsp[-4].data), d); - fclose(f); - } --#line 1689 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 25: --#line 261 "dtc-parser.y" /* yacc.c:1646 */ -+ case 29: -+#line 287 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } --#line 1697 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1729 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 26: --#line 268 "dtc-parser.y" /* yacc.c:1646 */ -+ case 30: -+#line 294 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = empty_data; - } --#line 1705 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1737 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 27: --#line 272 "dtc-parser.y" /* yacc.c:1646 */ -+ case 31: -+#line 298 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = (yyvsp[-1].data); - } --#line 1713 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1745 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 28: --#line 276 "dtc-parser.y" /* yacc.c:1646 */ -+ case 32: -+#line 302 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } --#line 1721 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1753 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 29: --#line 283 "dtc-parser.y" /* yacc.c:1646 */ -+ case 33: -+#line 309 "dtc-parser.y" /* yacc.c:1646 */ - { - unsigned long long bits; - -@@ -1737,20 +1769,20 @@ yyreduce: - (yyval.array).data = empty_data; - (yyval.array).bits = bits; - } --#line 1741 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 30: --#line 299 "dtc-parser.y" /* yacc.c:1646 */ -+ case 34: -+#line 325 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.array).data = empty_data; - (yyval.array).bits = 32; - } --#line 1750 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1782 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 31: --#line 304 "dtc-parser.y" /* yacc.c:1646 */ -+ case 35: -+#line 330 "dtc-parser.y" /* yacc.c:1646 */ - { - if ((yyvsp[-1].array).bits < 64) { - uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; -@@ -1769,11 +1801,11 @@ yyreduce: - - (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); - } --#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1805 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 32: --#line 323 "dtc-parser.y" /* yacc.c:1646 */ -+ case 36: -+#line 349 "dtc-parser.y" /* yacc.c:1646 */ - { - uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); - -@@ -1787,129 +1819,129 @@ yyreduce: - - (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); - } --#line 1791 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1823 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 33: --#line 337 "dtc-parser.y" /* yacc.c:1646 */ -+ case 37: -+#line 363 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); - } --#line 1799 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 36: --#line 346 "dtc-parser.y" /* yacc.c:1646 */ -+ case 40: -+#line 372 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.integer) = (yyvsp[-1].integer); - } --#line 1807 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1839 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 39: --#line 357 "dtc-parser.y" /* yacc.c:1646 */ -+ case 43: -+#line 383 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } --#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1845 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 41: --#line 362 "dtc-parser.y" /* yacc.c:1646 */ -+ case 45: -+#line 388 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } --#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1851 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 43: --#line 367 "dtc-parser.y" /* yacc.c:1646 */ -+ case 47: -+#line 393 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } --#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1857 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 45: --#line 372 "dtc-parser.y" /* yacc.c:1646 */ -+ case 49: -+#line 398 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } --#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1863 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 47: --#line 377 "dtc-parser.y" /* yacc.c:1646 */ -+ case 51: -+#line 403 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } --#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1869 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 49: --#line 382 "dtc-parser.y" /* yacc.c:1646 */ -+ case 53: -+#line 408 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } --#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1875 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 51: --#line 387 "dtc-parser.y" /* yacc.c:1646 */ -+ case 55: -+#line 413 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } --#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1881 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 52: --#line 388 "dtc-parser.y" /* yacc.c:1646 */ -+ case 56: -+#line 414 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } --#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1887 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 54: --#line 393 "dtc-parser.y" /* yacc.c:1646 */ -+ case 58: -+#line 419 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } --#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1893 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 55: --#line 394 "dtc-parser.y" /* yacc.c:1646 */ -+ case 59: -+#line 420 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } --#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1899 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 56: --#line 395 "dtc-parser.y" /* yacc.c:1646 */ -+ case 60: -+#line 421 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } --#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1905 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 57: --#line 396 "dtc-parser.y" /* yacc.c:1646 */ -+ case 61: -+#line 422 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } --#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1911 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 58: --#line 400 "dtc-parser.y" /* yacc.c:1646 */ -+ case 62: -+#line 426 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } --#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1917 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 59: --#line 401 "dtc-parser.y" /* yacc.c:1646 */ -+ case 63: -+#line 427 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } --#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1923 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 61: --#line 406 "dtc-parser.y" /* yacc.c:1646 */ -+ case 65: -+#line 432 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } --#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 62: --#line 407 "dtc-parser.y" /* yacc.c:1646 */ -+ case 66: -+#line 433 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } --#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 64: --#line 412 "dtc-parser.y" /* yacc.c:1646 */ -+ case 68: -+#line 438 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } --#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 65: --#line 414 "dtc-parser.y" /* yacc.c:1646 */ -+ case 69: -+#line 440 "dtc-parser.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].integer) != 0) { - (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); -@@ -1918,11 +1950,11 @@ yyreduce: - (yyval.integer) = 0; - } - } --#line 1922 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1954 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 66: --#line 423 "dtc-parser.y" /* yacc.c:1646 */ -+ case 70: -+#line 449 "dtc-parser.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].integer) != 0) { - (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); -@@ -1931,103 +1963,103 @@ yyreduce: - (yyval.integer) = 0; - } - } --#line 1935 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1967 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 69: --#line 436 "dtc-parser.y" /* yacc.c:1646 */ -+ case 73: -+#line 462 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = -(yyvsp[0].integer); } --#line 1941 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1973 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 70: --#line 437 "dtc-parser.y" /* yacc.c:1646 */ -+ case 74: -+#line 463 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = ~(yyvsp[0].integer); } --#line 1947 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1979 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 71: --#line 438 "dtc-parser.y" /* yacc.c:1646 */ -+ case 75: -+#line 464 "dtc-parser.y" /* yacc.c:1646 */ - { (yyval.integer) = !(yyvsp[0].integer); } --#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 72: --#line 443 "dtc-parser.y" /* yacc.c:1646 */ -+ case 76: -+#line 469 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = empty_data; - } --#line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 73: --#line 447 "dtc-parser.y" /* yacc.c:1646 */ -+ case 77: -+#line 473 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); - } --#line 1969 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2001 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 74: --#line 451 "dtc-parser.y" /* yacc.c:1646 */ -+ case 78: -+#line 477 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); - } --#line 1977 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2009 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 75: --#line 458 "dtc-parser.y" /* yacc.c:1646 */ -+ case 79: -+#line 484 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.nodelist) = NULL; - } --#line 1985 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2017 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 76: --#line 462 "dtc-parser.y" /* yacc.c:1646 */ -+ case 80: -+#line 488 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); - } --#line 1993 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2025 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 77: --#line 466 "dtc-parser.y" /* yacc.c:1646 */ -+ case 81: -+#line 492 "dtc-parser.y" /* yacc.c:1646 */ - { - ERROR(&(yylsp[0]), "Properties must precede subnodes"); - YYERROR; - } --#line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2034 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 78: --#line 474 "dtc-parser.y" /* yacc.c:1646 */ -+ case 82: -+#line 500 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); - } --#line 2010 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2042 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 79: --#line 478 "dtc-parser.y" /* yacc.c:1646 */ -+ case 83: -+#line 504 "dtc-parser.y" /* yacc.c:1646 */ - { - (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); - } --#line 2018 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2050 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - -- case 80: --#line 482 "dtc-parser.y" /* yacc.c:1646 */ -+ case 84: -+#line 508 "dtc-parser.y" /* yacc.c:1646 */ - { - add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); - (yyval.node) = (yyvsp[0].node); - } --#line 2027 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2059 "dtc-parser.tab.c" /* yacc.c:1646 */ - break; - - --#line 2031 "dtc-parser.tab.c" /* yacc.c:1646 */ -+#line 2063 "dtc-parser.tab.c" /* yacc.c:1646 */ - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires -@@ -2262,7 +2294,7 @@ yyreturn: - #endif - return yyresult; - } --#line 488 "dtc-parser.y" /* yacc.c:1906 */ -+#line 514 "dtc-parser.y" /* yacc.c:1906 */ - - - void yyerror(char const *s) -diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped -index 30867c6..6aa512c 100644 ---- a/scripts/dtc/dtc-parser.tab.h_shipped -+++ b/scripts/dtc/dtc-parser.tab.h_shipped -@@ -1,8 +1,8 @@ --/* A Bison parser, made by GNU Bison 3.0.2. */ -+/* A Bison parser, made by GNU Bison 3.0.4. */ - - /* Bison interface for Yacc-like parsers in C - -- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. -+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by -@@ -46,35 +46,36 @@ extern int yydebug; - enum yytokentype - { - DT_V1 = 258, -- DT_MEMRESERVE = 259, -- DT_LSHIFT = 260, -- DT_RSHIFT = 261, -- DT_LE = 262, -- DT_GE = 263, -- DT_EQ = 264, -- DT_NE = 265, -- DT_AND = 266, -- DT_OR = 267, -- DT_BITS = 268, -- DT_DEL_PROP = 269, -- DT_DEL_NODE = 270, -- DT_PROPNODENAME = 271, -- DT_LITERAL = 272, -- DT_CHAR_LITERAL = 273, -- DT_BYTE = 274, -- DT_STRING = 275, -- DT_LABEL = 276, -- DT_REF = 277, -- DT_INCBIN = 278 -+ DT_PLUGIN = 259, -+ DT_MEMRESERVE = 260, -+ DT_LSHIFT = 261, -+ DT_RSHIFT = 262, -+ DT_LE = 263, -+ DT_GE = 264, -+ DT_EQ = 265, -+ DT_NE = 266, -+ DT_AND = 267, -+ DT_OR = 268, -+ DT_BITS = 269, -+ DT_DEL_PROP = 270, -+ DT_DEL_NODE = 271, -+ DT_PROPNODENAME = 272, -+ DT_LITERAL = 273, -+ DT_CHAR_LITERAL = 274, -+ DT_BYTE = 275, -+ DT_STRING = 276, -+ DT_LABEL = 277, -+ DT_REF = 278, -+ DT_INCBIN = 279 - }; - #endif - - /* Value type. */ - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED --typedef union YYSTYPE YYSTYPE; -+ - union YYSTYPE - { --#line 38 "dtc-parser.y" /* yacc.c:1909 */ -+#line 39 "dtc-parser.y" /* yacc.c:1909 */ - - char *propnodename; - char *labelref; -@@ -92,9 +93,12 @@ union YYSTYPE - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ unsigned int flags; - --#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */ -+#line 99 "dtc-parser.tab.h" /* yacc.c:1909 */ - }; -+ -+typedef union YYSTYPE YYSTYPE; - # define YYSTYPE_IS_TRIVIAL 1 - # define YYSTYPE_IS_DECLARED 1 - #endif -diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y -index 000873f..ca3f500 100644 ---- a/scripts/dtc/dtc-parser.y -+++ b/scripts/dtc/dtc-parser.y -@@ -19,6 +19,7 @@ - */ - %{ - #include <stdio.h> -+#include <inttypes.h> - - #include "dtc.h" - #include "srcpos.h" -@@ -31,7 +32,7 @@ extern void yyerror(char const *s); - treesource_error = true; \ - } while (0) - --extern struct boot_info *the_boot_info; -+extern struct dt_info *parser_output; - extern bool treesource_error; - %} - -@@ -52,9 +53,11 @@ extern bool treesource_error; - struct node *nodelist; - struct reserve_info *re; - uint64_t integer; -+ unsigned int flags; - } - - %token DT_V1 -+%token DT_PLUGIN - %token DT_MEMRESERVE - %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR - %token DT_BITS -@@ -71,6 +74,8 @@ extern bool treesource_error; - - %type <data> propdata - %type <data> propdataprefix -+%type <flags> header -+%type <flags> headers - %type <re> memreserve - %type <re> memreserves - %type <array> arrayprefix -@@ -101,10 +106,31 @@ extern bool treesource_error; - %% - - sourcefile: -- DT_V1 ';' memreserves devicetree -+ headers memreserves devicetree - { -- the_boot_info = build_boot_info($3, $4, -- guess_boot_cpuid($4)); -+ parser_output = build_dt_info($1, $2, $3, -+ guess_boot_cpuid($3)); -+ } -+ ; -+ -+header: -+ DT_V1 ';' -+ { -+ $$ = DTSF_V1; -+ } -+ | DT_V1 ';' DT_PLUGIN ';' -+ { -+ $$ = DTSF_V1 | DTSF_PLUGIN; -+ } -+ ; -+ -+headers: -+ header -+ | header headers -+ { -+ if ($2 != $1) -+ ERROR(&@2, "Header flags don't match earlier ones"); -+ $$ = $1; - } - ; - -@@ -145,10 +171,10 @@ devicetree: - { - struct node *target = get_node_by_ref($1, $3); - -- add_label(&target->labels, $2); -- if (target) -+ if (target) { -+ add_label(&target->labels, $2); - merge_nodes(target, $4); -- else -+ } else - ERROR(&@3, "Label or path %s not found", $3); - $$ = $1; - } -diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c -index 5fa23c4..f5eed9d 100644 ---- a/scripts/dtc/dtc.c -+++ b/scripts/dtc/dtc.c -@@ -30,7 +30,16 @@ int quiet; /* Level of quietness */ - int reservenum; /* Number of memory reservation slots */ - int minsize; /* Minimum blob size */ - int padsize; /* Additional padding to blob */ -+int alignsize; /* Additional padding to blob accroding to the alignsize */ - int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ -+int generate_symbols; /* enable symbols & fixup support */ -+int generate_fixups; /* suppress generation of fixups on symbol support */ -+int auto_label_aliases; /* auto generate labels -> aliases */ -+ -+static int is_power_of_2(int x) -+{ -+ return (x > 0) && ((x & (x - 1)) == 0); -+} - - static void fill_fullpaths(struct node *tree, const char *prefix) - { -@@ -53,7 +62,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix) - #define FDT_VERSION(version) _FDT_VERSION(version) - #define _FDT_VERSION(version) #version - static const char usage_synopsis[] = "dtc [options] <input file>"; --static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; -+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv"; - static struct option const usage_long_opts[] = { - {"quiet", no_argument, NULL, 'q'}, - {"in-format", a_argument, NULL, 'I'}, -@@ -64,6 +73,7 @@ static struct option const usage_long_opts[] = { - {"reserve", a_argument, NULL, 'R'}, - {"space", a_argument, NULL, 'S'}, - {"pad", a_argument, NULL, 'p'}, -+ {"align", a_argument, NULL, 'a'}, - {"boot-cpu", a_argument, NULL, 'b'}, - {"force", no_argument, NULL, 'f'}, - {"include", a_argument, NULL, 'i'}, -@@ -71,6 +81,8 @@ static struct option const usage_long_opts[] = { - {"phandle", a_argument, NULL, 'H'}, - {"warning", a_argument, NULL, 'W'}, - {"error", a_argument, NULL, 'E'}, -+ {"symbols", no_argument, NULL, '@'}, -+ {"auto-alias", no_argument, NULL, 'A'}, - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'v'}, - {NULL, no_argument, NULL, 0x0}, -@@ -91,6 +103,7 @@ static const char * const usage_opts_help[] = { - "\n\tMake space for <number> reserve map entries (for dtb and asm output)", - "\n\tMake the blob at least <bytes> long (extra space)", - "\n\tAdd padding to the blob of <bytes> long (extra space)", -+ "\n\tMake the blob align to the <bytes> (extra space)", - "\n\tSet the physical boot cpu", - "\n\tTry to produce output even if the input tree has errors", - "\n\tAdd a path to search for include files", -@@ -101,6 +114,8 @@ static const char * const usage_opts_help[] = { - "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", - "\n\tEnable/disable warnings (prefix with \"no-\")", - "\n\tEnable/disable errors (prefix with \"no-\")", -+ "\n\tEnable generation of symbols", -+ "\n\tEnable auto-alias of labels", - "\n\tPrint this help and exit", - "\n\tPrint version and exit", - NULL, -@@ -123,7 +138,7 @@ static const char *guess_type_by_name(const char *fname, const char *fallback) - static const char *guess_input_format(const char *fname, const char *fallback) - { - struct stat statbuf; -- uint32_t magic; -+ fdt32_t magic; - FILE *f; - - if (stat(fname, &statbuf) != 0) -@@ -144,8 +159,7 @@ static const char *guess_input_format(const char *fname, const char *fallback) - } - fclose(f); - -- magic = fdt32_to_cpu(magic); -- if (magic == FDT_MAGIC) -+ if (fdt32_to_cpu(magic) == FDT_MAGIC) - return "dtb"; - - return guess_type_by_name(fname, fallback); -@@ -153,7 +167,7 @@ static const char *guess_input_format(const char *fname, const char *fallback) - - int main(int argc, char *argv[]) - { -- struct boot_info *bi; -+ struct dt_info *dti; - const char *inform = NULL; - const char *outform = NULL; - const char *outname = "-"; -@@ -169,6 +183,7 @@ int main(int argc, char *argv[]) - reservenum = 0; - minsize = 0; - padsize = 0; -+ alignsize = 0; - - while ((opt = util_getopt_long()) != EOF) { - switch (opt) { -@@ -196,6 +211,12 @@ int main(int argc, char *argv[]) - case 'p': - padsize = strtol(optarg, NULL, 0); - break; -+ case 'a': -+ alignsize = strtol(optarg, NULL, 0); -+ if (!is_power_of_2(alignsize)) -+ die("Invalid argument \"%d\" to -a option\n", -+ alignsize); -+ break; - case 'f': - force = true; - break; -@@ -234,6 +255,13 @@ int main(int argc, char *argv[]) - parse_checks_option(false, true, optarg); - break; - -+ case '@': -+ generate_symbols = 1; -+ break; -+ case 'A': -+ auto_label_aliases = 1; -+ break; -+ - case 'h': - usage(NULL); - default: -@@ -272,27 +300,45 @@ int main(int argc, char *argv[]) - } - } - if (streq(inform, "dts")) -- bi = dt_from_source(arg); -+ dti = dt_from_source(arg); - else if (streq(inform, "fs")) -- bi = dt_from_fs(arg); -+ dti = dt_from_fs(arg); - else if(streq(inform, "dtb")) -- bi = dt_from_blob(arg); -+ dti = dt_from_blob(arg); - else - die("Unknown input format \"%s\"\n", inform); - -+ dti->outname = outname; -+ - if (depfile) { - fputc('\n', depfile); - fclose(depfile); - } - - if (cmdline_boot_cpuid != -1) -- bi->boot_cpuid_phys = cmdline_boot_cpuid; -+ dti->boot_cpuid_phys = cmdline_boot_cpuid; -+ -+ fill_fullpaths(dti->dt, ""); -+ process_checks(force, dti); -+ -+ /* on a plugin, generate by default */ -+ if (dti->dtsflags & DTSF_PLUGIN) { -+ generate_fixups = 1; -+ } - -- fill_fullpaths(bi->dt, ""); -- process_checks(force, bi); -+ if (auto_label_aliases) -+ generate_label_tree(dti, "aliases", false); -+ -+ if (generate_symbols) -+ generate_label_tree(dti, "__symbols__", true); -+ -+ if (generate_fixups) { -+ generate_fixups_tree(dti, "__fixups__"); -+ generate_local_fixups_tree(dti, "__local_fixups__"); -+ } - - if (sort) -- sort_tree(bi); -+ sort_tree(dti); - - if (streq(outname, "-")) { - outf = stdout; -@@ -304,11 +350,11 @@ int main(int argc, char *argv[]) - } - - if (streq(outform, "dts")) { -- dt_to_source(outf, bi); -+ dt_to_source(outf, dti); - } else if (streq(outform, "dtb")) { -- dt_to_blob(outf, bi, outversion); -+ dt_to_blob(outf, dti, outversion); - } else if (streq(outform, "asm")) { -- dt_to_asm(outf, bi, outversion); -+ dt_to_asm(outf, dti, outversion); - } else if (streq(outform, "null")) { - /* do nothing */ - } else { -diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h -index 56212c8..403b79d 100644 ---- a/scripts/dtc/dtc.h -+++ b/scripts/dtc/dtc.h -@@ -43,7 +43,6 @@ - #define debug(...) - #endif - -- - #define DEFAULT_FDT_VERSION 17 - - /* -@@ -53,7 +52,11 @@ extern int quiet; /* Level of quietness */ - extern int reservenum; /* Number of memory reservation slots */ - extern int minsize; /* Minimum blob size */ - extern int padsize; /* Additional padding to blob */ -+extern int alignsize; /* Additional padding to blob accroding to the alignsize */ - extern int phandle_format; /* Use linux,phandle or phandle properties */ -+extern int generate_symbols; /* generate symbols for nodes with labels */ -+extern int generate_fixups; /* generate fixups */ -+extern int auto_label_aliases; /* auto generate labels -> aliases */ - - #define PHANDLE_LEGACY 0x1 - #define PHANDLE_EPAPR 0x2 -@@ -110,7 +113,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m, - struct data data_merge(struct data d1, struct data d2); - struct data data_append_cell(struct data d, cell_t word); - struct data data_append_integer(struct data d, uint64_t word, int bits); --struct data data_append_re(struct data d, const struct fdt_reserve_entry *re); -+struct data data_append_re(struct data d, uint64_t address, uint64_t size); - struct data data_append_addr(struct data d, uint64_t addr); - struct data data_append_byte(struct data d, uint8_t byte); - struct data data_append_zeroes(struct data d, int len); -@@ -201,6 +204,8 @@ void delete_property(struct property *prop); - void add_child(struct node *parent, struct node *child); - void delete_node_by_name(struct node *parent, char *name); - void delete_node(struct node *node); -+void append_to_property(struct node *node, -+ char *name, const void *data, int len); - - const char *get_unitname(struct node *node); - struct property *get_property(struct node *node, const char *propname); -@@ -221,7 +226,7 @@ uint32_t guess_boot_cpuid(struct node *tree); - /* Boot info (tree plus memreserve information */ - - struct reserve_info { -- struct fdt_reserve_entry re; -+ uint64_t address, size; - - struct reserve_info *next; - -@@ -235,35 +240,45 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list, - struct reserve_info *new); - - --struct boot_info { -+struct dt_info { -+ unsigned int dtsflags; - struct reserve_info *reservelist; -- struct node *dt; /* the device tree */ - uint32_t boot_cpuid_phys; -+ struct node *dt; /* the device tree */ -+ const char *outname; /* filename being written to, "-" for stdout */ - }; - --struct boot_info *build_boot_info(struct reserve_info *reservelist, -- struct node *tree, uint32_t boot_cpuid_phys); --void sort_tree(struct boot_info *bi); -+/* DTS version flags definitions */ -+#define DTSF_V1 0x0001 /* /dts-v1/ */ -+#define DTSF_PLUGIN 0x0002 /* /plugin/ */ -+ -+struct dt_info *build_dt_info(unsigned int dtsflags, -+ struct reserve_info *reservelist, -+ struct node *tree, uint32_t boot_cpuid_phys); -+void sort_tree(struct dt_info *dti); -+void generate_label_tree(struct dt_info *dti, char *name, bool allocph); -+void generate_fixups_tree(struct dt_info *dti, char *name); -+void generate_local_fixups_tree(struct dt_info *dti, char *name); - - /* Checks */ - - void parse_checks_option(bool warn, bool error, const char *arg); --void process_checks(bool force, struct boot_info *bi); -+void process_checks(bool force, struct dt_info *dti); - - /* Flattened trees */ - --void dt_to_blob(FILE *f, struct boot_info *bi, int version); --void dt_to_asm(FILE *f, struct boot_info *bi, int version); -+void dt_to_blob(FILE *f, struct dt_info *dti, int version); -+void dt_to_asm(FILE *f, struct dt_info *dti, int version); - --struct boot_info *dt_from_blob(const char *fname); -+struct dt_info *dt_from_blob(const char *fname); - - /* Tree source */ - --void dt_to_source(FILE *f, struct boot_info *bi); --struct boot_info *dt_from_source(const char *f); -+void dt_to_source(FILE *f, struct dt_info *dti); -+struct dt_info *dt_from_source(const char *f); - - /* FS trees */ - --struct boot_info *dt_from_fs(const char *dirname); -+struct dt_info *dt_from_fs(const char *dirname); - - #endif /* _DTC_H */ -diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c -index ec14954..fcf7154 100644 ---- a/scripts/dtc/flattree.c -+++ b/scripts/dtc/flattree.c -@@ -49,7 +49,7 @@ static struct version_info { - - struct emitter { - void (*cell)(void *, cell_t); -- void (*string)(void *, char *, int); -+ void (*string)(void *, const char *, int); - void (*align)(void *, int); - void (*data)(void *, struct data); - void (*beginnode)(void *, struct label *labels); -@@ -64,7 +64,7 @@ static void bin_emit_cell(void *e, cell_t val) - *dtbuf = data_append_cell(*dtbuf, val); - } - --static void bin_emit_string(void *e, char *str, int len) -+static void bin_emit_string(void *e, const char *str, int len) - { - struct data *dtbuf = e; - -@@ -144,22 +144,14 @@ static void asm_emit_cell(void *e, cell_t val) - (val >> 8) & 0xff, val & 0xff); - } - --static void asm_emit_string(void *e, char *str, int len) -+static void asm_emit_string(void *e, const char *str, int len) - { - FILE *f = e; -- char c = 0; - -- if (len != 0) { -- /* XXX: ewww */ -- c = str[len]; -- str[len] = '\0'; -- } -- -- fprintf(f, "\t.string\t\"%s\"\n", str); -- -- if (len != 0) { -- str[len] = c; -- } -+ if (len != 0) -+ fprintf(f, "\t.string\t\"%.*s\"\n", len, str); -+ else -+ fprintf(f, "\t.string\t\"%s\"\n", str); - } - - static void asm_emit_align(void *e, int a) -@@ -179,7 +171,7 @@ static void asm_emit_data(void *e, struct data d) - emit_offset_label(f, m->ref, m->offset); - - while ((d.len - off) >= sizeof(uint32_t)) { -- asm_emit_cell(e, fdt32_to_cpu(*((uint32_t *)(d.val+off)))); -+ asm_emit_cell(e, fdt32_to_cpu(*((fdt32_t *)(d.val+off)))); - off += sizeof(uint32_t); - } - -@@ -318,17 +310,16 @@ static struct data flatten_reserve_list(struct reserve_info *reservelist, - { - struct reserve_info *re; - struct data d = empty_data; -- static struct fdt_reserve_entry null_re = {0,0}; - int j; - - for (re = reservelist; re; re = re->next) { -- d = data_append_re(d, &re->re); -+ d = data_append_re(d, re->address, re->size); - } - /* - * Add additional reserved slots if the user asked for them. - */ - for (j = 0; j < reservenum; j++) { -- d = data_append_re(d, &null_re); -+ d = data_append_re(d, 0, 0); - } - - return d; -@@ -366,7 +357,7 @@ static void make_fdt_header(struct fdt_header *fdt, - fdt->size_dt_struct = cpu_to_fdt32(dtsize); - } - --void dt_to_blob(FILE *f, struct boot_info *bi, int version) -+void dt_to_blob(FILE *f, struct dt_info *dti, int version) - { - struct version_info *vi = NULL; - int i; -@@ -384,29 +375,36 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version) - if (!vi) - die("Unknown device tree blob version %d\n", version); - -- flatten_tree(bi->dt, &bin_emitter, &dtbuf, &strbuf, vi); -+ flatten_tree(dti->dt, &bin_emitter, &dtbuf, &strbuf, vi); - bin_emit_cell(&dtbuf, FDT_END); - -- reservebuf = flatten_reserve_list(bi->reservelist, vi); -+ reservebuf = flatten_reserve_list(dti->reservelist, vi); - - /* Make header */ - make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len, -- bi->boot_cpuid_phys); -+ dti->boot_cpuid_phys); - - /* - * If the user asked for more space than is used, adjust the totalsize. - */ - if (minsize > 0) { - padlen = minsize - fdt32_to_cpu(fdt.totalsize); -- if ((padlen < 0) && (quiet < 1)) -- fprintf(stderr, -- "Warning: blob size %d >= minimum size %d\n", -- fdt32_to_cpu(fdt.totalsize), minsize); -+ if (padlen < 0) { -+ padlen = 0; -+ if (quiet < 1) -+ fprintf(stderr, -+ "Warning: blob size %d >= minimum size %d\n", -+ fdt32_to_cpu(fdt.totalsize), minsize); -+ } - } - - if (padsize > 0) - padlen = padsize; - -+ if (alignsize > 0) -+ padlen = ALIGN(fdt32_to_cpu(fdt.totalsize) + padlen, alignsize) -+ - fdt32_to_cpu(fdt.totalsize); -+ - if (padlen > 0) { - int tsize = fdt32_to_cpu(fdt.totalsize); - tsize += padlen; -@@ -460,7 +458,7 @@ static void dump_stringtable_asm(FILE *f, struct data strbuf) - } - } - --void dt_to_asm(FILE *f, struct boot_info *bi, int version) -+void dt_to_asm(FILE *f, struct dt_info *dti, int version) - { - struct version_info *vi = NULL; - int i; -@@ -500,7 +498,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) - - if (vi->flags & FTF_BOOTCPUID) { - fprintf(f, "\t/* boot_cpuid_phys */\n"); -- asm_emit_cell(f, bi->boot_cpuid_phys); -+ asm_emit_cell(f, dti->boot_cpuid_phys); - } - - if (vi->flags & FTF_STRTABSIZE) { -@@ -530,18 +528,18 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) - * Use .long on high and low halfs of u64s to avoid .quad - * as it appears .quad isn't available in some assemblers. - */ -- for (re = bi->reservelist; re; re = re->next) { -+ for (re = dti->reservelist; re; re = re->next) { - struct label *l; - - for_each_label(re->labels, l) { - fprintf(f, "\t.globl\t%s\n", l->label); - fprintf(f, "%s:\n", l->label); - } -- ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32)); -+ ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->address >> 32)); - ASM_EMIT_BELONG(f, "0x%08x", -- (unsigned int)(re->re.address & 0xffffffff)); -- ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32)); -- ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff)); -+ (unsigned int)(re->address & 0xffffffff)); -+ ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size >> 32)); -+ ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size & 0xffffffff)); - } - for (i = 0; i < reservenum; i++) { - fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); -@@ -550,7 +548,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) - fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); - - emit_label(f, symprefix, "struct_start"); -- flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi); -+ flatten_tree(dti->dt, &asm_emitter, f, &strbuf, vi); - - fprintf(f, "\t/* FDT_END */\n"); - asm_emit_cell(f, FDT_END); -@@ -572,6 +570,8 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) - if (padsize > 0) { - fprintf(f, "\t.space\t%d, 0\n", padsize); - } -+ if (alignsize > 0) -+ asm_emit_align(f, alignsize); - emit_label(f, symprefix, "blob_abs_end"); - - data_free(strbuf); -@@ -600,7 +600,7 @@ static void flat_read_chunk(struct inbuf *inb, void *p, int len) - - static uint32_t flat_read_word(struct inbuf *inb) - { -- uint32_t val; -+ fdt32_t val; - - assert(((inb->ptr - inb->base) % sizeof(val)) == 0); - -@@ -709,13 +709,15 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) - * First pass, count entries. - */ - while (1) { -+ uint64_t address, size; -+ - flat_read_chunk(inb, &re, sizeof(re)); -- re.address = fdt64_to_cpu(re.address); -- re.size = fdt64_to_cpu(re.size); -- if (re.size == 0) -+ address = fdt64_to_cpu(re.address); -+ size = fdt64_to_cpu(re.size); -+ if (size == 0) - break; - -- new = build_reserve_entry(re.address, re.size); -+ new = build_reserve_entry(address, size); - reservelist = add_reserve_entry(reservelist, new); - } - -@@ -797,13 +799,18 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, - } - } while (val != FDT_END_NODE); - -+ if (node->name != flatname) { -+ free(flatname); -+ } -+ - return node; - } - - --struct boot_info *dt_from_blob(const char *fname) -+struct dt_info *dt_from_blob(const char *fname) - { - FILE *f; -+ fdt32_t magic_buf, totalsize_buf; - uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys; - uint32_t off_dt, off_str, off_mem_rsvmap; - int rc; -@@ -820,7 +827,7 @@ struct boot_info *dt_from_blob(const char *fname) - - f = srcfile_relative_open(fname, NULL); - -- rc = fread(&magic, sizeof(magic), 1, f); -+ rc = fread(&magic_buf, sizeof(magic_buf), 1, f); - if (ferror(f)) - die("Error reading DT blob magic number: %s\n", - strerror(errno)); -@@ -831,11 +838,11 @@ struct boot_info *dt_from_blob(const char *fname) - die("Mysterious short read reading magic number\n"); - } - -- magic = fdt32_to_cpu(magic); -+ magic = fdt32_to_cpu(magic_buf); - if (magic != FDT_MAGIC) - die("Blob has incorrect magic number\n"); - -- rc = fread(&totalsize, sizeof(totalsize), 1, f); -+ rc = fread(&totalsize_buf, sizeof(totalsize_buf), 1, f); - if (ferror(f)) - die("Error reading DT blob size: %s\n", strerror(errno)); - if (rc < 1) { -@@ -845,7 +852,7 @@ struct boot_info *dt_from_blob(const char *fname) - die("Mysterious short read reading blob size\n"); - } - -- totalsize = fdt32_to_cpu(totalsize); -+ totalsize = fdt32_to_cpu(totalsize_buf); - if (totalsize < FDT_V1_SIZE) - die("DT blob size (%d) is too small\n", totalsize); - -@@ -929,5 +936,5 @@ struct boot_info *dt_from_blob(const char *fname) - - fclose(f); - -- return build_boot_info(reservelist, tree, boot_cpuid_phys); -+ return build_dt_info(DTSF_V1, reservelist, tree, boot_cpuid_phys); - } -diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c -index 6d1beec..ae7d06c 100644 ---- a/scripts/dtc/fstree.c -+++ b/scripts/dtc/fstree.c -@@ -79,13 +79,12 @@ static struct node *read_fstree(const char *dirname) - return tree; - } - --struct boot_info *dt_from_fs(const char *dirname) -+struct dt_info *dt_from_fs(const char *dirname) - { - struct node *tree; - - tree = read_fstree(dirname); - tree = name_node(tree, ""); - -- return build_boot_info(NULL, tree, guess_boot_cpuid(tree)); -+ return build_dt_info(DTSF_V1, NULL, tree, guess_boot_cpuid(tree)); - } -- -diff --git a/scripts/dtc/libfdt/Makefile.libfdt b/scripts/dtc/libfdt/Makefile.libfdt -index 09c322e..098b3f3 100644 ---- a/scripts/dtc/libfdt/Makefile.libfdt -+++ b/scripts/dtc/libfdt/Makefile.libfdt -@@ -7,5 +7,5 @@ LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1 - LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h - LIBFDT_VERSION = version.lds - LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \ -- fdt_addresses.c -+ fdt_addresses.c fdt_overlay.c - LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o) -diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c -index 50cce86..3d00d2e 100644 ---- a/scripts/dtc/libfdt/fdt_ro.c -+++ b/scripts/dtc/libfdt/fdt_ro.c -@@ -88,6 +88,32 @@ static int _fdt_string_eq(const void *fdt, int stroffset, - return (strlen(p) == len) && (memcmp(p, s, len) == 0); - } - -+uint32_t fdt_get_max_phandle(const void *fdt) -+{ -+ uint32_t max_phandle = 0; -+ int offset; -+ -+ for (offset = fdt_next_node(fdt, -1, NULL);; -+ offset = fdt_next_node(fdt, offset, NULL)) { -+ uint32_t phandle; -+ -+ if (offset == -FDT_ERR_NOTFOUND) -+ return max_phandle; -+ -+ if (offset < 0) -+ return (uint32_t)-1; -+ -+ phandle = fdt_get_phandle(fdt, offset); -+ if (phandle == (uint32_t)-1) -+ continue; -+ -+ if (phandle > max_phandle) -+ max_phandle = phandle; -+ } -+ -+ return 0; -+} -+ - int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) - { - FDT_CHECK_HEADER(fdt); -@@ -545,7 +571,7 @@ int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property) - - list = fdt_getprop(fdt, nodeoffset, property, &length); - if (!list) -- return -length; -+ return length; - - end = list + length; - -@@ -571,7 +597,7 @@ int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property, - - list = fdt_getprop(fdt, nodeoffset, property, &length); - if (!list) -- return -length; -+ return length; - - len = strlen(string) + 1; - end = list + length; -diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c -index 8be02b1..3fd5847 100644 ---- a/scripts/dtc/libfdt/fdt_rw.c -+++ b/scripts/dtc/libfdt/fdt_rw.c -@@ -191,17 +191,13 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) - int fdt_del_mem_rsv(void *fdt, int n) - { - struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); -- int err; - - FDT_RW_CHECK_HEADER(fdt); - - if (n >= fdt_num_mem_rsv(fdt)) - return -FDT_ERR_NOTFOUND; - -- err = _fdt_splice_mem_rsv(fdt, re, 1, 0); -- if (err) -- return err; -- return 0; -+ return _fdt_splice_mem_rsv(fdt, re, 1, 0); - } - - static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, -@@ -287,7 +283,8 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name, - if (err) - return err; - -- memcpy(prop->data, val, len); -+ if (len) -+ memcpy(prop->data, val, len); - return 0; - } - -diff --git a/scripts/dtc/libfdt/fdt_strerror.c b/scripts/dtc/libfdt/fdt_strerror.c -index e6c3cee..9677a18 100644 ---- a/scripts/dtc/libfdt/fdt_strerror.c -+++ b/scripts/dtc/libfdt/fdt_strerror.c -@@ -69,6 +69,7 @@ static struct fdt_errtabent fdt_errtable[] = { - - FDT_ERRTABENT(FDT_ERR_BADOFFSET), - FDT_ERRTABENT(FDT_ERR_BADPATH), -+ FDT_ERRTABENT(FDT_ERR_BADPHANDLE), - FDT_ERRTABENT(FDT_ERR_BADSTATE), - - FDT_ERRTABENT(FDT_ERR_TRUNCATED), -@@ -76,6 +77,11 @@ static struct fdt_errtabent fdt_errtable[] = { - FDT_ERRTABENT(FDT_ERR_BADVERSION), - FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE), - FDT_ERRTABENT(FDT_ERR_BADLAYOUT), -+ FDT_ERRTABENT(FDT_ERR_INTERNAL), -+ FDT_ERRTABENT(FDT_ERR_BADNCELLS), -+ FDT_ERRTABENT(FDT_ERR_BADVALUE), -+ FDT_ERRTABENT(FDT_ERR_BADOVERLAY), -+ FDT_ERRTABENT(FDT_ERR_NOPHANDLES), - }; - #define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0])) - -diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c -index c5bbb68..6aaab39 100644 ---- a/scripts/dtc/libfdt/fdt_wip.c -+++ b/scripts/dtc/libfdt/fdt_wip.c -@@ -55,21 +55,42 @@ - - #include "libfdt_internal.h" - -+int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, -+ const char *name, int namelen, -+ uint32_t idx, const void *val, -+ int len) -+{ -+ void *propval; -+ int proplen; -+ -+ propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen, -+ &proplen); -+ if (!propval) -+ return proplen; -+ -+ if (proplen < (len + idx)) -+ return -FDT_ERR_NOSPACE; -+ -+ memcpy((char *)propval + idx, val, len); -+ return 0; -+} -+ - int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, - const void *val, int len) - { -- void *propval; -+ const void *propval; - int proplen; - -- propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen); -+ propval = fdt_getprop(fdt, nodeoffset, name, &proplen); - if (! propval) - return proplen; - - if (proplen != len) - return -FDT_ERR_NOSPACE; - -- memcpy(propval, val, len); -- return 0; -+ return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name, -+ strlen(name), 0, -+ val, len); - } - - static void _fdt_nop_region(void *start, int len) -diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h -index 59ca339..9e71bb9 100644 ---- a/scripts/dtc/libfdt/libfdt.h -+++ b/scripts/dtc/libfdt/libfdt.h -@@ -61,7 +61,7 @@ - #define FDT_ERR_NOTFOUND 1 - /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ - #define FDT_ERR_EXISTS 2 -- /* FDT_ERR_EXISTS: Attemped to create a node or property which -+ /* FDT_ERR_EXISTS: Attempted to create a node or property which - * already exists */ - #define FDT_ERR_NOSPACE 3 - /* FDT_ERR_NOSPACE: Operation needed to expand the device -@@ -79,8 +79,10 @@ - * (e.g. missing a leading / for a function which requires an - * absolute path) */ - #define FDT_ERR_BADPHANDLE 6 -- /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle -- * value. phandle values of 0 and -1 are not permitted. */ -+ /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle. -+ * This can be caused either by an invalid phandle property -+ * length, or the phandle value was either 0 or -1, which are -+ * not permitted. */ - #define FDT_ERR_BADSTATE 7 - /* FDT_ERR_BADSTATE: Function was passed an incomplete device - * tree created by the sequential-write functions, which is -@@ -126,7 +128,16 @@ - * value. For example: a property expected to contain a string list - * is not NUL-terminated within the length of its value. */ - --#define FDT_ERR_MAX 15 -+#define FDT_ERR_BADOVERLAY 16 -+ /* FDT_ERR_BADOVERLAY: The device tree overlay, while -+ * correctly structured, cannot be applied due to some -+ * unexpected or missing value, property or node. */ -+ -+#define FDT_ERR_NOPHANDLES 17 -+ /* FDT_ERR_NOPHANDLES: The device tree doesn't have any -+ * phandle available anymore without causing an overflow */ -+ -+#define FDT_ERR_MAX 17 - - /**********************************************************************/ - /* Low-level functions (you probably don't need these) */ -@@ -168,27 +179,55 @@ int fdt_first_subnode(const void *fdt, int offset); - */ - int fdt_next_subnode(const void *fdt, int offset); - -+/** -+ * fdt_for_each_subnode - iterate over all subnodes of a parent -+ * -+ * @node: child node (int, lvalue) -+ * @fdt: FDT blob (const void *) -+ * @parent: parent node (int) -+ * -+ * This is actually a wrapper around a for loop and would be used like so: -+ * -+ * fdt_for_each_subnode(node, fdt, parent) { -+ * Use node -+ * ... -+ * } -+ * -+ * if ((node < 0) && (node != -FDT_ERR_NOT_FOUND)) { -+ * Error handling -+ * } -+ * -+ * Note that this is implemented as a macro and @node is used as -+ * iterator in the loop. The parent variable be constant or even a -+ * literal. -+ * -+ */ -+#define fdt_for_each_subnode(node, fdt, parent) \ -+ for (node = fdt_first_subnode(fdt, parent); \ -+ node >= 0; \ -+ node = fdt_next_subnode(fdt, node)) -+ - /**********************************************************************/ - /* General functions */ - /**********************************************************************/ - - #define fdt_get_header(fdt, field) \ - (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) --#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) -+#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) - #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) - #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) - #define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) - #define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) - #define fdt_version(fdt) (fdt_get_header(fdt, version)) --#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) --#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) --#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) -+#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) -+#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) -+#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) - #define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) - - #define __fdt_set_hdr(name) \ - static inline void fdt_set_##name(void *fdt, uint32_t val) \ - { \ -- struct fdt_header *fdth = (struct fdt_header*)fdt; \ -+ struct fdt_header *fdth = (struct fdt_header *)fdt; \ - fdth->name = cpu_to_fdt32(val); \ - } - __fdt_set_hdr(magic); -@@ -259,6 +298,21 @@ int fdt_move(const void *fdt, void *buf, int bufsize); - const char *fdt_string(const void *fdt, int stroffset); - - /** -+ * fdt_get_max_phandle - retrieves the highest phandle in a tree -+ * @fdt: pointer to the device tree blob -+ * -+ * fdt_get_max_phandle retrieves the highest phandle in the given -+ * device tree. This will ignore badly formatted phandles, or phandles -+ * with a value of 0 or -1. -+ * -+ * returns: -+ * the highest phandle on success -+ * 0, if no phandle was found in the device tree -+ * -1, if an error occurred -+ */ -+uint32_t fdt_get_max_phandle(const void *fdt); -+ -+/** - * fdt_num_mem_rsv - retrieve the number of memory reserve map entries - * @fdt: pointer to the device tree blob - * -@@ -318,8 +372,9 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, - * returns: - * structure block offset of the requested subnode (>=0), on success - * -FDT_ERR_NOTFOUND, if the requested subnode does not exist -- * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag -- * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE -+ * tag -+ * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, - * -FDT_ERR_BADSTRUCTURE, -@@ -351,7 +406,8 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); - * address). - * - * returns: -- * structure block offset of the node with the requested path (>=0), on success -+ * structure block offset of the node with the requested path (>=0), on -+ * success - * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid - * -FDT_ERR_NOTFOUND, if the requested node does not exist - * -FDT_ERR_BADMAGIC, -@@ -375,10 +431,12 @@ int fdt_path_offset(const void *fdt, const char *path); - * - * returns: - * pointer to the node's name, on success -- * If lenp is non-NULL, *lenp contains the length of that name (>=0) -+ * If lenp is non-NULL, *lenp contains the length of that name -+ * (>=0) - * NULL, on error - * if lenp is non-NULL *lenp contains an error code (<0): -- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE -+ * tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, standard meanings -@@ -427,6 +485,33 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset); - int fdt_next_property_offset(const void *fdt, int offset); - - /** -+ * fdt_for_each_property_offset - iterate over all properties of a node -+ * -+ * @property_offset: property offset (int, lvalue) -+ * @fdt: FDT blob (const void *) -+ * @node: node offset (int) -+ * -+ * This is actually a wrapper around a for loop and would be used like so: -+ * -+ * fdt_for_each_property_offset(property, fdt, node) { -+ * Use property -+ * ... -+ * } -+ * -+ * if ((property < 0) && (property != -FDT_ERR_NOT_FOUND)) { -+ * Error handling -+ * } -+ * -+ * Note that this is implemented as a macro and property is used as -+ * iterator in the loop. The node variable can be constant or even a -+ * literal. -+ */ -+#define fdt_for_each_property_offset(property, fdt, node) \ -+ for (property = fdt_first_property_offset(fdt, node); \ -+ property >= 0; \ -+ property = fdt_next_property_offset(fdt, property)) -+ -+/** - * fdt_get_property_by_offset - retrieve the property at a given offset - * @fdt: pointer to the device tree blob - * @offset: offset of the property to retrieve -@@ -490,7 +575,8 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, - * NULL, on error - * if lenp is non-NULL, *lenp contains an error code (<0): - * -FDT_ERR_NOTFOUND, node does not have named property -- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE -+ * tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -554,6 +640,13 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, - */ - const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, - const char *name, int namelen, int *lenp); -+static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset, -+ const char *name, int namelen, -+ int *lenp) -+{ -+ return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name, -+ namelen, lenp); -+} - - /** - * fdt_getprop - retrieve the value of a given property -@@ -575,7 +668,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, - * NULL, on error - * if lenp is non-NULL, *lenp contains an error code (<0): - * -FDT_ERR_NOTFOUND, node does not have named property -- * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE -+ * tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -617,7 +711,7 @@ const char *fdt_get_alias_namelen(const void *fdt, - const char *name, int namelen); - - /** -- * fdt_get_alias - retreive the path referenced by a given alias -+ * fdt_get_alias - retrieve the path referenced by a given alias - * @fdt: pointer to the device tree blob - * @name: name of the alias th look up - * -@@ -647,7 +741,7 @@ const char *fdt_get_alias(const void *fdt, const char *name); - * 0, on success - * buf contains the absolute path of the node at - * nodeoffset, as a NUL-terminated string. -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1) - * characters and will not fit in the given buffer. - * -FDT_ERR_BADMAGIC, -@@ -677,11 +771,11 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); - * structure from the start to nodeoffset. - * - * returns: -- - * structure block offset of the node at node offset's ancestor - * of depth supernodedepth (>=0), on success -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag --* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of -+ * nodeoffset - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -703,7 +797,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, - * - * returns: - * depth of the node at nodeoffset (>=0), on success -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -726,7 +820,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset); - * returns: - * structure block offset of the parent of the node at nodeoffset - * (>=0), on success -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -766,7 +860,7 @@ int fdt_parent_offset(const void *fdt, int nodeoffset); - * on success - * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the - * tree after startoffset -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -813,7 +907,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); - * 1, if the node has a 'compatible' property, but it does not list - * the given string - * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property -- * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -850,7 +944,7 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset, - * on success - * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the - * tree after startoffset -- * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -960,7 +1054,8 @@ const char *fdt_stringlist_get(const void *fdt, int nodeoffset, - * returns: - * 0 <= n < FDT_MAX_NCELLS, on success - * 2, if the node has no #address-cells property -- * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #address-cells property -+ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid -+ * #address-cells property - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -980,7 +1075,8 @@ int fdt_address_cells(const void *fdt, int nodeoffset); - * returns: - * 0 <= n < FDT_MAX_NCELLS, on success - * 2, if the node has no #address-cells property -- * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #size-cells property -+ * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid -+ * #size-cells property - * -FDT_ERR_BADMAGIC, - * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, -@@ -995,6 +1091,27 @@ int fdt_size_cells(const void *fdt, int nodeoffset); - /**********************************************************************/ - - /** -+ * fdt_setprop_inplace_namelen_partial - change a property's value, -+ * but not its size -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to change -+ * @name: name of the property to change -+ * @namelen: number of characters of name to consider -+ * @idx: index of the property to change in the array -+ * @val: pointer to data to replace the property value with -+ * @len: length of the property value -+ * -+ * Identical to fdt_setprop_inplace(), but modifies the given property -+ * starting from the given index, and using only the first characters -+ * of the name. It is useful when you want to manipulate only one value of -+ * an array and you have a string that doesn't end with \0. -+ */ -+int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, -+ const char *name, int namelen, -+ uint32_t idx, const void *val, -+ int len); -+ -+/** - * fdt_setprop_inplace - change a property's value, but not its size - * @fdt: pointer to the device tree blob - * @nodeoffset: offset of the node whose property to change -@@ -1410,6 +1527,36 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, - #define fdt_setprop_string(fdt, nodeoffset, name, str) \ - fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) - -+ -+/** -+ * fdt_setprop_empty - set a property to an empty value -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to change -+ * @name: name of the property to change -+ * -+ * fdt_setprop_empty() sets the value of the named property in the -+ * given node to an empty (zero length) value, or creates a new empty -+ * property if it does not already exist. -+ * -+ * This function may insert or delete data from the blob, and will -+ * therefore change the offsets of some existing nodes. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to -+ * contain the new property value -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADLAYOUT, -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_BADLAYOUT, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+#define fdt_setprop_empty(fdt, nodeoffset, name) \ -+ fdt_setprop((fdt), (nodeoffset), (name), NULL, 0) -+ - /** - * fdt_appendprop - append to or create a property - * @fdt: pointer to the device tree blob -@@ -1604,9 +1751,11 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, - * change the offsets of some existing nodes. - - * returns: -- * structure block offset of the created nodeequested subnode (>=0), on success -+ * structure block offset of the created nodeequested subnode (>=0), on -+ * success - * -FDT_ERR_NOTFOUND, if the requested subnode does not exist -- * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE -+ * tag - * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of - * the given name - * -FDT_ERR_NOSPACE, if there is insufficient free space in the -@@ -1644,6 +1793,37 @@ int fdt_add_subnode(void *fdt, int parentoffset, const char *name); - */ - int fdt_del_node(void *fdt, int nodeoffset); - -+/** -+ * fdt_overlay_apply - Applies a DT overlay on a base DT -+ * @fdt: pointer to the base device tree blob -+ * @fdto: pointer to the device tree overlay blob -+ * -+ * fdt_overlay_apply() will apply the given device tree overlay on the -+ * given base device tree. -+ * -+ * Expect the base device tree to be modified, even if the function -+ * returns an error. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOSPACE, there's not enough space in the base device tree -+ * -FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or -+ * properties in the base DT -+ * -FDT_ERR_BADPHANDLE, -+ * -FDT_ERR_BADOVERLAY, -+ * -FDT_ERR_NOPHANDLES, -+ * -FDT_ERR_INTERNAL, -+ * -FDT_ERR_BADLAYOUT, -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADOFFSET, -+ * -FDT_ERR_BADPATH, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+int fdt_overlay_apply(void *fdt, void *fdto); -+ - /**********************************************************************/ - /* Debugging / informational functions */ - /**********************************************************************/ -diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h -index 9dea97d..952056c 100644 ---- a/scripts/dtc/libfdt/libfdt_env.h -+++ b/scripts/dtc/libfdt/libfdt_env.h -@@ -54,19 +54,20 @@ - - #include <stddef.h> - #include <stdint.h> -+#include <stdlib.h> - #include <string.h> - - #ifdef __CHECKER__ --#define __force __attribute__((force)) --#define __bitwise __attribute__((bitwise)) -+#define FDT_FORCE __attribute__((force)) -+#define FDT_BITWISE __attribute__((bitwise)) - #else --#define __force --#define __bitwise -+#define FDT_FORCE -+#define FDT_BITWISE - #endif - --typedef uint16_t __bitwise fdt16_t; --typedef uint32_t __bitwise fdt32_t; --typedef uint64_t __bitwise fdt64_t; -+typedef uint16_t FDT_BITWISE fdt16_t; -+typedef uint32_t FDT_BITWISE fdt32_t; -+typedef uint64_t FDT_BITWISE fdt64_t; - - #define EXTRACT_BYTE(x, n) ((unsigned long long)((uint8_t *)&x)[n]) - #define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1)) -@@ -79,29 +80,29 @@ typedef uint64_t __bitwise fdt64_t; - - static inline uint16_t fdt16_to_cpu(fdt16_t x) - { -- return (__force uint16_t)CPU_TO_FDT16(x); -+ return (FDT_FORCE uint16_t)CPU_TO_FDT16(x); - } - static inline fdt16_t cpu_to_fdt16(uint16_t x) - { -- return (__force fdt16_t)CPU_TO_FDT16(x); -+ return (FDT_FORCE fdt16_t)CPU_TO_FDT16(x); - } - - static inline uint32_t fdt32_to_cpu(fdt32_t x) - { -- return (__force uint32_t)CPU_TO_FDT32(x); -+ return (FDT_FORCE uint32_t)CPU_TO_FDT32(x); - } - static inline fdt32_t cpu_to_fdt32(uint32_t x) - { -- return (__force fdt32_t)CPU_TO_FDT32(x); -+ return (FDT_FORCE fdt32_t)CPU_TO_FDT32(x); - } - - static inline uint64_t fdt64_to_cpu(fdt64_t x) - { -- return (__force uint64_t)CPU_TO_FDT64(x); -+ return (FDT_FORCE uint64_t)CPU_TO_FDT64(x); - } - static inline fdt64_t cpu_to_fdt64(uint64_t x) - { -- return (__force fdt64_t)CPU_TO_FDT64(x); -+ return (FDT_FORCE fdt64_t)CPU_TO_FDT64(x); - } - #undef CPU_TO_FDT64 - #undef CPU_TO_FDT32 -diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c -index e229b84..3673de0 100644 ---- a/scripts/dtc/livetree.c -+++ b/scripts/dtc/livetree.c -@@ -204,7 +204,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) - } - } - -- /* if no collision occured, add child to the old node. */ -+ /* if no collision occurred, add child to the old node. */ - if (new_child) - add_child(old_node, new_child); - } -@@ -242,7 +242,7 @@ void delete_property_by_name(struct node *node, char *name) - struct property *prop = node->proplist; - - while (prop) { -- if (!strcmp(prop->name, name)) { -+ if (streq(prop->name, name)) { - delete_property(prop); - return; - } -@@ -275,7 +275,7 @@ void delete_node_by_name(struct node *parent, char *name) - struct node *node = parent->children; - - while (node) { -- if (!strcmp(node->name, name)) { -+ if (streq(node->name, name)) { - delete_node(node); - return; - } -@@ -296,14 +296,31 @@ void delete_node(struct node *node) - delete_labels(&node->labels); - } - -+void append_to_property(struct node *node, -+ char *name, const void *data, int len) -+{ -+ struct data d; -+ struct property *p; -+ -+ p = get_property(node, name); -+ if (p) { -+ d = data_append_data(p->val, data, len); -+ p->val = d; -+ } else { -+ d = data_append_data(empty_data, data, len); -+ p = build_property(name, d); -+ add_property(node, p); -+ } -+} -+ - struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size) - { - struct reserve_info *new = xmalloc(sizeof(*new)); - - memset(new, 0, sizeof(*new)); - -- new->re.address = address; -- new->re.size = size; -+ new->address = address; -+ new->size = size; - - return new; - } -@@ -335,17 +352,19 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list, - return list; - } - --struct boot_info *build_boot_info(struct reserve_info *reservelist, -- struct node *tree, uint32_t boot_cpuid_phys) -+struct dt_info *build_dt_info(unsigned int dtsflags, -+ struct reserve_info *reservelist, -+ struct node *tree, uint32_t boot_cpuid_phys) - { -- struct boot_info *bi; -+ struct dt_info *dti; - -- bi = xmalloc(sizeof(*bi)); -- bi->reservelist = reservelist; -- bi->dt = tree; -- bi->boot_cpuid_phys = boot_cpuid_phys; -+ dti = xmalloc(sizeof(*dti)); -+ dti->dtsflags = dtsflags; -+ dti->reservelist = reservelist; -+ dti->dt = tree; -+ dti->boot_cpuid_phys = boot_cpuid_phys; - -- return bi; -+ return dti; - } - - /* -@@ -374,7 +393,7 @@ struct property *get_property(struct node *node, const char *propname) - cell_t propval_cell(struct property *prop) - { - assert(prop->val.len == sizeof(cell_t)); -- return fdt32_to_cpu(*((cell_t *)prop->val.val)); -+ return fdt32_to_cpu(*((fdt32_t *)prop->val.val)); - } - - struct property *get_property_by_label(struct node *tree, const char *label, -@@ -580,24 +599,24 @@ static int cmp_reserve_info(const void *ax, const void *bx) - a = *((const struct reserve_info * const *)ax); - b = *((const struct reserve_info * const *)bx); - -- if (a->re.address < b->re.address) -+ if (a->address < b->address) - return -1; -- else if (a->re.address > b->re.address) -+ else if (a->address > b->address) - return 1; -- else if (a->re.size < b->re.size) -+ else if (a->size < b->size) - return -1; -- else if (a->re.size > b->re.size) -+ else if (a->size > b->size) - return 1; - else - return 0; - } - --static void sort_reserve_entries(struct boot_info *bi) -+static void sort_reserve_entries(struct dt_info *dti) - { - struct reserve_info *ri, **tbl; - int n = 0, i = 0; - -- for (ri = bi->reservelist; -+ for (ri = dti->reservelist; - ri; - ri = ri->next) - n++; -@@ -607,14 +626,14 @@ static void sort_reserve_entries(struct boot_info *bi) - - tbl = xmalloc(n * sizeof(*tbl)); - -- for (ri = bi->reservelist; -+ for (ri = dti->reservelist; - ri; - ri = ri->next) - tbl[i++] = ri; - - qsort(tbl, n, sizeof(*tbl), cmp_reserve_info); - -- bi->reservelist = tbl[0]; -+ dti->reservelist = tbl[0]; - for (i = 0; i < (n-1); i++) - tbl[i]->next = tbl[i+1]; - tbl[n-1]->next = NULL; -@@ -704,8 +723,258 @@ static void sort_node(struct node *node) - sort_node(c); - } - --void sort_tree(struct boot_info *bi) -+void sort_tree(struct dt_info *dti) -+{ -+ sort_reserve_entries(dti); -+ sort_node(dti->dt); -+} -+ -+/* utility helper to avoid code duplication */ -+static struct node *build_and_name_child_node(struct node *parent, char *name) -+{ -+ struct node *node; -+ -+ node = build_node(NULL, NULL); -+ name_node(node, xstrdup(name)); -+ add_child(parent, node); -+ -+ return node; -+} -+ -+static struct node *build_root_node(struct node *dt, char *name) -+{ -+ struct node *an; -+ -+ an = get_subnode(dt, name); -+ if (!an) -+ an = build_and_name_child_node(dt, name); -+ -+ if (!an) -+ die("Could not build root node /%s\n", name); -+ -+ return an; -+} -+ -+static bool any_label_tree(struct dt_info *dti, struct node *node) -+{ -+ struct node *c; -+ -+ if (node->labels) -+ return true; -+ -+ for_each_child(node, c) -+ if (any_label_tree(dti, c)) -+ return true; -+ -+ return false; -+} -+ -+static void generate_label_tree_internal(struct dt_info *dti, -+ struct node *an, struct node *node, -+ bool allocph) - { -- sort_reserve_entries(bi); -- sort_node(bi->dt); -+ struct node *dt = dti->dt; -+ struct node *c; -+ struct property *p; -+ struct label *l; -+ -+ /* if there are labels */ -+ if (node->labels) { -+ -+ /* now add the label in the node */ -+ for_each_label(node->labels, l) { -+ -+ /* check whether the label already exists */ -+ p = get_property(an, l->label); -+ if (p) { -+ fprintf(stderr, "WARNING: label %s already" -+ " exists in /%s", l->label, -+ an->name); -+ continue; -+ } -+ -+ /* insert it */ -+ p = build_property(l->label, -+ data_copy_mem(node->fullpath, -+ strlen(node->fullpath) + 1)); -+ add_property(an, p); -+ } -+ -+ /* force allocation of a phandle for this node */ -+ if (allocph) -+ (void)get_node_phandle(dt, node); -+ } -+ -+ for_each_child(node, c) -+ generate_label_tree_internal(dti, an, c, allocph); -+} -+ -+static bool any_fixup_tree(struct dt_info *dti, struct node *node) -+{ -+ struct node *c; -+ struct property *prop; -+ struct marker *m; -+ -+ for_each_property(node, prop) { -+ m = prop->val.markers; -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ if (!get_node_by_ref(dti->dt, m->ref)) -+ return true; -+ } -+ } -+ -+ for_each_child(node, c) { -+ if (any_fixup_tree(dti, c)) -+ return true; -+ } -+ -+ return false; -+} -+ -+static void add_fixup_entry(struct dt_info *dti, struct node *fn, -+ struct node *node, struct property *prop, -+ struct marker *m) -+{ -+ char *entry; -+ -+ /* m->ref can only be a REF_PHANDLE, but check anyway */ -+ assert(m->type == REF_PHANDLE); -+ -+ /* there shouldn't be any ':' in the arguments */ -+ if (strchr(node->fullpath, ':') || strchr(prop->name, ':')) -+ die("arguments should not contain ':'\n"); -+ -+ xasprintf(&entry, "%s:%s:%u", -+ node->fullpath, prop->name, m->offset); -+ append_to_property(fn, m->ref, entry, strlen(entry) + 1); -+ -+ free(entry); -+} -+ -+static void generate_fixups_tree_internal(struct dt_info *dti, -+ struct node *fn, -+ struct node *node) -+{ -+ struct node *dt = dti->dt; -+ struct node *c; -+ struct property *prop; -+ struct marker *m; -+ struct node *refnode; -+ -+ for_each_property(node, prop) { -+ m = prop->val.markers; -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ refnode = get_node_by_ref(dt, m->ref); -+ if (!refnode) -+ add_fixup_entry(dti, fn, node, prop, m); -+ } -+ } -+ -+ for_each_child(node, c) -+ generate_fixups_tree_internal(dti, fn, c); -+} -+ -+static bool any_local_fixup_tree(struct dt_info *dti, struct node *node) -+{ -+ struct node *c; -+ struct property *prop; -+ struct marker *m; -+ -+ for_each_property(node, prop) { -+ m = prop->val.markers; -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ if (get_node_by_ref(dti->dt, m->ref)) -+ return true; -+ } -+ } -+ -+ for_each_child(node, c) { -+ if (any_local_fixup_tree(dti, c)) -+ return true; -+ } -+ -+ return false; -+} -+ -+static void add_local_fixup_entry(struct dt_info *dti, -+ struct node *lfn, struct node *node, -+ struct property *prop, struct marker *m, -+ struct node *refnode) -+{ -+ struct node *wn, *nwn; /* local fixup node, walk node, new */ -+ fdt32_t value_32; -+ char **compp; -+ int i, depth; -+ -+ /* walk back retreiving depth */ -+ depth = 0; -+ for (wn = node; wn; wn = wn->parent) -+ depth++; -+ -+ /* allocate name array */ -+ compp = xmalloc(sizeof(*compp) * depth); -+ -+ /* store names in the array */ -+ for (wn = node, i = depth - 1; wn; wn = wn->parent, i--) -+ compp[i] = wn->name; -+ -+ /* walk the path components creating nodes if they don't exist */ -+ for (wn = lfn, i = 1; i < depth; i++, wn = nwn) { -+ /* if no node exists, create it */ -+ nwn = get_subnode(wn, compp[i]); -+ if (!nwn) -+ nwn = build_and_name_child_node(wn, compp[i]); -+ } -+ -+ free(compp); -+ -+ value_32 = cpu_to_fdt32(m->offset); -+ append_to_property(wn, prop->name, &value_32, sizeof(value_32)); -+} -+ -+static void generate_local_fixups_tree_internal(struct dt_info *dti, -+ struct node *lfn, -+ struct node *node) -+{ -+ struct node *dt = dti->dt; -+ struct node *c; -+ struct property *prop; -+ struct marker *m; -+ struct node *refnode; -+ -+ for_each_property(node, prop) { -+ m = prop->val.markers; -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ refnode = get_node_by_ref(dt, m->ref); -+ if (refnode) -+ add_local_fixup_entry(dti, lfn, node, prop, m, refnode); -+ } -+ } -+ -+ for_each_child(node, c) -+ generate_local_fixups_tree_internal(dti, lfn, c); -+} -+ -+void generate_label_tree(struct dt_info *dti, char *name, bool allocph) -+{ -+ if (!any_label_tree(dti, dti->dt)) -+ return; -+ generate_label_tree_internal(dti, build_root_node(dti->dt, name), -+ dti->dt, allocph); -+} -+ -+void generate_fixups_tree(struct dt_info *dti, char *name) -+{ -+ if (!any_fixup_tree(dti, dti->dt)) -+ return; -+ generate_fixups_tree_internal(dti, build_root_node(dti->dt, name), -+ dti->dt); -+} -+ -+void generate_local_fixups_tree(struct dt_info *dti, char *name) -+{ -+ if (!any_local_fixup_tree(dti, dti->dt)) -+ return; -+ generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name), -+ dti->dt); - } -diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c -index f534c22..9d38459 100644 ---- a/scripts/dtc/srcpos.c -+++ b/scripts/dtc/srcpos.c -@@ -246,46 +246,27 @@ srcpos_copy(struct srcpos *pos) - return pos_new; - } - -- -- --void --srcpos_dump(struct srcpos *pos) --{ -- printf("file : \"%s\"\n", -- pos->file ? (char *) pos->file : "<no file>"); -- printf("first_line : %d\n", pos->first_line); -- printf("first_column: %d\n", pos->first_column); -- printf("last_line : %d\n", pos->last_line); -- printf("last_column : %d\n", pos->last_column); -- printf("file : %s\n", pos->file->name); --} -- -- - char * - srcpos_string(struct srcpos *pos) - { - const char *fname = "<no-file>"; - char *pos_str; -- int rc; - -- if (pos) -+ if (pos->file && pos->file->name) - fname = pos->file->name; - - - if (pos->first_line != pos->last_line) -- rc = asprintf(&pos_str, "%s:%d.%d-%d.%d", fname, -- pos->first_line, pos->first_column, -- pos->last_line, pos->last_column); -+ xasprintf(&pos_str, "%s:%d.%d-%d.%d", fname, -+ pos->first_line, pos->first_column, -+ pos->last_line, pos->last_column); - else if (pos->first_column != pos->last_column) -- rc = asprintf(&pos_str, "%s:%d.%d-%d", fname, -- pos->first_line, pos->first_column, -- pos->last_column); -+ xasprintf(&pos_str, "%s:%d.%d-%d", fname, -+ pos->first_line, pos->first_column, -+ pos->last_column); - else -- rc = asprintf(&pos_str, "%s:%d.%d", fname, -- pos->first_line, pos->first_column); -- -- if (rc == -1) -- die("Couldn't allocate in srcpos string"); -+ xasprintf(&pos_str, "%s:%d.%d", fname, -+ pos->first_line, pos->first_column); - - return pos_str; - } -diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h -index f81827b..7caca82 100644 ---- a/scripts/dtc/srcpos.h -+++ b/scripts/dtc/srcpos.h -@@ -22,6 +22,7 @@ - - #include <stdio.h> - #include <stdbool.h> -+#include "util.h" - - struct srcfile_state { - FILE *f; -@@ -105,14 +106,11 @@ extern struct srcpos srcpos_empty; - extern void srcpos_update(struct srcpos *pos, const char *text, int len); - extern struct srcpos *srcpos_copy(struct srcpos *pos); - extern char *srcpos_string(struct srcpos *pos); --extern void srcpos_dump(struct srcpos *pos); -- --extern void srcpos_verror(struct srcpos *pos, const char *prefix, -- const char *fmt, va_list va) -- __attribute__((format(printf, 3, 0))); --extern void srcpos_error(struct srcpos *pos, const char *prefix, -- const char *fmt, ...) -- __attribute__((format(printf, 3, 4))); -+ -+extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix, -+ const char *fmt, va_list va); -+extern void PRINTF(3, 4) srcpos_error(struct srcpos *pos, const char *prefix, -+ const char *fmt, ...); - - extern void srcpos_set_line(char *f, int l); - -diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c -index a55d1d1..2461a3d 100644 ---- a/scripts/dtc/treesource.c -+++ b/scripts/dtc/treesource.c -@@ -25,12 +25,12 @@ extern FILE *yyin; - extern int yyparse(void); - extern YYLTYPE yylloc; - --struct boot_info *the_boot_info; -+struct dt_info *parser_output; - bool treesource_error; - --struct boot_info *dt_from_source(const char *fname) -+struct dt_info *dt_from_source(const char *fname) - { -- the_boot_info = NULL; -+ parser_output = NULL; - treesource_error = false; - - srcfile_push(fname); -@@ -43,7 +43,7 @@ struct boot_info *dt_from_source(const char *fname) - if (treesource_error) - die("Syntax error parsing input tree\n"); - -- return the_boot_info; -+ return parser_output; - } - - static void write_prefix(FILE *f, int level) -@@ -137,7 +137,7 @@ static void write_propval_string(FILE *f, struct data val) - static void write_propval_cells(FILE *f, struct data val) - { - void *propend = val.val + val.len; -- cell_t *cp = (cell_t *)val.val; -+ fdt32_t *cp = (fdt32_t *)val.val; - struct marker *m = val.markers; - - fprintf(f, "<"); -@@ -263,22 +263,22 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level) - } - - --void dt_to_source(FILE *f, struct boot_info *bi) -+void dt_to_source(FILE *f, struct dt_info *dti) - { - struct reserve_info *re; - - fprintf(f, "/dts-v1/;\n\n"); - -- for (re = bi->reservelist; re; re = re->next) { -+ for (re = dti->reservelist; re; re = re->next) { - struct label *l; - - for_each_label(re->labels, l) - fprintf(f, "%s: ", l->label); - fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", -- (unsigned long long)re->re.address, -- (unsigned long long)re->re.size); -+ (unsigned long long)re->address, -+ (unsigned long long)re->size); - } - -- write_tree_source_node(f, bi->dt, 0); -+ write_tree_source_node(f, dti->dt, 0); - } - -diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c -index fb124ee..9953c32 100644 ---- a/scripts/dtc/util.c -+++ b/scripts/dtc/util.c -@@ -46,6 +46,36 @@ char *xstrdup(const char *s) - return d; - } - -+/* based in part from (3) vsnprintf */ -+int xasprintf(char **strp, const char *fmt, ...) -+{ -+ int n, size = 128; /* start with 128 bytes */ -+ char *p; -+ va_list ap; -+ -+ /* initial pointer is NULL making the fist realloc to be malloc */ -+ p = NULL; -+ while (1) { -+ p = xrealloc(p, size); -+ -+ /* Try to print in the allocated space. */ -+ va_start(ap, fmt); -+ n = vsnprintf(p, size, fmt, ap); -+ va_end(ap); -+ -+ /* If that worked, return the string. */ -+ if (n > -1 && n < size) -+ break; -+ /* Else try again with more space. */ -+ if (n > -1) /* glibc 2.1 */ -+ size = n + 1; /* precisely what is needed */ -+ else /* glibc 2.0 */ -+ size *= 2; /* twice the old size */ -+ } -+ *strp = p; -+ return strlen(p); -+} -+ - char *join_path(const char *path, const char *name) - { - int lenp = strlen(path); -@@ -366,7 +396,7 @@ void utilfdt_print_data(const char *data, int len) - } while (s < data + len); - - } else if ((len % 4) == 0) { -- const uint32_t *cell = (const uint32_t *)data; -+ const fdt32_t *cell = (const fdt32_t *)data; - - printf(" = <"); - for (i = 0, len /= 4; i < len; i++) -@@ -382,15 +412,16 @@ void utilfdt_print_data(const char *data, int len) - } - } - --void util_version(void) -+void NORETURN util_version(void) - { - printf("Version: %s\n", DTC_VERSION); - exit(0); - } - --void util_usage(const char *errmsg, const char *synopsis, -- const char *short_opts, struct option const long_opts[], -- const char * const opts_help[]) -+void NORETURN util_usage(const char *errmsg, const char *synopsis, -+ const char *short_opts, -+ struct option const long_opts[], -+ const char * const opts_help[]) - { - FILE *fp = errmsg ? stderr : stdout; - const char a_arg[] = "<arg>"; -diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h -index f800b60..ad5f411 100644 ---- a/scripts/dtc/util.h -+++ b/scripts/dtc/util.h -@@ -25,9 +25,17 @@ - * USA - */ - -+#ifdef __GNUC__ -+#define PRINTF(i, j) __attribute__((format (printf, i, j))) -+#define NORETURN __attribute__((noreturn)) -+#else -+#define PRINTF(i, j) -+#define NORETURN -+#endif -+ - #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - --static inline void __attribute__((noreturn)) die(const char *str, ...) -+static inline void NORETURN PRINTF(1, 2) die(const char *str, ...) - { - va_list ap; - -@@ -53,12 +61,14 @@ static inline void *xrealloc(void *p, size_t len) - void *new = realloc(p, len); - - if (!new) -- die("realloc() failed (len=%d)\n", len); -+ die("realloc() failed (len=%zd)\n", len); - - return new; - } - - extern char *xstrdup(const char *s); -+ -+extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...); - extern char *join_path(const char *path, const char *name); - - /** -@@ -187,7 +197,7 @@ void utilfdt_print_data(const char *data, int len); - /** - * Show source version and exit - */ --void util_version(void) __attribute__((noreturn)); -+void NORETURN util_version(void); - - /** - * Show usage and exit -@@ -201,9 +211,10 @@ void util_version(void) __attribute__((noreturn)); - * @param long_opts The structure of long options - * @param opts_help An array of help strings (should align with long_opts) - */ --void util_usage(const char *errmsg, const char *synopsis, -- const char *short_opts, struct option const long_opts[], -- const char * const opts_help[]) __attribute__((noreturn)); -+void NORETURN util_usage(const char *errmsg, const char *synopsis, -+ const char *short_opts, -+ struct option const long_opts[], -+ const char * const opts_help[]); - - /** - * Show usage and exit -diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h -index ad9b05a..859564e 100644 ---- a/scripts/dtc/version_gen.h -+++ b/scripts/dtc/version_gen.h -@@ -1 +1 @@ --#define DTC_VERSION "DTC 1.4.1-g53bf130b" -+#define DTC_VERSION "DTC 1.4.4" -diff --git a/scripts/package/builddeb b/scripts/package/builddeb -index 3c575cd..172be74 100755 ---- a/scripts/package/builddeb -+++ b/scripts/package/builddeb -@@ -69,7 +69,7 @@ set_debarch() { - echo "" >&2 - echo "** ** ** WARNING ** ** **" >&2 - echo "" >&2 -- echo "Your architecture doesn't have it's equivalent" >&2 -+ echo "Your architecture doesn't have its equivalent" >&2 - echo "Debian userspace architecture defined!" >&2 - echo "Falling back to using your current userspace instead!" >&2 - echo "Please add support for $UTS_MACHINE to ${0} ..." >&2 -@@ -151,9 +151,18 @@ else - fi - - if grep -q "^CONFIG_OF=y" $KCONFIG_CONFIG ; then -+ mkdir -p "$tmpdir/boot/dtbs/$version" - # Only some architectures with OF support have this target - if grep -q dtbs_install "${srctree}/arch/$SRCARCH/Makefile"; then -- $MAKE KBUILD_SRC= INSTALL_DTBS_PATH="$tmpdir/usr/lib/$packagename" dtbs_install -+ $MAKE KBUILD_SRC= INSTALL_DTBS_PATH="$tmpdir/boot/dtbs/$version" dtbs_install -+ else -+ $MAKE KBUILD_SRC= dtbs -+ find arch/arm/boot/ -iname "*.dtb" -exec cp -v '{}' "$tmpdir/boot/dtbs/$version" \; -+ fi -+ -+ #make dtbs_install seems to add an .old directory -+ if [ -d "$tmpdir/boot/dtbs/$version.old" ] ; then -+ rm -rf "$tmpdir/boot/dtbs/$version.old" - fi - fi - -@@ -262,10 +271,10 @@ EOF - cat <<EOF > debian/copyright - This is a packacked upstream version of the Linux kernel. - --The sources may be found at most Linux ftp sites, including: --ftp://ftp.kernel.org/pub/linux/kernel -+The sources may be found at most Linux archive sites, including: -+https://www.kernel.org/pub/linux/kernel - --Copyright: 1991 - 2015 Linus Torvalds and others. -+Copyright: 1991 - 2017 Linus Torvalds and others. - - The git repository for mainline kernel development is at: - git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git -@@ -288,7 +297,6 @@ Section: kernel - Priority: optional - Maintainer: $maintainer - Build-Depends: $build_depends --Standards-Version: 3.8.4 - Homepage: http://www.kernel.org/ - EOF - -@@ -296,7 +304,6 @@ if [ "$ARCH" = "um" ]; then - cat <<EOF >> debian/control - - Package: $packagename --Provides: linux-image, linux-image-2.6, linux-modules-$version - Architecture: any - Description: User Mode Linux kernel, version $version - User-mode Linux is a port of the Linux kernel to its own system call -@@ -313,7 +320,6 @@ else - cat <<EOF >> debian/control - - Package: $packagename --Provides: linux-image, linux-image-2.6, linux-modules-$version - Suggests: $fwpackagename - Architecture: any - Description: Linux kernel, version $version -@@ -346,7 +352,6 @@ rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles" - cat <<EOF >> debian/control - - Package: $kernel_headers_packagename --Provides: linux-headers, linux-headers-2.6 - Architecture: any - Description: Linux kernel headers for $KERNELRELEASE on \${kernel:debarch} - This package provides kernel header files for $KERNELRELEASE on \${kernel:debarch} -@@ -404,7 +409,6 @@ if [ -n "$BUILD_DEBUG" ] ; then - - Package: $dbg_packagename - Section: debug --Provides: linux-debug, linux-debug-$version - Architecture: any - Description: Linux kernel debugging symbols for $version - This package will come in handy if you need to debug the kernel. It provides -diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index c67667b..0f40b09 100644 ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -135,6 +135,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_TAS5086 if I2C - select SND_SOC_TAS571X if I2C - select SND_SOC_TAS5720 if I2C -+ select SND_SOC_TDM - select SND_SOC_TFA9879 if I2C - select SND_SOC_TLV320AIC23_I2C if I2C - select SND_SOC_TLV320AIC23_SPI if SPI_MASTER -@@ -812,6 +813,9 @@ config SND_SOC_TAS5720 - Enable support for Texas Instruments TAS5720L/M high-efficiency mono - Class-D audio power amplifiers. - -+config SND_SOC_TDM -+ tristate "Generic TDM codec" -+ - config SND_SOC_TFA9879 - tristate "NXP Semiconductors TFA9879 amplifier" - depends on I2C -diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index 958cd49..ea82c79 100644 ---- a/sound/soc/codecs/Makefile -+++ b/sound/soc/codecs/Makefile -@@ -142,6 +142,7 @@ snd-soc-sti-sas-objs := sti-sas.o - snd-soc-tas5086-objs := tas5086.o - snd-soc-tas571x-objs := tas571x.o - snd-soc-tas5720-objs := tas5720.o -+snd-soc-tdm-objs := tdm.o - snd-soc-tfa9879-objs := tfa9879.o - snd-soc-tlv320aic23-objs := tlv320aic23.o - snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o -@@ -363,6 +364,7 @@ obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o - obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o - obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o - obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o -+obj-$(CONFIG_SND_SOC_TDM) += snd-soc-tdm.o - obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o - obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o - obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o -diff --git a/sound/soc/codecs/spdif_transmitter.c b/sound/soc/codecs/spdif_transmitter.c -index ee36753..b682f12 100644 ---- a/sound/soc/codecs/spdif_transmitter.c -+++ b/sound/soc/codecs/spdif_transmitter.c -@@ -27,7 +27,9 @@ - #define STUB_RATES SNDRV_PCM_RATE_8000_192000 - #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ - SNDRV_PCM_FMTBIT_S20_3LE | \ -- SNDRV_PCM_FMTBIT_S24_LE) -+ SNDRV_PCM_FMTBIT_S24_3LE | \ -+ SNDRV_PCM_FMTBIT_S24_LE | \ -+ SNDRV_PCM_FMTBIT_S32_LE) - - static const struct snd_soc_dapm_widget dit_widgets[] = { - SND_SOC_DAPM_OUTPUT("spdif-out"), -diff --git b/sound/soc/codecs/tdm.c b/sound/soc/codecs/tdm.c -new file mode 100644 -index 0000000..b8fb3b8 ---- /dev/null -+++ b/sound/soc/codecs/tdm.c -@@ -0,0 +1,112 @@ -+/* -+ * ALSA SoC generic TDM codec driver -+ * -+ * Author: Matthijs van Duin <matthijsvanduin@gmail.com> -+ * Copyright: (C) 2016 Dutch & Dutch -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * TODO Allow customization via device tree. -+ */ -+ -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/slab.h> -+#include <sound/soc.h> -+#include <sound/pcm.h> -+#include <sound/initval.h> -+#include <linux/of.h> -+ -+#define DRV_NAME "tdm-audio" -+ -+/* As far as I can tell the LE/3LE/BE/3BE suffix merely indicates how the data -+ * was represented in memory, so why would the codec care? On the other hand, -+ * how do you indicate the bit-endianness on wire? */ -+ -+#define TDM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ -+ SNDRV_PCM_FMTBIT_U8 | \ -+ SNDRV_PCM_FMTBIT_S16_LE | \ -+ SNDRV_PCM_FMTBIT_U16_LE | \ -+ SNDRV_PCM_FMTBIT_S20_3LE | \ -+ SNDRV_PCM_FMTBIT_U20_3LE | \ -+ SNDRV_PCM_FMTBIT_S24_3LE | \ -+ SNDRV_PCM_FMTBIT_U24_3LE | \ -+ SNDRV_PCM_FMTBIT_S24_LE | \ -+ SNDRV_PCM_FMTBIT_U24_LE | \ -+ SNDRV_PCM_FMTBIT_S32_LE | \ -+ SNDRV_PCM_FMTBIT_U32_LE) -+ -+static const struct snd_soc_dapm_widget tdm_audio_widgets[] = { -+ SND_SOC_DAPM_OUTPUT("Sink"), -+ SND_SOC_DAPM_INPUT("Source"), -+}; -+ -+static const struct snd_soc_dapm_route tdm_audio_routes[] = { -+ { "Sink", NULL, "Playback" }, -+ { "Capture", NULL, "Source" }, -+}; -+ -+static struct snd_soc_codec_driver soc_codec_tdm_audio = { -+ .component_driver = { -+ .dapm_widgets = tdm_audio_widgets, -+ .num_dapm_widgets = ARRAY_SIZE(tdm_audio_widgets), -+ .dapm_routes = tdm_audio_routes, -+ .num_dapm_routes = ARRAY_SIZE(tdm_audio_routes), -+ }, -+}; -+ -+static struct snd_soc_dai_driver tdm_audio_dai = { -+ .name = "tdm_audio", -+ .playback = { -+ .stream_name = "Playback", -+ .channels_min = 1, -+ .channels_max = 16, -+ .rates = SNDRV_PCM_RATE_CONTINUOUS, -+ .formats = TDM_FORMATS, -+ }, -+ .capture = { -+ .stream_name = "Capture", -+ .channels_min = 1, -+ .channels_max = 16, -+ .rates = SNDRV_PCM_RATE_CONTINUOUS, -+ .formats = TDM_FORMATS, -+ }, -+}; -+ -+static int tdm_audio_probe(struct platform_device *pdev) -+{ -+ return snd_soc_register_codec(&pdev->dev, &soc_codec_tdm_audio, -+ &tdm_audio_dai, 1); -+} -+ -+static int tdm_audio_remove(struct platform_device *pdev) -+{ -+ snd_soc_unregister_codec(&pdev->dev); -+ return 0; -+} -+ -+#ifdef CONFIG_OF -+static const struct of_device_id tdm_audio_dt_ids[] = { -+ { .compatible = "linux,tdm-audio", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, tdm_audio_dt_ids); -+#endif -+ -+static struct platform_driver tdm_audio_driver = { -+ .probe = tdm_audio_probe, -+ .remove = tdm_audio_remove, -+ .driver = { -+ .name = DRV_NAME, -+ .of_match_table = of_match_ptr(tdm_audio_dt_ids), -+ }, -+}; -+ -+module_platform_driver(tdm_audio_driver); -+ -+MODULE_AUTHOR("Matthijs van Duin <matthijs@dutchdutch.com>"); -+MODULE_DESCRIPTION("Generic TDM codec driver"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:" DRV_NAME); -diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c -index 3c5a980..35e441c 100644 ---- a/sound/soc/davinci/davinci-mcasp.c -+++ b/sound/soc/davinci/davinci-mcasp.c -@@ -151,6 +151,8 @@ static void mcasp_set_ctl_reg(struct davinci_mcasp *mcasp, u32 ctl_reg, u32 val) - mcasp_set_bits(mcasp, ctl_reg, val); - - /* programming GBLCTL needs to read back from GBLCTL and verfiy */ -+ ctl_reg = DAVINCI_MCASP_GBLCTL_REG; -+ - /* loop count is to avoid the lock-up */ - for (i = 0; i < 1000; i++) { - if ((mcasp_get_reg(mcasp, ctl_reg) & val) == val) -@@ -572,6 +574,12 @@ static int __davinci_mcasp_set_clkdiv(struct davinci_mcasp *mcasp, int div_id, - * tdm_slot width by dividing the the ratio by the - * number of configured tdm slots. - */ -+ if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) { -+ if (div != 128) -+ dev_warn(mcasp->dev, -+ "%s(): BCLK/LRCLK %d requested, must be 128 for DIT mode", __func__, div); -+ break; -+ } - mcasp->slot_width = div / mcasp->tdm_slots; - if (div % mcasp->tdm_slots) - dev_warn(mcasp->dev, -@@ -696,56 +704,59 @@ static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai *dai, - } - - static int davinci_config_channel_size(struct davinci_mcasp *mcasp, -- int sample_width) -+ u32 sample_width) - { -- u32 fmt; -- u32 tx_rotate = (sample_width / 4) & 0x7; -- u32 mask = (1ULL << sample_width) - 1; -- u32 slot_width = sample_width; -+ u32 mask, tx_rotate, rx_rotate; -+ u32 slot_width, fmt; - - /* -- * For captured data we should not rotate, inversion and masking is -- * enoguh to get the data to the right position: -- * Format data from bus after reverse (XRBUF) -- * S16_LE: |LSB|MSB|xxx|xxx| |xxx|xxx|MSB|LSB| -- * S24_3LE: |LSB|DAT|MSB|xxx| |xxx|MSB|DAT|LSB| -- * S24_LE: |LSB|DAT|MSB|xxx| |xxx|MSB|DAT|LSB| -- * S32_LE: |LSB|DAT|DAT|MSB| |MSB|DAT|DAT|LSB| -+ * Sample data is always right-justified. Apply mask and rotate right -+ * to left-justified. For receive the steps are in reverse order (but -+ * still rotates right). - */ -- u32 rx_rotate = 0; -+ mask = GENMASK(sample_width, 0); -+ mcasp_set_reg(mcasp, DAVINCI_MCASP_TXMASK_REG, mask); -+ mcasp_set_reg(mcasp, DAVINCI_MCASP_RXMASK_REG, mask); -+ -+ tx_rotate = sample_width; -+ rx_rotate = -sample_width; - - /* -- * Setting the tdm slot width either with set_clkdiv() or -- * set_tdm_slot() allows us to for example send 32 bits per -- * channel to the codec, while only 16 of them carry audio -- * payload. -+ * For big-endian formats (everything except DIT), McASP needs the slot -+ * data to be left-aligned for transmit, whereas received slot data is -+ * delivered right-aligned: -+ * -+ * +-----------------------------------------------+---------------+ -+ * <--shift-out- slot data | | -+ * +-----------------------------------------------+---------------+ -+ * -+ * +---------------+-----------------------------------------------+ -+ * | | slot data <--shift-in-- -+ * +---------------+-----------------------------------------------+ -+ * -+ * For little-endian formats (DIT only) the reverse is true. - */ -- if (mcasp->slot_width) { -- /* -- * When we have more bclk then it is needed for the -- * data, we need to use the rotation to move the -- * received samples to have correct alignment. -- */ -- slot_width = mcasp->slot_width; -- rx_rotate = (slot_width - sample_width) / 4; -+ if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) { -+ tx_rotate -= 24; -+ slot_width = 32; -+ fmt = 0; /* little endian */ -+ } else { -+ slot_width = mcasp->slot_width ?: sample_width; -+ rx_rotate += slot_width; -+ fmt = TXORD; /* big endian */ - } - - /* mapping of the XSSZ bit-field as described in the datasheet */ -- fmt = (slot_width >> 1) - 1; -+ fmt |= TXSSZ((slot_width >> 1) - 1); - -- if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) { -- mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt), -- RXSSZ(0x0F)); -- mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSSZ(fmt), -- TXSSZ(0x0F)); -- mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(tx_rotate), -- TXROT(7)); -- mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXROT(rx_rotate), -- RXROT(7)); -- mcasp_set_reg(mcasp, DAVINCI_MCASP_RXMASK_REG, mask); -- } -+ tx_rotate = TXROT((tx_rotate & 31) >> 2); -+ rx_rotate = TXROT((rx_rotate & 31) >> 2); - -- mcasp_set_reg(mcasp, DAVINCI_MCASP_TXMASK_REG, mask); -+ if (!mcasp->dat_port) -+ fmt |= TXSEL; -+ -+ mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, fmt | tx_rotate, 0xffff); -+ mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, fmt | rx_rotate, 0xffff); - - return 0; - } -@@ -866,7 +877,6 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream, - int total_slots; - int active_serializers; - u32 mask = 0; -- u32 busel = 0; - - total_slots = mcasp->tdm_slots; - -@@ -902,17 +912,12 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream, - } - mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC); - -- if (!mcasp->dat_port) -- busel = TXSEL; -- - if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); -- mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); - mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, - FSXMOD(total_slots), FSXMOD(0x1FF)); - } else if (stream == SNDRV_PCM_STREAM_CAPTURE) { - mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); -- mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); - mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, - FSRMOD(total_slots), FSRMOD(0x1FF)); - /* -@@ -935,23 +940,13 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp, - u32 cs_value = 0; - u8 *cs_bytes = (u8*) &cs_value; - -- /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0 -- and LSB first */ -- mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(6) | TXSSZ(15)); -- - /* Set TX frame synch : DIT Mode, 1 bit width, internal, rising edge */ - mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE | FSXMOD(0x180)); - - /* Set the TX tdm : for all the slots */ - mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, 0xFFFFFFFF); - -- /* Set the TX clock controls : div = 1 and internal */ -- mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE | TX_ASYNC); -- -- mcasp_clr_bits(mcasp, DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS); -- -- /* Only 44100 and 48000 are valid, both have the same setting */ -- mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(3)); -+ mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC); - - /* Enable the DIT */ - mcasp_set_bits(mcasp, DAVINCI_MCASP_TXDITCTL_REG, DITEN); -@@ -1049,6 +1044,15 @@ static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp, - return error_ppm; - } - -+static uint mcasp_clocks_per_slot(struct davinci_mcasp *mcasp, uint width) -+{ -+ if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) -+ return 64; -+ if (mcasp->slot_width) -+ return mcasp->slot_width; -+ return width; -+} -+ - static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *cpu_dai) -@@ -1068,12 +1072,9 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, - * the machine driver, we need to calculate the ratio. - */ - if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) { -- int slots = mcasp->tdm_slots; -- int rate = params_rate(params); -- int sbits = params_width(params); -- -- if (mcasp->slot_width) -- sbits = mcasp->slot_width; -+ uint slots = mcasp->tdm_slots; -+ uint rate = params_rate(params); -+ uint sbits = mcasp_clocks_per_slot(mcasp, params_width(params)); - - davinci_mcasp_calc_clk_div(mcasp, rate * sbits * slots, true); - } -@@ -1103,11 +1104,13 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, - word_length = 16; - break; - -- case SNDRV_PCM_FORMAT_U24_3LE: -- case SNDRV_PCM_FORMAT_S24_3LE: -- word_length = 24; -+ case SNDRV_PCM_FORMAT_U20_3LE: -+ case SNDRV_PCM_FORMAT_S20_3LE: -+ word_length = 20; - break; - -+ case SNDRV_PCM_FORMAT_U24_3LE: -+ case SNDRV_PCM_FORMAT_S24_3LE: - case SNDRV_PCM_FORMAT_U24_LE: - case SNDRV_PCM_FORMAT_S24_LE: - word_length = 24; -@@ -1169,14 +1172,11 @@ static int davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params *params, - struct davinci_mcasp_ruledata *rd = rule->private; - struct snd_interval *ri = - hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); -- int sbits = params_width(params); -- int slots = rd->mcasp->tdm_slots; -+ uint sbits = mcasp_clocks_per_slot(rd->mcasp, params_width(params)); -+ uint slots = rd->mcasp->tdm_slots; - struct snd_interval range; - int i; - -- if (rd->mcasp->slot_width) -- sbits = rd->mcasp->slot_width; -- - snd_interval_any(&range); - range.empty = 1; - -@@ -1223,8 +1223,7 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params, - uint sbits = snd_pcm_format_width(i); - int ppm; - -- if (rd->mcasp->slot_width) -- sbits = rd->mcasp->slot_width; -+ sbits = mcasp_clocks_per_slot(rd->mcasp, sbits); - - ppm = davinci_mcasp_calc_clk_div(rd->mcasp, - sbits * slots * rate, -@@ -1834,7 +1833,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev) - - mcasp->op_mode = pdata->op_mode; - /* sanity check for tdm slots parameter */ -- if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) { -+ if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE) { -+ mcasp->tdm_slots = 2; -+ } else { - if (pdata->tdm_slots < 2) { - dev_err(&pdev->dev, "invalid tdm slots: %d\n", - pdata->tdm_slots); -diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h -index afddc80..ecc33cb 100644 ---- a/sound/soc/davinci/davinci-mcasp.h -+++ b/sound/soc/davinci/davinci-mcasp.h -@@ -82,12 +82,12 @@ - /* Serializer n Control Register */ - #define DAVINCI_MCASP_XRSRCTL_BASE_REG 0x180 - #define DAVINCI_MCASP_XRSRCTL_REG(n) (DAVINCI_MCASP_XRSRCTL_BASE_REG + \ -- (n << 2)) -+ ((n) << 2)) - - /* Transmit Buffer for Serializer n */ --#define DAVINCI_MCASP_TXBUF_REG(n) (0x200 + (n << 2)) -+#define DAVINCI_MCASP_TXBUF_REG(n) (0x200 + ((n) << 2)) - /* Receive Buffer for Serializer n */ --#define DAVINCI_MCASP_RXBUF_REG(n) (0x280 + (n << 2)) -+#define DAVINCI_MCASP_RXBUF_REG(n) (0x280 + ((n) << 2)) - - /* McASP FIFO Registers */ - #define DAVINCI_MCASP_V2_AFIFO_BASE (0x1010) -@@ -109,7 +109,7 @@ - /* - * DAVINCI_MCASP_PFUNC_REG - Pin Function / GPIO Enable Register Bits - */ --#define AXR(n) (1<<n) -+#define AXR(n) (1<<(n)) - #define PFUNC_AMUTE BIT(25) - #define ACLKX BIT(26) - #define AHCLKX BIT(27) -@@ -121,7 +121,7 @@ - /* - * DAVINCI_MCASP_PDIR_REG - Pin Direction Register Bits - */ --#define AXR(n) (1<<n) -+#define AXR(n) (1<<(n)) - #define PDIR_AMUTE BIT(25) - #define ACLKX BIT(26) - #define AHCLKX BIT(27) -@@ -142,22 +142,22 @@ - */ - #define TXROT(val) (val) - #define TXSEL BIT(3) --#define TXSSZ(val) (val<<4) --#define TXPBIT(val) (val<<8) --#define TXPAD(val) (val<<13) -+#define TXSSZ(val) ((val)<<4) -+#define TXPBIT(val) ((val)<<8) -+#define TXPAD(val) ((val)<<13) - #define TXORD BIT(15) --#define FSXDLY(val) (val<<16) -+#define FSXDLY(val) ((val)<<16) - - /* - * DAVINCI_MCASP_RXFMT_REG - Receive Bitstream Format Register Bits - */ - #define RXROT(val) (val) - #define RXSEL BIT(3) --#define RXSSZ(val) (val<<4) --#define RXPBIT(val) (val<<8) --#define RXPAD(val) (val<<13) -+#define RXSSZ(val) ((val)<<4) -+#define RXPBIT(val) ((val)<<8) -+#define RXPAD(val) ((val)<<13) - #define RXORD BIT(15) --#define FSRDLY(val) (val<<16) -+#define FSRDLY(val) ((val)<<16) - - /* - * DAVINCI_MCASP_TXFMCTL_REG - Transmit Frame Control Register Bits -@@ -165,7 +165,7 @@ - #define FSXPOL BIT(0) - #define AFSXE BIT(1) - #define FSXDUR BIT(4) --#define FSXMOD(val) (val<<7) -+#define FSXMOD(val) ((val)<<7) - - /* - * DAVINCI_MCASP_RXFMCTL_REG - Receive Frame Control Register Bits -@@ -173,7 +173,7 @@ - #define FSRPOL BIT(0) - #define AFSRE BIT(1) - #define FSRDUR BIT(4) --#define FSRMOD(val) (val<<7) -+#define FSRMOD(val) ((val)<<7) - - /* - * DAVINCI_MCASP_ACLKXCTL_REG - Transmit Clock Control Register Bits -@@ -229,17 +229,17 @@ - */ - #define LBEN BIT(0) - #define LBORD BIT(1) --#define LBGENMODE(val) (val<<2) -+#define LBGENMODE(val) ((val)<<2) - - /* - * DAVINCI_MCASP_TXTDMSLOT_REG - Transmit TDM Slot Register configuration - */ --#define TXTDMS(n) (1<<n) -+#define TXTDMS(n) (1<<(n)) - - /* - * DAVINCI_MCASP_RXTDMSLOT_REG - Receive TDM Slot Register configuration - */ --#define RXTDMS(n) (1<<n) -+#define RXTDMS(n) (1<<(n)) - - /* - * DAVINCI_MCASP_GBLCTL_REG - Global Control Register Bits diff --git a/kernels/linux-libre-lts-knock/tcp_stealth_4.9_1.diff b/kernels/linux-libre-lts-knock/tcp_stealth_4.9_1.diff deleted file mode 100644 index 40ca22975..000000000 --- a/kernels/linux-libre-lts-knock/tcp_stealth_4.9_1.diff +++ /dev/null @@ -1,642 +0,0 @@ -diff --git a/include/linux/tcp.h b/include/linux/tcp.h -index a17ae7b..e48e86f 100644 ---- a/include/linux/tcp.h -+++ b/include/linux/tcp.h -@@ -19,6 +19,7 @@ - - - #include <linux/skbuff.h> -+#include <linux/cryptohash.h> - #include <linux/win_minmax.h> - #include <net/sock.h> - #include <net/inet_connection_sock.h> -@@ -353,6 +354,21 @@ struct tcp_sock { - struct tcp_md5sig_info __rcu *md5sig_info; - #endif - -+#ifdef CONFIG_TCP_STEALTH -+/* Stealth TCP socket configuration */ -+ struct { -+ #define TCP_STEALTH_MODE_AUTH BIT(0) -+ #define TCP_STEALTH_MODE_INTEGRITY BIT(1) -+ #define TCP_STEALTH_MODE_INTEGRITY_LEN BIT(2) -+ u8 mode; -+ u8 secret[MD5_MESSAGE_BYTES]; -+ u16 integrity_hash; -+ size_t integrity_len; -+ struct skb_mstamp mstamp; -+ bool saw_tsval; -+ } stealth; -+#endif -+ - /* TCP fastopen related information */ - struct tcp_fastopen_request *fastopen_req; - /* fastopen_rsk points to request_sock that resulted in this big -diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h -index 3f36d45..ec392a1 100644 ---- a/include/net/secure_seq.h -+++ b/include/net/secure_seq.h -@@ -14,5 +14,10 @@ u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, - __be16 sport, __be16 dport); - u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, - __be16 sport, __be16 dport); -+#ifdef CONFIG_TCP_STEALTH -+u32 tcp_stealth_do_auth(struct sock *sk, struct sk_buff *skb); -+u32 tcp_stealth_sequence_number(struct sock *sk, __be32 *daddr, -+ u32 daddr_size, __be16 dport); -+#endif - - #endif /* _NET_SECURE_SEQ */ -diff --git a/include/net/tcp.h b/include/net/tcp.h -index 123979f..f7a0d7c 100644 ---- a/include/net/tcp.h -+++ b/include/net/tcp.h -@@ -429,6 +429,12 @@ void tcp_parse_options(const struct sk_buff *skb, - struct tcp_options_received *opt_rx, - int estab, struct tcp_fastopen_cookie *foc); - const u8 *tcp_parse_md5sig_option(const struct tcphdr *th); -+#ifdef CONFIG_TCP_STEALTH -+const bool tcp_parse_tsval_option(u32 *tsval, const struct tcphdr *th); -+int tcp_stealth_integrity(u16 *hash, u8 *secret, u8 *payload, int len); -+#define be32_isn_to_be16_av(x) (((__be16 *)&x)[0]) -+#define be32_isn_to_be16_ih(x) (((__be16 *)&x)[1]) -+#endif - - /* - * TCP v4 functions exported for the inet6 API -diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h -index 73ac0db..d2a35e9 100644 ---- a/include/uapi/linux/tcp.h -+++ b/include/uapi/linux/tcp.h -@@ -116,6 +116,9 @@ enum { - #define TCP_SAVE_SYN 27 /* Record SYN headers for new connections */ - #define TCP_SAVED_SYN 28 /* Get SYN headers recorded for connection */ - #define TCP_REPAIR_WINDOW 29 /* Get/set window parameters */ -+#define TCP_STEALTH 30 -+#define TCP_STEALTH_INTEGRITY 31 -+#define TCP_STEALTH_INTEGRITY_LEN 32 - - struct tcp_repair_opt { - __u32 opt_code; -diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c -index fd3ce46..2d49cee 100644 ---- a/net/core/secure_seq.c -+++ b/net/core/secure_seq.c -@@ -8,7 +8,11 @@ - #include <linux/ktime.h> - #include <linux/string.h> - #include <linux/net.h> -+#include <linux/socket.h> -+#include <linux/ip.h> -+#include <linux/ipv6.h> - -+#include <net/tcp.h> - #include <net/secure_seq.h> - - #if IS_ENABLED(CONFIG_IPV6) || IS_ENABLED(CONFIG_INET) -@@ -39,6 +43,102 @@ static u32 seq_scale(u32 seq) - } - #endif - -+#ifdef CONFIG_TCP_STEALTH -+u32 tcp_stealth_sequence_number(struct sock *sk, __be32 *daddr, -+ u32 daddr_size, __be16 dport) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct tcp_md5sig_key *md5; -+ -+ __u32 sec[MD5_MESSAGE_BYTES / sizeof(__u32)]; -+ __u32 i; -+ __u32 tsval = 0; -+ -+ __be32 iv[MD5_DIGEST_WORDS] = { 0 }; -+ __be32 isn; -+ -+ memcpy(iv, daddr, (daddr_size > sizeof(iv)) ? sizeof(iv) : daddr_size); -+ -+#ifdef CONFIG_TCP_MD5SIG -+ md5 = tp->af_specific->md5_lookup(sk, sk); -+#else -+ md5 = NULL; -+#endif -+ if (likely(sysctl_tcp_timestamps && !md5) || tp->stealth.saw_tsval) -+ tsval = tp->stealth.mstamp.stamp_jiffies; -+ -+ ((__be16 *)iv)[2] ^= cpu_to_be16(tp->stealth.integrity_hash); -+ iv[2] ^= cpu_to_be32(tsval); -+ ((__be16 *)iv)[6] ^= dport; -+ -+ for (i = 0; i < MD5_DIGEST_WORDS; i++) -+ iv[i] = le32_to_cpu(iv[i]); -+ for (i = 0; i < MD5_MESSAGE_BYTES / sizeof(__le32); i++) -+ sec[i] = le32_to_cpu(((__le32 *)tp->stealth.secret)[i]); -+ -+ md5_transform(iv, sec); -+ -+ isn = cpu_to_be32(iv[0]) ^ cpu_to_be32(iv[1]) ^ -+ cpu_to_be32(iv[2]) ^ cpu_to_be32(iv[3]); -+ -+ if (tp->stealth.mode & TCP_STEALTH_MODE_INTEGRITY) -+ be32_isn_to_be16_ih(isn) = -+ cpu_to_be16(tp->stealth.integrity_hash); -+ -+ return be32_to_cpu(isn); -+} -+EXPORT_SYMBOL(tcp_stealth_sequence_number); -+ -+u32 tcp_stealth_do_auth(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct tcphdr *th = tcp_hdr(skb); -+ __be32 isn = th->seq; -+ __be32 hash; -+ __be32 *daddr; -+ u32 daddr_size; -+ -+ tp->stealth.saw_tsval = -+ tcp_parse_tsval_option(&tp->stealth.mstamp.stamp_jiffies, th); -+ -+ if (tp->stealth.mode & TCP_STEALTH_MODE_INTEGRITY_LEN) -+ tp->stealth.integrity_hash = -+ be16_to_cpu(be32_isn_to_be16_ih(isn)); -+ -+ switch (tp->inet_conn.icsk_inet.sk.sk_family) { -+#if IS_ENABLED(CONFIG_IPV6) -+ case PF_INET6: -+ daddr_size = sizeof(ipv6_hdr(skb)->daddr.s6_addr32); -+ daddr = ipv6_hdr(skb)->daddr.s6_addr32; -+ break; -+#endif -+ case PF_INET: -+ daddr_size = sizeof(ip_hdr(skb)->daddr); -+ daddr = &ip_hdr(skb)->daddr; -+ break; -+ default: -+ pr_err("TCP Stealth: Unknown network layer protocol, stop!\n"); -+ return 1; -+ } -+ -+ hash = tcp_stealth_sequence_number(sk, daddr, daddr_size, th->dest); -+ cpu_to_be32s(&hash); -+ -+ if (tp->stealth.mode & TCP_STEALTH_MODE_AUTH && -+ tp->stealth.mode & TCP_STEALTH_MODE_INTEGRITY_LEN && -+ be32_isn_to_be16_av(isn) == be32_isn_to_be16_av(hash)) -+ return 0; -+ -+ if (tp->stealth.mode & TCP_STEALTH_MODE_AUTH && -+ !(tp->stealth.mode & TCP_STEALTH_MODE_INTEGRITY_LEN) && -+ isn == hash) -+ return 0; -+ -+ return 1; -+} -+EXPORT_SYMBOL(tcp_stealth_do_auth); -+#endif -+ - #if IS_ENABLED(CONFIG_IPV6) - __u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr, - __be16 sport, __be16 dport) -diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig -index b54b3ca..9ec6794 100644 ---- a/net/ipv4/Kconfig -+++ b/net/ipv4/Kconfig -@@ -728,3 +728,13 @@ config TCP_MD5SIG - on the Internet. - - If unsure, say N. -+ -+config TCP_STEALTH -+ bool "TCP: Stealth TCP socket support" -+ default n -+ ---help--- -+ This option enables support for stealth TCP sockets. If you do not -+ know what this means, you do not need it. -+ -+ If unsure, say N. -+ -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index 814af89..c9f2ba5 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -269,6 +269,7 @@ - #include <linux/err.h> - #include <linux/time.h> - #include <linux/slab.h> -+#include <linux/vmalloc.h> - - #include <net/icmp.h> - #include <net/inet_common.h> -@@ -2386,6 +2387,49 @@ static int tcp_repair_options_est(struct tcp_sock *tp, - return 0; - } - -+#ifdef CONFIG_TCP_STEALTH -+int tcp_stealth_integrity(__be16 *hash, u8 *secret, u8 *payload, int len) -+{ -+ struct scatterlist sg[2]; -+ struct crypto_ahash *tfm; -+ struct ahash_request *req; -+ __be16 h[MD5_DIGEST_WORDS * 2]; -+ int i; -+ int err = 0; -+ -+ tfm = crypto_alloc_ahash("md5", 0, CRYPTO_ALG_ASYNC); -+ if (IS_ERR(tfm)) { -+ err = -PTR_ERR(tfm); -+ goto out; -+ } -+ req = ahash_request_alloc(tfm, GFP_ATOMIC); -+ if (!req) -+ err = -EFAULT; -+ goto out; -+ -+ sg_init_table(sg, 2); -+ sg_set_buf(&sg[0], secret, MD5_MESSAGE_BYTES); -+ sg_set_buf(&sg[1], payload, len); -+ -+ ahash_request_set_callback(req, 0, NULL, NULL); -+ ahash_request_set_crypt(req, sg, (u8 *)h, MD5_MESSAGE_BYTES + len); -+ -+ if (crypto_ahash_digest(req)) { -+ err = -EFAULT; -+ goto out; -+ } -+ -+ *hash = be16_to_cpu(h[0]); -+ for (i = 1; i < MD5_DIGEST_WORDS * 2; i++) -+ *hash ^= be16_to_cpu(h[i]); -+ -+out: -+ ahash_request_free(req); -+ crypto_free_ahash(tfm); -+ return err; -+} -+#endif -+ - /* - * Socket option code for TCP. - */ -@@ -2417,6 +2461,66 @@ static int do_tcp_setsockopt(struct sock *sk, int level, - release_sock(sk); - return err; - } -+#ifdef CONFIG_TCP_STEALTH -+ case TCP_STEALTH: { -+ u8 secret[MD5_MESSAGE_BYTES] = { 0 }; -+ -+ val = copy_from_user(secret, optval, -+ min_t(unsigned int, optlen, -+ MD5_MESSAGE_BYTES)); -+ if (val != 0) -+ return -EFAULT; -+ -+ lock_sock(sk); -+ memcpy(tp->stealth.secret, secret, MD5_MESSAGE_BYTES); -+ tp->stealth.mode = TCP_STEALTH_MODE_AUTH; -+ tp->stealth.mstamp.v64 = 0; -+ tp->stealth.saw_tsval = false; -+ release_sock(sk); -+ return err; -+ } -+ case TCP_STEALTH_INTEGRITY: { -+ u8 *payload; -+ -+ lock_sock(sk); -+ -+ if (!(tp->stealth.mode & TCP_STEALTH_MODE_AUTH)) { -+ err = -EOPNOTSUPP; -+ goto stealth_integrity_out_1; -+ } -+ -+ if (optlen < 1 || optlen > USHRT_MAX) { -+ err = -EINVAL; -+ goto stealth_integrity_out_1; -+ } -+ -+ payload = vmalloc(optlen); -+ if (!payload) { -+ err = -ENOMEM; -+ goto stealth_integrity_out_1; -+ } -+ -+ val = copy_from_user(payload, optval, optlen); -+ if (val != 0) { -+ err = -EFAULT; -+ goto stealth_integrity_out_2; -+ } -+ -+ err = tcp_stealth_integrity(&tp->stealth.integrity_hash, -+ tp->stealth.secret, payload, -+ optlen); -+ if (err) -+ goto stealth_integrity_out_2; -+ -+ tp->stealth.mode |= TCP_STEALTH_MODE_INTEGRITY; -+ -+stealth_integrity_out_2: -+ vfree(payload); -+stealth_integrity_out_1: -+ release_sock(sk); -+ return err; -+ } -+#endif - default: - /* fallthru */ - break; -@@ -2671,6 +2775,18 @@ static int do_tcp_setsockopt(struct sock *sk, int level, - tp->notsent_lowat = val; - sk->sk_write_space(sk); - break; -+#ifdef CONFIG_TCP_STEALTH -+ case TCP_STEALTH_INTEGRITY_LEN: -+ if (!(tp->stealth.mode & TCP_STEALTH_MODE_AUTH)) { -+ err = -EOPNOTSUPP; -+ } else if (val < 1 || val > USHRT_MAX) { -+ err = -EINVAL; -+ } else { -+ tp->stealth.integrity_len = val; -+ tp->stealth.mode |= TCP_STEALTH_MODE_INTEGRITY_LEN; -+ } -+ break; -+#endif - default: - err = -ENOPROTOOPT; - break; -diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c -index c71d49c..24f6d73 100644 ---- a/net/ipv4/tcp_input.c -+++ b/net/ipv4/tcp_input.c -@@ -77,6 +77,9 @@ - #include <linux/errqueue.h> - - int sysctl_tcp_timestamps __read_mostly = 1; -+#ifdef CONFIG_TCP_STEALTH -+EXPORT_SYMBOL(sysctl_tcp_timestamps); -+#endif - int sysctl_tcp_window_scaling __read_mostly = 1; - int sysctl_tcp_sack __read_mostly = 1; - int sysctl_tcp_fack __read_mostly = 1; -@@ -3926,6 +3929,47 @@ static bool tcp_fast_parse_options(const struct sk_buff *skb, - return true; - } - -+#ifdef CONFIG_TCP_STEALTH -+/* Parse only the TSVal field of the TCP Timestamp option header. -+ */ -+const bool tcp_parse_tsval_option(u32 *tsval, const struct tcphdr *th) -+{ -+ int length = (th->doff << 2) - sizeof(*th); -+ const u8 *ptr = (const u8 *)(th + 1); -+ -+ /* If the TCP option is too short, we can short cut */ -+ if (length < TCPOLEN_TIMESTAMP) -+ return false; -+ -+ while (length > 0) { -+ int opcode = *ptr++; -+ int opsize; -+ -+ switch (opcode) { -+ case TCPOPT_EOL: -+ return false; -+ case TCPOPT_NOP: -+ length--; -+ continue; -+ case TCPOPT_TIMESTAMP: -+ opsize = *ptr++; -+ if (opsize != TCPOLEN_TIMESTAMP || opsize > length) -+ return false; -+ *tsval = get_unaligned_be32(ptr); -+ return true; -+ default: -+ opsize = *ptr++; -+ if (opsize < 2 || opsize > length) -+ return false; -+ } -+ ptr += opsize - 2; -+ length -= opsize; -+ } -+ return false; -+} -+EXPORT_SYMBOL(tcp_parse_tsval_option); -+#endif -+ - #ifdef CONFIG_TCP_MD5SIG - /* - * Parse MD5 Signature option -@@ -4631,6 +4675,31 @@ err: - - } - -+#ifdef CONFIG_TCP_STEALTH -+static int __tcp_stealth_integrity_check(struct sock *sk, struct sk_buff *skb) -+{ -+ struct tcphdr *th = tcp_hdr(skb); -+ struct tcp_sock *tp = tcp_sk(sk); -+ u16 hash; -+ __be32 seq = cpu_to_be32(TCP_SKB_CB(skb)->seq - 1); -+ char *data = skb->data + th->doff * 4; -+ int len = skb->len - th->doff * 4; -+ -+ if (len < tp->stealth.integrity_len) -+ return 1; -+ -+ if (tcp_stealth_integrity(&hash, tp->stealth.secret, data, -+ tp->stealth.integrity_len)) -+ return 1; -+ -+ if (be32_isn_to_be16_ih(seq) != cpu_to_be16(hash)) -+ return 1; -+ -+ tp->stealth.mode &= ~TCP_STEALTH_MODE_INTEGRITY_LEN; -+ return 0; -+} -+#endif -+ - static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) - { - struct tcp_sock *tp = tcp_sk(sk); -@@ -4641,6 +4710,15 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) - __kfree_skb(skb); - return; - } -+ -+#ifdef CONFIG_TCP_STEALTH -+ if (unlikely(tp->stealth.mode & TCP_STEALTH_MODE_INTEGRITY_LEN) && -+ __tcp_stealth_integrity_check(sk, skb)) { -+ tcp_reset(sk); -+ goto drop; -+ } -+#endif -+ - skb_dst_drop(skb); - __skb_pull(skb, tcp_hdr(skb)->doff * 4); - -@@ -5456,6 +5534,15 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb, - int eaten = 0; - bool fragstolen = false; - -+#ifdef CONFIG_TCP_STEALTH -+ if (unlikely(tp->stealth.mode & -+ TCP_STEALTH_MODE_INTEGRITY_LEN) && -+ __tcp_stealth_integrity_check(sk, skb)) { -+ tcp_reset(sk); -+ goto discard; -+ } -+#endif -+ - if (tp->ucopy.task == current && - tp->copied_seq == tp->rcv_nxt && - len - tcp_header_len <= tp->ucopy.len && -diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c -index 2259114..542da7a 100644 ---- a/net/ipv4/tcp_ipv4.c -+++ b/net/ipv4/tcp_ipv4.c -@@ -74,6 +74,7 @@ - #include <net/xfrm.h> - #include <net/secure_seq.h> - #include <net/busy_poll.h> -+#include <net/secure_seq.h> - - #include <linux/inet.h> - #include <linux/ipv6.h> -@@ -233,6 +234,21 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) - sk->sk_gso_type = SKB_GSO_TCPV4; - sk_setup_caps(sk, &rt->dst); - -+#ifdef CONFIG_TCP_STEALTH -+ /* If CONFIG_TCP_STEALTH is defined, we need to know the timestamp as -+ * early as possible and thus move taking the snapshot of tcp_time_stamp -+ * here. -+ */ -+ skb_mstamp_get(&tp->stealth.mstamp); -+ -+ if (!tp->write_seq && likely(!tp->repair) && -+ unlikely(tp->stealth.mode & TCP_STEALTH_MODE_AUTH)) -+ tp->write_seq = tcp_stealth_sequence_number(sk, -+ &inet->inet_daddr, -+ sizeof(inet->inet_daddr), -+ usin->sin_port); -+#endif -+ - if (!tp->write_seq && likely(!tp->repair)) - tp->write_seq = secure_tcp_sequence_number(inet->inet_saddr, - inet->inet_daddr, -@@ -1382,6 +1398,8 @@ static struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb) - */ - int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) - { -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct tcphdr *th = tcp_hdr(skb); - struct sock *rsk; - - if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ -@@ -1403,6 +1421,15 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) - if (tcp_checksum_complete(skb)) - goto csum_err; - -+#ifdef CONFIG_TCP_STEALTH -+ if (sk->sk_state == TCP_LISTEN && th->syn && !th->fin && -+ unlikely(tp->stealth.mode & TCP_STEALTH_MODE_AUTH) && -+ tcp_stealth_do_auth(sk, skb)) { -+ rsk = sk; -+ goto reset; -+ } -+#endif -+ - if (sk->sk_state == TCP_LISTEN) { - struct sock *nsk = tcp_v4_cookie_check(sk, skb); - -diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c -index 896e9df..7bf3142 100644 ---- a/net/ipv4/tcp_output.c -+++ b/net/ipv4/tcp_output.c -@@ -939,6 +939,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, - tcb = TCP_SKB_CB(skb); - memset(&opts, 0, sizeof(opts)); - -+#ifdef TCP_STEALTH -+ if (unlikely(tcb->tcp_flags & TCPHDR_SYN && -+ tp->stealth.mode & TCP_STEALTH_MODE_AUTH)) { -+ skb->skb_mstamp = tp->stealth.mstamp; -+ } -+#endif -+ - if (unlikely(tcb->tcp_flags & TCPHDR_SYN)) - tcp_options_size = tcp_syn_options(sk, skb, &opts, &md5); - else -@@ -3349,7 +3356,15 @@ int tcp_connect(struct sock *sk) - return -ENOBUFS; - - tcp_init_nondata_skb(buff, tp->write_seq++, TCPHDR_SYN); -+#ifdef CONFIG_TCP_STEALTH -+ /* The timetamp was already made at the time the ISN was generated -+ * as we need to know its value in the stealth_tcp_sequence_number() -+ * function. -+ */ -+ tp->retrans_stamp = tp->stealth.mstamp.stamp_jiffies; -+#else - tp->retrans_stamp = tcp_time_stamp; -+#endif - tcp_connect_queue_skb(sk, buff); - tcp_ecn_send_syn(sk, buff); - -diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c -index b9f1fee..b301a49 100644 ---- a/net/ipv6/tcp_ipv6.c -+++ b/net/ipv6/tcp_ipv6.c -@@ -62,6 +62,7 @@ - #include <net/inet_common.h> - #include <net/secure_seq.h> - #include <net/busy_poll.h> -+#include <net/secure_seq.h> - - #include <linux/proc_fs.h> - #include <linux/seq_file.h> -@@ -278,6 +279,21 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, - - sk_set_txhash(sk); - -+#ifdef CONFIG_TCP_STEALTH -+ /* If CONFIG_TCP_STEALTH is defined, we need to know the timestamp as -+ * early as possible and thus move taking the snapshot of tcp_time_stamp -+ * here. -+ */ -+ skb_mstamp_get(&tp->stealth.mstamp); -+ -+ if (!tp->write_seq && likely(!tp->repair) && -+ unlikely(tp->stealth.mode & TCP_STEALTH_MODE_AUTH)) -+ tp->write_seq = tcp_stealth_sequence_number(sk, -+ sk->sk_v6_daddr.s6_addr32, -+ sizeof(sk->sk_v6_daddr), -+ inet->inet_dport); -+#endif -+ - if (!tp->write_seq && likely(!tp->repair)) - tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32, - sk->sk_v6_daddr.s6_addr32, -@@ -1215,7 +1231,8 @@ static void tcp_v6_restore_cb(struct sk_buff *skb) - static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) - { - struct ipv6_pinfo *np = inet6_sk(sk); -- struct tcp_sock *tp; -+ struct tcp_sock *tp = tcp_sk(sk); -+ struct tcphdr *th = tcp_hdr(skb); - struct sk_buff *opt_skb = NULL; - - /* Imagine: socket is IPv6. IPv4 packet arrives, -@@ -1275,6 +1292,13 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) - if (tcp_checksum_complete(skb)) - goto csum_err; - -+#ifdef CONFIG_TCP_STEALTH -+ if (sk->sk_state == TCP_LISTEN && th->syn && !th->fin && -+ tp->stealth.mode & TCP_STEALTH_MODE_AUTH && -+ tcp_stealth_do_auth(sk, skb)) -+ goto reset; -+#endif -+ - if (sk->sk_state == TCP_LISTEN) { - struct sock *nsk = tcp_v6_cookie_check(sk, skb); - diff --git a/pcr/openrc-security/PKGBUILD b/pcr/openrc-security/PKGBUILD index 044b522e6..0cda35e80 100644 --- a/pcr/openrc-security/PKGBUILD +++ b/pcr/openrc-security/PKGBUILD @@ -14,13 +14,12 @@ pkgname=('apparmor-openrc' 'shorewall-openrc' 'shorewall6-openrc' 'firewalld-openrc') -pkgver=20170927 +pkgver=20171031 pkgrel=1 pkgdesc="OpenRC init scripts" arch=('any') url="https://github.com/manjaro/packages-openrc" license=('GPL2') -# groups=('openrc-base' 'base-nosystemd') groups=('openrc-security') conflicts=('systemd-sysvcompat') source=("iptables.confd::${_url}/net-firewall/iptables/files/iptables-1.4.13.confd" @@ -83,7 +82,7 @@ package_firewalld-openrc() { install=firewalld.install _inst_initd 'firewalld' - sed -e 's|/usr/sbin|/usr/bin|g' + sed -e 's|/usr/sbin|/usr/bin|g' -i ${pkgdir}/etc/init.d/firewalld } package_apparmor-openrc() { @@ -110,5 +109,5 @@ package_shorewall6-openrc() { _inst_initd 'shorewall6' _inst_confd 'shorewall6' - sed -e 's|/usr/sbin|/usr/bin|g' + sed -e 's|/usr/sbin|/usr/bin|g' -i ${pkgdir}/etc/init.d/shorewall6 } |